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

182 lines
5.0 KiB
JavaScript
Raw Normal View History

2019-04-08 12:35:28 +00:00
import EJSON from 'ejson';
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 '../../realm';
2019-04-17 17:01:03 +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
2018-12-05 20:52:08 +00:00
const unsubscribe = subscriptions => subscriptions.forEach(sub => sub.unsubscribe().catch(() => console.log('unsubscribeRoom')));
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
2019-02-07 15:48:10 +00:00
export default function subscribeRoom({ rid }) {
2019-04-08 12:35:28 +00:00
let promises;
let connectedListener;
let disconnectedListener;
let notifyRoomListener;
let messageReceivedListener;
const typingTimeouts = {};
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 });
};
2019-04-08 12:35:28 +00:00
const getUserTyping = username => (
database
.memoryDatabase.objects('usersTyping')
.filtered('rid = $0 AND username = $1', rid, username)
);
const removeUserTyping = (username) => {
const userTyping = getUserTyping(username);
try {
database.memoryDatabase.write(() => {
database.memoryDatabase.delete(userTyping);
});
if (typingTimeouts[username]) {
clearTimeout(typingTimeouts[username]);
typingTimeouts[username] = null;
}
} catch (error) {
2019-05-28 16:18:46 +00:00
log('err_remove_user_typing', error);
2019-04-08 12:35:28 +00:00
}
};
const addUserTyping = (username) => {
const userTyping = getUserTyping(username);
// prevent duplicated
if (userTyping.length === 0) {
try {
database.memoryDatabase.write(() => {
database.memoryDatabase.create('usersTyping', { rid, username });
});
if (typingTimeouts[username]) {
clearTimeout(typingTimeouts[username]);
typingTimeouts[username] = null;
}
typingTimeouts[username] = setTimeout(() => {
removeUserTyping(username);
}, 10000);
} catch (error) {
2019-05-28 16:18:46 +00:00
log('err_add_user_typing', error);
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) {
addUserTyping(username);
} else {
removeUserTyping(username);
}
} else if (ev === 'deleteMessage') {
database.write(() => {
if (ddpMessage && ddpMessage.fields && ddpMessage.fields.args.length > 0) {
const { _id } = ddpMessage.fields.args[0];
const message = database.objects('messages').filtered('_id = $0', _id);
database.delete(message);
2019-04-17 17:01:03 +00:00
const thread = database.objects('threads').filtered('_id = $0', _id);
database.delete(thread);
const threadMessage = database.objects('threadMessages').filtered('_id = $0', _id);
database.delete(threadMessage);
const cleanTmids = database.objects('messages').filtered('tmid = $0', _id).snapshot();
if (cleanTmids && cleanTmids.length) {
cleanTmids.forEach((m) => {
m.tmid = null;
});
}
2019-04-08 12:35:28 +00:00
}
});
}
});
2019-04-17 17:01:03 +00:00
const read = debounce(() => {
const [room] = database.objects('subscriptions').filtered('rid = $0', rid);
if (room && room._id) {
2019-04-17 17:01:03 +00:00
this.readMessages(rid);
}
}, 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]));
2019-04-08 12:35:28 +00:00
if (rid !== message.rid) {
return;
}
requestAnimationFrame(() => {
try {
database.write(() => {
2019-04-17 17:01:03 +00:00
database.create('messages', message, true);
// if it's a thread "header"
if (message.tlm) {
database.create('threads', message, true);
} else if (message.tmid) {
message.rid = message.tmid;
database.create('threadMessages', message, true);
}
2019-04-08 12:35:28 +00:00
});
2019-04-17 17:01:03 +00:00
read();
2019-04-08 12:35:28 +00:00
} catch (e) {
console.warn('handleMessageReceived', e);
}
});
});
const stop = () => {
if (promises) {
promises.then(unsubscribe);
promises = false;
}
if (connectedListener) {
connectedListener.then(removeListener);
connectedListener = false;
}
if (disconnectedListener) {
disconnectedListener.then(removeListener);
disconnectedListener = false;
2019-02-07 15:48:10 +00:00
}
2019-04-08 12:35:28 +00:00
if (notifyRoomListener) {
notifyRoomListener.then(removeListener);
notifyRoomListener = false;
}
if (messageReceivedListener) {
messageReceivedListener.then(removeListener);
messageReceivedListener = false;
}
Object.keys(typingTimeouts).forEach((key) => {
if (typingTimeouts[key]) {
clearTimeout(typingTimeouts[key]);
typingTimeouts[key] = null;
}
});
database.memoryDatabase.write(() => {
const usersTyping = database.memoryDatabase.objects('usersTyping').filtered('rid == $0', rid);
database.memoryDatabase.delete(usersTyping);
});
};
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
try {
2019-02-07 15:48:10 +00:00
promises = this.sdk.subscribeRoom(rid);
2018-12-05 20:52:08 +00:00
} catch (e) {
2019-05-28 16:18:46 +00:00
log('err_subscribe_room', e);
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
};
}