diff --git a/dist/index.js b/dist/index.js index 06cb349f..65230bc0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1260,7 +1260,10 @@ this.handleReaction = (reaction) => { if (!checkMatchesObjectStructure(reaction, ChatMessageReactionReference)) return; - this.addReaction(reaction); + const reactionPath = this.getReactionPath(reaction.fileId); + const action = reaction.isDeleting ? this.storageModel.remove : this.storageModel.writeStringifiable; + action(reactionPath, reaction); + this.reactionHandlerManager.trigger(reaction); }; this.handleMessageSent = (chatMessage) => { chatMessage.status = "sent" /* Sent */; @@ -1296,11 +1299,6 @@ chatMessage.stringifiedFile ); }; - this.addReaction = async (reaction) => { - const reactionPath = this.getReactionPath(reaction.fileId); - this.storageModel.writeStringifiable(reactionPath, reaction); - this.reactionHandlerManager.trigger(reaction); - }; this.getNameAndChannel = () => { const senderName = this.settingsModel.username; if (senderName == "") return false; @@ -1338,17 +1336,18 @@ chatMessage.body = decryptedBody; chatMessage.stringifiedFile = decryptedFile; }; - this.sendReaction = async (messageId, content) => { + this.sendReaction = async (messageId, content, isDeleting) => { const nameAndChannel = this.getNameAndChannel(); if (nameAndChannel == false) return; const [senderName, combinedChannel] = nameAndChannel; const reaction = _ChatModel.createMessageReaction( messageId, senderName, - content + content, + isDeleting ); this.sendMessage("", reaction); - this.addReaction(reaction); + this.handleReaction(reaction); }; this.subscribe = () => { this.connectionModel.addChannel(this.info.primaryChannel); @@ -1489,13 +1488,14 @@ }; } static { - this.createMessageReaction = (messageId, sender, content) => { + this.createMessageReaction = (messageId, sender, content, isDeleting) => { const fileContent = FileModel2.createFileContent(v4_default(), "reaction"); const reaction = { ...fileContent, messageId, sender, - content + content, + isDeleting }; return reaction; }; @@ -1526,7 +1526,8 @@ type: "reaction", messageId: "", sender: "", - content: "" + content: "", + isDeleting: false }; // src/Model/Chat/chatListModel.ts @@ -2051,25 +2052,29 @@ this.isPresentingInfoModal.value = false; }; // reactions - this.addReaction = (reaction) => { + this.handleReaction = (reaction) => { + function setReaction(mapState) { + if (reaction.isDeleting) { + mapState.remove(reaction.sender); + } else { + mapState.set(reaction.sender, reaction); + } + } switch (reaction.content) { case "\u{1F44D}" /* ThumbsUp */: - return this.reactionsThumbsUp.set(reaction.sender, reaction); + return setReaction(this.reactionsThumbsUp); case "\u2705" /* Check */: - return this.reactionsCheck.set(reaction.sender, reaction); + return setReaction(this.reactionsCheck); case "\u2757\uFE0F" /* Attention */: - return this.reactionsAttention.set(reaction.sender, reaction); + return setReaction(this.reactionsAttention); case "\u203C\uFE0F" /* DoubleAttention */: - return this.reactionsDoubleAttention.set( - reaction.sender, - reaction - ); + return setReaction(this.reactionsDoubleAttention); case "\u2753" /* Question */: - return this.reactionsQuestion.set(reaction.sender, reaction); + return setReaction(this.reactionsQuestion); } }; - this.sendReaction = (content) => { - this.messagePageViewModel.sendReaction(this.chatMessage.id, content); + this.sendReaction = (content, isDeleting) => { + this.messagePageViewModel.sendReaction(this.chatMessage.id, content, isDeleting); }; // load this.loadData = () => { @@ -2109,8 +2114,8 @@ this.chatViewModel.chatModel.addMessage(chatMessage); messageViewModel.loadData(); }; - this.sendReaction = (messageId, content) => { - this.chatViewModel.chatModel.sendReaction(messageId, content); + this.sendReaction = (messageId, content, isDeleting) => { + this.chatViewModel.chatModel.sendReaction(messageId, content, isDeleting); }; // view this.showChatMessage = (chatMessage) => { @@ -2131,10 +2136,10 @@ ); } }; - this.showReaction = (reaction) => { + this.handleReaction = (reaction) => { const messageViewModel = this.chatMessageViewModels.value.get(reaction.messageId); if (messageViewModel == void 0) return; - messageViewModel.addReaction(reaction); + messageViewModel.handleReaction(reaction); }; // load this.loadData = () => { @@ -2143,7 +2148,7 @@ this.showChatMessage(chatMessage); } for (const reaction of this.chatViewModel.chatModel.reactions) { - this.showReaction(reaction); + this.handleReaction(reaction); } }; this.chatViewModel = chatViewModel; @@ -3309,7 +3314,7 @@ ); chatModel.reactionHandlerManager.addHandler( (reaction) => { - this.messagePageViewModel.showReaction(reaction); + this.messagePageViewModel.handleReaction(reaction); } ); this.loadPageSelection(); @@ -3934,8 +3939,11 @@ // src/View/Components/messageReactionButton.tsx function MessageReactionButton(chatMessageViewModel, content) { + let audioLabel; + let count; + let isActive; function sendReaction() { - chatMessageViewModel.sendReaction(content); + chatMessageViewModel.sendReaction(content, isActive.value); } function getUsername() { return chatMessageViewModel.messagePageViewModel.chatViewModel.settingsViewModel.username.value; @@ -3943,9 +3951,6 @@ function checkIsHighlighted(mapState) { return mapState.value.has(getUsername()); } - let audioLabel; - let count; - let isActive; switch (content) { case "\u{1F44D}" /* ThumbsUp */: { audioLabel = translations.chatPage.message.thumbsUpReaction; @@ -3979,7 +3984,9 @@ count = chatMessageViewModel.reactionsDoubleAttentionCount; isActive = createProxyState( [chatMessageViewModel.reactionsDoubleAttention], - () => checkIsHighlighted(chatMessageViewModel.reactionsDoubleAttention) + () => checkIsHighlighted( + chatMessageViewModel.reactionsDoubleAttention + ) ); break; } diff --git a/src/Model/Chat/chatModel.ts b/src/Model/Chat/chatModel.ts index ccbc5486..5c75b931 100644 --- a/src/Model/Chat/chatModel.ts +++ b/src/Model/Chat/chatModel.ts @@ -111,7 +111,11 @@ export default class ChatModel { !checkMatchesObjectStructure(reaction, ChatMessageReactionReference) ) return; - this.addReaction(reaction); + const reactionPath: string[] = this.getReactionPath(reaction.fileId); + const action = reaction.isDeleting ? this.storageModel.remove : this.storageModel.writeStringifiable; + action(reactionPath, reaction); + this.reactionHandlerManager.trigger(reaction); + }; handleMessageSent = (chatMessage: ChatMessage): void => { @@ -158,12 +162,6 @@ export default class ChatModel { ); }; - addReaction = async (reaction: ChatMessageReaction): Promise => { - const reactionPath: string[] = this.getReactionPath(reaction.fileId); - this.storageModel.writeStringifiable(reactionPath, reaction); - this.reactionHandlerManager.trigger(reaction); - }; - getNameAndChannel = (): [string, string] | false => { const senderName = this.settingsModel.username; if (senderName == "") return false; @@ -215,6 +213,7 @@ export default class ChatModel { sendReaction = async ( messageId: string, content: ReactionSymbols, + isDeleting: boolean, ): Promise => { const nameAndChannel = this.getNameAndChannel(); if (nameAndChannel == false) return; @@ -224,9 +223,10 @@ export default class ChatModel { messageId, senderName, content, + isDeleting, ); this.sendMessage("", reaction); - this.addReaction(reaction); + this.handleReaction(reaction); }; subscribe = (): void => { @@ -408,6 +408,7 @@ export default class ChatModel { messageId: string, sender: string, content: ReactionSymbols, + isDeleting: boolean, ): ChatMessageReaction => { const fileContent = FileModel.createFileContent(v4(), "reaction"); const reaction: ChatMessageReaction = { @@ -416,6 +417,7 @@ export default class ChatModel { messageId, sender, content, + isDeleting, }; return reaction; }; @@ -463,6 +465,7 @@ export interface ChatMessageReaction messageId: string; sender: string; content: ReactionSymbols | string; + isDeleting: boolean; } // references @@ -502,4 +505,6 @@ export const ChatMessageReactionReference: ChatMessageReaction = { messageId: "", sender: "", content: "", + + isDeleting: false, }; diff --git a/src/View/Components/messageReactionButton.tsx b/src/View/Components/messageReactionButton.tsx index ddecaa47..ef1ad588 100644 --- a/src/View/Components/messageReactionButton.tsx +++ b/src/View/Components/messageReactionButton.tsx @@ -7,8 +7,12 @@ export function MessageReactionButton( chatMessageViewModel: ChatMessageViewModel, content: ReactionSymbols, ) { + let audioLabel: string; + let count: React.State; + let isActive: React.State; + function sendReaction() { - chatMessageViewModel.sendReaction(content); + chatMessageViewModel.sendReaction(content, isActive.value); } function getUsername(): string { @@ -20,10 +24,6 @@ export function MessageReactionButton( return mapState.value.has(getUsername()); } - let audioLabel: string; - let count: React.State; - let isActive: React.State; - switch (content) { case ReactionSymbols.ThumbsUp: { audioLabel = translations.chatPage.message.thumbsUpReaction; diff --git a/src/ViewModel/Chat/chatMessageViewModel.ts b/src/ViewModel/Chat/chatMessageViewModel.ts index 70dcd769..5b62bee5 100644 --- a/src/ViewModel/Chat/chatMessageViewModel.ts +++ b/src/ViewModel/Chat/chatMessageViewModel.ts @@ -76,26 +76,31 @@ export default class ChatMessageViewModel { }; // reactions - addReaction = (reaction: ChatMessageReaction): void => { + handleReaction = (reaction: ChatMessageReaction): void => { + function setReaction(mapState: React.MapState) { + if (reaction.isDeleting) { + mapState.remove(reaction.sender); + } else { + mapState.set(reaction.sender, reaction); + } + } + switch (reaction.content) { case ReactionSymbols.ThumbsUp: - return this.reactionsThumbsUp.set(reaction.sender, reaction); + return setReaction(this.reactionsThumbsUp); case ReactionSymbols.Check: - return this.reactionsCheck.set(reaction.sender, reaction); + return setReaction(this.reactionsCheck); case ReactionSymbols.Attention: - return this.reactionsAttention.set(reaction.sender, reaction); + return setReaction(this.reactionsAttention); case ReactionSymbols.DoubleAttention: - return this.reactionsDoubleAttention.set( - reaction.sender, - reaction, - ); + return setReaction(this.reactionsDoubleAttention); case ReactionSymbols.Question: - return this.reactionsQuestion.set(reaction.sender, reaction); + return setReaction(this.reactionsQuestion); } }; - sendReaction = (content: ReactionSymbols): void => { - this.messagePageViewModel.sendReaction(this.chatMessage.id, content); + sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => { + this.messagePageViewModel.sendReaction(this.chatMessage.id, content, isDeleting); }; // load diff --git a/src/ViewModel/Chat/chatViewModel.ts b/src/ViewModel/Chat/chatViewModel.ts index 0fbf46a8..53c136a9 100644 --- a/src/ViewModel/Chat/chatViewModel.ts +++ b/src/ViewModel/Chat/chatViewModel.ts @@ -181,7 +181,7 @@ export default class ChatViewModel { ); chatModel.reactionHandlerManager.addHandler( (reaction: ChatMessageReaction) => { - this.messagePageViewModel.showReaction(reaction); + this.messagePageViewModel.handleReaction(reaction); }, ); diff --git a/src/ViewModel/Pages/messagePageViewModel.ts b/src/ViewModel/Pages/messagePageViewModel.ts index facea8d8..42aa3e3b 100644 --- a/src/ViewModel/Pages/messagePageViewModel.ts +++ b/src/ViewModel/Pages/messagePageViewModel.ts @@ -41,8 +41,8 @@ export default class MessagePageViewModel { messageViewModel.loadData(); }; - sendReaction = (messageId: string, content: ReactionSymbols): void => { - this.chatViewModel.chatModel.sendReaction(messageId, content); + sendReaction = (messageId: string, content: ReactionSymbols, isDeleting: boolean): void => { + this.chatViewModel.chatModel.sendReaction(messageId, content, isDeleting); }; // view @@ -68,11 +68,11 @@ export default class MessagePageViewModel { } }; - showReaction = (reaction: ChatMessageReaction): void => { + handleReaction = (reaction: ChatMessageReaction): void => { const messageViewModel: ChatMessageViewModel | undefined = this.chatMessageViewModels.value.get(reaction.messageId); if (messageViewModel == undefined) return; - messageViewModel.addReaction(reaction); + messageViewModel.handleReaction(reaction); }; // load @@ -82,7 +82,7 @@ export default class MessagePageViewModel { this.showChatMessage(chatMessage); } for (const reaction of this.chatViewModel.chatModel.reactions) { - this.showReaction(reaction); + this.handleReaction(reaction); } };