PLT-5499 Indicate start of new messages in posts list (#279)
* Indicate start of new messages in posts list * Use flag prop to indicate start of new messages in posts list * Declare style props with View.propTypes.style
This commit is contained in:
parent
584096aea8
commit
0bf26e95b0
8 changed files with 87 additions and 9 deletions
|
|
@ -91,7 +91,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
|||
|
||||
export default class Post extends React.Component {
|
||||
static propTypes = {
|
||||
style: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.number]),
|
||||
style: View.propTypes.style,
|
||||
post: React.PropTypes.object.isRequired,
|
||||
user: React.PropTypes.object,
|
||||
displayName: React.PropTypes.string,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export default class DateHeader extends React.Component {
|
|||
static propTypes = {
|
||||
date: React.PropTypes.object.isRequired,
|
||||
theme: React.PropTypes.object.isRequired,
|
||||
style: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.number])
|
||||
style: View.propTypes.style
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
|
|||
50
app/components/post_list/new_messages_divider.js
Normal file
50
app/components/post_list/new_messages_divider.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
textContainer: {
|
||||
marginHorizontal: 15
|
||||
},
|
||||
line: {
|
||||
flex: 1,
|
||||
height: 1,
|
||||
backgroundColor: '#ffaf53',
|
||||
opacity: 0.2
|
||||
},
|
||||
text: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#ffaf53'
|
||||
}
|
||||
});
|
||||
|
||||
function NewMessagesDivider(props) {
|
||||
return (
|
||||
<View style={[style.container, props.style]}>
|
||||
<View style={style.line}/>
|
||||
<View style={style.textContainer}>
|
||||
<FormattedText
|
||||
id='post_list.newMsg'
|
||||
defaultMessage='New Messages'
|
||||
style={style.text}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.line}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
NewMessagesDivider.propTypes = {
|
||||
style: View.propTypes.style
|
||||
};
|
||||
|
||||
export default NewMessagesDivider;
|
||||
|
|
@ -9,9 +9,11 @@ import {
|
|||
|
||||
import Post from 'app/components/post';
|
||||
|
||||
import {Constants} from 'service/constants';
|
||||
import {addDatesToPostList} from 'service/utils/post_utils';
|
||||
|
||||
import DateHeader from './date_header';
|
||||
import NewMessagesDivider from './new_messages_divider';
|
||||
|
||||
const style = StyleSheet.create({
|
||||
container: {
|
||||
|
|
@ -27,24 +29,28 @@ export default class PostList extends React.Component {
|
|||
posts: React.PropTypes.array.isRequired,
|
||||
theme: React.PropTypes.object.isRequired,
|
||||
onPostPress: React.PropTypes.func,
|
||||
renderReplies: React.PropTypes.bool
|
||||
renderReplies: React.PropTypes.bool,
|
||||
indicateNewMessages: React.PropTypes.bool,
|
||||
lastViewedAt: React.PropTypes.number
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {posts, indicateNewMessages, lastViewedAt} = this.props;
|
||||
this.state = {
|
||||
dataSource: new ListView.DataSource({
|
||||
rowHasChanged: (a, b) => a !== b
|
||||
}).cloneWithRows(addDatesToPostList(this.props.posts))
|
||||
}).cloneWithRows(addDatesToPostList(posts, indicateNewMessages, lastViewedAt))
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.posts !== this.props.posts) {
|
||||
this.setState({
|
||||
dataSource: this.state.dataSource.cloneWithRows(addDatesToPostList(nextProps.posts))
|
||||
});
|
||||
const {posts, indicateNewMessages, lastViewedAt} = nextProps;
|
||||
const dataSource = this.state.dataSource.cloneWithRows(
|
||||
addDatesToPostList(posts, indicateNewMessages, lastViewedAt)
|
||||
);
|
||||
this.setState({dataSource});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +58,14 @@ export default class PostList extends React.Component {
|
|||
if (row instanceof Date) {
|
||||
return this.renderDateHeader(row);
|
||||
}
|
||||
if (row === Constants.START_OF_NEW_MESSAGES) {
|
||||
return (
|
||||
<NewMessagesDivider
|
||||
theme={this.props.theme}
|
||||
style={style.row}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderPost(row);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export default class ChannelPostList extends PureComponent {
|
|||
goToThread: PropTypes.func.isRequired
|
||||
}).isRequired,
|
||||
channel: PropTypes.object.isRequired,
|
||||
myMember: PropTypes.object.isRequired,
|
||||
posts: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
|
|
@ -39,6 +40,8 @@ export default class ChannelPostList extends PureComponent {
|
|||
posts={this.props.posts}
|
||||
onPostPress={this.goToThread}
|
||||
renderReplies={true}
|
||||
indicateNewMessages={true}
|
||||
lastViewedAt={this.props.myMember.last_viewed_at}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ const getPostsInCurrentChannelWithReplyProps = createSelector(
|
|||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
...ownProps,
|
||||
myMember: state.entities.channels.myMembers[ownProps.channel.id],
|
||||
posts: getPostsInCurrentChannelWithReplyProps(state)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ const Constants = {
|
|||
DISPLAY_PREFER_NICKNAME: 'nickname_full_name',
|
||||
DISPLAY_PREFER_FULL_NAME: 'full_name',
|
||||
|
||||
START_OF_NEW_MESSAGES: 'start-of-new-messages',
|
||||
|
||||
POST_HEADER_CHANGE: 'system_header_change',
|
||||
POST_PURPOSE_CHANGE: 'system_purpose_change'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ export function isSystemMessage(post) {
|
|||
return post.type && post.type.startsWith(Constants.SYSTEM_MESSAGE_PREFIX);
|
||||
}
|
||||
|
||||
export function addDatesToPostList(posts) {
|
||||
export function addDatesToPostList(posts, indicateNewMessages, lastViewedAt) {
|
||||
const out = [];
|
||||
|
||||
let lastDate = null;
|
||||
let subsequentPostIsUnread = false;
|
||||
let postIsUnread;
|
||||
for (const post of posts) {
|
||||
const postDate = new Date(post.create_at);
|
||||
|
||||
|
|
@ -21,6 +23,12 @@ export function addDatesToPostList(posts) {
|
|||
|
||||
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