add frontend interface to send reactions
This commit is contained in:
@@ -214,7 +214,7 @@ export default class ChatModel {
|
||||
|
||||
sendReaction = async (
|
||||
messageId: string,
|
||||
content: ReactionSymbol,
|
||||
content: ReactionSymbols,
|
||||
): Promise<void> => {
|
||||
const nameAndChannel = this.getNameAndChannel();
|
||||
if (nameAndChannel == false) return;
|
||||
@@ -407,7 +407,7 @@ export default class ChatModel {
|
||||
static createMessageReaction = (
|
||||
messageId: string,
|
||||
sender: string,
|
||||
content: ReactionSymbol,
|
||||
content: ReactionSymbols,
|
||||
): ChatMessageReaction => {
|
||||
const fileContent = FileModel.createFileContent(v4(), "reaction");
|
||||
const reaction: ChatMessageReaction = {
|
||||
@@ -422,7 +422,13 @@ export default class ChatModel {
|
||||
}
|
||||
|
||||
// types
|
||||
export type ReactionSymbol = "👍" | "✅" | "❗️" | "‼️" | "❓";
|
||||
export enum ReactionSymbols {
|
||||
ThumbsUp = "👍",
|
||||
Check = "✅",
|
||||
Attention = "❗️",
|
||||
DoubleAttention = "‼️",
|
||||
Question = "❓",
|
||||
}
|
||||
|
||||
export interface ChatInfo extends ValidObject {
|
||||
primaryChannel: string;
|
||||
@@ -456,7 +462,7 @@ export interface ChatMessageReaction
|
||||
extends ValidObject, FileContent<"reaction"> {
|
||||
messageId: string;
|
||||
sender: string;
|
||||
content: ReactionSymbol | string;
|
||||
content: ReactionSymbols | string;
|
||||
}
|
||||
|
||||
// references
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import * as React from "bloatless-react";
|
||||
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||
import { translations } from "../translations";
|
||||
|
||||
export function MessageReactionButton(
|
||||
chatMessageViewModel: ChatMessageViewModel,
|
||||
content: ReactionSymbols,
|
||||
) {
|
||||
function sendReaction() {
|
||||
chatMessageViewModel.sendReaction(content);
|
||||
}
|
||||
|
||||
function getUsername(): string {
|
||||
return chatMessageViewModel.messagePageViewModel.chatViewModel
|
||||
.settingsViewModel.username.value;
|
||||
}
|
||||
|
||||
function checkIsHighlighted(mapState: React.MapState<any>): boolean {
|
||||
return mapState.value.has(getUsername());
|
||||
}
|
||||
|
||||
let audioLabel: string;
|
||||
let count: React.State<number>;
|
||||
let isActive: React.State<boolean>;
|
||||
|
||||
switch (content) {
|
||||
case ReactionSymbols.ThumbsUp: {
|
||||
audioLabel = translations.chatPage.message.thumbsUpReaction;
|
||||
count = chatMessageViewModel.reactionsThumbsUpCount;
|
||||
isActive = React.createProxyState(
|
||||
[chatMessageViewModel.reactionsThumbsUp],
|
||||
() =>
|
||||
checkIsHighlighted(chatMessageViewModel.reactionsThumbsUp),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Check: {
|
||||
audioLabel = translations.chatPage.message.checkReaction;
|
||||
count = chatMessageViewModel.reactionsCheckCount;
|
||||
isActive = React.createProxyState(
|
||||
[chatMessageViewModel.reactionsCheck],
|
||||
() => checkIsHighlighted(chatMessageViewModel.reactionsCheck),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Attention: {
|
||||
audioLabel = translations.chatPage.message.attentionReaction;
|
||||
count = chatMessageViewModel.reactionsAttentionCount;
|
||||
isActive = React.createProxyState(
|
||||
[chatMessageViewModel.reactionsAttention],
|
||||
() =>
|
||||
checkIsHighlighted(chatMessageViewModel.reactionsAttention),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.DoubleAttention: {
|
||||
audioLabel = translations.chatPage.message.doubleAttentionReaction;
|
||||
count = chatMessageViewModel.reactionsDoubleAttentionCount;
|
||||
isActive = React.createProxyState(
|
||||
[chatMessageViewModel.reactionsDoubleAttention],
|
||||
() =>
|
||||
checkIsHighlighted(
|
||||
chatMessageViewModel.reactionsDoubleAttention,
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ReactionSymbols.Question: {
|
||||
audioLabel = translations.chatPage.message.questionReaction;
|
||||
count = chatMessageViewModel.reactionsQuestionCount;
|
||||
isActive = React.createProxyState(
|
||||
[chatMessageViewModel.reactionsQuestion],
|
||||
() =>
|
||||
checkIsHighlighted(chatMessageViewModel.reactionsQuestion),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
class="flex"
|
||||
on:click={sendReaction}
|
||||
aria-label={audioLabel}
|
||||
toggle:selected={isActive}
|
||||
>
|
||||
{content}
|
||||
<span subscribe:innerText={count}></span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,8 @@ import * as React from "bloatless-react";
|
||||
|
||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||
import { translations } from "../translations";
|
||||
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||
import { MessageReactionButton } from "../Components/messageReactionButton";
|
||||
|
||||
export function ChatMessageInfoModal(
|
||||
chatMessageViewModel: ChatMessageViewModel,
|
||||
@@ -87,6 +89,31 @@ export function ChatMessageInfoModal(
|
||||
<span class="icon">key</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<div class="flex-row gap">
|
||||
{MessageReactionButton(
|
||||
chatMessageViewModel,
|
||||
ReactionSymbols.ThumbsUp,
|
||||
)}
|
||||
{MessageReactionButton(
|
||||
chatMessageViewModel,
|
||||
ReactionSymbols.Check,
|
||||
)}
|
||||
{MessageReactionButton(
|
||||
chatMessageViewModel,
|
||||
ReactionSymbols.Attention,
|
||||
)}
|
||||
{MessageReactionButton(
|
||||
chatMessageViewModel,
|
||||
ReactionSymbols.DoubleAttention,
|
||||
)}
|
||||
{MessageReactionButton(
|
||||
chatMessageViewModel,
|
||||
ReactionSymbols.Question,
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
<button on:click={chatMessageViewModel.hideInfoModal}>
|
||||
{translations.general.closeButton}
|
||||
|
||||
@@ -186,6 +186,14 @@ const englishTranslations = {
|
||||
resendMessageButton: "Resend message",
|
||||
decryptMessageButton: "Decrypt message",
|
||||
deleteMessageButton: "Delete message",
|
||||
|
||||
//
|
||||
|
||||
thumbsUpReaction: "Reaction: thumbs up",
|
||||
checkReaction: "Reaction: check",
|
||||
attentionReaction: "Reaction: exclamation mark",
|
||||
doubleAttentionReaction: "Reaction: double exclamation mark",
|
||||
questionReaction: "Reaction: question mark",
|
||||
},
|
||||
|
||||
task: {
|
||||
@@ -449,6 +457,14 @@ const allTranslations: { [language: string]: typeof englishTranslations } = {
|
||||
resendMessageButton: "Nachricht erneut senden",
|
||||
decryptMessageButton: "Nachricht entschlüsseln",
|
||||
deleteMessageButton: "Nachricht löschen",
|
||||
|
||||
//
|
||||
|
||||
thumbsUpReaction: "Reaktion: Daumen hoch",
|
||||
checkReaction: "Reaktion: Haken",
|
||||
attentionReaction: "Reaktion: Ausrufezeichen",
|
||||
doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen",
|
||||
questionReaction: "Reaktion: Fragezeichen",
|
||||
},
|
||||
|
||||
task: {
|
||||
@@ -694,6 +710,14 @@ const allTranslations: { [language: string]: typeof englishTranslations } = {
|
||||
resendMessageButton: "Reenviar mensaje",
|
||||
decryptMessageButton: "Desencriptar mensaje",
|
||||
deleteMessageButton: "Eliminar mensaje",
|
||||
|
||||
//
|
||||
|
||||
thumbsUpReaction: "Reacción: pulgar hacia arriba",
|
||||
checkReaction: "Reacción: marca de verificación",
|
||||
attentionReaction: "Reaccion: signo de atención",
|
||||
doubleAttentionReaction: "Reaccion: signo de atención doble",
|
||||
questionReaction: "Reaccion: signo de interrogación",
|
||||
},
|
||||
|
||||
task: {
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
ChatMessageReaction,
|
||||
ChatMessageReactionReference,
|
||||
ChatMessageStatus,
|
||||
ReactionSymbol,
|
||||
ReactionSymbols,
|
||||
} from "../../Model/Chat/chatModel";
|
||||
|
||||
import CoreViewModel from "../Global/coreViewModel";
|
||||
@@ -31,6 +31,27 @@ export default class ChatMessageViewModel {
|
||||
reactionsDoubleAttention = new React.MapState<ChatMessageReaction>();
|
||||
reactionsQuestion = new React.MapState<ChatMessageReaction>();
|
||||
|
||||
reactionsThumbsUpCount = React.createProxyState(
|
||||
[this.reactionsThumbsUp],
|
||||
() => this.reactionsThumbsUp.value.size,
|
||||
);
|
||||
reactionsCheckCount = React.createProxyState(
|
||||
[this.reactionsCheck],
|
||||
() => this.reactionsCheck.value.size,
|
||||
);
|
||||
reactionsAttentionCount = React.createProxyState(
|
||||
[this.reactionsAttention],
|
||||
() => this.reactionsAttention.value.size,
|
||||
);
|
||||
reactionsDoubleAttentionCount = React.createProxyState(
|
||||
[this.reactionsDoubleAttention],
|
||||
() => this.reactionsDoubleAttention.value.size,
|
||||
);
|
||||
reactionsQuestionCount = React.createProxyState(
|
||||
[this.reactionsQuestion],
|
||||
() => this.reactionsQuestion.value.size,
|
||||
);
|
||||
|
||||
// state
|
||||
isPresentingInfoModal: React.State<boolean> = new React.State(false);
|
||||
|
||||
@@ -57,22 +78,26 @@ export default class ChatMessageViewModel {
|
||||
// reactions
|
||||
addReaction = (reaction: ChatMessageReaction): void => {
|
||||
switch (reaction.content) {
|
||||
case "👍":
|
||||
return this.reactionsThumbsUp.set(reaction.fileId, reaction);
|
||||
case "✅":
|
||||
return this.reactionsCheck.set(reaction.fileId, reaction);
|
||||
case "❗️":
|
||||
return this.reactionsAttention.set(reaction.fileId, reaction);
|
||||
case "‼️":
|
||||
case ReactionSymbols.ThumbsUp:
|
||||
return this.reactionsThumbsUp.set(reaction.sender, reaction);
|
||||
case ReactionSymbols.Check:
|
||||
return this.reactionsCheck.set(reaction.sender, reaction);
|
||||
case ReactionSymbols.Attention:
|
||||
return this.reactionsAttention.set(reaction.sender, reaction);
|
||||
case ReactionSymbols.DoubleAttention:
|
||||
return this.reactionsDoubleAttention.set(
|
||||
reaction.fileId,
|
||||
reaction.sender,
|
||||
reaction,
|
||||
);
|
||||
case "❓":
|
||||
return this.reactionsQuestion.set(reaction.fileId, reaction);
|
||||
case ReactionSymbols.Question:
|
||||
return this.reactionsQuestion.set(reaction.sender, reaction);
|
||||
}
|
||||
};
|
||||
|
||||
sendReaction = (content: ReactionSymbols): void => {
|
||||
this.messagePageViewModel.sendReaction(this.chatMessage.id, content);
|
||||
};
|
||||
|
||||
// load
|
||||
loadData = (): void => {
|
||||
this.channel = this.chatMessage.channel;
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as React from "bloatless-react";
|
||||
import {
|
||||
ChatMessage,
|
||||
ChatMessageReaction,
|
||||
ReactionSymbol,
|
||||
ReactionSymbols,
|
||||
} from "../../Model/Chat/chatModel";
|
||||
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
||||
import ChatViewModel from "../Chat/chatViewModel";
|
||||
@@ -41,7 +41,7 @@ export default class MessagePageViewModel {
|
||||
messageViewModel.loadData();
|
||||
};
|
||||
|
||||
sendReaction = (messageId: string, content: ReactionSymbol): void => {
|
||||
sendReaction = (messageId: string, content: ReactionSymbols): void => {
|
||||
this.chatViewModel.chatModel.sendReaction(messageId, content);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user