diff --git a/frontend/src/lib/types/message.ts b/frontend/src/lib/types/message.ts index 7604b4889b89a2aa5eb301513630295e1434ff29..15440ff81efe2f1973e5be33c1323071e01164fc 100644 --- a/frontend/src/lib/types/message.ts +++ b/frontend/src/lib/types/message.ts @@ -17,7 +17,7 @@ export default class Message { private _versions = writable([] as { content: string; date: Date }[]); private _feedbacks = writable([] as Feedback[]); private _replyTo: string; - private _reactions = writable<{ userId: string; emoji: string }[]>([]); + private _reactions = writable<{ userId: string; emoji: string }[]>([]); public constructor( id: number, @@ -91,24 +91,24 @@ export default class Message { } get reactions(): Writable<{ userId: string; emoji: string }[]> { - return this._reactions; - } - - addReaction(userId: string, emoji: string) { - this._reactions.update(reactions => { - const existing = reactions.find(r => r.userId === userId); - if (existing) { - existing.emoji = emoji; - } else { - reactions.push({ userId, emoji }); - } - return reactions; - }); - } - - removeReaction(userId: string) { - this._reactions.update(reactions => reactions.filter(r => r.userId !== userId)); - } + return this._reactions; + } + + addReaction(userId: string, emoji: string) { + this._reactions.update((reactions) => { + const existing = reactions.find((r) => r.userId === userId); + if (existing) { + existing.emoji = emoji; + } else { + reactions.push({ userId, emoji }); + } + return reactions; + }); + } + + removeReaction(userId: string) { + this._reactions.update((reactions) => reactions.filter((r) => r.userId !== userId)); + } async update(content: string, metadata: { message: string; date: number }[]): Promise<boolean> { const response = await updateMessageAPI( @@ -130,7 +130,7 @@ export default class Message { async getMessageById(id: number): Promise<Message | null> { try { - const response = await getMessagesAPI(fetch, this._session.id); + const response = await getMessagesAPI(fetch, this._session.id); if (!response) { toastAlert('Failed to retrieve messages from the server.'); return null; diff --git a/frontend/src/routes/sessions/[id]/Message.svelte b/frontend/src/routes/sessions/[id]/Message.svelte index b8f5a67e36ab60cf822e1a033077c141de195dd5..128e9be66da7bd011c3e6a5e37975ba0c105468e 100644 --- a/frontend/src/routes/sessions/[id]/Message.svelte +++ b/frontend/src/routes/sessions/[id]/Message.svelte @@ -36,7 +36,7 @@ let messageVersions = $state(message.versions); let showReactions = writable(false); - const emojiList = ["ðŸ‘", "â¤ï¸", "😂", "😮", "😢", "👎"]; + const emojiList = ['ðŸ‘', 'â¤ï¸', '😂', '😮', '😢', '👎']; function startEdit() { isEdit = true; @@ -191,18 +191,18 @@ } function reactToMessage(emoji: string) { - let reactions = get(message.reactions); - - let currentReaction = reactions.find(r => r.userId === String(user.id)); - - if (currentReaction && currentReaction.emoji === emoji) { - message.removeReaction(String(user.id)); - } else { - message.addReaction(String(user.id), emoji); - } - - showReactions.set(false); -} + let reactions = get(message.reactions); + + let currentReaction = reactions.find((r) => r.userId === String(user.id)); + + if (currentReaction && currentReaction.emoji === emoji) { + message.removeReaction(String(user.id)); + } else { + message.addReaction(String(user.id), emoji); + } + + showReactions.set(false); + } </script> <div @@ -219,16 +219,17 @@ /> </div> - <div class="relative group chat-bubble text-black" - class:bg-blue-50={isSender} - class:bg-gray-300={!isSender} - onmouseover={() => showReactions.set(true)} - onmouseleave={() => showReactions.set(false)} - onfocus={() => showReactions.set(true)} - onblur={() => showReactions.set(false)} - role="button" - tabindex="0" -> + <div + class="relative group chat-bubble text-black" + class:bg-blue-50={isSender} + class:bg-gray-300={!isSender} + onmouseover={() => showReactions.set(true)} + onmouseleave={() => showReactions.set(false)} + onfocus={() => showReactions.set(true)} + onblur={() => showReactions.set(false)} + role="button" + tabindex="0" + > {#if replyToMessage} <a href={`#${replyToMessage.uuid}`} @@ -317,7 +318,7 @@ <Icon src={ArrowUturnLeft} class="w-5 h-full text-gray-500 hover:text-gray-800" /> </button> {/if} - + {#if get(message.reactions).length > 0} <div class="flex items-center space-x-2 mt-2"> {#each get(message.reactions) as reaction} @@ -327,14 +328,17 @@ {/each} </div> {/if} - + {#if $showReactions} <div class="absolute bottom-0 left-0 flex space-x-2 p-2 bg-white border rounded-lg shadow-lg"> {#each emojiList as emoji} - <button type="button" class="cursor-pointer text-lg hover:bg-gray-300 p-1 rounded-lg" + <button + type="button" + class="cursor-pointer text-lg hover:bg-gray-300 p-1 rounded-lg" onclick={() => reactToMessage(emoji)} onkeydown={(e) => e.key === 'Enter' && reactToMessage(emoji)} - aria-label={`React with ${emoji}`}> + aria-label={`React with ${emoji}`} + > {emoji} </button> {/each} @@ -350,7 +354,6 @@ </button> {/if} </div> - </div> <div class="absolute invisible rounded-xl border border-gray-400 bg-white divide-x"