Files
CT/src/ViewModel/Chat/chatMessageViewModel.ts
T

207 lines
6.7 KiB
TypeScript
Raw Normal View History

2026-04-18 11:55:01 +00:00
import MessagePageViewModel from "../Pages/messagePageViewModel";
import CoreViewModel from "../Global/coreViewModel";
2026-09-23 00:09:09 +02:00
import * as React from "../../react";
2026-04-06 20:47:49 +00:00
import {
ChatMessage,
ChatMessageReaction,
2026-04-08 14:02:12 +00:00
ChatMessageStatuses,
2026-04-07 18:39:55 +00:00
ReactionSymbols,
2026-04-06 20:47:49 +00:00
} from "../../Model/Chat/chatModel";
2024-07-21 01:12:35 +02:00
export default class ChatMessageViewModel {
2026-04-01 08:29:39 +00:00
// data
chatMessage: ChatMessage;
2026-09-09 00:04:27 +02:00
channel: string = "";
sender: string = "";
dateSent: string = "";
2026-04-01 08:29:39 +00:00
body: React.State<string> = new React.State("");
inlineReply: ChatMessageViewModel | undefined = undefined;
2026-09-23 14:44:34 +02:00
replies: React.MapState<ChatMessageViewModel> = new React.MapState();
replyCount: React.State<number> = React.createProxyState([this.replies], ()=>this.replies.value.size);
2026-04-08 14:02:12 +00:00
status: React.State<ChatMessageStatuses | any> = new React.State<any>(
2026-04-01 08:29:39 +00:00
undefined,
);
sentByUser: boolean;
2024-07-26 03:14:55 +02:00
2026-04-11 21:01:23 +00:00
isHidden = new React.State<boolean>(false);
allReactions = new React.MapState<ChatMessageReaction>();
2026-04-11 19:26:13 +00:00
userReaction = new React.State<ReactionSymbols | string | undefined>(
undefined,
);
reactionsThumbsUp = React.MapState<ChatMessageReaction>;
reactionsCheck = React.MapState<ChatMessageReaction>;
reactionsStop = React.MapState<ChatMessageReaction>;
reactionsAttention = React.MapState<ChatMessageReaction>;
reactionsDoubleAttention = React.MapState<ChatMessageReaction>;
reactionsQuestion = React.MapState<ChatMessageReaction>;
2026-04-06 20:47:49 +00:00
generateReactionCountProxyState = (
content: ReactionSymbols,
): React.State<number> => {
return React.createProxyState(
[this.allReactions],
() =>
[...this.allReactions.value.values()].filter(
(x) => x.content == content,
).length,
);
};
reactionsThumbsUpCount = this.generateReactionCountProxyState(
ReactionSymbols.ThumbsUp,
2026-04-07 18:39:55 +00:00
);
reactionsCheckCount = this.generateReactionCountProxyState(
ReactionSymbols.Check,
2026-04-07 18:39:55 +00:00
);
reactionsStopCount = this.generateReactionCountProxyState(
ReactionSymbols.Stop,
);
reactionsAttentionCount = this.generateReactionCountProxyState(
ReactionSymbols.Attention,
2026-04-07 18:39:55 +00:00
);
reactionsDoubleAttentionCount = this.generateReactionCountProxyState(
ReactionSymbols.DoubleAttention,
2026-04-07 18:39:55 +00:00
);
reactionsQuestionCount = this.generateReactionCountProxyState(
ReactionSymbols.Question,
2026-04-07 18:39:55 +00:00
);
2026-04-01 08:29:39 +00:00
// state
isPresentingInfoModal: React.State<boolean> = new React.State(false);
2024-07-21 01:12:35 +02:00
2026-04-01 08:29:39 +00:00
// methods
copyMessage = (): void => {
navigator.clipboard.writeText(this.body.value);
};
resendMessage = (): void => {
this.messagePageViewModel.sendMessageFromBody(this.body.value);
};
decryptMessage = (): void => {
this.messagePageViewModel.decryptMessage(this);
};
2024-07-21 13:13:41 +02:00
reply = (): void => {
2026-04-15 12:47:10 +00:00
this.messagePageViewModel.setReply(this);
this.hideInfoModal();
};
cancelReply = (): void => {
if (this.messagePageViewModel.replyingMessage.value != this) return;
2026-04-15 12:47:10 +00:00
this.messagePageViewModel.setReply(undefined);
};
2026-04-01 08:29:39 +00:00
// view
showInfoModal = (): void => {
this.isPresentingInfoModal.value = true;
};
2024-07-23 13:09:46 +02:00
2026-04-01 08:29:39 +00:00
hideInfoModal = (): void => {
this.isPresentingInfoModal.value = false;
};
2024-07-23 13:09:46 +02:00
2026-04-06 20:47:49 +00:00
// reactions
2026-04-07 18:48:01 +00:00
handleReaction = (reaction: ChatMessageReaction): void => {
if (reaction.isDeleting) {
this.allReactions.remove(reaction.sender);
} else {
this.allReactions.set(reaction.sender, reaction);
2026-04-07 18:48:01 +00:00
}
2026-04-11 19:26:13 +00:00
if (reaction.sender != this.coreViewModel.settingsModel.username)
return;
this.userReaction.value = reaction.isDeleting
? undefined
: reaction.content;
2026-04-06 20:47:49 +00:00
};
2026-04-07 18:48:01 +00:00
sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => {
this.messagePageViewModel.sendReaction(
this.chatMessage.id,
content,
isDeleting,
);
2026-04-07 18:39:55 +00:00
};
2026-04-01 08:29:39 +00:00
// load
loadData = (): void => {
this.channel = this.chatMessage.channel;
this.sender = this.chatMessage.sender;
this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString();
this.body.value = this.chatMessage.body;
this.status.value = this.chatMessage.status;
if (this.chatMessage.inlineReplyId) {
2026-04-15 12:47:10 +00:00
this.inlineReply =
this.messagePageViewModel.chatMessageViewModels.value.get(
this.chatMessage.inlineReplyId,
);
2026-09-23 14:44:34 +02:00
this.inlineReply.replies.set(this.chatMessage.id, this);
}
2026-04-01 08:29:39 +00:00
};
2024-07-21 13:13:41 +02:00
2026-04-01 08:29:39 +00:00
// init
constructor(
2026-04-13 10:58:21 +00:00
public readonly coreViewModel: CoreViewModel,
public readonly messagePageViewModel: MessagePageViewModel,
2026-04-01 08:29:39 +00:00
chatMessage: ChatMessage,
sentByUser: boolean,
) {
this.chatMessage = chatMessage;
this.sentByUser = sentByUser;
this.loadData();
2026-04-11 21:01:23 +00:00
2026-09-23 14:44:34 +02:00
let hideForReactions: boolean = false;
let hideForReplyView: boolean = false;
const updateHiding = () => {
this.isHidden.value = hideForReactions || hideForReplyView;
}
2026-04-11 21:01:23 +00:00
this.messagePageViewModel.reactionFilter.subscribe((content) => {
if (content == undefined) {
2026-09-23 14:44:34 +02:00
hideForReactions = false;
2026-04-11 21:01:23 +00:00
return;
}
2026-04-13 11:23:17 +00:00
let count: number = 0;
2026-04-11 21:01:23 +00:00
switch (content) {
case ReactionSymbols.ThumbsUp: {
count = this.reactionsThumbsUpCount.value;
break;
}
case ReactionSymbols.Check: {
count = this.reactionsCheckCount.value;
break;
}
case ReactionSymbols.Stop: {
count = this.reactionsStopCount.value;
break;
}
case ReactionSymbols.Attention: {
count = this.reactionsAttentionCount.value;
break;
}
case ReactionSymbols.DoubleAttention: {
count = this.reactionsDoubleAttentionCount.value;
break;
}
case ReactionSymbols.Question: {
count = this.reactionsQuestionCount.value;
break;
}
}
2026-09-23 14:44:34 +02:00
hideForReactions = count == 0;
updateHiding();
});
2026-09-23 14:44:34 +02:00
this.messagePageViewModel.replyViewSelectedMessage.subscribe(selectedMessage => {
if (selectedMessage == undefined) hideForReplyView = false;
else if (selectedMessage == this) hideForReplyView = false;
else if (selectedMessage == this.inlineReply) hideForReplyView = false;
else hideForReplyView = true;
updateHiding();
})
2026-04-01 08:29:39 +00:00
}
2024-07-21 01:12:35 +02:00
}