Rocket.Chat.ReactNative/app/sagas/deepLinking.js

119 lines
3.3 KiB
JavaScript

import {
takeLatest, take, select, put, all, delay
} from 'redux-saga/effects';
import RNUserDefaults from 'rn-user-defaults';
import Navigation from '../lib/Navigation';
import * as types from '../actions/actionsTypes';
import { selectServerRequest } from '../actions/server';
import { inviteLinksSetToken, inviteLinksRequest } from '../actions/inviteLinks';
import database from '../lib/database';
import RocketChat from '../lib/rocketchat';
import EventEmitter from '../utils/events';
import { appStart } from '../actions';
import { localAuthenticate } from '../utils/localAuthentication';
const roomTypes = {
channel: 'c', direct: 'd', group: 'p', channels: 'l'
};
const handleInviteLink = function* handleInviteLink({ params, requireLogin = false }) {
if (params.path && params.path.startsWith('invite/')) {
const token = params.path.replace('invite/', '');
if (requireLogin) {
yield put(inviteLinksSetToken(token));
} else {
yield put(inviteLinksRequest(token));
}
}
};
const navigate = function* navigate({ params }) {
yield put(appStart('inside'));
if (params.path) {
const [type, name] = params.path.split('/');
if (type !== 'invite') {
const room = yield RocketChat.canOpenRoom(params);
if (room) {
yield Navigation.navigate('RoomsListView');
Navigation.navigate('RoomView', {
name,
t: roomTypes[type],
roomUserId: RocketChat.getUidDirectMessage(room),
...room
});
}
} else {
yield handleInviteLink({ params });
}
}
};
const handleOpen = function* handleOpen({ params }) {
if (!params.host) {
return;
}
let { host } = params;
if (!/^(http|https)/.test(host)) {
host = `https://${ params.host }`;
}
// remove last "/" from host
if (host.slice(-1) === '/') {
host = host.slice(0, host.length - 1);
}
const [server, user] = yield all([
RNUserDefaults.get('currentServer'),
RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ host }`)
]);
// TODO: needs better test
// if deep link is from same server
if (server === host && user) {
const connected = yield select(state => state.server.connected);
if (!connected) {
yield localAuthenticate(host);
yield put(selectServerRequest(host));
yield take(types.SERVER.SELECT_SUCCESS);
}
yield navigate({ params });
} else {
// search if deep link's server already exists
const serversDB = database.servers;
const serversCollection = serversDB.collections.get('servers');
try {
const servers = yield serversCollection.find(host);
if (servers && user) {
yield localAuthenticate(host);
yield put(selectServerRequest(host));
yield take(types.LOGIN.SUCCESS);
yield navigate({ params });
return;
}
} catch (e) {
// do nothing?
}
// if deep link is from a different server
const result = yield RocketChat.getServerInfo(host);
if (!result.success) {
return;
}
Navigation.navigate('NewServerView', { previousServer: server });
yield delay(1000);
EventEmitter.emit('NewServer', { server: host });
if (params.token) {
yield take(types.SERVER.SELECT_SUCCESS);
yield RocketChat.connect({ server: host, user: { token: params.token } });
} else {
yield handleInviteLink({ params, requireLogin: true });
}
}
};
const root = function* root() {
yield takeLatest(types.DEEP_LINKING.OPEN, handleOpen);
};
export default root;