implement contacts with messaging

This commit is contained in:
marlon-erler
2026-09-27 03:01:43 +02:00
parent c5d61a5790
commit a9fba4646d
8 changed files with 118 additions and 98 deletions
+4 -3
View File
@@ -37,9 +37,10 @@ export function ChatMessage(
{InlineReply(chatMessageViewModel)} {InlineReply(chatMessageViewModel)}
<div class="main tile"> <div class="main tile">
<div class="text-container"> <div class="text-container">
<span class="sender-name ellipsis"> <span
{chatMessageViewModel.senderName} class="sender-name ellipsis"
</span> subscribe:innerText={chatMessageViewModel.contact.name}
></span>
<span <span
class="body" class="body"
subscribe:innerText={chatMessageViewModel.body} subscribe:innerText={chatMessageViewModel.body}
+3
View File
@@ -6,6 +6,7 @@ import ConnectionViewModel from "../Global/connectionViewModel";
import * as React from "../../react"; import * as React from "../../react";
import { IndexManager } from "../../Model/Utility/utility"; import { IndexManager } from "../../Model/Utility/utility";
import ChatModel from "../../Model/Chat/chatModel"; import ChatModel from "../../Model/Chat/chatModel";
import ContactListViewModel from "../Global/contactViewModel";
export default class ChatListViewModel { export default class ChatListViewModel {
notificationViewModel: NotificationViewModel; notificationViewModel: NotificationViewModel;
@@ -61,6 +62,7 @@ export default class ChatListViewModel {
this.notificationViewModel, this.notificationViewModel,
this.connectionViewModel, this.connectionViewModel,
this, this,
this.contactListViewModel,
); );
}; };
@@ -97,6 +99,7 @@ export default class ChatListViewModel {
public readonly coreViewModel: CoreViewModel, public readonly coreViewModel: CoreViewModel,
public readonly settingsViewModel: SettingsViewModel, public readonly settingsViewModel: SettingsViewModel,
public readonly connectionViewModel: ConnectionViewModel, public readonly connectionViewModel: ConnectionViewModel,
public readonly contactListViewModel: ContactListViewModel,
) { ) {
this.notificationViewModel = new NotificationViewModel(this); this.notificationViewModel = new NotificationViewModel(this);
+2 -2
View File
@@ -7,13 +7,13 @@ import {
ChatMessageStatuses, ChatMessageStatuses,
ReactionSymbols, ReactionSymbols,
} from "../../Model/Chat/chatModel"; } from "../../Model/Chat/chatModel";
import {ContactViewModel} from "../Global/contactViewModel";
export default class ChatMessageViewModel { export default class ChatMessageViewModel {
// data // data
chatMessage: ChatMessage; chatMessage: ChatMessage;
channel: string = ""; channel: string = "";
senderId: string = ""; senderId: string = "";
senderName: string = "";
dateSent: string = ""; dateSent: string = "";
body: React.State<string> = new React.State(""); body: React.State<string> = new React.State("");
inlineReply: ChatMessageViewModel | undefined = undefined; inlineReply: ChatMessageViewModel | undefined = undefined;
@@ -185,7 +185,6 @@ export default class ChatMessageViewModel {
loadData = (): void => { loadData = (): void => {
this.channel = this.chatMessage.channel; this.channel = this.chatMessage.channel;
this.senderId = this.chatMessage.senderId; this.senderId = this.chatMessage.senderId;
this.senderName = this.chatMessage.senderName;
this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString(); this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString();
this.body.value = this.chatMessage.body; this.body.value = this.chatMessage.body;
this.status.value = this.chatMessage.status; this.status.value = this.chatMessage.status;
@@ -204,6 +203,7 @@ export default class ChatMessageViewModel {
public readonly coreViewModel: CoreViewModel, public readonly coreViewModel: CoreViewModel,
public readonly messagePageViewModel: MessagePageViewModel, public readonly messagePageViewModel: MessagePageViewModel,
chatMessage: ChatMessage, chatMessage: ChatMessage,
public contact: ContactViewModel,
sentByUser: boolean, sentByUser: boolean,
) { ) {
this.chatMessage = chatMessage; this.chatMessage = chatMessage;
+3
View File
@@ -21,6 +21,7 @@ import ChatModel, {
ChatMessage, ChatMessage,
ChatMessageReaction, ChatMessageReaction,
} from "../../Model/Chat/chatModel"; } from "../../Model/Chat/chatModel";
import ContactListViewModel from "../Global/contactViewModel";
export default class ChatViewModel extends ContextHost<ChatPageTypes> { export default class ChatViewModel extends ContextHost<ChatPageTypes> {
calendarViewModel: CalendarPageViewModel; calendarViewModel: CalendarPageViewModel;
@@ -149,6 +150,7 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
public readonly notificationViewModel: NotificationViewModel, public readonly notificationViewModel: NotificationViewModel,
public readonly connectionViewModel: ConnectionViewModel, public readonly connectionViewModel: ConnectionViewModel,
public readonly chatListViewModel: ChatListViewModel, public readonly chatListViewModel: ChatListViewModel,
public readonly contactListViewModel: ContactListViewModel,
) { ) {
super("chat", coreViewModel); super("chat", coreViewModel);
@@ -167,6 +169,7 @@ export default class ChatViewModel extends ContextHost<ChatPageTypes> {
this.messagePageViewModel = new MessagePageViewModel( this.messagePageViewModel = new MessagePageViewModel(
this.coreViewModel, this.coreViewModel,
this, this,
this.contactListViewModel,
); );
this.settingsPageViewModel = new SettingsPageViewModel( this.settingsPageViewModel = new SettingsPageViewModel(
this.coreViewModel, this.coreViewModel,
+13 -5
View File
@@ -3,22 +3,30 @@ import * as React from "../../react";
export default class ContactListViewModel { export default class ContactListViewModel {
// state // state
contacts: React.MapState<ContactViewModel> = new React.MapState(); contacts: Map<string, ContactViewModel> = new Map();
// main // main
updateContact = (id: string, name: string): void => { updateContact = (id: string, name: string): ContactViewModel => {
if (this.contacts.value.has(id)) { const match = this.contacts.get(id);
this.contacts.value.get(id)!.name.value = name; if (match) {
return; match.name.value = name;
return match;
} }
const vm = new ContactViewModel(id, name); const vm = new ContactViewModel(id, name);
this.contacts.set(id, vm); this.contacts.set(id, vm);
return vm;
} }
handleContact = (contact: [string, string]): void => { handleContact = (contact: [string, string]): void => {
this.updateContact(...contact); 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 // load
loadData = (): void => { loadData = (): void => {
const contacts: [string, string][] = this.contactListModel.loadContacts(); const contacts: [string, string][] = this.contactListModel.loadContacts();
+2 -2
View File
@@ -1,7 +1,7 @@
import CoreViewModel, { Context } from "./coreViewModel"; import CoreViewModel, { Context } from "./coreViewModel";
import * as React from "../../react"; import * as React from "../../react";
import { CommonKeys } from "../../View/keystrokes"; 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 { export default class SettingsViewModel extends Context {
// state // state
@@ -126,7 +126,7 @@ export default class SettingsViewModel extends Context {
}; };
// init // init
constructor(public readonly coreViewModel: CoreViewModel) { constructor(public readonly coreViewModel: CoreViewModel, public readonly settingsModel: SettingsModel) {
super("settings"); super("settings");
this.username.value = coreViewModel.settingsModel.username; this.username.value = coreViewModel.settingsModel.username;
+6 -2
View File
@@ -9,6 +9,7 @@ import {
ChatMessageReaction, ChatMessageReaction,
ReactionSymbols, ReactionSymbols,
} from "../../Model/Chat/chatModel"; } from "../../Model/Chat/chatModel";
import ContactListViewModel from "../Global/contactViewModel";
export default class MessagePageViewModel extends Context { export default class MessagePageViewModel extends Context {
// state // state
@@ -106,12 +107,14 @@ export default class MessagePageViewModel extends Context {
// view // view
showChatMessage = (chatMessage: ChatMessage): void => { showChatMessage = (chatMessage: ChatMessage): void => {
const contact = this.contactListViewModel.unwrapContact(chatMessage.senderId, chatMessage.senderName);
const chatMessageViewModel = new ChatMessageViewModel( const chatMessageViewModel = new ChatMessageViewModel(
this.coreViewModel, this.coreViewModel,
this, this,
chatMessage, chatMessage,
chatMessage.senderName == contact,
this.chatViewModel.settingsViewModel.username.value, chatMessage.senderId ==
this.chatViewModel.settingsViewModel.settingsModel.userid
); );
const existingChatMessageViewModel: ChatMessageViewModel | undefined = const existingChatMessageViewModel: ChatMessageViewModel | undefined =
@@ -194,6 +197,7 @@ export default class MessagePageViewModel extends Context {
constructor( constructor(
public readonly coreViewModel: CoreViewModel, public readonly coreViewModel: CoreViewModel,
public readonly chatViewModel: ChatViewModel, public readonly chatViewModel: ChatViewModel,
public readonly contactListViewModel: ContactListViewModel,
) { ) {
super("message-page"); super("message-page");
this.restoreFilter(); this.restoreFilter();
+2 -1
View File
@@ -46,13 +46,14 @@ const coreViewModel = new CoreViewModel(
); );
const storageViewModel = new StorageViewModel(coreViewModel); const storageViewModel = new StorageViewModel(coreViewModel);
const settingsViewModel = new SettingsViewModel(coreViewModel); const settingsViewModel = new SettingsViewModel(coreViewModel, settingsModel);
const contactListViewModel = new ContactListViewModel(contactListModel); const contactListViewModel = new ContactListViewModel(contactListModel);
const connectionViewModel = new ConnectionViewModel(coreViewModel); const connectionViewModel = new ConnectionViewModel(coreViewModel);
const chatListViewModel = new ChatListViewModel( const chatListViewModel = new ChatListViewModel(
coreViewModel, coreViewModel,
settingsViewModel, settingsViewModel,
connectionViewModel, connectionViewModel,
contactListViewModel,
); );
const fileTransferViewModel = new FileTransferViewModel(coreViewModel); const fileTransferViewModel = new FileTransferViewModel(coreViewModel);