[Gekidou MM-3972] Websocket Events - Reaction and emojis (#5920)

* Wip

* update name so it references changing the reaction on a post

* handleAddEmoji -> handleAddCustomEmoji

* add remove reaction logic

* sanitizeReactions
  * use skipSync to return early if not deleting any records that are
    not in the server db
  * return the filtered delete results and have the handler destroy the
    records

* fix lint

* use forEach instead of map.

* PR feedback

* PR feedback

* Update app/actions/websocket/reactions.ts

* remove console.log

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
Jason Frerich
2022-02-03 04:14:08 -06:00
committed by GitHub
parent 4e8d655167
commit f815f6b3e5
5 changed files with 82 additions and 6 deletions

View File

@@ -22,6 +22,7 @@ import {queryCurrentUser} from '@queries/servers/user';
import {handleChannelDeletedEvent, handleUserAddedToChannelEvent, handleUserRemovedFromChannelEvent} from './channel';
import {handleNewPostEvent, handlePostDeleted, handlePostEdited, handlePostUnread} from './posts';
import {handlePreferenceChangedEvent, handlePreferencesChangedEvent, handlePreferencesDeletedEvent} from './preferences';
import {handleAddCustomEmoji, handleReactionRemovedFromPostEvent, handleReactionAddedToPostEvent} from './reactions';
import {handleUserRoleUpdatedEvent, handleTeamMemberRoleUpdatedEvent, handleRoleUpdatedEvent} from './roles';
import {handleLeaveTeamEvent, handleUserAddedToTeamEvent, handleUpdateTeamEvent} from './teams';
import {handleUserUpdatedEvent} from './users';
@@ -260,17 +261,17 @@ export async function handleEvent(serverUrl: string, msg: WebSocketMessage) {
// handleHelloEvent(msg);
// break;
case WebsocketEvents.REACTION_ADDED:
handleReactionAddedToPostEvent(serverUrl, msg);
break;
// return dispatch(handleReactionAddedEvent(msg));
case WebsocketEvents.REACTION_REMOVED:
handleReactionRemovedFromPostEvent(serverUrl, msg);
break;
// return dispatch(handleReactionRemovedEvent(msg));
case WebsocketEvents.EMOJI_ADDED:
handleAddCustomEmoji(serverUrl, msg);
break;
// return dispatch(handleAddEmoji(msg));
case WebsocketEvents.LICENSE_CHANGED:
break;

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
export async function handleAddCustomEmoji(serverUrl: string, msg: WebSocketMessage): Promise<void> {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
return;
}
try {
const emoji = JSON.parse(msg.data.emoji) as CustomEmoji;
await operator.handleCustomEmojis({
prepareRecordsOnly: false,
emojis: [emoji],
});
} catch {
// Do nothing
}
}
export async function handleReactionAddedToPostEvent(serverUrl: string, msg: WebSocketMessage): Promise<void> {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
return;
}
try {
const reaction = JSON.parse(msg.data.reaction) as Reaction;
await operator.handleReactions({
prepareRecordsOnly: false,
skipSync: true,
postsReactions: [{
post_id: reaction.post_id,
reactions: [reaction],
}],
});
} catch {
// Do nothing
}
}
export async function handleReactionRemovedFromPostEvent(serverUrl: string, msg: WebSocketMessage): Promise<void> {
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
if (!database) {
return;
}
try {
const msgReaction = JSON.parse(msg.data.reaction) as Reaction;
const reaction = await database.get(MM_TABLES.SERVER.REACTION).query(
Q.where('emoji_name', msgReaction.emoji_name),
Q.where('post_id', msgReaction.post_id),
Q.where('user_id', msgReaction.user_id),
).fetch();
if (reaction.length) {
await database.write(async () => {
await reaction[0].destroyPermanently();
});
}
} catch {
// Do nothing
}
}

View File

@@ -152,6 +152,7 @@ const UserHandler = (superclass: any) => class extends superclass {
database: this.database,
post_id,
rawReactions: rawValues,
skipSync,
});
if (createReactions?.length) {
@@ -165,6 +166,7 @@ const UserHandler = (superclass: any) => class extends superclass {
}
if (deleteReactions?.length && !skipSync) {
deleteReactions.forEach((outCast) => outCast.prepareDestroyPermanently());
batchRecords.push(...deleteReactions);
}
}

View File

@@ -19,7 +19,7 @@ const {REACTION} = MM_TABLES.SERVER;
* @param {RawReaction[]} sanitizeReactions.rawReactions
* @returns {Promise<{createReactions: RawReaction[], deleteReactions: Reaction[]}>}
*/
export const sanitizeReactions = async ({database, post_id, rawReactions}: SanitizeReactionsArgs) => {
export const sanitizeReactions = async ({database, post_id, rawReactions, skipSync}: SanitizeReactionsArgs) => {
const reactions = (await database.collections.
get(REACTION).
query(Q.where('post_id', post_id)).
@@ -45,10 +45,13 @@ export const sanitizeReactions = async ({database, post_id, rawReactions}: Sanit
}
}
if (skipSync) {
return {createReactions, deleteReactions: []};
}
// finding out elements to delete using array subtract
const deleteReactions = reactions.
filter((reaction) => !similarObjects.includes(reaction)).
map((outCast) => outCast.prepareDestroyPermanently());
filter((reaction) => !similarObjects.includes(reaction));
return {createReactions, deleteReactions};
};

View File

@@ -92,6 +92,7 @@ export type SanitizeReactionsArgs = {
database: Database;
post_id: string;
rawReactions: Reaction[];
skipSync?: boolean;
};
export type ChainPostsArgs = {