Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions app/lib/connect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import database from './database';
import { useSsl } from '../utils/url';
import { connectSuccess } from '../actions/connect';
import reduxStore from './createStore';

const CURRENT_SERVER = 'currentServer';

const Connect = {
stopListener(listener) {
return listener && listener.stop();
},
onStreamData(...args) {
return this.rocketChatInstance.onStreamData(...args);
},
connect({ server, user, logoutOnError = false }) {
return new Promise((resolve) => {
if (!this.rocketChatInstance || this.rocketChatInstance.client.host !== server) {
database.setActiveDB(server);
}
reduxStore.dispatch(connectRequest());

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

if (this.connectedListener) {
this.connectedListener.then(this.stopListener);
}

if (this.closeListener) {
this.closeListener.then(this.stopListener);
}

if (this.usersListener) {
this.usersListener.then(this.stopListener);
}

if (this.notifyLoggedListener) {
this.notifyLoggedListener.then(this.stopListener);
}

RocketChat.unsubscribeRooms();

EventEmitter.emit('INQUIRY_UNSUBSCRIBE');

if (this.rocketChatInstance) {
this.rocketChatInstance.disconnect();
this.rocketChatInstance = null;
}

if (this.code) {
this.code = null;
}

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

const sdkConnect = () => this.rocketChatInstance.connect()
.then(() => {
const { server: currentServer } = reduxStore.getState().server;
if (user && user.token && server === currentServer) {
reduxStore.dispatch(loginRequest({ resume: user.token }, logoutOnError));
}
})
.catch((err) => {
console.log('connect error', err);

// when `connect` raises an error, we try again in 10 seconds
this.connectTimeout = setTimeout(() => {
if (this.rocketChatInstance?.client?.host === server) {
sdkConnect();
}
}, 10000);
});

sdkConnect();

this.connectedListener = this.rocketChatInstance.onStreamData('connected', () => {
reduxStore.dispatch(connectSuccess());
});

this.closeListener = this.rocketChatInstance.onStreamData('close', () => {
reduxStore.dispatch(disconnect());
});

this.usersListener = this.rocketChatInstance.onStreamData('users',
protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));

this.notifyLoggedListener = this.rocketChatInstance.onStreamData('stream-notify-logged',
protectedFunction(async(ddpMessage) => {
const { eventName } = ddpMessage.fields;
if (/user-status/.test(eventName)) {
this.activeUsers = this.activeUsers || {};
// Check if timer has ran out if it exists
if (!this._setUserTimer) {
this._setUserTimer = setTimeout(() => {
const activeUsersBatch = this.activeUsers;
InteractionManager.runAfterInteractions(() => {
reduxStore.dispatch(setActiveUsers(activeUsersBatch));
});
this._setUserTimer = null;
return this.activeUsers = {};
}, 10000);
}
const userStatus = ddpMessage.fields.args[0];
const [id,, status, statusText] = userStatus;
this.activeUsers[id] = { status: STATUSES[status], statusText };

const { user: loggedUser } = reduxStore.getState().login;
if (loggedUser && loggedUser.id === id) {
reduxStore.dispatch(setUser({ status: STATUSES[status], statusText }));
}
} else if (/updateAvatar/.test(eventName)) {
const { username, etag } = ddpMessage.fields.args[0];
const db = database.active;
const userCollection = db.collections.get('users');
try {
const [userRecord] = await userCollection.query(Q.where('username',
Q.eq(username))).fetch();
await db.action(async() => {
await userRecord.update((u) => {
u.avatarETag = etag;
});
});
} catch {
// We can't create a new record since we don't receive the user._id
}
} else if (/Users:NameChanged/.test(eventName)) {
const userNameChanged = ddpMessage.fields.args[0];
const db = database.active;
const userCollection = db.collections.get('users');
try {
const userRecord = await userCollection.find(userNameChanged._id);
await db.action(async() => {
await userRecord.update((u) => {
Object.assign(u, userNameChanged);
});
});
} catch {
// User not found
await db.action(async() => {
await userCollection.create((u) => {
u._raw = sanitizedRaw({ id: userNameChanged._id }, userCollection.schema);
Object.assign(u, userNameChanged);
});
});
}
}
}));

resolve();
});
}
}

export default Connection;
145 changes: 0 additions & 145 deletions app/lib/rocketchat.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from '@rocket.chat/sdk';
import { Q } from '@nozbe/watermelondb';
import AsyncStorage from '@react-native-community/async-storage';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import RNFetchBlob from 'rn-fetch-blob';

import reduxStore from './createStore';
Expand All @@ -24,7 +23,6 @@ import { shareSelectServer, shareSetUser, shareSetSettings } from '../actions/sh
import subscribeRooms from './methods/subscriptions/rooms';
import getUsersPresence, { getUserPresence, subscribeUsersPresence } from './methods/getUsersPresence';

import protectedFunction from './methods/helpers/protectedFunction';
import readMessages from './methods/readMessages';
import getSettings, { getLoginSettings, setSettings } from './methods/getSettings';

Expand Down Expand Up @@ -57,7 +55,6 @@ import { selectServerFailure } from '../actions/server';
import { useSsl } from '../utils/url';
import UserPreferences from './userPreferences';
import { Encryption } from './encryption';
import EventEmitter from '../utils/events';
import { sanitizeLikeString } from './database/utils';

const TOKEN_KEY = 'reactnativemeteor_usertoken';
Expand Down Expand Up @@ -160,9 +157,6 @@ const RocketChat = {
message: I18n.t('Not_RC_Server', { contact: I18n.t('Contact_your_server_admin') })
};
},
stopListener(listener) {
return listener && listener.stop();
},
// Abort all requests and create a new AbortController
abort() {
if (this.controller) {
Expand All @@ -173,142 +167,6 @@ const RocketChat = {
}
this.controller = new AbortController();
},
connect({ server, user, logoutOnError = false }) {
return new Promise((resolve) => {
if (!this.sdk || this.sdk.client.host !== server) {
database.setActiveDB(server);
}
reduxStore.dispatch(connectRequest());

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

if (this.connectedListener) {
this.connectedListener.then(this.stopListener);
}

if (this.closeListener) {
this.closeListener.then(this.stopListener);
}

if (this.usersListener) {
this.usersListener.then(this.stopListener);
}

if (this.notifyLoggedListener) {
this.notifyLoggedListener.then(this.stopListener);
}

this.unsubscribeRooms();

EventEmitter.emit('INQUIRY_UNSUBSCRIBE');

if (this.sdk) {
this.sdk.disconnect();
this.sdk = null;
}

if (this.code) {
this.code = null;
}

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

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

// when `connect` raises an error, we try again in 10 seconds
this.connectTimeout = setTimeout(() => {
if (this.sdk?.client?.host === server) {
sdkConnect();
}
}, 10000);
});

sdkConnect();

this.connectedListener = this.sdk.onStreamData('connected', () => {
reduxStore.dispatch(connectSuccess());
});

this.closeListener = this.sdk.onStreamData('close', () => {
reduxStore.dispatch(disconnect());
});

this.usersListener = this.sdk.onStreamData('users', protectedFunction(ddpMessage => RocketChat._setUser(ddpMessage)));

this.notifyLoggedListener = this.sdk.onStreamData('stream-notify-logged', protectedFunction(async(ddpMessage) => {
const { eventName } = ddpMessage.fields;
if (/user-status/.test(eventName)) {
this.activeUsers = this.activeUsers || {};
if (!this._setUserTimer) {
this._setUserTimer = setTimeout(() => {
const activeUsersBatch = this.activeUsers;
InteractionManager.runAfterInteractions(() => {
reduxStore.dispatch(setActiveUsers(activeUsersBatch));
});
this._setUserTimer = null;
return this.activeUsers = {};
}, 10000);
}
const userStatus = ddpMessage.fields.args[0];
const [id,, status, statusText] = userStatus;
this.activeUsers[id] = { status: STATUSES[status], statusText };

const { user: loggedUser } = reduxStore.getState().login;
if (loggedUser && loggedUser.id === id) {
reduxStore.dispatch(setUser({ status: STATUSES[status], statusText }));
}
} else if (/updateAvatar/.test(eventName)) {
const { username, etag } = ddpMessage.fields.args[0];
const db = database.active;
const userCollection = db.collections.get('users');
try {
const [userRecord] = await userCollection.query(Q.where('username', Q.eq(username))).fetch();
await db.action(async() => {
await userRecord.update((u) => {
u.avatarETag = etag;
});
});
} catch {
// We can't create a new record since we don't receive the user._id
}
} else if (/Users:NameChanged/.test(eventName)) {
const userNameChanged = ddpMessage.fields.args[0];
const db = database.active;
const userCollection = db.collections.get('users');
try {
const userRecord = await userCollection.find(userNameChanged._id);
await db.action(async() => {
await userRecord.update((u) => {
Object.assign(u, userNameChanged);
});
});
} catch {
// User not found
await db.action(async() => {
await userCollection.create((u) => {
u._raw = sanitizedRaw({ id: userNameChanged._id }, userCollection.schema);
Object.assign(u, userNameChanged);
});
});
}
}
}));

resolve();
});
},

async shareExtensionInit(server) {
database.setShareDB(server);

Expand Down Expand Up @@ -800,9 +658,6 @@ const RocketChat = {
unsubscribe(subscription) {
return this.sdk.unsubscribe(subscription);
},
onStreamData(...args) {
return this.sdk.onStreamData(...args);
},
emitTyping(room, typing = true) {
const { login, settings } = reduxStore.getState();
const { UI_Use_Real_Name } = settings;
Expand Down