A self hosted chat application with end-to-end encrypted messaging.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
4.8 KiB

import { Subject } from "../observe/Observable";
import { Observer } from "../observe/Observer";
import { JsonAPI } from "../singleton/JsonAPI";
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
import { ChatModelHelper } from "./ChatModelHelper";
import log = require('loglevel');
import { ObserverData } from "../observe/ObserverData";
interface Params {
userName: string,
data: ChatMessageViewModel[],
op: string
}
export class ChatModel implements Subject<ChatMessageViewModel> {
/**
* @type {Observer[]} List of subscribers. In real life, the list of
* subscribers can be stored more comprehensively (categorized by event
* type, etc.).
*/
private readonly _observers: Observer<ChatMessageViewModel>[] = [];
private readonly _messagePageMap: Map<string, number>;
private readonly _messagesMap: Map<string, ChatMessageViewModel[]>;
private readonly _chatModelHelper: ChatModelHelper;
constructor(chatModelHelper: ChatModelHelper) {
this._messagePageMap = new Map();
this._messagesMap = new Map();
this._chatModelHelper = chatModelHelper;
}
/**
* The subscription management methods.
*/
public attach(observer: Observer<ChatMessageViewModel>): void {
log.info('Subject: Attached an observer.');
this._observers.push(observer);
}
public detach(observer: Observer<ChatMessageViewModel>): void {
const observerIndex = this._observers.indexOf(observer);
this._observers.splice(observerIndex, 1);
log.info('Subject: Detached an observer.');
}
private storeUserMessages(username: string, messages: ChatMessageViewModel[], op: string) {
switch (op) {
case "clear": this._messagesMap.set(username, []);
case "page": this._messagesMap.set(username, messages.concat(this.getStoredUserMessages(username))); break;
// case "page": this._messagesMap.set(username, messages);
case "new": this._messagesMap.set(username, this.getStoredUserMessages(username).concat(messages)); break;
default: new Error("Invalid option");
}
}
private getStoredUserMessages(username: string): ChatMessageViewModel[] {
let temp = this._messagesMap.get(username);
if (temp == null)
return [];
else {
return temp;
}
}
/**
* Trigger an update in each subscriber.
*/
public notify(p: Params): void {
log.info('Subject: Notifying observers...');
switch (p.op) {
case "clear": {
const od: ObserverData<ChatMessageViewModel> = { data: [], op: "clear" }
for (const observer of this._observers) {
observer.update(od);
}
} break;
case "new": {
const od: ObserverData<ChatMessageViewModel> = { data: p.data, op: p.op }
for (const observer of this._observers) {
observer.update(od);
}
} break;
case "page": {
const od: ObserverData<ChatMessageViewModel> = { data: p.data, op: p.op }
for (const observer of this._observers) {
observer.update(od);
}
} break;
default: { log.error("error") }
}
}
public someBusinessMethod(chatMessageList: ChatMessageViewModel[]): void {
}
public clear(): void {
log.info("Clearing model")
this._messagePageMap.set(JsonAPI.contactName!, 0);
this.storeUserMessages(JsonAPI.contactName!, Array(), "clear");
this.notify({ userName: "", data: [], op: "clear" })
}
public async getMessages(contactName: string, passphrase: string, lastMessageTime: string | null, op: string): Promise<ChatMessageViewModel[]> {
if (this._messagePageMap.get(contactName) == null)
this._messagePageMap.set(contactName, 0);
const pageNumber = this._messagePageMap.get(contactName)
const cVMs = await this._chatModelHelper.getMessages(contactName, passphrase, pageNumber!, lastMessageTime, op);
if (cVMs != null) {
log.info('Subject: My state has just changed')
const existingMessages = this.getStoredUserMessages(contactName);
log.debug('existing message:')
log.debug(existingMessages);
log.debug('new messages:')
log.debug(cVMs);
this.storeUserMessages(contactName, cVMs, op);
this.notify({ userName: contactName, data: cVMs, op: op });
}
else {
log.error('Messages were null');
}
if (cVMs.length != 0) {
this._messagePageMap.set(contactName, this._messagePageMap.get(contactName)! + 1);
}
return cVMs;
}
}