forked from Ivasoft/mattermost-mobile
* Extract common observers to queries * Separate also queries and more agressive refactoring * Use query to avoid throws from findAndObserve * Fix minor error * Address feedback * Address feedback * Address feedback * Fix model types * Address feedback
115 lines
4.6 KiB
TypeScript
115 lines
4.6 KiB
TypeScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
import {Model} from '@nozbe/watermelondb';
|
|
import {DeviceEventEmitter} from 'react-native';
|
|
|
|
import {updateChannelsDisplayName} from '@actions/local/channel';
|
|
import {fetchMe, fetchUsersByIds} from '@actions/remote/user';
|
|
import {General, Events, Preferences} from '@constants';
|
|
import DatabaseManager from '@database/manager';
|
|
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
|
|
import WebsocketManager from '@init/websocket_manager';
|
|
import {queryChannelsByTypes, queryUserChannelsByTypes} from '@queries/servers/channel';
|
|
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
|
import {getCommonSystemValues} from '@queries/servers/system';
|
|
import {getCurrentUser} from '@queries/servers/user';
|
|
import {displayUsername} from '@utils/user';
|
|
|
|
export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMessage) {
|
|
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
|
if (!operator) {
|
|
return;
|
|
}
|
|
|
|
const {database} = operator;
|
|
const currentUser = await getCurrentUser(database);
|
|
if (!currentUser) {
|
|
return;
|
|
}
|
|
|
|
const user: UserProfile = msg.data.user;
|
|
const modelsToBatch: Model[] = [];
|
|
let userToSave = user;
|
|
|
|
if (user.id === currentUser.id) {
|
|
if (user.update_at > (currentUser?.updateAt || 0)) {
|
|
// ESR: 6.5
|
|
if (!user.notify_props || !Object.keys(user.notify_props).length) {
|
|
// Current user is sanitized so we fetch it from the server
|
|
// Need to request me to make sure we don't override with sanitized fields from the
|
|
// websocket event
|
|
const me = await fetchMe(serverUrl, true);
|
|
if (me.user) {
|
|
userToSave = me.user;
|
|
}
|
|
}
|
|
|
|
// Update GMs display name if locale has changed
|
|
if (user.locale !== currentUser.locale) {
|
|
const channels = await queryChannelsByTypes(database, [General.GM_CHANNEL]).fetch();
|
|
if (channels.length) {
|
|
const {models} = await updateChannelsDisplayName(serverUrl, channels, [user], true);
|
|
if (models?.length) {
|
|
modelsToBatch.push(...models);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
const channels = await queryUserChannelsByTypes(database, user.id, [General.DM_CHANNEL, General.GM_CHANNEL]).fetch();
|
|
if (channels.length) {
|
|
const {models} = await updateChannelsDisplayName(serverUrl, channels, [user], true);
|
|
if (models?.length) {
|
|
modelsToBatch.push(...models);
|
|
}
|
|
}
|
|
}
|
|
|
|
const userModel = await operator.handleUsers({users: [userToSave], prepareRecordsOnly: true});
|
|
modelsToBatch.push(...userModel);
|
|
|
|
try {
|
|
await operator.batchRecords(modelsToBatch);
|
|
} catch {
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
export async function handleUserTypingEvent(serverUrl: string, msg: WebSocketMessage) {
|
|
const currentServerUrl = await DatabaseManager.getActiveServerUrl();
|
|
if (currentServerUrl === serverUrl) {
|
|
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
|
if (!database) {
|
|
return;
|
|
}
|
|
|
|
const {config, license} = await getCommonSystemValues(database);
|
|
|
|
const {users, existingUsers} = await fetchUsersByIds(serverUrl, [msg.data.user_id]);
|
|
const user = users?.[0] || existingUsers?.[0];
|
|
|
|
const namePreference = await queryPreferencesByCategoryAndName(database, Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.NAME_NAME_FORMAT).fetch();
|
|
const teammateDisplayNameSetting = getTeammateNameDisplaySetting(namePreference, config, license);
|
|
const currentUser = await getCurrentUser(database);
|
|
const username = displayUsername(user, currentUser?.locale, teammateDisplayNameSetting);
|
|
const data = {
|
|
channelId: msg.broadcast.channel_id,
|
|
rootId: msg.data.parent_id,
|
|
userId: msg.data.user_id,
|
|
username,
|
|
now: Date.now(),
|
|
};
|
|
DeviceEventEmitter.emit(Events.USER_TYPING, data);
|
|
|
|
setTimeout(() => {
|
|
DeviceEventEmitter.emit(Events.USER_STOP_TYPING, data);
|
|
}, parseInt(config.TimeBetweenUserTypingUpdatesMilliseconds, 10));
|
|
}
|
|
}
|
|
|
|
export const userTyping = async (serverUrl: string, channelId: string, rootId?: string) => {
|
|
const client = WebsocketManager.getClient(serverUrl);
|
|
client?.sendUserTypingEvent(channelId, rootId);
|
|
};
|