From 83777e975905915685ed70a0fe73392c68008c8f Mon Sep 17 00:00:00 2001 From: Pavel <14926950+prichodko@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:30:43 +0200 Subject: [PATCH] Update handling of reactions (#277) * fix: reactions argument in callback * replace object with Set in reactions * update reactions in UI --- packages/status-js/src/client.ts | 2 +- packages/status-js/src/client/chat.ts | 26 ++++++++++---- .../src/client/community/get-reactions.ts | 29 ++++------------ .../client/community/handle-waku-message.ts | 15 ++++---- .../src/client/community/map-chat-message.ts | 34 +++++-------------- .../src/components/reaction-popover/index.tsx | 11 ++++-- .../chat/components/chat-message/index.tsx | 4 ++- .../components/chat-message/reactions.tsx | 33 ++++++++++-------- 8 files changed, 74 insertions(+), 80 deletions(-) diff --git a/packages/status-js/src/client.ts b/packages/status-js/src/client.ts index aee6ae62..eddbed17 100644 --- a/packages/status-js/src/client.ts +++ b/packages/status-js/src/client.ts @@ -104,7 +104,7 @@ class Client { } public handleWakuMessage = (wakuMessage: WakuMessage): void => { - handleWakuMessage(wakuMessage, this, this.community, this.account) + handleWakuMessage(wakuMessage, this, this.community) } } diff --git a/packages/status-js/src/client/chat.ts b/packages/status-js/src/client/chat.ts index 947d0916..c7229730 100644 --- a/packages/status-js/src/client/chat.ts +++ b/packages/status-js/src/client/chat.ts @@ -277,7 +277,7 @@ export class Chat { public handleEmojiReaction = ( messageId: string, reaction: EmojiReaction, - isMe: boolean + publicKey: string ) => { let messageIndex = this.messages.length while (--messageIndex >= 0) { @@ -295,7 +295,7 @@ export class Chat { this.messages[messageIndex].reactions = getReactions( reaction, this.messages[messageIndex].reactions, - isMe + publicKey ) this.emitMessages(this.messages) @@ -379,16 +379,30 @@ export class Chat { public sendReaction = async ( chatId: string, messageId: string, - reaction: EmojiReaction.Type + reaction: keyof ChatMessage['reactions'] ) => { + if (!this.client.account) { + throw new Error('Account not initialized') + } + + const message = this.getMessage(messageId) + + if (!message) { + throw new Error('Message not found') + } + + const retracted = message.reactions[reaction].has( + this.client.account.publicKey + ) + const payload = EmojiReaction.encode({ clock: BigInt(Date.now()), chatId: chatId, - messageType: 'COMMUNITY_CHAT', - grant: new Uint8Array([]), + messageType: 'COMMUNITY_CHAT' as MessageType, messageId, - retracted: false, type: reaction, + retracted, + grant: new Uint8Array([]), }) await this.client.sendWakuMessage( diff --git a/packages/status-js/src/client/community/get-reactions.ts b/packages/status-js/src/client/community/get-reactions.ts index 52aaa186..89730d45 100644 --- a/packages/status-js/src/client/community/get-reactions.ts +++ b/packages/status-js/src/client/community/get-reactions.ts @@ -3,40 +3,25 @@ import type { EmojiReaction } from '../../../protos/emoji-reaction' type Reaction = Exclude<`${EmojiReaction.Type}`, 'UNKNOWN_EMOJI_REACTION_TYPE'> export type Reactions = { - [key in Reaction]: { - count: number - me: boolean - } + [key in Reaction]: Set } export function getReactions( reaction: EmojiReaction, reactions: Reactions, - isMe: boolean -) { + publicKey: string +): Reactions { const { type, retracted } = reaction if (type === 'UNKNOWN_EMOJI_REACTION_TYPE') { return reactions } - const _reaction = { - count: reactions[type].count, - me: reactions[type].me, - } - - if (retracted && _reaction.count !== 0) { - _reaction.count -= 1 + if (retracted) { + reactions[type].delete(publicKey) } else { - _reaction.count += 1 + reactions[type].add(publicKey) } - if (isMe) { - _reaction.me = retracted ? false : true - } - - return { - ...reactions, - [type]: _reaction, - } + return reactions } diff --git a/packages/status-js/src/client/community/handle-waku-message.ts b/packages/status-js/src/client/community/handle-waku-message.ts index 98c0f5a4..6e2f326e 100644 --- a/packages/status-js/src/client/community/handle-waku-message.ts +++ b/packages/status-js/src/client/community/handle-waku-message.ts @@ -15,7 +15,6 @@ import { recoverPublicKey } from '../../utils/recover-public-key' import { getChatUuid } from './get-chat-uuid' import { mapChatMessage } from './map-chat-message' -import type { Account } from '../../account' import type { Client } from '../../client' import type { Community } from './community' import type { WakuMessage } from 'js-waku' @@ -24,8 +23,7 @@ export function handleWakuMessage( wakuMessage: WakuMessage, // state client: Client, - community: Community, - account?: Account + community: Community ): void { // decode (layers) if (!wakuMessage.payload) { @@ -151,11 +149,14 @@ export function handleWakuMessage( const messageId = decodedPayload.messageId const chatUuid = getChatUuid(decodedPayload.chatId) - const isMe = account?.publicKey === `0x${bytesToHex(publicKey)}` - community.chats - .get(chatUuid) - ?.handleEmojiReaction(messageId, decodedPayload, isMe) + const chat = community.chats.get(chatUuid) + + chat?.handleEmojiReaction( + messageId, + decodedPayload, + `0x${bytesToHex(publicKey)}` + ) success = true diff --git a/packages/status-js/src/client/community/map-chat-message.ts b/packages/status-js/src/client/community/map-chat-message.ts index 58479820..054ec9c3 100644 --- a/packages/status-js/src/client/community/map-chat-message.ts +++ b/packages/status-js/src/client/community/map-chat-message.ts @@ -6,40 +6,24 @@ export function mapChatMessage( props: { messageId: string chatUuid: string + publicKey: string } ): ChatMessage { - const { messageId, chatUuid } = props + const { messageId, chatUuid, publicKey } = props const message = { ...decodedMessage, messageId, chatUuid, pinned: false, + signer: publicKey, reactions: { - THUMBS_UP: { - count: 0, - me: false, - }, - THUMBS_DOWN: { - count: 0, - me: false, - }, - LOVE: { - count: 0, - me: false, - }, - LAUGH: { - count: 0, - me: false, - }, - SAD: { - count: 0, - me: false, - }, - ANGRY: { - count: 0, - me: false, - }, + THUMBS_UP: new Set(), + THUMBS_DOWN: new Set(), + LOVE: new Set(), + LAUGH: new Set(), + SAD: new Set(), + ANGRY: new Set(), }, } diff --git a/packages/status-react/src/components/reaction-popover/index.tsx b/packages/status-react/src/components/reaction-popover/index.tsx index ed71b140..692ad8f5 100644 --- a/packages/status-react/src/components/reaction-popover/index.tsx +++ b/packages/status-react/src/components/reaction-popover/index.tsx @@ -1,5 +1,6 @@ import React from 'react' +import { useAccount } from '~/src/protocol' import { styled } from '~/src/styles/config' import { Flex, Image, Popover, PopoverTrigger } from '~/src/system' @@ -43,18 +44,22 @@ export const emojis: Record = { export const ReactionPopover = (props: Props) => { const { reactions, children, onClick, ...popoverProps } = props + const { account } = useAccount() + return ( {children} {Object.entries(emojis).map(([type, emoji]) => { - const reaction = reactions[type] + const value = reactions[type] + const me = account ? value.has('0x' + account.publicKey) : false + return ( ) }