From 2ec5916593c74e1a16878a0a8f79d705cc458db1 Mon Sep 17 00:00:00 2001 From: Aaron Ogle Date: Fri, 19 Jan 2018 15:06:55 -0600 Subject: [PATCH 01/14] attempt to add last message --- app/lib/realm.js | 1 + app/lib/rocketchat.js | 7 +++++++ app/presentation/RoomItem.js | 6 +++++- app/views/RoomsListView/index.js | 8 ++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/lib/realm.js b/app/lib/realm.js index 17d30e26a..b67661669 100644 --- a/app/lib/realm.js +++ b/app/lib/realm.js @@ -49,6 +49,7 @@ const roomsSchema = { properties: { _id: 'string', t: 'string', + lastMessage: 'messages', _updatedAt: { type: 'date', optional: true } } }; diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index dc0bf1bd6..188178a8f 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -432,10 +432,17 @@ const RocketChat = { } return subscription; }); + database.write(() => { data.forEach(subscription => database.create('subscriptions', subscription, true)); }); + + database.write(() => { + rooms.forEach(room => + database.create('rooms', room, true)); + }); + this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false); this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false); return data; diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index d198f91fc..82bd362a0 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -52,6 +52,7 @@ export default class RoomItem extends React.PureComponent { type: PropTypes.string.isRequired, name: PropTypes.string.isRequired, _updatedAt: PropTypes.instanceOf(Date), + lastMessage: PropTypes.object, favorite: PropTypes.bool, alert: PropTypes.bool, unread: PropTypes.number, @@ -94,11 +95,13 @@ export default class RoomItem extends React.PureComponent { render() { const { - favorite, alert, unread, userMentions, name, _updatedAt + favorite, alert, unread, userMentions, name, lastMessage, _updatedAt } = this.props; const date = this.formatDate(_updatedAt); + console.log("do we have a last message?", lastMessage); + let accessibilityLabel = name; if (unread === 1) { accessibilityLabel += `, ${ unread } alert`; @@ -118,6 +121,7 @@ export default class RoomItem extends React.PureComponent { {this.icon} { name } + {lastMessage ? {lastMessage.u.username}: {lastMessage.msg} : No Message} {_updatedAt ? { date } : null} {this.renderNumber(unread, userMentions)} diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index f22926723..c1d63f6ec 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -48,6 +48,7 @@ export default class RoomsListView extends React.Component { searchText: '' }; this.data = database.objects('subscriptions').sorted('roomUpdatedAt', true); + } componentDidMount() { @@ -79,6 +80,12 @@ export default class RoomsListView extends React.Component { this.search(text); } + getLastMessage = (subscription) => { + const room = database.objects('rooms').sorted('_updatedAt', true).slice().find(({ _id }) => _id === subscription.rid); + console.log('ROOM', room); + return room.lastMessage; + } + search(text) { const searchText = text.trim(); if (searchText === '') { @@ -202,6 +209,7 @@ export default class RoomsListView extends React.Component { alert={item.alert} unread={item.unread} userMentions={item.userMentions} + lastMessage={this.getLastMessage(item)} favorite={item.f} name={item.name} _updatedAt={item.roomUpdatedAt} From f2a310531acea39b60b2852abe45385ca435696b Mon Sep 17 00:00:00 2001 From: Aaron Ogle Date: Fri, 19 Jan 2018 15:30:34 -0600 Subject: [PATCH 02/14] Adjust for another go --- app/lib/rocketchat.js | 5 +---- app/views/RoomsListView/index.js | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 188178a8f..781ed2112 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -432,13 +432,10 @@ const RocketChat = { } return subscription; }); - + database.write(() => { data.forEach(subscription => database.create('subscriptions', subscription, true)); - }); - - database.write(() => { rooms.forEach(room => database.create('rooms', room, true)); }); diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index c1d63f6ec..69f39d004 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -81,7 +81,7 @@ export default class RoomsListView extends React.Component { } getLastMessage = (subscription) => { - const room = database.objects('rooms').sorted('_updatedAt', true).slice().find(({ _id }) => _id === subscription.rid); + const [ room ] = database.objects('rooms').filtered('_id = $0', subscription.rid).slice(); console.log('ROOM', room); return room.lastMessage; } From 7fda5a528db077fb8d82bf568b9cc913bec6a717 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 14 Feb 2018 18:34:45 -0200 Subject: [PATCH 03/14] almost done, missing custom emojy yet --- app/lib/realm.js | 7 +- app/lib/rocketchat.js | 28 +++++--- app/presentation/RoomItem.js | 109 +++++++++++++++++++++---------- app/views/RoomsListView/index.js | 7 +- package-lock.json | 5 -- 5 files changed, 100 insertions(+), 56 deletions(-) diff --git a/app/lib/realm.js b/app/lib/realm.js index 7087ac26e..bca5a7a11 100644 --- a/app/lib/realm.js +++ b/app/lib/realm.js @@ -81,7 +81,8 @@ const subscriptionSchema = { // userMentions: 0, // groupMentions: 0, roomUpdatedAt: { type: 'date', optional: true }, - ro: { type: 'bool', optional: true } + ro: { type: 'bool', optional: true }, + lastMessage: { type: 'messages', optional: true } } }; @@ -135,7 +136,7 @@ const attachment = { const url = { name: 'url', properties: { - _id: 'int', + // _id: { type: 'int', optional: true }, url: { type: 'string', optional: true }, title: { type: 'string', optional: true }, description: { type: 'string', optional: true }, @@ -184,7 +185,7 @@ const messagesSchema = { groupable: { type: 'bool', optional: true }, avatar: { type: 'string', optional: true }, attachments: { type: 'list', objectType: 'attachment' }, - urls: { type: 'list', objectType: 'url' }, + urls: { type: 'list', objectType: 'url', default: [] }, _updatedAt: { type: 'date', optional: true }, status: { type: 'int', optional: true }, pinned: { type: 'bool', optional: true }, diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index d561e5e09..0e1b12119 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -92,7 +92,7 @@ const RocketChat = { reduxStore.dispatch(connectFailure()); }); - this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); + // this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); this.ddp.on('users', (ddpMessage) => { if (ddpMessage.collection === 'users') { @@ -128,11 +128,15 @@ const RocketChat = { const sub = database.objects('subscriptions').filtered('rid == $0', data._id)[0]; database.write(() => { sub.roomUpdatedAt = data._updatedAt; + if (data.lastMessage) { + // data.lastMessage.url = data.lastMessage.url || []; + } + sub.lastMessage = data.lastMessage; sub.ro = data.ro; }); } }); - }); + }).catch(console.log); }, me({ server, token, userId }) { @@ -428,6 +432,10 @@ const RocketChat = { const room = rooms.find(({ _id }) => _id === subscription.rid); if (room) { subscription.roomUpdatedAt = room._updatedAt; + // if (room.lastMessage) { + // room.lastMessage.url = room.lastMessage.url || []; + // } + subscription.lastMessage = room.lastMessage; subscription.ro = room.ro; } if (subscription.roles) { @@ -436,12 +444,16 @@ const RocketChat = { return subscription; }); - database.write(() => { - data.forEach(subscription => - database.create('subscriptions', subscription, true)); - rooms.forEach(room => - database.create('rooms', room, true)); - }); + try { + database.write(() => { + data.forEach(subscription => database.create('subscriptions', subscription, true)); + // rooms.forEach(room => database.create('rooms', room, true)); + }); + } catch (e) { + alert(JSON.stringify(e)); + } finally { + + } this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false); this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false); diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index 82bd362a0..c3b742030 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -2,6 +2,9 @@ import React from 'react'; import moment from 'moment'; import PropTypes from 'prop-types'; import { View, Text, StyleSheet } from 'react-native'; +import { emojify } from 'react-emojione'; +import { connect } from 'react-redux'; + import Avatar from '../containers/Avatar'; import Touch from '../utils/touch/index'; //eslint-disable-line @@ -9,29 +12,45 @@ const styles = StyleSheet.create({ container: { flexDirection: 'row', paddingHorizontal: 16, - paddingVertical: 10, - alignItems: 'center' + paddingVertical: 12, + alignItems: 'flex-start', + borderBottomWidth: 0.5, + borderBottomColor: '#ddd' }, number: { - minWidth: 20, - borderRadius: 3, + minWidth: 25, + borderRadius: 4, backgroundColor: '#1d74f5', color: '#fff', - textAlign: 'center', overflow: 'hidden', fontSize: 14, + paddingVertical: 4, paddingHorizontal: 5, - paddingVertical: 2 + + textAlign: 'center', + alignItems: 'center', + justifyContent: 'center' }, roomNameView: { flex: 1, + height: '100%', marginLeft: 16, marginRight: 4 }, roomName: { flex: 1, + fontSize: 18, + color: '#444', + fontWeight: 'bold', + marginRight: 8 + }, + lastMessage: { + flex: 1, + flexShrink: 1, fontSize: 16, - color: '#444' + color: '#444', + marginRight: 8 + // margin: 0 }, alert: { fontWeight: 'bold' @@ -39,14 +58,44 @@ const styles = StyleSheet.create({ favorite: { // backgroundColor: '#eee' }, - update: { + row: { + width: '100%', flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center' + }, + update: { fontSize: 10, - // height: 10, - color: '#888' + color: '#888', + alignItems: 'center', + justifyContent: 'center' } }); +const renderNumber = (unread, userMentions) => { + if (!unread || unread <= 0) { + return; + } + + if (unread >= 1000) { + unread = '999+'; + } + + if (userMentions > 0) { + unread = `@ ${ unread }`; + } + + return ( + + { unread } + + ); +}; + +@connect(state => ({ + StoreLastMessage: state.settings.Store_Last_Message +})) export default class RoomItem extends React.PureComponent { static propTypes = { type: PropTypes.string.isRequired, @@ -63,7 +112,7 @@ export default class RoomItem extends React.PureComponent { get icon() { const { type, name, baseUrl } = this.props; - return ; + return ; } formatDate = date => moment(date).calendar(null, { @@ -73,26 +122,6 @@ export default class RoomItem extends React.PureComponent { sameElse: 'MMM D' }) - renderNumber = (unread, userMentions) => { - if (!unread || unread <= 0) { - return; - } - - if (unread >= 1000) { - unread = '999+'; - } - - if (userMentions > 0) { - unread = `@ ${ unread }`; - } - - return ( - - { unread } - - ); - } - render() { const { favorite, alert, unread, userMentions, name, lastMessage, _updatedAt @@ -100,7 +129,7 @@ export default class RoomItem extends React.PureComponent { const date = this.formatDate(_updatedAt); - console.log("do we have a last message?", lastMessage); + console.log('do we have a last message?', lastMessage); let accessibilityLabel = name; if (unread === 1) { @@ -120,11 +149,19 @@ export default class RoomItem extends React.PureComponent { {this.icon} - { name } - {lastMessage ? {lastMessage.u.username}: {lastMessage.msg} : No Message} - {_updatedAt ? { date } : null} + + { name } + {_updatedAt ? { date } : null} + + + + + {!this.props.StoreLastMessage ? '' : lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'} + + + {renderNumber(unread, userMentions)} + - {this.renderNumber(unread, userMentions)} ); diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 69f39d004..7cabb4827 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -48,7 +48,6 @@ export default class RoomsListView extends React.Component { searchText: '' }; this.data = database.objects('subscriptions').sorted('roomUpdatedAt', true); - } componentDidMount() { @@ -81,9 +80,9 @@ export default class RoomsListView extends React.Component { } getLastMessage = (subscription) => { - const [ room ] = database.objects('rooms').filtered('_id = $0', subscription.rid).slice(); + const [room] = database.objects('rooms').filtered('_id = $0', subscription.rid).slice(); console.log('ROOM', room); - return room.lastMessage; + return room && room.lastMessage; } search(text) { @@ -209,8 +208,8 @@ export default class RoomsListView extends React.Component { alert={item.alert} unread={item.unread} userMentions={item.userMentions} - lastMessage={this.getLastMessage(item)} favorite={item.f} + lastMessage={item.lastMessage} name={item.name} _updatedAt={item.roomUpdatedAt} key={item._id} diff --git a/package-lock.json b/package-lock.json index 57ab9160a..a7b1330c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12573,11 +12573,6 @@ "requires": { "lodash": "4.17.4", "react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git#3a4084f0a1063e23ae6435facdf1f79152558d15" - }, - "dependencies": { - "react-native-keyboard-tracking-view": { - "version": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git#3a4084f0a1063e23ae6435facdf1f79152558d15" - } } }, "react-native-keyboard-tracking-view": { From 40cb3e536bb9d8807498de163a446f984c70e68e Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 14 Feb 2018 19:26:15 -0200 Subject: [PATCH 04/14] fix lint --- __tests__/__snapshots__/RoomItem.js.snap | 750 ++++++--- .../__snapshots__/Storyshots.test.js.snap | 1481 +++++++++++------ app/lib/rocketchat.js | 8 +- app/presentation/RoomItem.js | 23 +- app/views/RoomView/index.js | 10 +- app/views/RoomsListView/index.js | 6 +- 6 files changed, 1548 insertions(+), 730 deletions(-) diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index 23643947b..14e65d1d0 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -33,10 +33,12 @@ exports[`render channel 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -53,8 +55,8 @@ exports[`render channel 1`] = ` Object { "backgroundColor": "#00BCD4", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -75,7 +77,7 @@ exports[`render channel 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ], Object { @@ -93,44 +95,89 @@ exports[`render channel 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - general - - - Nov 10 - + + general + + + Nov 10 + + + + + + + @@ -170,10 +217,12 @@ exports[`render no icon 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -190,8 +239,8 @@ exports[`render no icon 1`] = ` Object { "backgroundColor": "#3F51B5", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -212,7 +261,7 @@ exports[`render no icon 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ], Object { @@ -230,44 +279,89 @@ exports[`render no icon 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - name - - - Nov 10 - + + name + + + Nov 10 + + + + + + + @@ -307,10 +401,12 @@ exports[`render private group 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -327,8 +423,8 @@ exports[`render private group 1`] = ` Object { "backgroundColor": "#FF9800", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -349,7 +445,7 @@ exports[`render private group 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ], Object { @@ -367,44 +463,89 @@ exports[`render private group 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - private-group - - - Nov 10 - + + private-group + + + Nov 10 + + + + + + + @@ -445,10 +586,12 @@ exports[`render unread +999 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -465,8 +608,8 @@ exports[`render unread +999 1`] = ` Object { "backgroundColor": "#3F51B5", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -482,7 +625,7 @@ exports[`render unread +999 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -495,65 +638,112 @@ exports[`render unread +999 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - name - - - Nov 10 - - - + name + + + Nov 10 + + + - 999+ - + > + + + + + 999+ + + + @@ -592,10 +782,12 @@ exports[`render unread 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -612,8 +804,8 @@ exports[`render unread 1`] = ` Object { "backgroundColor": "#3F51B5", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -629,7 +821,7 @@ exports[`render unread 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -642,65 +834,112 @@ exports[`render unread 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - name - - - Nov 10 - - - + name + + + Nov 10 + + + - 1 - + > + + + + + 1 + + + @@ -739,10 +978,12 @@ exports[`renders correctly 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -759,8 +1000,8 @@ exports[`renders correctly 1`] = ` Object { "backgroundColor": "#3F51B5", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -776,7 +1017,7 @@ exports[`renders correctly 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -789,44 +1030,89 @@ exports[`renders correctly 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - name - - - Nov 10 - + + name + + + Nov 10 + + + + + + + diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index 7a0a3c1bb..eb5aadeff 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -189,10 +189,12 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -209,8 +211,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` Object { "backgroundColor": "#8BC34A", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -226,7 +228,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -239,44 +241,89 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - rocket.cat - - - Nov 10 - + + rocket.cat + + + Nov 10 + + + + + + + @@ -311,10 +358,12 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -331,8 +380,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` Object { "backgroundColor": "#8BC34A", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -348,7 +397,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -361,46 +410,91 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - rocket.cat - - - Nov 10 - + + rocket.cat + + + Nov 10 + + + + + + + @@ -435,10 +529,12 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -455,8 +551,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` Object { "backgroundColor": "#8BC34A", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -472,7 +568,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -485,65 +581,112 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - rocket.cat - - - Nov 10 - - - + rocket.cat + + + Nov 10 + + + - 1 - + > + + + + + 1 + + + - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries - - - Nov 10 - - - + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Nov 10 + + + - 9 - + > + + + + + 9 + + + - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries - - - Nov 10 - - - + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Nov 10 + + + - 99 - + > + + + + + 99 + + + - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries - - - Nov 10 - - - + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Nov 10 + + + - 100 - + > + + + + + 100 + + + - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries - - - Nov 10 - - - + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Nov 10 + + + - 999+ - + > + + + + + 999+ + + + - - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries - - - Nov 10 - - - + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries + + + Nov 10 + + + - @ 999+ - + > + + + + + @ 999+ + + + - - W - - - Nov 10 - + + W + + + Nov 10 + + + + + + + @@ -1411,10 +1846,12 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -1431,8 +1868,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` Object { "backgroundColor": "#9C27B0", "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -1448,7 +1885,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -1461,44 +1898,89 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - WW - - - Nov 10 - + + WW + + + Nov 10 + + + + + + + @@ -1533,10 +2015,12 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Array [ Object { - "alignItems": "center", + "alignItems": "flex-start", + "borderBottomColor": "#ddd", + "borderBottomWidth": 0.5, "flexDirection": "row", "paddingHorizontal": 16, - "paddingVertical": 10, + "paddingVertical": 12, }, undefined, ] @@ -1553,8 +2037,8 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` Object { "backgroundColor": undefined, "borderRadius": 4, - "height": 40, - "width": 40, + "height": 56, + "width": 56, }, undefined, ] @@ -1570,7 +2054,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 20, + "fontSize": 28, }, ] } @@ -1583,44 +2067,89 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` style={ Object { "flex": 1, + "height": "100%", "marginLeft": 16, "marginRight": 4, } } > - - - - - Nov 10 - + + + + + Nov 10 + + + + + + + diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 0e1b12119..b0ab7fea9 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -92,7 +92,7 @@ const RocketChat = { reduxStore.dispatch(connectFailure()); }); - // this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); + this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); this.ddp.on('users', (ddpMessage) => { if (ddpMessage.collection === 'users') { @@ -128,9 +128,6 @@ const RocketChat = { const sub = database.objects('subscriptions').filtered('rid == $0', data._id)[0]; database.write(() => { sub.roomUpdatedAt = data._updatedAt; - if (data.lastMessage) { - // data.lastMessage.url = data.lastMessage.url || []; - } sub.lastMessage = data.lastMessage; sub.ro = data.ro; }); @@ -432,9 +429,6 @@ const RocketChat = { const room = rooms.find(({ _id }) => _id === subscription.rid); if (room) { subscription.roomUpdatedAt = room._updatedAt; - // if (room.lastMessage) { - // room.lastMessage.url = room.lastMessage.url || []; - // } subscription.lastMessage = room.lastMessage; subscription.ro = room.ro; } diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index c3b742030..17eb42572 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -100,6 +100,7 @@ export default class RoomItem extends React.PureComponent { static propTypes = { type: PropTypes.string.isRequired, name: PropTypes.string.isRequired, + StoreLastMessage: PropTypes.bool, _updatedAt: PropTypes.instanceOf(Date), lastMessage: PropTypes.object, favorite: PropTypes.bool, @@ -115,6 +116,18 @@ export default class RoomItem extends React.PureComponent { return ; } + get lastMessage() { + const { + lastMessage + } = this.props; + + if (!this.props.StoreLastMessage) { + return ''; + } + + return lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'; + } + formatDate = date => moment(date).calendar(null, { lastDay: '[Yesterday]', sameDay: 'h:mm A', @@ -124,13 +137,11 @@ export default class RoomItem extends React.PureComponent { render() { const { - favorite, alert, unread, userMentions, name, lastMessage, _updatedAt + favorite, alert, unread, userMentions, name, _updatedAt } = this.props; const date = this.formatDate(_updatedAt); - console.log('do we have a last message?', lastMessage); - let accessibilityLabel = name; if (unread === 1) { accessibilityLabel += `, ${ unread } alert`; @@ -154,11 +165,7 @@ export default class RoomItem extends React.PureComponent { {_updatedAt ? { date } : null} - - - {!this.props.StoreLastMessage ? '' : lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'} - - + {this.lastMessage} {renderNumber(unread, userMentions)} diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index 4d32ca07d..c0172d9b7 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -90,11 +90,11 @@ export default class RoomView extends React.Component { this.rooms.addListener(this.updateRoom); } - componentWillReceiveProps(nextProps) { - if (this.props.layoutAnimation !== nextProps.layoutAnimation) { - LayoutAnimation.spring(); - } - } + // componentWillReceiveProps(nextProps) { + // // if (this.props.layoutAnimation !== nextProps.layoutAnimation) { + // // LayoutAnimation.spring(); + // // } + // } shouldComponentUpdate(nextProps, nextState) { return !(equal(this.props, nextProps) && equal(this.state, nextState)); } diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 7cabb4827..a495be776 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -3,7 +3,7 @@ import { ListView } from 'realm/react-native'; import React from 'react'; import PropTypes from 'prop-types'; import Icon from 'react-native-vector-icons/Ionicons'; -import { Platform, View, TextInput, SafeAreaView } from 'react-native'; +import { Platform, View, TextInput, SafeAreaView, LayoutAnimation } from 'react-native'; import { connect } from 'react-redux'; import * as actions from '../../actions'; import * as server from '../../actions/connect'; @@ -69,7 +69,9 @@ export default class RoomsListView extends React.Component { this.search(props.searchText); } } - + componentWillUpdate() { + LayoutAnimation.easeInEaseOut(); + } componentWillUnmount() { this.data.removeAllListeners(); } From 96b86255d35872ce03e59c178a86bc674328e5eb Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 14 Feb 2018 21:13:52 -0200 Subject: [PATCH 05/14] lint --- app/views/RoomView/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index c0172d9b7..ee0594d34 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Text, View, Button, LayoutAnimation } from 'react-native'; +import { Text, View, Button } from 'react-native'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import equal from 'deep-equal'; @@ -51,8 +51,8 @@ export default class RoomView extends React.Component { Message_TimeFormat: PropTypes.string, loading: PropTypes.bool, actionMessage: PropTypes.object, - toggleReactionPicker: PropTypes.func.isRequired, - layoutAnimation: PropTypes.instanceOf(Date) + toggleReactionPicker: PropTypes.func.isRequired + // layoutAnimation: PropTypes.instanceOf(Date) }; static navigationOptions = ({ navigation }) => ({ From ad6b4e649368f981a4bbb0d79f41776359cd6385 Mon Sep 17 00:00:00 2001 From: Aaron Ogle Date: Thu, 15 Feb 2018 02:13:45 -0600 Subject: [PATCH 06/14] fix lint --- app/lib/rocketchat.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index b0ab7fea9..fc0cc31ac 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -445,8 +445,6 @@ const RocketChat = { }); } catch (e) { alert(JSON.stringify(e)); - } finally { - } this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false); From 2966eed8d941bdd082703aa46c1476a1cb4ae836 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 15 Feb 2018 14:48:20 -0200 Subject: [PATCH 07/14] Android imports --- .../app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java | 2 +- .../app/src/main/java/com/rocketchatrn/CustomTabsHelper.java | 2 +- .../app/src/main/java/com/rocketchatrn/MainApplication.java | 3 ++- .../main/java/com/rocketchatrn/RocketChatNativePackage.java | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java b/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java index 605a058ed..e0a9db1fe 100644 --- a/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java +++ b/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java @@ -1,4 +1,4 @@ -package com.rocketchatrn; +package chat.rocket.reactnative; import android.content.Intent; import android.content.pm.ResolveInfo; diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java b/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java index 99934ec33..b7f3eb72f 100644 --- a/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java +++ b/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java @@ -1,4 +1,4 @@ -package com.rocketchatrn; +package chat.rocket.reactnative; import android.content.Context; import android.content.Intent; diff --git a/android/app/src/main/java/com/rocketchatrn/MainApplication.java b/android/app/src/main/java/com/rocketchatrn/MainApplication.java index beb8cc02c..986de10f3 100644 --- a/android/app/src/main/java/com/rocketchatrn/MainApplication.java +++ b/android/app/src/main/java/com/rocketchatrn/MainApplication.java @@ -44,7 +44,8 @@ public class MainApplication extends Application implements ReactApplication { new ReactVideoPackage(), new SplashScreenReactPackage(), new RCTToastPackage(), - new KeyboardInputPackage(MainApplication.this) + new KeyboardInputPackage(MainApplication.this), + new RocketChatNativePackage() ); } }; diff --git a/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java b/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java index bbc20f72c..16cef0197 100644 --- a/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java +++ b/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java @@ -1,4 +1,4 @@ -package com.rocketchatrn; +package chat.rocket.reactnative; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; From 6bd4cd5f9c717cf6745a31c6dc255f5f9eda66d2 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 15 Feb 2018 17:56:55 -0200 Subject: [PATCH 08/14] Custom emoji --- app/containers/message/Markdown.js | 22 +++++++---- app/presentation/RoomItem.js | 62 +++++++++++++++++++++++++----- package-lock.json | 2 +- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js index 805c915f8..3303f29ce 100644 --- a/app/containers/message/Markdown.js +++ b/app/containers/message/Markdown.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Text, StyleSheet } from 'react-native'; +import { Text, StyleSheet, ViewPropTypes } from 'react-native'; import PropTypes from 'prop-types'; import EasyMarkdown from 'react-native-easy-markdown'; // eslint-disable-line import SimpleMarkdown from 'simple-markdown'; @@ -17,13 +17,15 @@ const BlockCode = ({ node, state }) => ( ); const mentionStyle = { color: '#13679a' }; -const Markdown = ({ msg, customEmojis }) => { +const Markdown = ({ + msg, customEmojis, style, markdownStyle, customRules, renderInline +}) => { if (!msg) { return null; } msg = emojify(msg, { output: 'unicode' }); - const rules = { + const defaultRules = { username: { order: -1, match: SimpleMarkdown.inlineRegex(/^@[0-9a-zA-Z-_.]+/), @@ -121,11 +123,13 @@ const Markdown = ({ msg, customEmojis }) => { }; const codeStyle = StyleSheet.flatten(styles.codeStyle); + style = StyleSheet.flatten(style); return ( {msg} ); @@ -133,7 +137,11 @@ const Markdown = ({ msg, customEmojis }) => { Markdown.propTypes = { msg: PropTypes.string.isRequired, - customEmojis: PropTypes.object + customEmojis: PropTypes.object, + style: ViewPropTypes.style, + markdownStyle: PropTypes.object, + customRules: PropTypes.object, + renderInline: PropTypes.bool }; BlockCode.propTypes = { diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index 17eb42572..cd590939b 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -4,9 +4,12 @@ import PropTypes from 'prop-types'; import { View, Text, StyleSheet } from 'react-native'; import { emojify } from 'react-emojione'; import { connect } from 'react-redux'; +import SimpleMarkdown from 'simple-markdown'; import Avatar from '../containers/Avatar'; import Touch from '../utils/touch/index'; //eslint-disable-line +import CustomEmoji from '../containers/EmojiPicker/CustomEmoji'; +import Markdown from '../containers/message/Markdown'; const styles = StyleSheet.create({ container: { @@ -47,10 +50,7 @@ const styles = StyleSheet.create({ lastMessage: { flex: 1, flexShrink: 1, - fontSize: 16, - color: '#444', marginRight: 8 - // margin: 0 }, alert: { fontWeight: 'bold' @@ -72,6 +72,36 @@ const styles = StyleSheet.create({ justifyContent: 'center' } }); +const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } }; + +const parseInline = (parse, content, state) => { + const isCurrentlyInline = state.inline || false; + state.inline = true; + const result = parse(content, state); + state.inline = isCurrentlyInline; + return result; +}; +const parseCaptureInline = (capture, parse, state) => ({ content: parseInline(parse, capture[1], state) }); +const customRules = { + strong: { + order: -4, + match: SimpleMarkdown.inlineRegex(/^\*\*([\s\S]+?)\*\*(?!\*)/), + parse: parseCaptureInline, + react: (node, output, state) => ({ + type: 'strong', + key: state.key, + props: { + children: output(node.content, state) + } + }) + }, + text: { + order: -3, + match: SimpleMarkdown.inlineRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/), + parse: capture => ({ content: capture[0] }), + react: node => node.content + } +} const renderNumber = (unread, userMentions) => { if (!unread || unread <= 0) { @@ -94,7 +124,8 @@ const renderNumber = (unread, userMentions) => { }; @connect(state => ({ - StoreLastMessage: state.settings.Store_Last_Message + StoreLastMessage: state.settings.Store_Last_Message, + customEmojis: state.customEmojis })) export default class RoomItem extends React.PureComponent { static propTypes = { @@ -108,7 +139,8 @@ export default class RoomItem extends React.PureComponent { unread: PropTypes.number, userMentions: PropTypes.number, baseUrl: PropTypes.string, - onPress: PropTypes.func + onPress: PropTypes.func, + customEmojis: PropTypes.object } get icon() { @@ -118,14 +150,18 @@ export default class RoomItem extends React.PureComponent { get lastMessage() { const { - lastMessage + lastMessage, alert } = this.props; if (!this.props.StoreLastMessage) { return ''; } - return lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'; + let msg = lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'; + if (alert) { + msg = `**${ msg }**`; + } + return msg; } formatDate = date => moment(date).calendar(null, { @@ -137,7 +173,7 @@ export default class RoomItem extends React.PureComponent { render() { const { - favorite, alert, unread, userMentions, name, _updatedAt + favorite, unread, userMentions, name, _updatedAt, customEmojis, baseUrl } = this.props; const date = this.formatDate(_updatedAt); @@ -165,7 +201,15 @@ export default class RoomItem extends React.PureComponent { {_updatedAt ? { date } : null} - {this.lastMessage} + {renderNumber(unread, userMentions)} diff --git a/package-lock.json b/package-lock.json index 7db7cef1a..b0fe2cf91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12505,7 +12505,7 @@ } }, "react-native-easy-markdown": { - "version": "git+https://github.com/diegolmello/react-native-easy-markdown.git#ed1afe45f870524f6c23a4ca1df97770f0979c74", + "version": "git+https://github.com/diegolmello/react-native-easy-markdown.git#600a79faf4fdac2c21cfebeb01f96b997674dabe", "requires": { "simple-markdown": "0.1.2" }, From a2865728619a0dad493e0e95f990fef843a32123 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 15 Feb 2018 18:01:10 -0200 Subject: [PATCH 09/14] Lint --- app/presentation/RoomItem.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index cd590939b..6a702530b 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -8,7 +8,6 @@ import SimpleMarkdown from 'simple-markdown'; import Avatar from '../containers/Avatar'; import Touch from '../utils/touch/index'; //eslint-disable-line -import CustomEmoji from '../containers/EmojiPicker/CustomEmoji'; import Markdown from '../containers/message/Markdown'; const styles = StyleSheet.create({ @@ -101,7 +100,7 @@ const customRules = { parse: capture => ({ content: capture[0] }), react: node => node.content } -} +}; const renderNumber = (unread, userMentions) => { if (!unread || unread <= 0) { From 8812ce571663be86e893c3268713f0cfe37da144 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Fri, 16 Feb 2018 13:37:53 -0200 Subject: [PATCH 10/14] Test update --- __tests__/__snapshots__/RoomItem.js.snap | 132 +--------- .../__snapshots__/Storyshots.test.js.snap | 239 +----------------- 2 files changed, 9 insertions(+), 362 deletions(-) diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index 14e65d1d0..cdcb1f8ef 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -156,28 +156,7 @@ exports[`render channel 1`] = ` "width": "100%", } } - > - - - - + /> @@ -340,28 +319,7 @@ exports[`render no icon 1`] = ` "width": "100%", } } - > - - - - + /> @@ -524,28 +482,7 @@ exports[`render private group 1`] = ` "width": "100%", } } - > - - - - + /> @@ -700,26 +637,6 @@ exports[`render unread +999 1`] = ` } } > - - - - - - - - - - + /> diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index eb5aadeff..8c21680da 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -302,28 +302,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "width": "100%", } } - > - - - - + /> @@ -471,30 +450,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "width": "100%", } } - > - - - - + /> @@ -643,26 +599,6 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` } } > - - - - - - - - - - - - - - - - - - - - - - + /> @@ -1959,28 +1772,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "width": "100%", } } - > - - - - + /> @@ -2128,28 +1920,7 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` "width": "100%", } } - > - - - - + /> From 93644ecb028d6412c3152835b6312520073dd8d4 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 16 Feb 2018 13:55:50 -0200 Subject: [PATCH 11/14] status on lastmessage --- android/app/src/main/assets/fonts/Feather.ttf | Bin 0 -> 55288 bytes app/containers/Avatar.js | 6 +- app/containers/message/Markdown.js | 1 + app/containers/status.js | 39 +++++++++++ app/lib/rocketchat.js | 14 ++-- app/presentation/RoomItem.js | 64 ++++++++++++++---- app/views/RoomsListView/index.js | 20 +++--- 7 files changed, 112 insertions(+), 32 deletions(-) create mode 100755 android/app/src/main/assets/fonts/Feather.ttf create mode 100644 app/containers/status.js diff --git a/android/app/src/main/assets/fonts/Feather.ttf b/android/app/src/main/assets/fonts/Feather.ttf new file mode 100755 index 0000000000000000000000000000000000000000..244854c5492eecee3ff136fbe461a517079dcdde GIT binary patch literal 55288 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 literal 0 HcmV?d00001 diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js index f547b7788..3ab6c266b 100644 --- a/app/containers/Avatar.js +++ b/app/containers/Avatar.js @@ -8,7 +8,7 @@ import avatarInitialsAndColor from '../utils/avatarInitialsAndColor'; const styles = StyleSheet.create({ iconContainer: { - overflow: 'hidden', + // overflow: 'hidden', justifyContent: 'center', alignItems: 'center' }, @@ -31,7 +31,8 @@ export default class Avatar extends React.PureComponent { avatar: PropTypes.string, size: PropTypes.number, borderRadius: PropTypes.number, - type: PropTypes.string + type: PropTypes.string, + children: PropTypes.object }; render() { const { @@ -68,6 +69,7 @@ export default class Avatar extends React.PureComponent { {initials} {image} + {this.props.children} ); } diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js index 3303f29ce..1b50f901d 100644 --- a/app/containers/message/Markdown.js +++ b/app/containers/message/Markdown.js @@ -138,6 +138,7 @@ const Markdown = ({ Markdown.propTypes = { msg: PropTypes.string.isRequired, customEmojis: PropTypes.object, + // eslint-disable-next-line react/no-typos style: ViewPropTypes.style, markdownStyle: PropTypes.object, customRules: PropTypes.object, diff --git a/app/containers/status.js b/app/containers/status.js new file mode 100644 index 000000000..d1351a276 --- /dev/null +++ b/app/containers/status.js @@ -0,0 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { StyleSheet, View, ViewPropTypes } from 'react-native'; +import { STATUS_COLORS } from '../constants/colors'; + +const styles = StyleSheet.create({ + status: { + borderRadius: 16, + width: 16, + height: 16 + } +}); + +@connect(state => ({ + activeUsers: state.activeUsers +})) + +export default class Status extends React.Component { + static propTypes = { + style: ViewPropTypes.style, + id: PropTypes.string, + activeUsers: PropTypes.object + }; + + shouldComponentUpdate(nextProps) { + const userId = this.props.id; + return this.status !== nextProps.activeUsers[userId]; + } + + get status() { + const userId = this.props.id; + return this.props.activeUsers[userId] || 'offline'; + } + + render() { + return (); + } +} diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index fc0cc31ac..292476bb1 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -438,14 +438,12 @@ const RocketChat = { return subscription; }); - try { - database.write(() => { - data.forEach(subscription => database.create('subscriptions', subscription, true)); - // rooms.forEach(room => database.create('rooms', room, true)); - }); - } catch (e) { - alert(JSON.stringify(e)); - } + + database.write(() => { + data.forEach(subscription => database.create('subscriptions', subscription, true)); + // rooms.forEach(room => database.create('rooms', room, true)); + }); + this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false); this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false); diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index 6a702530b..7bd7d08a5 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -2,11 +2,12 @@ import React from 'react'; import moment from 'moment'; import PropTypes from 'prop-types'; import { View, Text, StyleSheet } from 'react-native'; -import { emojify } from 'react-emojione'; + import { connect } from 'react-redux'; import SimpleMarkdown from 'simple-markdown'; import Avatar from '../containers/Avatar'; +import Status from '../containers/status'; import Touch from '../utils/touch/index'; //eslint-disable-line import Markdown from '../containers/message/Markdown'; @@ -15,7 +16,7 @@ const styles = StyleSheet.create({ flexDirection: 'row', paddingHorizontal: 16, paddingVertical: 12, - alignItems: 'flex-start', + alignItems: 'center', borderBottomWidth: 0.5, borderBottomColor: '#ddd' }, @@ -43,13 +44,18 @@ const styles = StyleSheet.create({ flex: 1, fontSize: 18, color: '#444', - fontWeight: 'bold', + marginRight: 8 }, lastMessage: { flex: 1, flexShrink: 1, - marginRight: 8 + marginRight: 8, + maxHeight: 20, + overflow: 'hidden', + flexDirection: 'row', + alignItems: 'flex-start', + justifyContent: 'flex-start' }, alert: { fontWeight: 'bold' @@ -58,6 +64,13 @@ const styles = StyleSheet.create({ // backgroundColor: '#eee' }, row: { + width: '100%', + flex: 1, + flexDirection: 'row', + alignItems: 'flex-end', + justifyContent: 'flex-end' + }, + firstRow: { width: '100%', flex: 1, flexDirection: 'row', @@ -69,6 +82,13 @@ const styles = StyleSheet.create({ color: '#888', alignItems: 'center', justifyContent: 'center' + }, + status: { + position: 'absolute', + bottom: -3, + right: -3, + borderWidth: 3, + borderColor: '#fff' } }); const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } }; @@ -123,6 +143,7 @@ const renderNumber = (unread, userMentions) => { }; @connect(state => ({ + user: state.login.user, StoreLastMessage: state.settings.Store_Last_Message, customEmojis: state.customEmojis })) @@ -137,28 +158,43 @@ export default class RoomItem extends React.PureComponent { alert: PropTypes.bool, unread: PropTypes.number, userMentions: PropTypes.number, - baseUrl: PropTypes.string, + id: PropTypes.string, onPress: PropTypes.func, customEmojis: PropTypes.object } get icon() { - const { type, name, baseUrl } = this.props; - return ; + const { + type, name, id + } = this.props; + return ({type === 'd' ? : null }); } get lastMessage() { const { - lastMessage, alert + lastMessage, alert, type } = this.props; if (!this.props.StoreLastMessage) { return ''; } + if (!lastMessage) { + return 'No Message'; + } + + + let prefix = ''; + + if (lastMessage.u.username === this.props.user.username) { + prefix = 'You: '; + } else if (type !== 'd') { + prefix = `${ lastMessage.u.username }: `; + } + + const msg = `${ prefix }${ lastMessage.msg.replace(/[\n\t\r]/igm, '') }`; - let msg = lastMessage ? `${ lastMessage.u.username }: ${ emojify(lastMessage.msg, { output: 'unicode' }) }` : 'No Message'; if (alert) { - msg = `**${ msg }**`; + return `**${ msg.slice(0, 30) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > 30 ? '...' : '' }**`; } return msg; } @@ -172,7 +208,7 @@ export default class RoomItem extends React.PureComponent { render() { const { - favorite, unread, userMentions, name, _updatedAt, customEmojis, baseUrl + favorite, unread, userMentions, name, _updatedAt, customEmojis, alert } = this.props; const date = this.formatDate(_updatedAt); @@ -195,19 +231,19 @@ export default class RoomItem extends React.PureComponent { {this.icon} - - { name } + + { name } {_updatedAt ? { date } : null} {renderNumber(unread, userMentions)} diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index a495be776..75b36c6e7 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -3,7 +3,7 @@ import { ListView } from 'realm/react-native'; import React from 'react'; import PropTypes from 'prop-types'; import Icon from 'react-native-vector-icons/Ionicons'; -import { Platform, View, TextInput, SafeAreaView, LayoutAnimation } from 'react-native'; +import { Platform, View, TextInput, SafeAreaView } from 'react-native'; import { connect } from 'react-redux'; import * as actions from '../../actions'; import * as server from '../../actions/connect'; @@ -18,6 +18,7 @@ import styles from './styles'; const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); @connect(state => ({ + user: state.login.user, server: state.server.server, login: state.login, Site_Url: state.settings.Site_Url, @@ -31,6 +32,7 @@ const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); export default class RoomsListView extends React.Component { static propTypes = { navigation: PropTypes.object.isRequired, + user: PropTypes.object, Site_Url: PropTypes.string, server: PropTypes.string, searchText: PropTypes.string @@ -69,9 +71,9 @@ export default class RoomsListView extends React.Component { this.search(props.searchText); } } - componentWillUpdate() { - LayoutAnimation.easeInEaseOut(); - } + // componentWillUpdate() { + // LayoutAnimation.easeInEaseOut(); + // } componentWillUnmount() { this.data.removeAllListeners(); } @@ -205,8 +207,9 @@ export default class RoomsListView extends React.Component { ); - renderItem = item => ( - { + const id = item.rid.replace(this.props.user.id, '').trim(); + return ( this._onPressItem(item)} - /> - ) + />); + } renderList = () => ( Date: Fri, 16 Feb 2018 14:02:04 -0200 Subject: [PATCH 12/14] snap --- __tests__/RoomItem.js | 2 +- __tests__/__snapshots__/RoomItem.js.snap | 237 +++++--- .../__snapshots__/Storyshots.test.js.snap | 558 +++++++++++++----- app/containers/status.js | 2 +- app/presentation/RoomItem.js | 2 +- 5 files changed, 556 insertions(+), 245 deletions(-) diff --git a/__tests__/RoomItem.js b/__tests__/RoomItem.js index cc4d76d28..253b5d45c 100644 --- a/__tests__/RoomItem.js +++ b/__tests__/RoomItem.js @@ -3,7 +3,7 @@ import { Provider } from 'react-redux'; import { createStore, combineReducers } from 'redux'; -const reducers = combineReducers({settings:() => ({})}); +const reducers = combineReducers({login:() => ({user: {}}), settings:() => ({})}); const store = createStore(reducers); import React from 'react'; diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index cdcb1f8ef..4bb3753e8 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -33,7 +33,7 @@ exports[`render channel 1`] = ` style={ Array [ Object { - "alignItems": "flex-start", + "alignItems": "center", "borderBottomColor": "#ddd", "borderBottomWidth": 0.5, "flexDirection": "row", @@ -50,13 +50,12 @@ exports[`render channel 1`] = ` Object { "alignItems": "center", "justifyContent": "center", - "overflow": "hidden", }, Object { "backgroundColor": "#00BCD4", "borderRadius": 4, - "height": 56, - "width": 56, + "height": 46, + "width": 46, }, undefined, ] @@ -77,7 +76,7 @@ exports[`render channel 1`] = ` "color": "#ffffff", }, Object { - "fontSize": 28, + "fontSize": 23, }, ], Object { @@ -118,13 +117,15 @@ exports[`render channel 1`] = ` ellipsizeMode="tail" numberOfLines={1} style={ - Object { - "color": "#444", - "flex": 1, - "fontSize": 18, - "fontWeight": "bold", - "marginRight": 8, - } + Array [ + Object { + "color": "#444", + "flex": 1, + "fontSize": 18, + "marginRight": 8, + }, + undefined, + ] } > general @@ -149,10 +150,10 @@ exports[`render channel 1`] = ` name @@ -312,10 +314,10 @@ exports[`render no icon 1`] = ` private-group @@ -475,10 +478,10 @@ exports[`render private group 1`] = ` + name @@ -629,10 +654,10 @@ exports[`render unread +999 1`] = ` + name @@ -805,10 +852,10 @@ exports[`render unread 1`] = ` + name @@ -981,10 +1050,10 @@ exports[`renders correctly 1`] = ` + rocket.cat @@ -295,10 +313,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + rocket.cat @@ -443,10 +485,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + rocket.cat @@ -591,10 +655,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries @@ -762,10 +850,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries @@ -933,10 +1043,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries @@ -1104,10 +1236,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries @@ -1275,10 +1429,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries @@ -1446,10 +1622,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + W @@ -1617,10 +1815,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + WW @@ -1765,10 +1985,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` + @@ -1913,10 +2155,10 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` { }; @connect(state => ({ - user: state.login.user, + user: state.login && state.login.user, StoreLastMessage: state.settings.Store_Last_Message, customEmojis: state.customEmojis })) From 77d7f51f305ac5a2dd4e912cb657d12e00dd5236 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 16 Feb 2018 15:11:10 -0200 Subject: [PATCH 13/14] small fix --- app/containers/MessageActions.js | 7 ++++--- app/containers/status.js | 2 +- app/presentation/RoomItem.js | 10 +++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/containers/MessageActions.js b/app/containers/MessageActions.js index e362c69d8..6a2de4b4a 100644 --- a/app/containers/MessageActions.js +++ b/app/containers/MessageActions.js @@ -18,6 +18,7 @@ import { } from '../actions/messages'; import { showToast } from '../utils/info'; +const returnAnArray = obj => obj || []; @connect( state => ({ showActions: state.messages.showActions, @@ -171,11 +172,11 @@ export default class MessageActions extends React.Component { } setPermissions(permissions) { - this.hasEditPermission = permissions['edit-message'] + this.hasEditPermission = returnAnArray(permissions['edit-message']) .some(item => this.mergedRoles.indexOf(item) !== -1); - this.hasDeletePermission = permissions['delete-message'] + this.hasDeletePermission = returnAnArray(permissions['delete-message']) .some(item => this.mergedRoles.indexOf(item) !== -1); - this.hasForceDeletePermission = permissions['force-delete-message'] + this.hasForceDeletePermission = returnAnArray(permissions['force-delete-message']) .some(item => this.mergedRoles.indexOf(item) !== -1); } diff --git a/app/containers/status.js b/app/containers/status.js index 297fa2c28..55a78fcc1 100644 --- a/app/containers/status.js +++ b/app/containers/status.js @@ -30,7 +30,7 @@ export default class Status extends React.Component { get status() { const userId = this.props.id; - return this.props.activeUsers && this.props.activeUsers[userId] || 'offline'; + return (this.props.activeUsers && this.props.activeUsers[userId]) || 'offline'; } render() { diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index b39a0cb68..946796b7d 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -160,7 +160,8 @@ export default class RoomItem extends React.PureComponent { userMentions: PropTypes.number, id: PropTypes.string, onPress: PropTypes.func, - customEmojis: PropTypes.object + customEmojis: PropTypes.object, + user: PropTypes.object } get icon() { @@ -193,10 +194,13 @@ export default class RoomItem extends React.PureComponent { const msg = `${ prefix }${ lastMessage.msg.replace(/[\n\t\r]/igm, '') }`; + const maxChars = 35; + + if (alert) { - return `**${ msg.slice(0, 30) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > 30 ? '...' : '' }**`; + return `**${ msg.slice(0, maxChars) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > maxChars ? '...' : '' }**`; } - return msg; + return `${ msg.slice(0, maxChars) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > maxChars ? '...' : '' }`; } formatDate = date => moment(date).calendar(null, { From a4a889bed0ba81f04debfbe8a36960843c767bcd Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 16 Feb 2018 20:57:46 -0200 Subject: [PATCH 14/14] fix performance status users --- android/gradle.properties | 2 +- app/actions/activeUsers.js | 4 ++-- app/lib/rocketchat.js | 32 +++++++++++++++++--------------- app/sagas/activeUsers.js | 25 ++++--------------------- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index 732c56e3e..a86312fd7 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -18,4 +18,4 @@ # org.gradle.parallel=true android.useDeprecatedNdk=true -# VERSIONCODE=999999999 +VERSIONCODE=999999999 diff --git a/app/actions/activeUsers.js b/app/actions/activeUsers.js index ab74a45d9..a273d7348 100644 --- a/app/actions/activeUsers.js +++ b/app/actions/activeUsers.js @@ -1,9 +1,9 @@ import * as types from './actionsTypes'; -export function requestActiveUser(user) { +export function requestActiveUser(users) { return { type: types.ACTIVE_USERS.REQUEST, - user + users }; } diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 292476bb1..f6fcfe8ed 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -45,21 +45,27 @@ const RocketChat = { throw new Error({ error: 'invalid server' }); }, _setUser(ddpMessage) { - let status; - if (!ddpMessage.fields) { - status = 'offline'; - } else { - status = ddpMessage.fields.status || 'offline'; - } - + this.activeUsers = this.activeUsers || {}; const { user } = reduxStore.getState().login; + + const status = (ddpMessage.fields && ddpMessage.fields.status) || 'offline'; + if (user && user.id === ddpMessage.id) { return reduxStore.dispatch(setUser({ status })); } - const activeUser = {}; - activeUser[ddpMessage.id] = status; - return reduxStore.dispatch(requestActiveUser(activeUser)); + if (this._setUserTimer) { + clearTimeout(this._setUserTimer); + this._setUserTimer = null; + } + + + this._setUserTimer = setTimeout(() => { + reduxStore.dispatch(requestActiveUser(this.activeUsers)); + this._setUserTimer = null; + return this.activeUsers = {}; + }, 1000); + this.activeUsers[ddpMessage.id] = status; }, reconnect() { if (this.ddp) { @@ -94,11 +100,7 @@ const RocketChat = { this.ddp.on('connected', () => this.ddp.subscribe('activeUsers', null, false)); - this.ddp.on('users', (ddpMessage) => { - if (ddpMessage.collection === 'users') { - return RocketChat._setUser(ddpMessage); - } - }); + this.ddp.on('users', ddpMessage => RocketChat._setUser(ddpMessage)); this.ddp.on('stream-room-messages', (ddpMessage) => { const message = this._buildMessage(ddpMessage.fields.args[0]); diff --git a/app/sagas/activeUsers.js b/app/sagas/activeUsers.js index de5c02582..70ca903ef 100644 --- a/app/sagas/activeUsers.js +++ b/app/sagas/activeUsers.js @@ -1,30 +1,13 @@ -import { put, take, race, fork } from 'redux-saga/effects'; -import { delay } from 'redux-saga'; +import { put, takeLatest } from 'redux-saga/effects'; import * as types from '../actions/actionsTypes'; import { setActiveUser } from '../actions/activeUsers'; -const watchActiveUsers = function* handleInput() { - let obj = {}; - while (true) { - const { status, timeout } = yield race({ - status: take(types.ACTIVE_USERS.REQUEST), - timeout: delay(3000) - }); - if (timeout && Object.keys(obj).length > 0) { - yield put(setActiveUser(obj)); - obj = {}; - } - if (status) { - obj = { - ...obj, - ...status.user - }; - } - } +const watchActiveUsers = function* handleInput({ users }) { + yield put(setActiveUser(users)); }; const root = function* root() { - yield fork(watchActiveUsers); + yield takeLatest(types.ACTIVE_USERS.REQUEST, watchActiveUsers); }; export default root;