2026-04-01 19:00:16 +00:00
|
|
|
import * as React from "bloatless-react";
|
2026-04-08 14:02:12 +00:00
|
|
|
import { ChatPageTypes } from "../Chat/chatViewModel";
|
2026-04-18 11:55:01 +00:00
|
|
|
import ChatListViewModel from "../Chat/chatListViewModel";
|
|
|
|
|
import ChatModel, { ChatMessage } from "../../Model/Chat/chatModel";
|
2026-04-01 19:00:16 +00:00
|
|
|
|
|
|
|
|
export default class NotificationViewModel {
|
|
|
|
|
// 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 => {
|
2026-04-13 11:23:17 +00:00
|
|
|
const notification: Notification =
|
|
|
|
|
NotificationViewModel.createNotification(message);
|
2026-04-01 19:00:16 +00:00
|
|
|
if (this.seenMessageIds.has(message.id)) return;
|
|
|
|
|
|
2026-04-15 10:43:52 +00:00
|
|
|
if (this.chatListViewModel.selectedChat.value == undefined) return;
|
|
|
|
|
|
2026-04-01 19:14:42 +00:00
|
|
|
const currentChat =
|
2026-08-29 02:10:26 +02:00
|
|
|
this.chatListViewModel.selectedChat.value.chatModel
|
|
|
|
|
.unwrappedPrimaryChannel;
|
2026-04-02 19:22:10 +00:00
|
|
|
const currentPage =
|
|
|
|
|
this.chatListViewModel.selectedChat.value.selectedPage.value;
|
|
|
|
|
if (
|
|
|
|
|
notification.chat == currentChat &&
|
2026-04-08 14:02:12 +00:00
|
|
|
currentPage == ChatPageTypes.Messages
|
2026-04-02 19:22:10 +00:00
|
|
|
)
|
|
|
|
|
return;
|
2026-04-01 19:00:16 +00:00
|
|
|
|
|
|
|
|
this.messagesInMarquee.push(notification);
|
|
|
|
|
this.startLoop();
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-01 19:14:42 +00:00
|
|
|
openNotification = () => {
|
2026-09-09 00:04:27 +02:00
|
|
|
const notification: Notification|undefined = this.marquee.value;
|
2026-04-01 19:14:42 +00:00
|
|
|
if (notification == undefined) return;
|
|
|
|
|
|
|
|
|
|
const chat = [
|
|
|
|
|
...this.chatListViewModel.chatViewModels.value.values(),
|
|
|
|
|
].find(
|
2026-08-29 02:10:26 +02:00
|
|
|
(chat) =>
|
|
|
|
|
chat.chatModel.unwrappedPrimaryChannel == notification.chat,
|
2026-04-01 19:14:42 +00:00
|
|
|
);
|
2026-09-09 00:04:27 +02:00
|
|
|
if (!chat) return;
|
2026-04-01 19:14:42 +00:00
|
|
|
chat.open();
|
2026-04-13 19:45:52 +00:00
|
|
|
chat.openPage(ChatPageTypes.Messages);
|
2026-04-01 19:14:42 +00:00
|
|
|
};
|
|
|
|
|
|
2026-04-01 19:00:16 +00:00
|
|
|
// loop
|
|
|
|
|
loop = () => {
|
|
|
|
|
if (this.messagesInMarquee.length == 0) {
|
|
|
|
|
this.marquee.value = undefined;
|
|
|
|
|
return this.stopLoop();
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-09 00:04:27 +02:00
|
|
|
const notification: Notification|undefined = this.messagesInMarquee.shift();
|
|
|
|
|
if (!notification) return;
|
2026-04-01 19:00:16 +00:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-01 19:14:42 +00:00
|
|
|
skipLoop = () => {
|
|
|
|
|
this.stopLoop();
|
|
|
|
|
this.startLoop();
|
2026-04-02 19:22:10 +00:00
|
|
|
};
|
2026-04-01 19:14:42 +00:00
|
|
|
|
2026-04-01 19:00:16 +00:00
|
|
|
// init
|
2026-08-29 02:10:26 +02:00
|
|
|
constructor(public readonly chatListViewModel: ChatListViewModel) {}
|
2026-04-01 19:00:16 +00:00
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
}
|