[IMPROVEMENT] Request user presence on demand (#1813)

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Djorkaeff Alexandre 2020-03-03 18:10:39 -03:00 committed by GitHub
parent cfab64283d
commit 6ada35e460
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 42 deletions

View File

@ -0,0 +1,72 @@
import { InteractionManager } from 'react-native';
import semver from 'semver';
import reduxStore from '../createStore';
import { setActiveUsers } from '../../actions/activeUsers';
export function subscribeUsersPresence() {
const serverVersion = reduxStore.getState().server.version;
// if server is lower than 1.1.0
if (serverVersion && semver.lt(semver.coerce(serverVersion), '1.1.0')) {
if (this.activeUsersSubTimeout) {
clearTimeout(this.activeUsersSubTimeout);
this.activeUsersSubTimeout = false;
}
this.activeUsersSubTimeout = setTimeout(() => {
this.sdk.subscribe('activeUsers');
}, 5000);
} else {
this.sdk.subscribe('stream-notify-logged', 'user-status');
}
}
let ids = [];
export default async function getUsersPresence() {
const serverVersion = reduxStore.getState().server.version;
// if server is greather than or equal 1.1.0
if (serverVersion && !semver.lt(semver.coerce(serverVersion), '1.1.0')) {
let params = {};
// if server is greather than or equal 3.0.0
if (serverVersion && !semver.lt(semver.coerce(serverVersion), '3.0.0')) {
// if not have any id
if (!ids.length) {
return;
}
// Request userPresence on demand
params = { ids: ids.join(',') };
ids = [];
}
// RC 1.1.0
const result = await this.sdk.get('users.presence', params);
if (result.success) {
const activeUsers = result.users.reduce((ret, item) => {
ret[item._id] = item.status;
return ret;
}, {});
InteractionManager.runAfterInteractions(() => {
reduxStore.dispatch(setActiveUsers(activeUsers));
});
}
}
}
let usersTimer = null;
export function getUserPresence(uid) {
const auth = reduxStore.getState().login.isAuthenticated;
if (!usersTimer) {
usersTimer = setTimeout(() => {
if (auth && ids.length) {
getUsersPresence.call(this);
}
usersTimer = null;
}, 2000);
}
ids.push(uid);
}

View File

@ -21,6 +21,7 @@ import {
} from '../actions/share'; } from '../actions/share';
import subscribeRooms from './methods/subscriptions/rooms'; import subscribeRooms from './methods/subscriptions/rooms';
import getUsersPresence, { getUserPresence, subscribeUsersPresence } from './methods/getUsersPresence';
import protectedFunction from './methods/helpers/protectedFunction'; import protectedFunction from './methods/helpers/protectedFunction';
import readMessages from './methods/readMessages'; import readMessages from './methods/readMessages';
@ -1065,42 +1066,9 @@ const RocketChat = {
this.activeUsers[ddpMessage.id] = ddpMessage.fields.status; this.activeUsers[ddpMessage.id] = ddpMessage.fields.status;
} }
}, },
getUserPresence() { getUsersPresence,
return new Promise(async(resolve) => { getUserPresence,
const serverVersion = reduxStore.getState().server.version; subscribeUsersPresence,
// if server is lower than 1.1.0
if (serverVersion && semver.lt(semver.coerce(serverVersion), '1.1.0')) {
if (this.activeUsersSubTimeout) {
clearTimeout(this.activeUsersSubTimeout);
this.activeUsersSubTimeout = false;
}
this.activeUsersSubTimeout = setTimeout(() => {
this.sdk.subscribe('activeUsers');
}, 5000);
return resolve();
} else {
const params = {};
// if (this.lastUserPresenceFetch) {
// params.from = this.lastUserPresenceFetch.toISOString();
// }
// RC 1.1.0
const result = await this.sdk.get('users.presence', params);
if (result.success) {
const activeUsers = result.users.reduce((ret, item) => {
ret[item._id] = item.status;
return ret;
}, {});
InteractionManager.runAfterInteractions(() => {
reduxStore.dispatch(setActiveUsers(activeUsers));
});
this.sdk.subscribe('stream-notify-logged', 'user-status');
return resolve();
}
}
});
},
getDirectory({ getDirectory({
query, count, offset, sort query, count, offset, sort
}) { }) {

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { View, Text } from 'react-native'; import { View, Text } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -40,8 +40,15 @@ const arePropsEqual = (oldProps, newProps) => {
}; };
const RoomItem = React.memo(({ const RoomItem = React.memo(({
onPress, width, favorite, toggleFav, isRead, rid, toggleRead, hideChannel, testID, unread, userMentions, name, _updatedAt, alert, type, avatarSize, baseUrl, userId, username, token, id, prid, showLastMessage, hideUnreadStatus, lastMessage, status, avatar, useRealName, theme onPress, width, favorite, toggleFav, isRead, rid, toggleRead, hideChannel, testID, unread, userMentions, name, _updatedAt, alert, type, avatarSize, baseUrl, userId, username, token, id, prid, showLastMessage, hideUnreadStatus, lastMessage, status, avatar, useRealName, getUserPresence, theme
}) => { }) => {
useEffect(() => {
if (type === 'd' && rid) {
const uid = rid.replace(userId, '');
getUserPresence(uid);
}
}, []);
const date = formatDate(_updatedAt); const date = formatDate(_updatedAt);
let accessibilityLabel = name; let accessibilityLabel = name;
@ -190,12 +197,14 @@ RoomItem.propTypes = {
avatar: PropTypes.bool, avatar: PropTypes.bool,
hideUnreadStatus: PropTypes.bool, hideUnreadStatus: PropTypes.bool,
useRealName: PropTypes.bool, useRealName: PropTypes.bool,
getUserPresence: PropTypes.func,
theme: PropTypes.string theme: PropTypes.string
}; };
RoomItem.defaultProps = { RoomItem.defaultProps = {
avatarSize: 48, avatarSize: 48,
status: 'offline' status: 'offline',
getUserPresence: () => {}
}; };
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({

View File

@ -71,8 +71,9 @@ const registerPushToken = function* registerPushToken() {
yield RocketChat.registerPushToken(); yield RocketChat.registerPushToken();
}; };
const fetchUserPresence = function* fetchUserPresence() { const fetchUsersPresence = function* fetchUserPresence() {
yield RocketChat.getUserPresence(); yield RocketChat.getUsersPresence();
yield RocketChat.subscribeUsersPresence();
}; };
const handleLoginSuccess = function* handleLoginSuccess({ user }) { const handleLoginSuccess = function* handleLoginSuccess({ user }) {
@ -87,7 +88,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
yield fork(fetchRoles); yield fork(fetchRoles);
yield fork(fetchSlashCommands); yield fork(fetchSlashCommands);
yield fork(registerPushToken); yield fork(registerPushToken);
yield fork(fetchUserPresence); yield fork(fetchUsersPresence);
I18n.locale = user.language; I18n.locale = user.language;
moment.locale(toMomentLocale(user.language)); moment.locale(toMomentLocale(user.language));

View File

@ -524,6 +524,8 @@ class RoomsListView extends React.Component {
getRoomAvatar = item => RocketChat.getRoomAvatar(item) getRoomAvatar = item => RocketChat.getRoomAvatar(item)
getUserPresence = uid => RocketChat.getUserPresence(uid)
goRoom = (item) => { goRoom = (item) => {
const { navigation } = this.props; const { navigation } = this.props;
this.cancelSearch(); this.cancelSearch();
@ -794,6 +796,7 @@ class RoomsListView extends React.Component {
toggleRead={this.toggleRead} toggleRead={this.toggleRead}
hideChannel={this.hideChannel} hideChannel={this.hideChannel}
useRealName={useRealName} useRealName={useRealName}
getUserPresence={this.getUserPresence}
/> />
); );
}; };