Skip to content
Snippets Groups Projects
rocketchat.js 26.8 KiB
Newer Older
import { AsyncStorage, InteractionManager } from 'react-native';
import semver from 'semver';
import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
import RNUserDefaults from 'rn-user-defaults';
import * as FileSystem from 'expo-file-system';
import reduxStore from './createStore';
import defaultSettings from '../constants/settings';
import messagesStatus from '../constants/messagesStatus';
import database from './realm';
import log from '../utils/log';
import { isIOS, getBundleId } from '../utils/deviceInfo';
import { extractHostname } from '../utils/server';
Guilherme Gazzo's avatar
Guilherme Gazzo committed

Diego Mello's avatar
Diego Mello committed
import {
Diego Mello's avatar
Diego Mello committed
	setUser, setLoginServices, loginRequest, loginFailure, logout
Diego Mello's avatar
Diego Mello committed
} from '../actions/login';
Diego Mello's avatar
Diego Mello committed
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
import {
	shareSelectServer, shareSetUser
} from '../actions/share';
Guilherme Gazzo's avatar
Guilherme Gazzo committed
import subscribeRooms from './methods/subscriptions/rooms';
import subscribeRoom from './methods/subscriptions/room';
Guilherme Gazzo's avatar
Guilherme Gazzo committed

Guilherme Gazzo's avatar
Guilherme Gazzo committed
import protectedFunction from './methods/helpers/protectedFunction';
import readMessages from './methods/readMessages';
import getSettings from './methods/getSettings';
Guilherme Gazzo's avatar
Guilherme Gazzo committed
import getRooms from './methods/getRooms';
import getPermissions from './methods/getPermissions';
import getCustomEmojis from './methods/getCustomEmojis';
import getSlashCommands from './methods/getSlashCommands';
import getRoles from './methods/getRoles';
Diego Mello's avatar
Diego Mello committed
import canOpenRoom from './methods/canOpenRoom';
Guilherme Gazzo's avatar
Guilherme Gazzo committed

import loadMessagesForRoom from './methods/loadMessagesForRoom';
import loadMissedMessages from './methods/loadMissedMessages';
Diego Mello's avatar
Diego Mello committed
import loadThreadMessages from './methods/loadThreadMessages';
Diego Mello's avatar
Diego Mello committed
import sendMessage, { getMessage, sendMessageCall } from './methods/sendMessage';
import { sendFileMessage, cancelUpload, isUploadActive } from './methods/sendFileMessage';
Guilherme Gazzo's avatar
Guilherme Gazzo committed

import { getDeviceToken } from '../notifications/push';
import { SERVERS, SERVER_URL } from '../constants/userDefaults';
Guilherme Gazzo's avatar
Guilherme Gazzo committed
const TOKEN_KEY = 'reactnativemeteor_usertoken';
const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
export const MARKDOWN_KEY = 'RC_MARKDOWN_KEY';
export const CRASH_REPORT_KEY = 'RC_CRASH_REPORT_KEY';
Guilherme Gazzo's avatar
Guilherme Gazzo committed
const returnAnArray = obj => obj || [];
const MIN_ROCKETCHAT_VERSION = '0.70.0';
const STATUSES = ['offline', 'online', 'away', 'busy'];

Rodrigo Nascimento's avatar
Rodrigo Nascimento committed
const RocketChat = {
Diego Mello's avatar
Diego Mello committed
	TOKEN_KEY,
	async subscribeRooms() {
		if (this.roomsSub) {
			this.roomsSub.stop();
		}
		this.roomsSub = await subscribeRooms.call(this);
	},
Guilherme Gazzo's avatar
Guilherme Gazzo committed
	subscribeRoom,
Diego Mello's avatar
Diego Mello committed
	canOpenRoom,
	createChannel({
		name, users, type, readOnly, broadcast
	}) {
		// RC 0.51.0
		return this.sdk.methodCall(type ? 'createPrivateGroup' : 'createChannel', name, users, readOnly, {}, { broadcast });
Rodrigo Nascimento's avatar
Rodrigo Nascimento committed
	async getUserToken() {
		try {
			return await RNUserDefaults.get(TOKEN_KEY);
Rodrigo Nascimento's avatar
Rodrigo Nascimento committed
		} catch (error) {
			console.warn(`RNUserDefaults error: ${ error.message }`);
Diego Mello's avatar
Diego Mello committed
	async getServerInfo(server) {
Diego Mello's avatar
Diego Mello committed
			const result = await fetch(`${ server }/api/info`).then(response => response.json());
			if (result.success) {
				if (semver.lt(result.version, MIN_ROCKETCHAT_VERSION)) {
					return {
						success: false,
						message: 'Invalid_server_version',
						messageOptions: {
Diego Mello's avatar
Diego Mello committed
							currentVersion: result.version,
							minVersion: MIN_ROCKETCHAT_VERSION
						}
					};
				}
Diego Mello's avatar
Diego Mello committed
				return result;
		} catch (e) {
		return {
			success: false,
			message: 'The_URL_is_invalid'
		};
Diego Mello's avatar
Diego Mello committed
	_setUser(ddpMessage) {
		this.activeUsers = this.activeUsers || {};
Diego Mello's avatar
Diego Mello committed
		const { user } = reduxStore.getState().login;
Diego Mello's avatar
Diego Mello committed
		if (ddpMessage.fields && user && user.id === ddpMessage.id) {
Diego Mello's avatar
Diego Mello committed
			reduxStore.dispatch(setUser(ddpMessage.fields));
		if (ddpMessage.cleared && user && user.id === ddpMessage.id) {
			reduxStore.dispatch(setUser({ status: 'offline' }));
		}

		if (!this._setUserTimer) {
			this._setUserTimer = setTimeout(() => {
				const batchUsers = this.activeUsers;
				InteractionManager.runAfterInteractions(() => {
					database.memoryDatabase.write(() => {
						Object.keys(batchUsers).forEach((key) => {
							if (batchUsers[key] && batchUsers[key].id) {
								try {
									const data = batchUsers[key];
									if (data.removed) {
										const userRecord = database.memoryDatabase.objectForPrimaryKey('activeUsers', data.id);
										if (userRecord) {
											userRecord.status = 'offline';
										}
									} else {
										database.memoryDatabase.create('activeUsers', data, true);
									}
								} catch (error) {
									console.log(error);
								}
							}
						});
					});
				});
				this._setUserTimer = null;
				return this.activeUsers = {};
			}, 10000);
Diego Mello's avatar
Diego Mello committed
		if (!ddpMessage.fields) {
			this.activeUsers[ddpMessage.id] = {
				id: ddpMessage.id,
				removed: true
			};
Diego Mello's avatar
Diego Mello committed
		} else {
			this.activeUsers[ddpMessage.id] = {
				id: ddpMessage.id, ...this.activeUsers[ddpMessage.id], ...ddpMessage.fields
			};
Diego Mello's avatar
Diego Mello committed
	},
Diego Mello's avatar
Diego Mello committed
	connect({ server, user }) {
		return new Promise((resolve) => {
			database.setActiveDB(server);
			reduxStore.dispatch(connectRequest());
Guilherme Gazzo's avatar
Guilherme Gazzo committed

			if (this.connectTimeout) {
				clearTimeout(this.connectTimeout);
			}
			if (this.roomsSub) {
				this.roomsSub.stop();
			}

			if (this.sdk) {
				this.sdk.disconnect();
				this.sdk = null;
			}
			// Use useSsl: false only if server url starts with http://
			const useSsl = !/http:\/\//.test(server);

			this.sdk = new RocketchatClient({ host: server, protocol: 'ddp', useSsl });
			this.getSettings();

			this.sdk.connect()
				.then(() => {
					if (user && user.token) {
						reduxStore.dispatch(loginRequest({ resume: user.token }));
					}
				})
				.catch((err) => {
					console.log('connect error', err);

					// when `connect` raises an error, we try again in 10 seconds
					this.connectTimeout = setTimeout(() => {
						this.connect({ server, user });
					}, 10000);
				});
			this.sdk.onStreamData('connected', () => {
				reduxStore.dispatch(connectSuccess());
				// const { isAuthenticated } = reduxStore.getState().login;
				// if (isAuthenticated) {
				// 	this.getUserPresence();
				// }
Loading
Loading full blame...