add message notifications

This commit is contained in:
marlon-erler
2026-04-01 19:00:16 +00:00
parent 8a997aab24
commit 3bd0287517
11 changed files with 256 additions and 18 deletions
+5
View File
@@ -8,11 +8,14 @@ import { IndexManager } from "../../Model/Utility/utility";
import SettingsViewModel from "../Global/settingsViewModel";
import StorageModel from "../../Model/Global/storageModel";
import ConnectionViewModel from "../Global/connectionViewModel";
import NotificationViewModel from "../Global/notificationViewModel";
import NotificationModel from "../../Model/Global/notificationModel";
export default class ChatListViewModel {
storageModel: StorageModel;
chatListModel: ChatListModel;
settingsViewModel: SettingsViewModel;
notificationViewModel: NotificationViewModel;
connectionViewModel: ConnectionViewModel;
// data
@@ -63,6 +66,7 @@ export default class ChatListViewModel {
this.storageModel,
chatModel,
this.settingsViewModel,
this.notificationViewModel,
this.connectionViewModel,
this,
);
@@ -105,6 +109,7 @@ export default class ChatListViewModel {
this.storageModel = storageModel;
this.chatListModel = chatListModel;
this.settingsViewModel = settingsViewModel;
this.notificationViewModel = new NotificationViewModel(this);
this.connectionViewModel = connectionViewModel;
this.loadChats();
+9 -3
View File
@@ -19,11 +19,13 @@ import SettingsViewModel from "../Global/settingsViewModel";
import TaskPageViewModel from "../Pages/taskPageViewModel";
import { translations } from "../../View/translations";
import ConnectionViewModel from "../Global/connectionViewModel";
import NotificationViewModel from "../Global/notificationViewModel";
export default class ChatViewModel {
chatModel: ChatModel;
storageModel: StorageModel;
settingsViewModel: SettingsViewModel;
notificationViewModel: NotificationViewModel;
connectionViewModel: ConnectionViewModel;
chatListViewModel: ChatListViewModel;
@@ -53,7 +55,7 @@ export default class ChatViewModel {
this.chatListViewModel.closeChat();
};
closeSubPages = (): void => { };
closeSubPages = (): void => {};
setColor = (color: Color): void => {
this.setDisplayedColor(color);
@@ -104,12 +106,12 @@ export default class ChatViewModel {
this.chatModel.setReadStatus(false);
}
this.hasUnreadMessages.value = this.chatModel.info.hasUnreadMessages;
}
};
setReadStatus = (hasUnreadMessages: boolean): void => {
this.chatModel.setReadStatus(hasUnreadMessages);
this.hasUnreadMessages.value = hasUnreadMessages;
}
};
// init
constructor(
@@ -117,6 +119,7 @@ export default class ChatViewModel {
storageModel: StorageModel,
chatModel: ChatModel,
settingsViewModel: SettingsViewModel,
notificationViewModel: NotificationViewModel,
connectionViewModel: ConnectionViewModel,
chatListViewModel: ChatListViewModel,
) {
@@ -125,6 +128,7 @@ export default class ChatViewModel {
this.chatModel = chatModel;
this.settingsViewModel = settingsViewModel;
this.connectionViewModel = connectionViewModel;
this.notificationViewModel = notificationViewModel;
this.chatListViewModel = chatListViewModel;
// page viewModels
@@ -155,6 +159,8 @@ export default class ChatViewModel {
(chatMessage: ChatMessage) => {
this.messagePageViewModel.showChatMessage(chatMessage);
this.updateReadStatus();
this.notificationViewModel.showNotification(chatMessage);
},
);
@@ -0,0 +1,74 @@
import * as React from "bloatless-react";
import ChatModel, { ChatMessage } from "../../Model/Chat/chatModel";
import ChatListViewModel from "../Chat/chatListViewModel";
export default class NotificationViewModel {
chatListViewModel: ChatListViewModel;
// data
seenMessageIds = new Set<string>();
messagesInMarquee: Notification[] = [];
marquee = new React.State<Notification | undefined>(undefined);
currentIndex = 0;
interval: number | undefined = undefined;
// main
showNotification = (message: ChatMessage): void => {
const notification = NotificationViewModel.createNotification(message);
if (this.seenMessageIds.has(message.id)) return;
const currentChat = this.chatListViewModel.selectedChat.value.chatModel.info.primaryChannel;
if (notification.chat == currentChat) return;
this.messagesInMarquee.push(notification);
this.startLoop();
};
// loop
loop = () => {
if (this.messagesInMarquee.length == 0) {
this.marquee.value = undefined;
return this.stopLoop();
}
const notification = this.messagesInMarquee.shift();
this.seenMessageIds.delete(notification.messageId);
this.marquee.value = notification;
};
startLoop = () => {
if (this.interval != undefined) return;
this.loop();
this.interval = setInterval(() => {
this.loop();
}, 5000);
};
stopLoop = () => {
clearInterval(this.interval);
this.interval = undefined;
};
// init
constructor(chatListViewModel: ChatListViewModel) {
this.chatListViewModel = chatListViewModel;
}
// util
static createNotification(message: ChatMessage): Notification {
return {
messageId: message.id,
chat: ChatModel.splitChannel(message.channel)[0],
sender: message.sender,
body: message.body,
};
}
}
export interface Notification {
messageId: string;
chat: string;
sender: string;
body: string;
}
+1 -1
View File
@@ -212,7 +212,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel {
this.showTask(taskFileContent);
},
);
// initiate
this.showToday();
}