Chore: Evaluate RocketChat v3 (#4155)

* remove roomSub from rocketchat

* remove _setUser

* remove this.activeUsersSubTimeout and IRocketChat imports

* remove this from connect

* remove rocketchat and comment abort controler

* fix lint

Co-authored-by: Alex Junior <alexalexandrejr@gmail.com>
This commit is contained in:
Gleidson Daniel Silva 2022-05-13 11:52:37 -03:00 committed by GitHub
parent f99ec9f8e3
commit 0a7082e2fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 129 additions and 141 deletions

View File

@ -1,19 +0,0 @@
import rocketchat from '../lib/rocketchat';
export type TRocketChat = typeof rocketchat;
export interface IRocketChat extends TRocketChat {
closeListener: any;
usersListener: any;
notifyAllListener: any;
rolesListener: any;
notifyLoggedListener: any;
activeUsers: any;
_setUserTimer: any;
connectedListener: any;
connectingListener: any;
connectTimeout: any;
sdk: any;
activeUsersSubTimeout: any;
roomsSub: any;
}

View File

@ -22,7 +22,6 @@ export * from './IUser';
export * from './IServer';
export * from './ILoggedUser';
export * from './IServerHistory';
export * from './IRocketChat';
export * from './ICertificate';
export * from './IUrl';
export * from './ICredentials';

View File

@ -6,20 +6,24 @@ import { store as reduxStore } from '../store/auxStore';
import { setActiveUsers } from '../../actions/activeUsers';
import { setUser } from '../../actions/login';
import database from '../database';
import { IRocketChat, IUser } from '../../definitions';
import { IUser } from '../../definitions';
import sdk from '../services/sdk';
import { compareServerVersion } from './helpers/compareServerVersion';
export function subscribeUsersPresence(this: IRocketChat) {
export const _activeUsersSubTimeout: { activeUsersSubTimeout: boolean | ReturnType<typeof setTimeout> } = {
activeUsersSubTimeout: false
};
export function subscribeUsersPresence() {
const serverVersion = reduxStore.getState().server.version as string;
// if server is lower than 1.1.0
if (compareServerVersion(serverVersion, 'lowerThan', '1.1.0')) {
if (this.activeUsersSubTimeout) {
clearTimeout(this.activeUsersSubTimeout);
this.activeUsersSubTimeout = false;
if (_activeUsersSubTimeout.activeUsersSubTimeout) {
clearTimeout(_activeUsersSubTimeout.activeUsersSubTimeout as number);
_activeUsersSubTimeout.activeUsersSubTimeout = false;
}
this.activeUsersSubTimeout = setTimeout(() => {
_activeUsersSubTimeout.activeUsersSubTimeout = setTimeout(() => {
sdk.subscribe('activeUsers');
}, 5000);
} else if (compareServerVersion(serverVersion, 'lowerThan', '4.1.0')) {

View File

@ -34,3 +34,4 @@ export * from './userPreferences';
export * from './userPreferencesMethods';
export * from './crashReport';
export * from './parseSettings';
export * from './subscribeRooms';

View File

@ -8,11 +8,13 @@ import { BASIC_AUTH_KEY } from '../../utils/fetch';
import database, { getDatabase } from '../database';
import { isSsl } from '../../utils/url';
import log from '../../utils/log';
import { ICertificate, IRocketChat } from '../../definitions';
import { ICertificate } from '../../definitions';
import sdk from '../services/sdk';
import { CURRENT_SERVER, E2E_PRIVATE_KEY, E2E_PUBLIC_KEY, E2E_RANDOM_PASSWORD_KEY, TOKEN_KEY } from '../constants';
import UserPreferences from './userPreferences';
import { Services } from '../services';
import { roomsSubscription } from './subscriptions/rooms';
import { _activeUsersSubTimeout } from '.';
function removeServerKeys({ server, userId }: { server: string; userId?: string | null }) {
UserPreferences.removeItem(`${TOKEN_KEY}-${server}`);
@ -98,15 +100,14 @@ export async function removeServer({ server }: { server: string }): Promise<void
}
}
export async function logout(this: IRocketChat, { server }: { server: string }): Promise<void> {
if (this.roomsSub) {
this.roomsSub.stop();
this.roomsSub = null;
export async function logout({ server }: { server: string }): Promise<void> {
if (roomsSubscription?.stop) {
roomsSubscription.stop();
}
if (this.activeUsersSubTimeout) {
clearTimeout(this.activeUsersSubTimeout);
this.activeUsersSubTimeout = false;
if (_activeUsersSubTimeout.activeUsersSubTimeout) {
clearTimeout(_activeUsersSubTimeout.activeUsersSubTimeout as number);
_activeUsersSubTimeout.activeUsersSubTimeout = false;
}
try {

View File

@ -2,16 +2,35 @@ import { InteractionManager } from 'react-native';
import { setActiveUsers } from '../../actions/activeUsers';
import { setUser } from '../../actions/login';
import { IUser } from '../../definitions';
import { store as reduxStore } from '../store/auxStore';
import { compareServerVersion } from './helpers/compareServerVersion';
// TODO
export function _setUser(this: any, ddpMessage: { fields: any; id: any; cleared: any }) {
this.activeUsers = this.activeUsers || {};
export interface IActiveUsers {
[key: string]: { status: string; statusText?: string } | string | boolean;
msg: string;
collection: string;
id: string;
cleared: boolean;
fields: {
emails: {
address: string;
verified: boolean;
}[];
username: string;
status: string;
};
}
export const _activeUsers = { activeUsers: {} as IActiveUsers };
export const _setUserTimer: { setUserTimer: null | ReturnType<typeof setTimeout> } = { setUserTimer: null };
export function _setUser(ddpMessage: IActiveUsers): void {
_activeUsers.activeUsers = _activeUsers.activeUsers || {};
const { user } = reduxStore.getState().login;
if (ddpMessage.fields && user && user.id === ddpMessage.id) {
reduxStore.dispatch(setUser(ddpMessage.fields));
reduxStore.dispatch(setUser(ddpMessage.fields as Partial<IUser>));
}
if (ddpMessage.cleared && user && user.id === ddpMessage.id) {
@ -20,21 +39,22 @@ export function _setUser(this: any, ddpMessage: { fields: any; id: any; cleared:
const serverVersion = reduxStore.getState().server.version;
if (compareServerVersion(serverVersion, 'lowerThan', '4.1.0')) {
if (!this._setUserTimer) {
this._setUserTimer = setTimeout(() => {
const activeUsersBatch = this.activeUsers;
if (!_setUserTimer.setUserTimer) {
_setUserTimer.setUserTimer = setTimeout(() => {
const activeUsersBatch = _activeUsers.activeUsers;
InteractionManager.runAfterInteractions(() => {
// @ts-ignore
reduxStore.dispatch(setActiveUsers(activeUsersBatch));
});
this._setUserTimer = null;
return (this.activeUsers = {});
_setUserTimer.setUserTimer = null;
_activeUsers.activeUsers = {} as IActiveUsers;
}, 10000);
}
}
if (!ddpMessage.fields) {
this.activeUsers[ddpMessage.id] = { status: 'offline' };
_activeUsers.activeUsers[ddpMessage.id] = { status: 'offline' };
} else if (ddpMessage.fields.status) {
this.activeUsers[ddpMessage.id] = { status: ddpMessage.fields.status };
_activeUsers.activeUsers[ddpMessage.id] = { status: ddpMessage.fields.status };
}
}

View File

@ -1,22 +1,18 @@
import log from '../../utils/log';
import subscribeRoomsTmp from './subscriptions/rooms';
import subscribeRoomsTmp, { roomsSubscription } from './subscriptions/rooms';
// TODO: remove this
export async function subscribeRooms(this: any) {
if (!this.roomsSub) {
export async function subscribeRooms(): Promise<void> {
if (!roomsSubscription?.stop) {
try {
// TODO: We need to change this naming. Maybe move this logic to the SDK?
this.roomsSub = await subscribeRoomsTmp.call(this);
await subscribeRoomsTmp();
} catch (e) {
log(e);
}
}
}
// TODO: remove this
export function unsubscribeRooms(this: any) {
if (this.roomsSub) {
this.roomsSub.stop();
this.roomsSub = null;
export function unsubscribeRooms(): void {
if (roomsSubscription?.stop) {
roomsSubscription.stop();
}
}

View File

@ -44,6 +44,8 @@ let queue: { [key: string]: ISubscription | IRoom } = {};
let subTimer: number | null | false = null;
const WINDOW_TIME = 500;
export let roomsSubscription: { stop: () => void } | null = null;
const createOrUpdateSubscription = async (subscription: ISubscription, room: IServerRoom | IRoom) => {
try {
const db = database.active;
@ -404,6 +406,7 @@ export default function subscribeRooms() {
clearTimeout(subTimer);
subTimer = false;
}
roomsSubscription = null;
};
streamListener = sdk.onStreamData('stream-notify-user', handleStreamMessageReceived);
@ -412,10 +415,8 @@ export default function subscribeRooms() {
// set the server that started this task
subServer = sdk.current.client.host;
sdk.current.subscribeNotifyUser().catch((e: unknown) => console.log(e));
return {
stop: () => stop()
};
roomsSubscription = { stop: () => stop() };
return null;
} catch (e) {
log(e);
return Promise.reject();

View File

@ -1,16 +0,0 @@
import { _setUser } from './methods/setUser';
import { logout } from './methods/logout';
import { subscribeRooms, unsubscribeRooms } from './methods/subscribeRooms';
import { subscribeUsersPresence } from './methods/getUsersPresence';
import { connect } from './services/connect';
const RocketChat = {
logout,
subscribeRooms,
unsubscribeRooms,
_setUser,
subscribeUsersPresence,
connect
};
export default RocketChat;

View File

@ -14,8 +14,7 @@ import { store } from '../store/auxStore';
import { loginRequest, setLoginServices, setUser } from '../../actions/login';
import sdk from './sdk';
import I18n from '../../i18n';
import RocketChat from '../rocketchat';
import { ICredentials, ILoggedUser, IRocketChat, STATUSES } from '../../definitions';
import { ICredentials, ILoggedUser, STATUSES } from '../../definitions';
import { isIOS } from '../../utils/deviceInfo';
import { connectRequest, connectSuccess, disconnect as disconnectAction } from '../../actions/connect';
import { updatePermission } from '../../actions/permissions';
@ -24,7 +23,7 @@ import { updateSettings } from '../../actions/settings';
import { defaultSettings, MIN_ROCKETCHAT_VERSION } from '../constants';
import { compareServerVersion } from '../methods/helpers/compareServerVersion';
import { onRolesChanged } from '../methods/getRoles';
import { getSettings } from '../methods';
import { getSettings, IActiveUsers, unsubscribeRooms, _activeUsers, _setUser, _setUserTimer } from '../methods';
interface IServices {
[index: string]: string | boolean;
@ -35,11 +34,15 @@ interface IServices {
service: string;
}
// FIXME: Remove `this` context
function connect(
this: IRocketChat,
{ server, logoutOnError = false }: { server: string; logoutOnError: boolean }
): Promise<void> {
let connectingListener: any;
let connectedListener: any;
let closeListener: any;
let usersListener: any;
let notifyAllListener: any;
let rolesListener: any;
let notifyLoggedListener: any;
function connect({ server, logoutOnError = false }: { server: string; logoutOnError: boolean }): Promise<void> {
return new Promise<void>(resolve => {
if (sdk.current?.client?.host === server) {
return resolve();
@ -49,39 +52,40 @@ function connect(
store.dispatch(connectRequest());
if (this.connectTimeout) {
clearTimeout(this.connectTimeout);
// It's not called anywhere else
// if (this.connectTimeout) {
// clearTimeout(this.connectTimeout);
// }
if (connectingListener) {
connectingListener.then(stopListener);
}
if (this.connectingListener) {
this.connectingListener.then(stopListener);
if (connectedListener) {
connectedListener.then(stopListener);
}
if (this.connectedListener) {
this.connectedListener.then(stopListener);
if (closeListener) {
closeListener.then(stopListener);
}
if (this.closeListener) {
this.closeListener.then(stopListener);
if (usersListener) {
usersListener.then(stopListener);
}
if (this.usersListener) {
this.usersListener.then(stopListener);
if (notifyAllListener) {
notifyAllListener.then(stopListener);
}
if (this.notifyAllListener) {
this.notifyAllListener.then(stopListener);
if (rolesListener) {
rolesListener.then(stopListener);
}
if (this.rolesListener) {
this.rolesListener.then(stopListener);
if (notifyLoggedListener) {
notifyLoggedListener.then(stopListener);
}
if (this.notifyLoggedListener) {
this.notifyLoggedListener.then(stopListener);
}
this.unsubscribeRooms();
unsubscribeRooms();
EventEmitter.emit('INQUIRY_UNSUBSCRIBE');
@ -97,11 +101,11 @@ function connect(
console.log('connect error', err);
});
this.connectingListener = sdk.current.onStreamData('connecting', () => {
connectingListener = sdk.current.onStreamData('connecting', () => {
store.dispatch(connectRequest());
});
this.connectedListener = sdk.current.onStreamData('connected', () => {
connectedListener = sdk.current.onStreamData('connected', () => {
const { connected } = store.getState().meteor;
if (connected) {
return;
@ -113,16 +117,16 @@ function connect(
}
});
this.closeListener = sdk.current.onStreamData('close', () => {
closeListener = sdk.current.onStreamData('close', () => {
store.dispatch(disconnectAction());
});
this.usersListener = sdk.current.onStreamData(
usersListener = sdk.current.onStreamData(
'users',
protectedFunction((ddpMessage: any) => RocketChat._setUser(ddpMessage))
protectedFunction((ddpMessage: any) => _setUser(ddpMessage))
);
this.notifyAllListener = sdk.current.onStreamData(
notifyAllListener = sdk.current.onStreamData(
'stream-notify-all',
protectedFunction(async (ddpMessage: { fields: { args?: any; eventName: string } }) => {
const { eventName } = ddpMessage.fields;
@ -150,7 +154,7 @@ function connect(
})
);
this.rolesListener = sdk.current.onStreamData(
rolesListener = sdk.current.onStreamData(
'stream-roles',
protectedFunction((ddpMessage: any) => onRolesChanged(ddpMessage))
);
@ -171,27 +175,29 @@ function connect(
}
});
this.notifyLoggedListener = sdk.current.onStreamData(
notifyLoggedListener = sdk.current.onStreamData(
'stream-notify-logged',
protectedFunction(async (ddpMessage: { fields: { args?: any; eventName?: any } }) => {
const { eventName } = ddpMessage.fields;
// `user-status` event is deprecated after RC 4.1 in favor of `stream-user-presence/${uid}`
if (/user-status/.test(eventName)) {
this.activeUsers = this.activeUsers || {};
if (!this._setUserTimer) {
this._setUserTimer = setTimeout(() => {
const activeUsersBatch = this.activeUsers;
_activeUsers.activeUsers = _activeUsers.activeUsers || {};
if (!_setUserTimer.setUserTimer) {
_setUserTimer.setUserTimer = setTimeout(() => {
const activeUsersBatch = _activeUsers.activeUsers;
InteractionManager.runAfterInteractions(() => {
// @ts-ignore
store.dispatch(setActiveUsers(activeUsersBatch));
});
this._setUserTimer = null;
return (this.activeUsers = {});
_setUserTimer.setUserTimer = null;
_activeUsers.activeUsers = {} as IActiveUsers;
return null;
}, 10000);
}
const userStatus = ddpMessage.fields.args[0];
const [id, , status, statusText] = userStatus;
this.activeUsers[id] = { status: STATUSES[status], statusText };
_activeUsers.activeUsers[id] = { status: STATUSES[status], statusText };
const { user: loggedUser } = store.getState().login;
if (loggedUser && loggedUser.id === id) {

View File

@ -16,10 +16,9 @@ import { TParams } from '../../definitions/ILivechatEditView';
import { store as reduxStore } from '../store/auxStore';
import { getDeviceToken } from '../notifications';
import { getBundleId, isIOS } from '../../utils/deviceInfo';
import { RoomTypes, roomTypeToApiType } from '../methods';
import { RoomTypes, roomTypeToApiType, unsubscribeRooms } from '../methods';
import sdk from './sdk';
import { compareServerVersion } from '../methods/helpers/compareServerVersion';
import RocketChat from '../rocketchat';
export const createChannel = ({
name,
@ -807,7 +806,7 @@ export const emitTyping = (room: IRoom, typing = true) => {
export function e2eResetOwnKey(): Promise<boolean | {}> {
// {} when TOTP is enabled
RocketChat.unsubscribeRooms();
unsubscribeRooms();
// RC 0.72.0
return sdk.methodCallWrapper('e2e.resetOwnE2EKey');

View File

@ -7,7 +7,6 @@ import { appStart } from '../actions/app';
import { selectServerRequest, serverFinishAdd } from '../actions/server';
import { loginFailure, loginSuccess, logout as logoutAction, setUser } from '../actions/login';
import { roomsRequest } from '../actions/rooms';
import RocketChat from '../lib/rocketchat';
import log, { events, logEvent } from '../utils/log';
import I18n, { setLanguage } from '../i18n';
import database from '../lib/database';
@ -30,14 +29,16 @@ import {
getSlashCommands,
getUserPresence,
isOmnichannelModuleAvailable,
subscribeSettings
logout,
subscribeSettings,
subscribeUsersPresence
} from '../lib/methods';
import { Services } from '../lib/services';
const getServer = state => state.server.server;
const loginWithPasswordCall = args => Services.loginWithPassword(args);
const loginCall = (credentials, isFromWebView) => Services.login(credentials, isFromWebView);
const logoutCall = args => RocketChat.logout(args);
const logoutCall = args => logout(args);
const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnError = false, isFromWebView = false }) {
logEvent(events.LOGIN_DEFAULT_LOGIN);
@ -114,7 +115,7 @@ const registerPushTokenFork = function* registerPushTokenFork() {
};
const fetchUsersPresenceFork = function* fetchUsersPresenceFork() {
RocketChat.subscribeUsersPresence();
subscribeUsersPresence();
};
const fetchEnterpriseModulesFork = function* fetchEnterpriseModulesFork({ user }) {

View File

@ -7,9 +7,8 @@ import { roomsFailure, roomsRefresh, roomsSuccess } from '../actions/rooms';
import database from '../lib/database';
import log from '../utils/log';
import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms';
import RocketChat from '../lib/rocketchat';
import buildMessage from '../lib/methods/helpers/buildMessage';
import { getRooms } from '../lib/methods';
import { getRooms, subscribeRooms } from '../lib/methods';
const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) {
const serversDB = database.servers;
@ -30,7 +29,7 @@ const updateRooms = function* updateRooms({ server, newRoomsUpdatedAt }) {
const handleRoomsRequest = function* handleRoomsRequest({ params }) {
try {
const serversDB = database.servers;
RocketChat.subscribeRooms();
subscribeRooms();
const newRoomsUpdatedAt = new Date();
let roomsUpdatedAt;
const server = yield select(state => state.server.server);

View File

@ -11,7 +11,6 @@ import { selectServerFailure, selectServerRequest, selectServerSuccess, serverFa
import { clearSettings } from '../actions/settings';
import { clearUser, setUser } from '../actions/login';
import { clearActiveUsers } from '../actions/activeUsers';
import RocketChat from '../lib/rocketchat';
import database from '../lib/database';
import log, { logServerVersion } from '../utils/log';
import I18n from '../i18n';
@ -25,6 +24,7 @@ import { RootEnum } from '../definitions';
import { CERTIFICATE_KEY, CURRENT_SERVER, TOKEN_KEY } from '../lib/constants';
import { getLoginSettings, setCustomEmojis, setEnterpriseModules, setPermissions, setRoles, setSettings } from '../lib/methods';
import { Services } from '../lib/services';
import { connect } from '../lib/services/connect';
const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
try {
@ -115,11 +115,11 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
if (user) {
yield put(clearSettings());
yield put(setUser(user));
yield RocketChat.connect({ server, logoutOnError: true });
yield connect({ server, logoutOnError: true });
yield put(appStart({ root: RootEnum.ROOT_INSIDE }));
} else {
yield put(clearUser());
yield RocketChat.connect({ server });
yield connect({ server });
yield put(appStart({ root: RootEnum.ROOT_OUTSIDE }));
}

View File

@ -2,8 +2,6 @@ import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
import RocketChat from '../lib/rocketchat';
export type TMethods = 'POST' | 'GET' | 'DELETE' | 'PUT' | 'post' | 'get' | 'delete' | 'put';
interface CustomHeaders {
@ -46,13 +44,11 @@ export default (url: string, options: IOptions = {}): Promise<Response> => {
if (options && options.headers) {
customOptions = { ...customOptions, headers: { ...options.headers, ...customOptions.headers } };
}
// TODO: Refactor when migrate rocketchat.js
// @ts-ignore
// WHAT?
if (RocketChat.controller) {
// @ts-ignore
const { signal } = RocketChat.controller;
customOptions = { ...customOptions, signal };
}
// TODO: Check if this really works and if anyone else has complained about this problem.
// if (RocketChat.controller) {
// // @ts-ignore
// const { signal } = RocketChat.controller;
// customOptions = { ...customOptions, signal };
// }
return fetch(url, customOptions);
};