Unread separator and Date separator (#154)
This commit is contained in:
parent
0636fd0266
commit
d3acc17fc1
|
@ -75,7 +75,7 @@ export default class MessageActions extends React.Component {
|
|||
};
|
||||
this.handleActionPress = this.handleActionPress.bind(this);
|
||||
this.options = [''];
|
||||
const { roles } = this.props.room[0];
|
||||
const { roles } = this.props.room;
|
||||
const roomRoles = Array.from(Object.keys(roles), i => roles[i].value);
|
||||
const userRoles = this.props.user.roles || [];
|
||||
this.mergedRoles = [...new Set([...roomRoles, ...userRoles])];
|
||||
|
@ -142,7 +142,7 @@ export default class MessageActions extends React.Component {
|
|||
let msg = `[ ](${ nextProps.permalink }) `;
|
||||
|
||||
// if original message wasn't sent by current user and neither from a direct room
|
||||
if (this.props.user.username !== this.props.actionMessage.u.username && this.props.room[0].t !== 'd') {
|
||||
if (this.props.user.username !== this.props.actionMessage.u.username && this.props.room.t !== 'd') {
|
||||
msg += `@${ this.props.actionMessage.u.username } `;
|
||||
}
|
||||
this.props.setInput({ msg });
|
||||
|
|
|
@ -20,7 +20,6 @@ import styles from './styles';
|
|||
const avatar = { marginRight: 10 };
|
||||
const flex = { flexDirection: 'row', flex: 1 };
|
||||
|
||||
|
||||
@connect(state => ({
|
||||
message: state.messages.message,
|
||||
editing: state.messages.editing,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import React from 'react';
|
||||
import { View, StyleSheet, Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
dateSeparator: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginVertical: 5
|
||||
},
|
||||
dateSeparatorLine: {
|
||||
borderTopColor: '#eaeaea',
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
flex: 1
|
||||
},
|
||||
dateSeparatorBadge: {
|
||||
color: '#444444',
|
||||
backgroundColor: '#fff',
|
||||
fontSize: 11,
|
||||
paddingHorizontal: 10,
|
||||
transform: [{ scaleY: -1 }]
|
||||
}
|
||||
});
|
||||
|
||||
const DateSeparator = ({ ts }) => {
|
||||
const text = moment(ts).format('MMMM DD, YYYY');
|
||||
return (
|
||||
<View style={styles.dateSeparator}>
|
||||
<View style={styles.dateSeparatorLine} />
|
||||
<Text style={styles.dateSeparatorBadge}>{text}</Text>
|
||||
<View style={styles.dateSeparatorLine} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
DateSeparator.propTypes = {
|
||||
ts: PropTypes.instanceOf(Date)
|
||||
};
|
||||
|
||||
export default DateSeparator;
|
|
@ -2,6 +2,10 @@ import { ListView as OldList } from 'realm/react-native';
|
|||
import React from 'react';
|
||||
import cloneReferencedElement from 'react-clone-referenced-element';
|
||||
import { ScrollView, ListView as OldList2 } from 'react-native';
|
||||
import moment from 'moment';
|
||||
import { connect } from 'react-redux';
|
||||
import DateSeparator from './DateSeparator';
|
||||
import UnreadSeparator from './UnreadSeparator';
|
||||
|
||||
const DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
|
||||
|
||||
|
@ -15,6 +19,10 @@ export class DataSource extends OldList.DataSource {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@connect(state => ({
|
||||
lastOpen: state.room.lastOpen
|
||||
}))
|
||||
export class ListView extends OldList2 {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -92,6 +100,19 @@ export class ListView extends OldList2 {
|
|||
rowID,
|
||||
this._onRowHighlighted,
|
||||
)());
|
||||
if (rowIdx !== rowIDs.length - 1) {
|
||||
const nextRowID = rowIDs[rowIdx + 1];
|
||||
const nextData = dataSource._dataBlob[sectionID][nextRowID];
|
||||
if (!moment(data.ts).isSame(nextData.ts, 'day')) {
|
||||
bodyComponents.push(<DateSeparator key={data.ts.toISOString()} ts={data.ts} />);
|
||||
}
|
||||
if (this.props.lastOpen &&
|
||||
moment(data.ts).isAfter(this.props.lastOpen) &&
|
||||
moment(nextData.ts).isBefore(this.props.lastOpen)
|
||||
) {
|
||||
bodyComponents.push(<UnreadSeparator key='unread-separator' />);
|
||||
}
|
||||
}
|
||||
// totalIndex += 1;
|
||||
rowCount += 1;
|
||||
if (rowCount === this.state.curRenderedRowsCount) {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import React from 'react';
|
||||
import { View, StyleSheet, Text } from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
firstUnread: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginVertical: 5
|
||||
},
|
||||
firstUnreadLine: {
|
||||
borderTopColor: 'red',
|
||||
borderTopWidth: StyleSheet.hairlineWidth,
|
||||
flex: 1
|
||||
},
|
||||
firstUnreadBadge: {
|
||||
color: 'red',
|
||||
backgroundColor: '#fff',
|
||||
fontSize: 11,
|
||||
paddingHorizontal: 10,
|
||||
transform: [{ scaleY: -1 }]
|
||||
}
|
||||
});
|
||||
|
||||
const UnreadSeparator = () => (
|
||||
<View style={styles.firstUnread}>
|
||||
<View style={styles.firstUnreadLine} />
|
||||
<Text style={styles.firstUnreadBadge}>unread messages</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default UnreadSeparator;
|
|
@ -7,7 +7,7 @@ import equal from 'deep-equal';
|
|||
|
||||
import { ListView } from './ListView';
|
||||
import * as actions from '../../actions';
|
||||
import { openRoom } from '../../actions/room';
|
||||
import { openRoom, setLastOpen } from '../../actions/room';
|
||||
import { editCancel } from '../../actions/messages';
|
||||
import database from '../../lib/realm';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
|
@ -33,20 +33,20 @@ const typing = () => <Typing />;
|
|||
Site_Url: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||
loading: state.messages.isFetching,
|
||||
user: state.login.user,
|
||||
lastOpened: state.room.lastOpen
|
||||
user: state.login.user
|
||||
}),
|
||||
dispatch => ({
|
||||
actions: bindActionCreators(actions, dispatch),
|
||||
openRoom: room => dispatch(openRoom(room)),
|
||||
editCancel: () => dispatch(editCancel())
|
||||
editCancel: () => dispatch(editCancel()),
|
||||
setLastOpen: date => dispatch(setLastOpen(date))
|
||||
})
|
||||
)
|
||||
export default class RoomView extends React.Component {
|
||||
static propTypes = {
|
||||
// lastOpened: PropTypes.instanceOf(Date),
|
||||
navigation: PropTypes.object.isRequired,
|
||||
openRoom: PropTypes.func.isRequired,
|
||||
setLastOpen: PropTypes.func.isRequired,
|
||||
user: PropTypes.object.isRequired,
|
||||
editCancel: PropTypes.func,
|
||||
rid: PropTypes.string,
|
||||
|
@ -73,7 +73,7 @@ export default class RoomView extends React.Component {
|
|||
.filtered('rid = $0', this.rid)
|
||||
.sorted('ts', true);
|
||||
const rowIds = this.data.map((row, index) => index);
|
||||
this.room = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
||||
[this.room] = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
||||
this.state = {
|
||||
dataSource: ds.cloneWithRows(this.data, rowIds),
|
||||
loaded: true,
|
||||
|
@ -85,7 +85,12 @@ export default class RoomView extends React.Component {
|
|||
this.props.navigation.setParams({
|
||||
title: this.name
|
||||
});
|
||||
this.props.openRoom({ rid: this.rid, name: this.name });
|
||||
this.props.openRoom({ rid: this.rid, name: this.name, ls: this.room.ls });
|
||||
if (this.room.alert || this.room.unread || this.room.userMentions) {
|
||||
this.props.setLastOpen(this.room.ls);
|
||||
} else {
|
||||
this.props.setLastOpen(null);
|
||||
}
|
||||
this.data.addListener(this.updateState);
|
||||
}
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
|
@ -129,7 +134,9 @@ export default class RoomView extends React.Component {
|
|||
});
|
||||
}, 50);
|
||||
|
||||
sendMessage = message => RocketChat.sendMessage(this.rid, message);
|
||||
sendMessage = message => RocketChat.sendMessage(this.rid, message).then(() => {
|
||||
this.props.setLastOpen(null);
|
||||
});
|
||||
|
||||
joinRoom = async() => {
|
||||
await RocketChat.joinRoom(this.props.rid);
|
||||
|
|
Loading…
Reference in New Issue