verdnatura-chat/app/lib/methods/subscriptions/room.js

246 lines
6.5 KiB
JavaScript
Raw Normal View History

2019-04-08 12:35:28 +00:00
import EJSON from 'ejson';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { InteractionManager } from 'react-native';
2019-04-08 12:35:28 +00:00
import log from '../../../utils/log';
2019-04-08 12:35:28 +00:00
import protectedFunction from '../helpers/protectedFunction';
import buildMessage from '../helpers/buildMessage';
import database from '../../database';
import reduxStore from '../../createStore';
import { addUserTyping, removeUserTyping, clearUserTyping } from '../../../actions/usersTyping';
2019-12-11 23:01:12 +00:00
import debounce from '../../../utils/debounce';
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
2020-01-29 20:20:36 +00:00
const unsubscribe = (subscriptions = []) => Promise.all(subscriptions.map(sub => sub.unsubscribe));
const removeListener = listener => listener.stop();
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
2020-01-29 20:20:36 +00:00
let promises;
let connectedListener;
let disconnectedListener;
let notifyRoomListener;
let messageReceivedListener;
2019-02-07 15:48:10 +00:00
export default function subscribeRoom({ rid }) {
console.log(`[RCRN] Subscribed to room ${ rid }`);
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
const handleConnection = () => {
this.loadMissedMessages({ rid }).catch(e => console.log(e));
2019-04-08 12:35:28 +00:00
};
const handleNotifyRoomReceived = protectedFunction((ddpMessage) => {
const [_rid, ev] = ddpMessage.fields.eventName.split('/');
if (rid !== _rid) {
return;
}
if (ev === 'typing') {
const [username, typing] = ddpMessage.fields.args;
if (typing) {
reduxStore.dispatch(addUserTyping(username));
2019-04-08 12:35:28 +00:00
} else {
reduxStore.dispatch(removeUserTyping(username));
2019-04-08 12:35:28 +00:00
}
} else if (ev === 'deleteMessage') {
InteractionManager.runAfterInteractions(async() => {
2019-04-08 12:35:28 +00:00
if (ddpMessage && ddpMessage.fields && ddpMessage.fields.args.length > 0) {
try {
const { _id } = ddpMessage.fields.args[0];
const db = database.active;
const msgCollection = db.collections.get('messages');
const threadsCollection = db.collections.get('threads');
const threadMessagesCollection = db.collections.get('thread_messages');
let deleteMessage;
let deleteThread;
let deleteThreadMessage;
// Delete message
try {
const m = await msgCollection.find(_id);
deleteMessage = m.prepareDestroyPermanently();
} catch (e) {
// Do nothing
}
// Delete thread
try {
const m = await threadsCollection.find(_id);
deleteThread = m.prepareDestroyPermanently();
} catch (e) {
// Do nothing
}
// Delete thread message
try {
const m = await threadMessagesCollection.find(_id);
deleteThreadMessage = m.prepareDestroyPermanently();
} catch (e) {
// Do nothing
}
await db.action(async() => {
await db.batch(
deleteMessage, deleteThread, deleteThreadMessage
);
2019-04-17 17:01:03 +00:00
});
} catch (e) {
log(e);
2019-04-17 17:01:03 +00:00
}
2019-04-08 12:35:28 +00:00
}
});
}
});
2019-12-11 23:01:12 +00:00
const read = debounce((lastOpen) => {
this.readMessages(rid, lastOpen);
}, 300);
2019-04-08 12:35:28 +00:00
const handleMessageReceived = protectedFunction((ddpMessage) => {
2019-04-17 17:01:03 +00:00
const message = buildMessage(EJSON.fromJSONValue(ddpMessage.fields.args[0]));
const lastOpen = new Date();
2019-04-08 12:35:28 +00:00
if (rid !== message.rid) {
return;
}
InteractionManager.runAfterInteractions(async() => {
const db = database.active;
const batch = [];
const msgCollection = db.collections.get('messages');
const threadsCollection = db.collections.get('threads');
const threadMessagesCollection = db.collections.get('thread_messages');
2019-12-11 23:01:12 +00:00
let messageRecord;
let threadRecord;
let threadMessageRecord;
// Create or update message
2019-04-08 12:35:28 +00:00
try {
2019-12-11 23:01:12 +00:00
messageRecord = await msgCollection.find(message._id);
} catch (error) {
2019-12-11 23:01:12 +00:00
// Do nothing
}
if (messageRecord) {
try {
const update = messageRecord.prepareUpdate((m) => {
Object.assign(m, message);
});
batch.push(update);
} catch (e) {
console.log(e);
}
} else {
batch.push(
msgCollection.prepareCreate(protectedFunction((m) => {
m._raw = sanitizedRaw({ id: message._id }, msgCollection.schema);
m.subscription.id = rid;
Object.assign(m, message);
}))
);
}
// Create or update thread
if (message.tlm) {
try {
2019-12-11 23:01:12 +00:00
threadRecord = await threadsCollection.find(message._id);
} catch (error) {
// Do nothing
}
if (threadRecord) {
batch.push(
2019-12-11 23:01:12 +00:00
threadRecord.prepareUpdate(protectedFunction((t) => {
Object.assign(t, message);
2019-12-11 23:01:12 +00:00
}))
);
2019-12-11 23:01:12 +00:00
} else {
batch.push(
threadsCollection.prepareCreate(protectedFunction((t) => {
t._raw = sanitizedRaw({ id: message._id }, threadsCollection.schema);
t.subscription.id = rid;
Object.assign(t, message);
}))
);
}
}
2019-04-08 12:35:28 +00:00
// Create or update thread message
if (message.tmid) {
try {
2019-12-11 23:01:12 +00:00
threadMessageRecord = await threadMessagesCollection.find(message._id);
} catch (error) {
// Do nothing
}
if (threadMessageRecord) {
batch.push(
2019-12-11 23:01:12 +00:00
threadMessageRecord.prepareUpdate(protectedFunction((tm) => {
Object.assign(tm, message);
tm.rid = message.tmid;
delete tm.tmid;
2019-12-11 23:01:12 +00:00
}))
);
2019-12-11 23:01:12 +00:00
} else {
batch.push(
threadMessagesCollection.prepareCreate(protectedFunction((tm) => {
tm._raw = sanitizedRaw({ id: message._id }, threadMessagesCollection.schema);
Object.assign(tm, message);
tm.subscription.id = rid;
tm.rid = message.tmid;
delete tm.tmid;
}))
);
}
}
2019-12-11 23:01:12 +00:00
read(lastOpen);
try {
await db.action(async() => {
await db.batch(...batch);
});
} catch (e) {
log(e);
2019-04-08 12:35:28 +00:00
}
});
});
2020-01-29 20:20:36 +00:00
const stop = async() => {
let params;
if (promises) {
2020-01-29 20:20:36 +00:00
try {
params = await promises;
await unsubscribe(params);
} catch (error) {
// Do nothing
}
promises = false;
}
if (connectedListener) {
2020-01-29 20:20:36 +00:00
params = await connectedListener;
removeListener(params);
connectedListener = false;
}
if (disconnectedListener) {
2020-01-29 20:20:36 +00:00
params = await disconnectedListener;
removeListener(params);
disconnectedListener = false;
2019-02-07 15:48:10 +00:00
}
2019-04-08 12:35:28 +00:00
if (notifyRoomListener) {
2020-01-29 20:20:36 +00:00
params = await notifyRoomListener;
removeListener(params);
2019-04-08 12:35:28 +00:00
notifyRoomListener = false;
}
if (messageReceivedListener) {
2020-01-29 20:20:36 +00:00
params = await messageReceivedListener;
removeListener(params);
2019-04-08 12:35:28 +00:00
messageReceivedListener = false;
}
reduxStore.dispatch(clearUserTyping());
};
connectedListener = this.sdk.onStreamData('connected', handleConnection);
disconnectedListener = this.sdk.onStreamData('close', handleConnection);
2019-04-08 12:35:28 +00:00
notifyRoomListener = this.sdk.onStreamData('stream-notify-room', handleNotifyRoomReceived);
messageReceivedListener = this.sdk.onStreamData('stream-room-messages', handleMessageReceived);
2018-12-05 20:52:08 +00:00
2020-01-29 20:20:36 +00:00
promises = this.sdk.subscribeRoom(rid);
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
return {
stop: () => stop()
Beta (#265) * Fabric iOS * Fabric configured on iOS and Android * - react-native-fabric configured - login tracked * README updated * Run scripts from README updated * README scripts * get rooms and messages by rest * user status * more improves * more improves * send pong on timeout * fix some methods * more tests * rest messages * Room actions (#266) * Toggle notifications * Search messages * Invite users * Mute/Unmute users in room * rocket.cat messages * Room topic layout fixed * Starred messages loading onEndReached * Room actions onEndReached * Unnecessary login request * Login loading * Login services fixed * User presence layout * ïmproves on room actions view * Removed unnecessary data from SelectedUsersView * load few messages on open room, search message improve * fix loading messages forever * Removed state from search * Custom message time format * secureTextEntry layout * Reduce android app size * Roles subscription fix * Public routes navigation * fix reconnect * - New login/register, login, register * proguard * Login flux * App init/restore * Android layout fixes * Multiple meteor connection requests fixed * Nested attachments * Nested attachments * fix check status * New login layout (#269) * Public routes navigation * New login/register, login, register * Multiple meteor connection requests fixed * Nested attachments * Button component * TextInput android layout fixed * Register fixed * Thinner close modal button * Requests /me after login only one time * Static images moved * fix reconnect * fix ddp * fix custom emoji * New message layout (#273) * Grouping messages * Message layout * Users typing animation * Image attachment layout
2018-04-24 19:34:03 +00:00
};
}