diff --git a/src/View/Components/chatMessage.tsx b/src/View/Components/chatMessage.tsx index 760de170..87498b37 100644 --- a/src/View/Components/chatMessage.tsx +++ b/src/View/Components/chatMessage.tsx @@ -37,9 +37,10 @@ export function ChatMessage( {InlineReply(chatMessageViewModel)}
- - {chatMessageViewModel.senderName} - + = new React.State(""); inlineReply: ChatMessageViewModel | undefined = undefined; @@ -185,7 +185,6 @@ export default class ChatMessageViewModel { loadData = (): void => { this.channel = this.chatMessage.channel; this.senderId = this.chatMessage.senderId; - this.senderName = this.chatMessage.senderName; this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString(); this.body.value = this.chatMessage.body; this.status.value = this.chatMessage.status; @@ -204,6 +203,7 @@ export default class ChatMessageViewModel { public readonly coreViewModel: CoreViewModel, public readonly messagePageViewModel: MessagePageViewModel, chatMessage: ChatMessage, + public contact: ContactViewModel, sentByUser: boolean, ) { this.chatMessage = chatMessage; diff --git a/src/ViewModel/Chat/chatViewModel.ts b/src/ViewModel/Chat/chatViewModel.ts index 625b900f..c2eb43c0 100644 --- a/src/ViewModel/Chat/chatViewModel.ts +++ b/src/ViewModel/Chat/chatViewModel.ts @@ -21,6 +21,7 @@ import ChatModel, { ChatMessage, ChatMessageReaction, } from "../../Model/Chat/chatModel"; +import ContactListViewModel from "../Global/contactViewModel"; export default class ChatViewModel extends ContextHost { calendarViewModel: CalendarPageViewModel; @@ -149,6 +150,7 @@ export default class ChatViewModel extends ContextHost { public readonly notificationViewModel: NotificationViewModel, public readonly connectionViewModel: ConnectionViewModel, public readonly chatListViewModel: ChatListViewModel, + public readonly contactListViewModel: ContactListViewModel, ) { super("chat", coreViewModel); @@ -167,6 +169,7 @@ export default class ChatViewModel extends ContextHost { this.messagePageViewModel = new MessagePageViewModel( this.coreViewModel, this, + this.contactListViewModel, ); this.settingsPageViewModel = new SettingsPageViewModel( this.coreViewModel, diff --git a/src/ViewModel/Global/contactViewModel.ts b/src/ViewModel/Global/contactViewModel.ts index bde6e77f..d17c3b90 100644 --- a/src/ViewModel/Global/contactViewModel.ts +++ b/src/ViewModel/Global/contactViewModel.ts @@ -3,22 +3,30 @@ import * as React from "../../react"; export default class ContactListViewModel { // state - contacts: React.MapState = new React.MapState(); + contacts: Map = new Map(); // main - updateContact = (id: string, name: string): void => { - if (this.contacts.value.has(id)) { - this.contacts.value.get(id)!.name.value = name; - return; + updateContact = (id: string, name: string): ContactViewModel => { + const match = this.contacts.get(id); + if (match) { + match.name.value = name; + return match; } const vm = new ContactViewModel(id, name); this.contacts.set(id, vm); + return vm; } handleContact = (contact: [string, string]): void => { this.updateContact(...contact); } + unwrapContact = (id: string, knownName: string): ContactViewModel => { + if (this.contacts.has(id)) + return this.contacts.get(id)! + return this.updateContact(id, knownName); + } + // load loadData = (): void => { const contacts: [string, string][] = this.contactListModel.loadContacts(); diff --git a/src/ViewModel/Global/settingsViewModel.ts b/src/ViewModel/Global/settingsViewModel.ts index 4f8f6579..659d804e 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -1,7 +1,7 @@ import CoreViewModel, { Context } from "./coreViewModel"; import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; -import { Languages, ThemeSettings } from "../../Model/Global/settingsModel"; +import SettingsModel, { Languages, ThemeSettings } from "../../Model/Global/settingsModel"; export default class SettingsViewModel extends Context { // state @@ -126,7 +126,7 @@ export default class SettingsViewModel extends Context { }; // init - constructor(public readonly coreViewModel: CoreViewModel) { + constructor(public readonly coreViewModel: CoreViewModel, public readonly settingsModel: SettingsModel) { super("settings"); this.username.value = coreViewModel.settingsModel.username; diff --git a/src/ViewModel/Pages/messagePageViewModel.ts b/src/ViewModel/Pages/messagePageViewModel.ts index 7ba72193..f306c959 100644 --- a/src/ViewModel/Pages/messagePageViewModel.ts +++ b/src/ViewModel/Pages/messagePageViewModel.ts @@ -9,6 +9,7 @@ import { ChatMessageReaction, ReactionSymbols, } from "../../Model/Chat/chatModel"; +import ContactListViewModel from "../Global/contactViewModel"; export default class MessagePageViewModel extends Context { // state @@ -106,135 +107,138 @@ export default class MessagePageViewModel extends Context { // view showChatMessage = (chatMessage: ChatMessage): void => { - const chatMessageViewModel = new ChatMessageViewModel( - this.coreViewModel, - this, - chatMessage, - chatMessage.senderName == - this.chatViewModel.settingsViewModel.username.value, - ); + const contact = this.contactListViewModel.unwrapContact(chatMessage.senderId, chatMessage.senderName); + const chatMessageViewModel = new ChatMessageViewModel( + this.coreViewModel, + this, + chatMessage, + contact, + chatMessage.senderId == + this.chatViewModel.settingsViewModel.settingsModel.userid + ); - const existingChatMessageViewModel: ChatMessageViewModel | undefined = - this.chatMessageViewModels.value.get(chatMessage.id); - if (existingChatMessageViewModel != undefined) { - existingChatMessageViewModel.body.value = chatMessage.body; - existingChatMessageViewModel.status.value = chatMessage.status; - } else { - this.chatMessageViewModels.set( - chatMessage.id, - chatMessageViewModel, - ); - } + const existingChatMessageViewModel: ChatMessageViewModel | undefined = + this.chatMessageViewModels.value.get(chatMessage.id); + if (existingChatMessageViewModel != undefined) { + existingChatMessageViewModel.body.value = chatMessage.body; + existingChatMessageViewModel.status.value = chatMessage.status; + } else { + this.chatMessageViewModels.set( + chatMessage.id, + chatMessageViewModel, + ); + } }; handleReaction = (reaction: ChatMessageReaction): void => { - const messageViewModel: ChatMessageViewModel | undefined = - this.chatMessageViewModels.value.get(reaction.messageId); - if (messageViewModel == undefined) return; - messageViewModel.handleReaction(reaction); + const messageViewModel: ChatMessageViewModel | undefined = + this.chatMessageViewModels.value.get(reaction.messageId); + if (messageViewModel == undefined) return; + messageViewModel.handleReaction(reaction); }; showFilterModal = (): void => { - this.isFilterModalOpen.value = true; + this.isFilterModalOpen.value = true; }; hideFilterModal = (): void => { - this.isFilterModalOpen.value = false; + this.isFilterModalOpen.value = false; }; revokeReactionFilter = (persist: boolean = true): void => { - this.reactionFilter.value = undefined; - if (persist) this.chatViewModel.chatModel.storeFilter(""); + this.reactionFilter.value = undefined; + if (persist) this.chatViewModel.chatModel.storeFilter(""); }; setReactionFilter = (content: ReactionSymbols): void => { - this.reactionFilter.value = content; - this.chatViewModel.chatModel.storeFilter(content); + this.reactionFilter.value = content; + this.chatViewModel.chatModel.storeFilter(content); }; resetFilter = (): void => { - this.revokeReactionFilter(); - this.searchViewModel.search(""); + this.revokeReactionFilter(); + this.searchViewModel.search(""); }; setReplyView = (message: ChatMessageViewModel): void => { - this.replyViewSelectedMessage.value = message; - this.revokeReactionFilter(false); - this.setReply(message, false); + this.replyViewSelectedMessage.value = message; + this.revokeReactionFilter(false); + this.setReply(message, false); }; resetReplyView = (): void => { - this.replyViewSelectedMessage.value = undefined; - this.resetReply(false); - this.restoreFilter(); + this.replyViewSelectedMessage.value = undefined; + this.resetReply(false); + this.restoreFilter(); }; setFocus = (): void => { - this.focusSetter.callSubscriptions(); + this.focusSetter.callSubscriptions(); }; // load loadData = (): void => { - this.chatMessageViewModels.clear(); - for (const chatMessage of this.chatViewModel.chatModel.messages) { - this.showChatMessage(chatMessage); - } - for (const reaction of this.chatViewModel.chatModel.reactions) { - this.handleReaction(reaction); - } + this.chatMessageViewModels.clear(); + for (const chatMessage of this.chatViewModel.chatModel.messages) { + this.showChatMessage(chatMessage); + } + for (const reaction of this.chatViewModel.chatModel.reactions) { + this.handleReaction(reaction); + } }; restoreFilter = (): void => { - const previousFilter = this.chatViewModel.chatModel.getFilter() as any; - if (Object.values(ReactionSymbols).includes(previousFilter)) - this.setReactionFilter(previousFilter); + const previousFilter = this.chatViewModel.chatModel.getFilter() as any; + if (Object.values(ReactionSymbols).includes(previousFilter)) + this.setReactionFilter(previousFilter); }; // init constructor( - public readonly coreViewModel: CoreViewModel, - public readonly chatViewModel: ChatViewModel, + public readonly coreViewModel: CoreViewModel, + public readonly chatViewModel: ChatViewModel, + public readonly contactListViewModel: ContactListViewModel, ) { - super("message-page"); - this.restoreFilter(); + super("message-page"); + this.restoreFilter(); - // states - this.cannotSendMessage = React.createProxyState( - [ - this.chatViewModel.settingsViewModel.username, - this.composingMessage, - ], - () => - this.chatViewModel.settingsViewModel.username.value == "" || - this.composingMessage.value == "", - ); + // states + this.cannotSendMessage = React.createProxyState( + [ + this.chatViewModel.settingsViewModel.username, + this.composingMessage, + ], + () => + this.chatViewModel.settingsViewModel.username.value == "" || + this.composingMessage.value == "", + ); - this.searchViewModel = new SearchViewModel( - this.chatMessageViewModels, - this.filteredMessageViewModels, - (chatMessageViewModel) => [chatMessageViewModel.body.value], - new React.ListState(), - ); + this.searchViewModel = new SearchViewModel( + this.chatMessageViewModels, + this.filteredMessageViewModels, + (chatMessageViewModel) => [chatMessageViewModel.body.value], + new React.ListState(), + ); - this.isFilterActive = React.createProxyState( - [this.searchViewModel.appliedQuery, this.reactionFilter], - () => - this.searchViewModel.appliedQuery.value != "" || - this.reactionFilter.value != undefined, - ); + this.isFilterActive = React.createProxyState( + [this.searchViewModel.appliedQuery, this.reactionFilter], + () => + this.searchViewModel.appliedQuery.value != "" || + this.reactionFilter.value != undefined, + ); - // keystrokes - this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal); - this.registerKeyStroke(CommonKeys.CloseOrCancel, () => { - if (this.isFilterModalOpen.value == true) { - this.hideFilterModal(); - } else { - this.replyingMessage.value = undefined; - } - }); - this.registerKeyStroke(CommonKeys.Reset, this.resetFilter); - this.registerKeyStroke(CommonKeys.Create, this.setFocus); + // keystrokes + this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal); + this.registerKeyStroke(CommonKeys.CloseOrCancel, () => { + if (this.isFilterModalOpen.value == true) { + this.hideFilterModal(); + } else { + this.replyingMessage.value = undefined; + } + }); + this.registerKeyStroke(CommonKeys.Reset, this.resetFilter); + this.registerKeyStroke(CommonKeys.Create, this.setFocus); - this.chatViewModel.registerContext(ChatPageTypes.Messages, this); + this.chatViewModel.registerContext(ChatPageTypes.Messages, this); } } diff --git a/src/index.tsx b/src/index.tsx index bf0d535b..a0346eea 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -46,13 +46,14 @@ const coreViewModel = new CoreViewModel( ); const storageViewModel = new StorageViewModel(coreViewModel); -const settingsViewModel = new SettingsViewModel(coreViewModel); +const settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel); const contactListViewModel = new ContactListViewModel(contactListModel); const connectionViewModel = new ConnectionViewModel(coreViewModel); const chatListViewModel = new ChatListViewModel( coreViewModel, settingsViewModel, connectionViewModel, + contactListViewModel, ); const fileTransferViewModel = new FileTransferViewModel(coreViewModel);