Chore: Migrate lib/rocketchat.js to TS - structure PoC (#3661)
Co-authored-by: Diego Mello <diegolmello@gmail.com> Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
977cfd2863
commit
a01d281032
|
@ -6,7 +6,7 @@ export interface IServer {
|
||||||
useRealName: boolean;
|
useRealName: boolean;
|
||||||
FileUpload_MediaTypeWhiteList: string;
|
FileUpload_MediaTypeWhiteList: string;
|
||||||
FileUpload_MaxFileSize: number;
|
FileUpload_MaxFileSize: number;
|
||||||
roomsUpdatedAt: Date;
|
roomsUpdatedAt: Date | null;
|
||||||
version: string;
|
version: string;
|
||||||
lastLocalAuthenticatedSession: Date;
|
lastLocalAuthenticatedSession: Date;
|
||||||
autoLock: boolean;
|
autoLock: boolean;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// https://github.com/RocketChat/Rocket.Chat/blob/develop/definition/ITeam.ts
|
// https://github.com/RocketChat/Rocket.Chat/blob/develop/definition/ITeam.ts
|
||||||
exports.TEAM_TYPE = {
|
export enum TEAM_TYPE {
|
||||||
PUBLIC: 0,
|
PUBLIC = 0,
|
||||||
PRIVATE: 1
|
PRIVATE = 1
|
||||||
};
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
import RocketChat, { THEME_PREFERENCES_KEY, CRASH_REPORT_KEY, ANALYTICS_EVENTS_KEY } from './rocketchat';
|
||||||
|
|
||||||
|
export { THEME_PREFERENCES_KEY, CRASH_REPORT_KEY, ANALYTICS_EVENTS_KEY };
|
||||||
|
export default RocketChat;
|
|
@ -0,0 +1,23 @@
|
||||||
|
import database from '../../database';
|
||||||
|
|
||||||
|
export default async function clearCache({ server }: { server: string }): Promise<void> {
|
||||||
|
try {
|
||||||
|
const serversDB = database.servers;
|
||||||
|
await serversDB.write(async () => {
|
||||||
|
const serverCollection = serversDB.get('servers');
|
||||||
|
const serverRecord = await serverCollection.find(server);
|
||||||
|
await serverRecord.update(s => {
|
||||||
|
s.roomsUpdatedAt = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const db = database.active;
|
||||||
|
await db.write(() => db.unsafeResetDatabase());
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import log from '../../../utils/log';
|
||||||
|
import { TMessageModel, TSubscriptionModel } from '../../../definitions';
|
||||||
|
import reduxStore from '../../createStore';
|
||||||
|
import getRoom from './getRoom';
|
||||||
|
import isGroupChat from './isGroupChat';
|
||||||
|
|
||||||
|
type TRoomType = 'p' | 'c' | 'd';
|
||||||
|
|
||||||
|
export default async function getPermalinkMessage(message: TMessageModel): Promise<string | null> {
|
||||||
|
let room: TSubscriptionModel;
|
||||||
|
try {
|
||||||
|
room = await getRoom(message.subscription.id);
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { server } = reduxStore.getState().server;
|
||||||
|
const roomType = {
|
||||||
|
p: 'group',
|
||||||
|
c: 'channel',
|
||||||
|
d: 'direct'
|
||||||
|
}[room.t as TRoomType];
|
||||||
|
return `${server}/${roomType}/${isGroupChat(room) ? room.rid : room.name}?msg=${message.id}`;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { TSubscriptionModel } from '../../../definitions';
|
||||||
|
import database from '../../database';
|
||||||
|
|
||||||
|
export default async function getRoom(rid: string): Promise<TSubscriptionModel> {
|
||||||
|
try {
|
||||||
|
const db = database.active;
|
||||||
|
const room = await db.get('subscriptions').find(rid);
|
||||||
|
return Promise.resolve(room);
|
||||||
|
} catch (error) {
|
||||||
|
return Promise.reject(new Error('Room not found'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { ISubscription, TSubscriptionModel } from '../../../definitions';
|
||||||
|
|
||||||
|
export default function isGroupChat(room: ISubscription | TSubscriptionModel): boolean {
|
||||||
|
return ((room.uids && room.uids.length > 2) || (room.usernames && room.usernames.length > 2)) ?? false;
|
||||||
|
}
|
|
@ -1,64 +1,70 @@
|
||||||
import { InteractionManager } from 'react-native';
|
|
||||||
import EJSON from 'ejson';
|
|
||||||
import { settings as RocketChatSettings, Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
|
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
import AsyncStorage from '@react-native-community/async-storage';
|
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
|
import AsyncStorage from '@react-native-community/async-storage';
|
||||||
|
import { Rocketchat as RocketchatClient, settings as RocketChatSettings } from '@rocket.chat/sdk';
|
||||||
|
import { InteractionManager } from 'react-native';
|
||||||
import RNFetchBlob from 'rn-fetch-blob';
|
import RNFetchBlob from 'rn-fetch-blob';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import { setActiveUsers } from '../../actions/activeUsers';
|
||||||
|
import { connectRequest, connectSuccess, disconnect } from '../../actions/connect';
|
||||||
import defaultSettings from '../constants/settings';
|
import { encryptionInit } from '../../actions/encryption';
|
||||||
import log from '../utils/log';
|
import { loginRequest, setLoginServices, setUser } from '../../actions/login';
|
||||||
import { getBundleId, isIOS } from '../utils/deviceInfo';
|
import { updatePermission } from '../../actions/permissions';
|
||||||
import fetch from '../utils/fetch';
|
import { selectServerFailure } from '../../actions/server';
|
||||||
import SSLPinning from '../utils/sslPinning';
|
import { updateSettings } from '../../actions/settings';
|
||||||
import { encryptionInit } from '../actions/encryption';
|
import { shareSelectServer, shareSetSettings, shareSetUser } from '../../actions/share';
|
||||||
import { loginRequest, setLoginServices, setUser } from '../actions/login';
|
import defaultSettings from '../../constants/settings';
|
||||||
import { connectRequest, connectSuccess, disconnect } from '../actions/connect';
|
import { TEAM_TYPE } from '../../definitions/ITeam';
|
||||||
import { shareSelectServer, shareSetSettings, shareSetUser } from '../actions/share';
|
import I18n from '../../i18n';
|
||||||
import { getDeviceToken } from '../notifications/push';
|
import { getDeviceToken } from '../../notifications/push';
|
||||||
import { setActiveUsers } from '../actions/activeUsers';
|
import { getBundleId, isIOS } from '../../utils/deviceInfo';
|
||||||
import I18n from '../i18n';
|
import EventEmitter from '../../utils/events';
|
||||||
import { twoFactor } from '../utils/twoFactor';
|
import fetch from '../../utils/fetch';
|
||||||
import { selectServerFailure } from '../actions/server';
|
import log from '../../utils/log';
|
||||||
import { useSsl } from '../utils/url';
|
import SSLPinning from '../../utils/sslPinning';
|
||||||
import EventEmitter from '../utils/events';
|
import { twoFactor } from '../../utils/twoFactor';
|
||||||
import { updatePermission } from '../actions/permissions';
|
import { useSsl } from '../../utils/url';
|
||||||
import { TEAM_TYPE } from '../definitions/ITeam';
|
import database from '../database';
|
||||||
import { updateSettings } from '../actions/settings';
|
import { sanitizeLikeString } from '../database/utils';
|
||||||
import { compareServerVersion } from './utils';
|
import { Encryption } from '../encryption';
|
||||||
import { store as reduxStore } from './auxStore';
|
import triggerBlockAction, { triggerCancel, triggerSubmitView } from '../methods/actions';
|
||||||
import database from './database';
|
import callJitsi, { callJitsiWithoutServer } from '../methods/callJitsi';
|
||||||
import subscribeRooms from './methods/subscriptions/rooms';
|
import canOpenRoom from '../methods/canOpenRoom';
|
||||||
import { getUserPresence, subscribeUsersPresence } from './methods/getUsersPresence';
|
|
||||||
import protectedFunction from './methods/helpers/protectedFunction';
|
|
||||||
import readMessages from './methods/readMessages';
|
|
||||||
import getSettings, { getLoginSettings, setSettings, subscribeSettings } from './methods/getSettings';
|
|
||||||
import getRooms from './methods/getRooms';
|
|
||||||
import { getPermissions, setPermissions } from './methods/getPermissions';
|
|
||||||
import { getCustomEmojis, setCustomEmojis } from './methods/getCustomEmojis';
|
|
||||||
import {
|
import {
|
||||||
getEnterpriseModules,
|
getEnterpriseModules,
|
||||||
hasLicense,
|
hasLicense,
|
||||||
isOmnichannelModuleAvailable,
|
isOmnichannelModuleAvailable,
|
||||||
setEnterpriseModules
|
setEnterpriseModules
|
||||||
} from './methods/enterpriseModules';
|
} from '../methods/enterpriseModules';
|
||||||
import getSlashCommands from './methods/getSlashCommands';
|
import { getCustomEmojis, setCustomEmojis } from '../methods/getCustomEmojis';
|
||||||
import { getRoles, onRolesChanged, setRoles } from './methods/getRoles';
|
import { getPermissions, setPermissions } from '../methods/getPermissions';
|
||||||
import canOpenRoom from './methods/canOpenRoom';
|
import { getRoles, onRolesChanged, setRoles } from '../methods/getRoles';
|
||||||
import triggerBlockAction, { triggerCancel, triggerSubmitView } from './methods/actions';
|
import getRooms from '../methods/getRooms';
|
||||||
import loadMessagesForRoom from './methods/loadMessagesForRoom';
|
import getSettings, { getLoginSettings, setSettings, subscribeSettings } from '../methods/getSettings';
|
||||||
import loadSurroundingMessages from './methods/loadSurroundingMessages';
|
import getSlashCommands from '../methods/getSlashCommands';
|
||||||
import loadNextMessages from './methods/loadNextMessages';
|
import protectedFunction from '../methods/helpers/protectedFunction';
|
||||||
import loadMissedMessages from './methods/loadMissedMessages';
|
import loadMessagesForRoom from '../methods/loadMessagesForRoom';
|
||||||
import loadThreadMessages from './methods/loadThreadMessages';
|
import loadMissedMessages from '../methods/loadMissedMessages';
|
||||||
import sendMessage, { resendMessage } from './methods/sendMessage';
|
import loadNextMessages from '../methods/loadNextMessages';
|
||||||
import { cancelUpload, isUploadActive, sendFileMessage } from './methods/sendFileMessage';
|
import loadSurroundingMessages from '../methods/loadSurroundingMessages';
|
||||||
import callJitsi, { callJitsiWithoutServer } from './methods/callJitsi';
|
import loadThreadMessages from '../methods/loadThreadMessages';
|
||||||
import logout, { removeServer } from './methods/logout';
|
import logout, { removeServer } from '../methods/logout';
|
||||||
import UserPreferences from './userPreferences';
|
import readMessages from '../methods/readMessages';
|
||||||
import { Encryption } from './encryption';
|
import { cancelUpload, isUploadActive, sendFileMessage } from '../methods/sendFileMessage';
|
||||||
import { sanitizeLikeString } from './database/utils';
|
import sendMessage, { resendMessage } from '../methods/sendMessage';
|
||||||
|
import subscribeRooms from '../methods/subscriptions/rooms';
|
||||||
|
import UserPreferences from '../userPreferences';
|
||||||
|
import { compareServerVersion } from '../utils';
|
||||||
|
import { getUserPresence, subscribeUsersPresence } from '../methods/getUsersPresence';
|
||||||
|
import { store as reduxStore } from '../auxStore';
|
||||||
|
// Methods
|
||||||
|
import clearCache from './methods/clearCache';
|
||||||
|
import getPermalinkMessage from './methods/getPermalinkMessage';
|
||||||
|
import getRoom from './methods/getRoom';
|
||||||
|
import isGroupChat from './methods/isGroupChat';
|
||||||
|
import getUserInfo from './services/getUserInfo';
|
||||||
|
// Services
|
||||||
|
import sdk from './services/sdk';
|
||||||
|
import toggleFavorite from './services/toggleFavorite';
|
||||||
|
|
||||||
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
||||||
const CURRENT_SERVER = 'currentServer';
|
const CURRENT_SERVER = 'currentServer';
|
||||||
|
@ -186,8 +192,7 @@ const RocketChat = {
|
||||||
return this?.sdk?.checkAndReopen();
|
return this?.sdk?.checkAndReopen();
|
||||||
},
|
},
|
||||||
disconnect() {
|
disconnect() {
|
||||||
this.sdk?.disconnect?.();
|
this.sdk = sdk.disconnect();
|
||||||
this.sdk = null;
|
|
||||||
},
|
},
|
||||||
connect({ server, user, logoutOnError = false }) {
|
connect({ server, user, logoutOnError = false }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -235,12 +240,7 @@ const RocketChat = {
|
||||||
|
|
||||||
EventEmitter.emit('INQUIRY_UNSUBSCRIBE');
|
EventEmitter.emit('INQUIRY_UNSUBSCRIBE');
|
||||||
|
|
||||||
if (this.code) {
|
this.sdk = sdk.initialize(server);
|
||||||
this.code = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The app can't reconnect if reopen interval is 5s while in development
|
|
||||||
this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl: useSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
|
||||||
this.getSettings();
|
this.getSettings();
|
||||||
|
|
||||||
this.sdk
|
this.sdk
|
||||||
|
@ -415,12 +415,8 @@ const RocketChat = {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shareSDK) {
|
this.shareSDK = sdk.disconnect();
|
||||||
this.shareSDK.disconnect();
|
this.shareSDK = sdk.initialize(server);
|
||||||
this.shareSDK = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.shareSDK = new RocketchatClient({ host: server, protocol: 'ddp', useSsl: useSsl(server) });
|
|
||||||
|
|
||||||
// set Server
|
// set Server
|
||||||
const currentServer = { server };
|
const currentServer = { server };
|
||||||
|
@ -473,10 +469,7 @@ const RocketChat = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closeShareExtension() {
|
closeShareExtension() {
|
||||||
if (this.shareSDK) {
|
this.shareSDK = sdk.disconnect();
|
||||||
this.shareSDK.disconnect();
|
|
||||||
this.shareSDK = null;
|
|
||||||
}
|
|
||||||
database.share = null;
|
database.share = null;
|
||||||
|
|
||||||
reduxStore.dispatch(shareSelectServer({}));
|
reduxStore.dispatch(shareSelectServer({}));
|
||||||
|
@ -651,27 +644,7 @@ const RocketChat = {
|
||||||
return this.sdk.post('users.removeOtherTokens', { userId });
|
return this.sdk.post('users.removeOtherTokens', { userId });
|
||||||
},
|
},
|
||||||
removeServer,
|
removeServer,
|
||||||
async clearCache({ server }) {
|
clearCache,
|
||||||
try {
|
|
||||||
const serversDB = database.servers;
|
|
||||||
await serversDB.action(async () => {
|
|
||||||
const serverCollection = serversDB.get('servers');
|
|
||||||
const serverRecord = await serverCollection.find(server);
|
|
||||||
await serverRecord.update(s => {
|
|
||||||
s.roomsUpdatedAt = null;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const db = database.active;
|
|
||||||
await db.action(() => db.unsafeResetDatabase());
|
|
||||||
} catch (e) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
},
|
|
||||||
registerPushToken() {
|
registerPushToken() {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
const token = getDeviceToken();
|
const token = getDeviceToken();
|
||||||
|
@ -991,31 +964,8 @@ const RocketChat = {
|
||||||
reportMessage(messageId) {
|
reportMessage(messageId) {
|
||||||
return this.post('chat.reportMessage', { messageId, description: 'Message reported by user' });
|
return this.post('chat.reportMessage', { messageId, description: 'Message reported by user' });
|
||||||
},
|
},
|
||||||
async getRoom(rid) {
|
getRoom,
|
||||||
try {
|
getPermalinkMessage,
|
||||||
const db = database.active;
|
|
||||||
const room = await db.get('subscriptions').find(rid);
|
|
||||||
return Promise.resolve(room);
|
|
||||||
} catch (error) {
|
|
||||||
return Promise.reject(new Error('Room not found'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getPermalinkMessage(message) {
|
|
||||||
let room;
|
|
||||||
try {
|
|
||||||
room = await RocketChat.getRoom(message.subscription.id);
|
|
||||||
} catch (e) {
|
|
||||||
log(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const { server } = reduxStore.getState().server;
|
|
||||||
const roomType = {
|
|
||||||
p: 'group',
|
|
||||||
c: 'channel',
|
|
||||||
d: 'direct'
|
|
||||||
}[room.t];
|
|
||||||
return `${server}/${roomType}/${this.isGroupChat(room) ? room.rid : room.name}?msg=${message.id}`;
|
|
||||||
},
|
|
||||||
getPermalinkChannel(channel) {
|
getPermalinkChannel(channel) {
|
||||||
const { server } = reduxStore.getState().server;
|
const { server } = reduxStore.getState().server;
|
||||||
const roomType = {
|
const roomType = {
|
||||||
|
@ -1062,10 +1012,7 @@ const RocketChat = {
|
||||||
// RC 0.62.2
|
// RC 0.62.2
|
||||||
return this.post('chat.react', { emoji, messageId });
|
return this.post('chat.react', { emoji, messageId });
|
||||||
},
|
},
|
||||||
toggleFavorite(roomId, favorite) {
|
toggleFavorite,
|
||||||
// RC 0.64.0
|
|
||||||
return this.post('rooms.favorite', { roomId, favorite });
|
|
||||||
},
|
|
||||||
toggleRead(read, roomId) {
|
toggleRead(read, roomId) {
|
||||||
if (read) {
|
if (read) {
|
||||||
return this.post('subscriptions.unread', { roomId });
|
return this.post('subscriptions.unread', { roomId });
|
||||||
|
@ -1091,21 +1038,7 @@ const RocketChat = {
|
||||||
return result?.records;
|
return result?.records;
|
||||||
},
|
},
|
||||||
methodCallWrapper(method, ...params) {
|
methodCallWrapper(method, ...params) {
|
||||||
const { API_Use_REST_For_DDP_Calls } = reduxStore.getState().settings;
|
return sdk.methodCallWrapper(method, ...params);
|
||||||
const { user } = reduxStore.getState().login;
|
|
||||||
if (API_Use_REST_For_DDP_Calls) {
|
|
||||||
const url = isEmpty(user) ? 'method.callAnon' : 'method.call';
|
|
||||||
return this.post(`${url}/${method}`, {
|
|
||||||
message: EJSON.stringify({ method, params })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const parsedParams = params.map(param => {
|
|
||||||
if (param instanceof Date) {
|
|
||||||
return { $date: new Date(param).getTime() };
|
|
||||||
}
|
|
||||||
return param;
|
|
||||||
});
|
|
||||||
return this.methodCall(method, ...parsedParams);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getUserRoles() {
|
getUserRoles() {
|
||||||
|
@ -1120,10 +1053,7 @@ const RocketChat = {
|
||||||
// RC 0.48.0
|
// RC 0.48.0
|
||||||
return this.sdk.get('channels.info', { roomId });
|
return this.sdk.get('channels.info', { roomId });
|
||||||
},
|
},
|
||||||
getUserInfo(userId) {
|
getUserInfo,
|
||||||
// RC 0.48.0
|
|
||||||
return this.sdk.get('users.info', { userId });
|
|
||||||
},
|
|
||||||
getUserPreferences(userId) {
|
getUserPreferences(userId) {
|
||||||
// RC 0.62.0
|
// RC 0.62.0
|
||||||
return this.sdk.get('users.getPreferences', { userId });
|
return this.sdk.get('users.getPreferences', { userId });
|
||||||
|
@ -1237,9 +1167,7 @@ const RocketChat = {
|
||||||
return !isUnread;
|
return !isUnread;
|
||||||
},
|
},
|
||||||
|
|
||||||
isGroupChat(room) {
|
isGroupChat,
|
||||||
return (room.uids && room.uids.length > 2) || (room.usernames && room.usernames.length > 2);
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleBlockUser(rid, blocked, block) {
|
toggleBlockUser(rid, blocked, block) {
|
||||||
if (block) {
|
if (block) {
|
||||||
|
@ -1312,62 +1240,10 @@ const RocketChat = {
|
||||||
return this.methodCallWrapper('saveRoomSettings', rid, params);
|
return this.methodCallWrapper('saveRoomSettings', rid, params);
|
||||||
},
|
},
|
||||||
post(...args) {
|
post(...args) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return sdk.post(...args);
|
||||||
const isMethodCall = args[0]?.startsWith('method.call/');
|
|
||||||
try {
|
|
||||||
const result = await this.sdk.post(...args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if API_Use_REST_For_DDP_Calls is enabled and it's a method call,
|
|
||||||
* responses have a different object structure
|
|
||||||
*/
|
|
||||||
if (isMethodCall) {
|
|
||||||
const response = JSON.parse(result.message);
|
|
||||||
if (response?.error) {
|
|
||||||
throw response.error;
|
|
||||||
}
|
|
||||||
return resolve(response.result);
|
|
||||||
}
|
|
||||||
return resolve(result);
|
|
||||||
} catch (e) {
|
|
||||||
const errorType = isMethodCall ? e?.error : e?.data?.errorType;
|
|
||||||
const totpInvalid = 'totp-invalid';
|
|
||||||
const totpRequired = 'totp-required';
|
|
||||||
if ([totpInvalid, totpRequired].includes(errorType)) {
|
|
||||||
const { details } = isMethodCall ? e : e?.data;
|
|
||||||
try {
|
|
||||||
await twoFactor({ method: details?.method, invalid: errorType === totpInvalid });
|
|
||||||
return resolve(this.post(...args));
|
|
||||||
} catch {
|
|
||||||
// twoFactor was canceled
|
|
||||||
return resolve({});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
methodCall(...args) {
|
methodCall(...args) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return sdk.methodCall(...args);
|
||||||
try {
|
|
||||||
const result = await this.sdk?.methodCall(...args, this.code || '');
|
|
||||||
return resolve(result);
|
|
||||||
} catch (e) {
|
|
||||||
if (e.error && (e.error === 'totp-required' || e.error === 'totp-invalid')) {
|
|
||||||
const { details } = e;
|
|
||||||
try {
|
|
||||||
this.code = await twoFactor({ method: details?.method, invalid: e.error === 'totp-invalid' });
|
|
||||||
return resolve(this.methodCall(...args));
|
|
||||||
} catch {
|
|
||||||
// twoFactor was canceled
|
|
||||||
return resolve({});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
sendEmailCode() {
|
sendEmailCode() {
|
||||||
const { username } = reduxStore.getState().login.user;
|
const { username } = reduxStore.getState().login.user;
|
|
@ -0,0 +1,6 @@
|
||||||
|
import sdk from './sdk';
|
||||||
|
|
||||||
|
export default function getUserInfo(userId: string) {
|
||||||
|
// RC 0.48.0
|
||||||
|
return sdk.get('users.info', { userId });
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
import { Rocketchat } from '@rocket.chat/sdk';
|
||||||
|
import isEmpty from 'lodash/isEmpty';
|
||||||
|
import EJSON from 'ejson';
|
||||||
|
|
||||||
|
import reduxStore from '../../createStore';
|
||||||
|
import { useSsl } from '../../../utils/url';
|
||||||
|
import { twoFactor } from '../../../utils/twoFactor';
|
||||||
|
|
||||||
|
class Sdk {
|
||||||
|
private sdk: typeof Rocketchat;
|
||||||
|
private code: any;
|
||||||
|
|
||||||
|
// TODO: We need to stop returning the SDK after all methods are dehydrated
|
||||||
|
initialize(server: string) {
|
||||||
|
this.code = null;
|
||||||
|
|
||||||
|
// The app can't reconnect if reopen interval is 5s while in development
|
||||||
|
this.sdk = new Rocketchat({ host: server, protocol: 'ddp', useSsl: useSsl(server), reopen: __DEV__ ? 20000 : 5000 });
|
||||||
|
return this.sdk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: evaluate the need for assigning "null" to this.sdk
|
||||||
|
* I'm returning "null" because we need to remove both instances of this.sdk here and on rocketchat.js
|
||||||
|
*/
|
||||||
|
disconnect() {
|
||||||
|
if (this.sdk) {
|
||||||
|
this.sdk.disconnect();
|
||||||
|
this.sdk = null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(...args: any[]): Promise<any> {
|
||||||
|
return this.sdk.get(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
post(...args: any[]): Promise<any> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const isMethodCall = args[0]?.startsWith('method.call/');
|
||||||
|
try {
|
||||||
|
const result = await this.sdk.post(...args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if API_Use_REST_For_DDP_Calls is enabled and it's a method call,
|
||||||
|
* responses have a different object structure
|
||||||
|
*/
|
||||||
|
if (isMethodCall) {
|
||||||
|
const response = JSON.parse(result.message);
|
||||||
|
if (response?.error) {
|
||||||
|
throw response.error;
|
||||||
|
}
|
||||||
|
return resolve(response.result);
|
||||||
|
}
|
||||||
|
return resolve(result);
|
||||||
|
} catch (e: any) {
|
||||||
|
const errorType = isMethodCall ? e?.error : e?.data?.errorType;
|
||||||
|
const totpInvalid = 'totp-invalid';
|
||||||
|
const totpRequired = 'totp-required';
|
||||||
|
if ([totpInvalid, totpRequired].includes(errorType)) {
|
||||||
|
const { details } = isMethodCall ? e : e?.data;
|
||||||
|
try {
|
||||||
|
await twoFactor({ method: details?.method, invalid: errorType === totpInvalid });
|
||||||
|
return resolve(this.post(...args));
|
||||||
|
} catch {
|
||||||
|
// twoFactor was canceled
|
||||||
|
return resolve({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
methodCall(...args: any[]): Promise<any> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const result = await this.sdk?.methodCall(...args, this.code || '');
|
||||||
|
return resolve(result);
|
||||||
|
} catch (e: any) {
|
||||||
|
if (e.error && (e.error === 'totp-required' || e.error === 'totp-invalid')) {
|
||||||
|
const { details } = e;
|
||||||
|
try {
|
||||||
|
this.code = await twoFactor({ method: details?.method, invalid: e.error === 'totp-invalid' });
|
||||||
|
return resolve(this.methodCall(...args));
|
||||||
|
} catch {
|
||||||
|
// twoFactor was canceled
|
||||||
|
return resolve({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
methodCallWrapper(method: string, ...params: any[]): Promise<any> {
|
||||||
|
const { API_Use_REST_For_DDP_Calls } = reduxStore.getState().settings;
|
||||||
|
const { user } = reduxStore.getState().login;
|
||||||
|
if (API_Use_REST_For_DDP_Calls) {
|
||||||
|
const url = isEmpty(user) ? 'method.callAnon' : 'method.call';
|
||||||
|
return this.post(`${url}/${method}`, {
|
||||||
|
message: EJSON.stringify({ method, params })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const parsedParams = params.map(param => {
|
||||||
|
if (param instanceof Date) {
|
||||||
|
return { $date: new Date(param).getTime() };
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
});
|
||||||
|
return this.methodCall(method, ...parsedParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sdk = new Sdk();
|
||||||
|
|
||||||
|
export default sdk;
|
|
@ -0,0 +1,6 @@
|
||||||
|
import sdk from './sdk';
|
||||||
|
|
||||||
|
// RC 0.64.0
|
||||||
|
const toggleFavorite = (roomId: string, favorite: boolean) => sdk.post('rooms.favorite', { roomId, favorite });
|
||||||
|
|
||||||
|
export default toggleFavorite;
|
|
@ -13,7 +13,7 @@ import Loading from '../containers/Loading';
|
||||||
import SafeAreaView from '../containers/SafeAreaView';
|
import SafeAreaView from '../containers/SafeAreaView';
|
||||||
import SearchBox from '../containers/SearchBox';
|
import SearchBox from '../containers/SearchBox';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
import { IApplicationState, IBaseScreen } from '../definitions';
|
import { IApplicationState, IBaseScreen, ISubscription } from '../definitions';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
@ -265,7 +265,7 @@ class SelectedUsersView extends React.Component<ISelectedUsersViewProps, ISelect
|
||||||
|
|
||||||
const data = (search.length > 0 ? search : chats)
|
const data = (search.length > 0 ? search : chats)
|
||||||
// filter DM between multiple users
|
// filter DM between multiple users
|
||||||
.filter(sub => !RocketChat.isGroupChat(sub));
|
.filter(sub => !RocketChat.isGroupChat(sub as ISubscription));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<FlatList
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useTheme } from '../../theme';
|
||||||
import { isAndroid, isTablet } from '../../utils/deviceInfo';
|
import { isAndroid, isTablet } from '../../utils/deviceInfo';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import { makeThreadName } from '../../utils/room';
|
import { makeThreadName } from '../../utils/room';
|
||||||
|
import { ISubscription } from '../../definitions';
|
||||||
|
|
||||||
const androidMarginLeft = isTablet ? 0 : 4;
|
const androidMarginLeft = isTablet ? 0 : 4;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ const styles = StyleSheet.create({
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IHeader {
|
interface IHeader {
|
||||||
room: { prid?: string; t?: string };
|
room: ISubscription;
|
||||||
thread: { id?: string };
|
thread: { id?: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue