PLT-5605 Fix logic for indicating start of new messages (#284)
* Fix placement of new messages separator * Ignore your own posts when determining start of new messages * Cache lastViewedAt in ChannelPostList until switching channels * Increase padding around DateHeader & NewMessagesDivider * Improve styling of new messages divider line * Use async await for ChannelDrawerList.onSelectChannel * Convert DateHeader to functional component
This commit is contained in:
parent
9d9fae43d7
commit
afe09babfa
8 changed files with 60 additions and 50 deletions
|
|
@ -166,13 +166,13 @@ class ChannelDrawerList extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
onSelectChannel = (channel) => {
|
||||
onSelectChannel = async (channel) => {
|
||||
const {
|
||||
currentChannel,
|
||||
currentTeam
|
||||
} = this.props;
|
||||
|
||||
this.props.onSelectChannel(channel.id);
|
||||
await this.props.onSelectChannel(channel.id);
|
||||
this.props.actions.viewChannel(currentTeam.id, channel.id);
|
||||
this.props.actions.markChannelAsRead(channel.id, currentChannel.id);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
|
||||
import FormattedDate from 'app/components/formatted_date';
|
||||
|
|
@ -11,16 +11,16 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
return StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
height: 28
|
||||
},
|
||||
dateContainer: {
|
||||
marginLeft: 15,
|
||||
marginRight: 15
|
||||
marginHorizontal: 15
|
||||
},
|
||||
line: {
|
||||
backgroundColor: theme.centerChannelColor,
|
||||
flex: 1,
|
||||
height: StyleSheet.hairlineWidth,
|
||||
backgroundColor: theme.centerChannelColor,
|
||||
opacity: 0.2
|
||||
},
|
||||
date: {
|
||||
|
|
@ -31,31 +31,31 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
});
|
||||
});
|
||||
|
||||
export default class DateHeader extends React.Component {
|
||||
static propTypes = {
|
||||
date: React.PropTypes.object.isRequired,
|
||||
theme: React.PropTypes.object.isRequired,
|
||||
style: View.propTypes.style
|
||||
};
|
||||
function DateHeader(props) {
|
||||
const style = getStyleSheet(props.theme);
|
||||
|
||||
render() {
|
||||
const style = getStyleSheet(this.props.theme);
|
||||
|
||||
return (
|
||||
<View style={[style.container, this.props.style]}>
|
||||
<View style={style.line}/>
|
||||
<View style={style.dateContainer}>
|
||||
<FormattedDate
|
||||
style={style.date}
|
||||
value={this.props.date}
|
||||
weekday='short'
|
||||
day='2-digit'
|
||||
month='short'
|
||||
year='numeric'
|
||||
/>
|
||||
</View>
|
||||
<View style={style.line}/>
|
||||
return (
|
||||
<View style={[style.container, props.style]}>
|
||||
<View style={style.line}/>
|
||||
<View style={style.dateContainer}>
|
||||
<FormattedDate
|
||||
style={style.date}
|
||||
value={props.date}
|
||||
weekday='short'
|
||||
day='2-digit'
|
||||
month='short'
|
||||
year='numeric'
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
<View style={style.line}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
DateHeader.propTypes = {
|
||||
date: PropTypes.object.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
style: View.propTypes.style
|
||||
};
|
||||
|
||||
export default DateHeader;
|
||||
|
|
|
|||
|
|
@ -9,16 +9,16 @@ import FormattedText from 'app/components/formatted_text';
|
|||
const style = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
height: 28
|
||||
},
|
||||
textContainer: {
|
||||
marginHorizontal: 15
|
||||
},
|
||||
line: {
|
||||
flex: 1,
|
||||
height: 1,
|
||||
backgroundColor: '#ffaf53',
|
||||
opacity: 0.2
|
||||
height: StyleSheet.hairlineWidth,
|
||||
backgroundColor: '#f80'
|
||||
},
|
||||
text: {
|
||||
fontSize: 14,
|
||||
|
|
|
|||
|
|
@ -31,24 +31,25 @@ export default class PostList extends React.Component {
|
|||
onPostPress: React.PropTypes.func,
|
||||
renderReplies: React.PropTypes.bool,
|
||||
indicateNewMessages: React.PropTypes.bool,
|
||||
currentUserId: React.PropTypes.string,
|
||||
lastViewedAt: React.PropTypes.number
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const {posts, indicateNewMessages, lastViewedAt} = this.props;
|
||||
const {posts, indicateNewMessages, currentUserId, lastViewedAt} = this.props;
|
||||
this.state = {
|
||||
dataSource: new ListView.DataSource({
|
||||
rowHasChanged: (a, b) => a !== b
|
||||
}).cloneWithRows(addDatesToPostList(posts, indicateNewMessages, lastViewedAt))
|
||||
}).cloneWithRows(addDatesToPostList(posts, indicateNewMessages, currentUserId, lastViewedAt))
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.posts !== this.props.posts) {
|
||||
const {posts, indicateNewMessages, lastViewedAt} = nextProps;
|
||||
const {posts, indicateNewMessages, currentUserId, lastViewedAt} = nextProps;
|
||||
const dataSource = this.state.dataSource.cloneWithRows(
|
||||
addDatesToPostList(posts, indicateNewMessages, lastViewedAt)
|
||||
addDatesToPostList(posts, indicateNewMessages, currentUserId, lastViewedAt)
|
||||
);
|
||||
this.setState({dataSource});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,17 @@ export default class ChannelPostList extends PureComponent {
|
|||
posts: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
state = {
|
||||
lastViewedAt: this.props.myMember.last_viewed_at
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.actions.loadPostsIfNecessary(this.props.channel);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.channel.id !== nextProps.channel.id) {
|
||||
this.setState({lastViewedAt: nextProps.myMember.last_viewed_at});
|
||||
this.props.actions.loadPostsIfNecessary(nextProps.channel);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +46,8 @@ export default class ChannelPostList extends PureComponent {
|
|||
onPostPress={this.goToThread}
|
||||
renderReplies={true}
|
||||
indicateNewMessages={true}
|
||||
lastViewedAt={this.props.myMember.last_viewed_at}
|
||||
currentUserId={this.props.myMember.user_id}
|
||||
lastViewedAt={this.state.lastViewedAt}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {goToThread} from 'app/actions/navigation';
|
|||
import {loadPostsIfNecessary} from 'app/actions/views/channel';
|
||||
|
||||
import {getAllPosts, getPostsInCurrentChannel} from 'service/selectors/entities/posts';
|
||||
import {getCurrentChannelMembership} from 'service/selectors/entities/channels';
|
||||
|
||||
import ChannelPostList from './channel_post_list';
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ const getPostsInCurrentChannelWithReplyProps = createSelector(
|
|||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
...ownProps,
|
||||
myMember: state.entities.channels.myMembers[ownProps.channel.id],
|
||||
myMember: getCurrentChannelMembership(state),
|
||||
posts: getPostsInCurrentChannelWithReplyProps(state)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default class ChannelDrawer extends React.PureComponent {
|
|||
}
|
||||
|
||||
selectChannel = (id) => {
|
||||
this.props.actions.handleSelectChannel(id);
|
||||
return this.props.actions.handleSelectChannel(id);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -7,13 +7,21 @@ export function isSystemMessage(post) {
|
|||
return post.type && post.type.startsWith(Constants.SYSTEM_MESSAGE_PREFIX);
|
||||
}
|
||||
|
||||
export function addDatesToPostList(posts, indicateNewMessages, lastViewedAt) {
|
||||
export function addDatesToPostList(posts, indicateNewMessages, currentUserId, lastViewedAt) {
|
||||
const out = [];
|
||||
|
||||
let lastDate = null;
|
||||
let subsequentPostIsUnread = false;
|
||||
let subsequentPostUserId;
|
||||
let postIsUnread;
|
||||
for (const post of posts) {
|
||||
postIsUnread = post.create_at > lastViewedAt;
|
||||
if (indicateNewMessages && subsequentPostIsUnread && !postIsUnread && subsequentPostUserId !== currentUserId) {
|
||||
out.push(Constants.START_OF_NEW_MESSAGES);
|
||||
}
|
||||
subsequentPostIsUnread = postIsUnread;
|
||||
subsequentPostUserId = post.user_id;
|
||||
|
||||
const postDate = new Date(post.create_at);
|
||||
|
||||
// Push on a date header if the last post was on a different day than the current one
|
||||
|
|
@ -23,12 +31,6 @@ export function addDatesToPostList(posts, indicateNewMessages, lastViewedAt) {
|
|||
|
||||
lastDate = postDate;
|
||||
out.push(post);
|
||||
|
||||
postIsUnread = post.create_at > lastViewedAt;
|
||||
if (indicateNewMessages && subsequentPostIsUnread && !postIsUnread) {
|
||||
out.push(Constants.START_OF_NEW_MESSAGES);
|
||||
}
|
||||
subsequentPostIsUnread = postIsUnread;
|
||||
}
|
||||
|
||||
// Push on the date header for the oldest post
|
||||
|
|
|
|||
Loading…
Reference in a new issue