diff --git a/chatto/src/main/javascript/ts/src/model/ChatModel.ts b/chatto/src/main/javascript/ts/src/model/ChatModel.ts index da7025b..e03caa3 100644 --- a/chatto/src/main/javascript/ts/src/model/ChatModel.ts +++ b/chatto/src/main/javascript/ts/src/model/ChatModel.ts @@ -3,162 +3,217 @@ import { Observer } from "../observe/Observer"; import { JsonAPI } from "../singleton/JsonAPI"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { ChatModelHelper } from "./ChatModelHelper"; -import log = require('loglevel'); +import log = require("loglevel"); import { ObserverData } from "../observe/ObserverData"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel"; import moment = require("moment"); interface Params { - userName: string, - data: ChatMessageViewModel[], - op: string + userName: string; + data: ChatMessageViewModel[]; + op: string; } export class ChatModel implements Subject { - /** - * @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[] = []; - private readonly _messagePageMap: Map; - private readonly _messagesMap: Map; - 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): void { - log.info('Subject: Attached an observer.'); - this._observers.push(observer); + /** + * @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[] = []; + private readonly _messagePageMap: Map; + private readonly _messagesMap: Map; + 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): void { + log.info("Subject: Attached an observer."); + this._observers.push(observer); + } + + public detach(observer: Observer): 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, []); + break; + 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; + case "update": + this._messagesMap.set( + username, + this.getStoredUserMessages(username).concat(messages) + ); + break; + default: + new Error("Invalid option"); } + } - public detach(observer: Observer): void { - const observerIndex = this._observers.indexOf(observer); - this._observers.splice(observerIndex, 1); - log.info('Subject: Detached an observer.'); + private getStoredUserMessages(username: string): ChatMessageViewModel[] { + let temp = this._messagesMap.get(username); + if (temp == null) return []; + else { + return temp; } - - private storeUserMessages(username: string, messages: ChatMessageViewModel[], op: string) { - switch (op) { - case "clear": this._messagesMap.set(username, []); break; - 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; - case "update": this._messagesMap.set(username, this.getStoredUserMessages(username).concat(messages)); break; - default: new Error("Invalid option"); + } + + /** + * Trigger an update in each subscriber. + */ + public notify(p: Params): void { + log.info("Subject: Notifying observers..."); + switch (p.op) { + case "clear": + { + const od: ObserverData = { + data: [], + op: "clear", + }; + for (const observer of this._observers) { + observer.update(od); + } } - - } - - private getStoredUserMessages(username: string): ChatMessageViewModel[] { - let temp = this._messagesMap.get(username); - if (temp == null) - return []; - else { - return temp; + break; + case "new": + { + const od: ObserverData = { + data: p.data, + op: p.op, + }; + for (const observer of this._observers) { + observer.update(od); + } } - } - - /** - * Trigger an update in each subscriber. - */ - public notify(p: Params): void { - log.info('Subject: Notifying observers...'); - switch (p.op) { - case "clear": { - const od: ObserverData = { data: [], op: "clear" } - for (const observer of this._observers) { - observer.update(od); - } - } break; - case "new": { - const od: ObserverData = { data: p.data, op: p.op } - for (const observer of this._observers) { - observer.update(od); - } - } break; - case "page": { - const od: ObserverData = { data: p.data, op: p.op } - for (const observer of this._observers) { - observer.update(od); - } - } break; - case "update": { - const od: ObserverData = { data: p.data, op: p.op } - for (const observer of this._observers) { - observer.update(od); - } - } break; - default: { log.error("error") } + break; + case "page": + { + const od: ObserverData = { + data: p.data, + op: p.op, + }; + for (const observer of this._observers) { + observer.update(od); + } } + break; + case "update": + { + const od: ObserverData = { + 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 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 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(vm: ActiveUserViewModel, op: string): Promise { - if (this._messagePageMap.get(vm.userName!) == null) - this._messagePageMap.set(vm.userName!, 0); - - const pageNumber = this._messagePageMap.get(vm.userName!) - const cVMs = await this._chatModelHelper.getMessages(vm.userName!, vm.passphrase, pageNumber!, vm.lastMessageTime!, op); - let cVMs2 = Array(); - if (cVMs != null) { - log.info('Subject: My state has just changed') - const existingMessages = this.getStoredUserMessages(vm.userName!); - log.debug('existing message:') - log.debug(existingMessages); - log.debug('new messages:') - log.debug(cVMs); - cVMs2 = cVMs.filter(c => { - const res = existingMessages.filter(m => { - if (moment(c.messageTime).isSame(moment(m.messageTime))) - return true; - }) - if (res.length > 0) - return false; - return true; - }) - if (cVMs2.length != 0 && op == "update") { - const lastMessageText = vm.lastMessageText = cVMs2[cVMs2.length - 1].message; - cVMs2.forEach(v => { - if (v.userName == vm.userName) { - v.lastMessageTime = cVMs2[cVMs2.length - 1].messageTime; - v.lastMessageText = cVMs2[cVMs2.length - 1].message.slice(0, 15) + "..." - } - }) - }; - - if (cVMs2.length != 0 && op != "update") { - - this._messagePageMap.set(vm.userName!, this._messagePageMap.get(vm.userName!)! + 1); - } - - this.storeUserMessages(vm.userName!, cVMs2, op); - this.notify({ userName: vm.userName!, data: cVMs2, op: op }); - } - else { - log.error('Messages were null'); - } - - return cVMs2; + public async getMessages( + aVm: ActiveUserViewModel, + op: string + ): Promise { + if (this._messagePageMap.get(aVm.userName!) == null) + this._messagePageMap.set(aVm.userName!, 0); + + const pageNumber = this._messagePageMap.get(aVm.userName!); + const cVMs = await this._chatModelHelper.getMessages( + aVm.userName!, + aVm.passphrase, + pageNumber!, + aVm.lastMessageTime!, + op + ); + let cVMsFiltered = Array(); + if (cVMs != null && cVMs.length != 0) { + log.info("Subject: My state has just changed"); + const existingMessages = this.getStoredUserMessages(aVm.userName!); + log.debug("existing message:"); + log.debug(existingMessages); + log.debug("new messages:"); + log.debug(cVMs); + + // filter duplicates + cVMsFiltered = cVMs.filter((c) => { + const res = existingMessages.filter((m) => { + if (moment(c.messageTime).isSame(moment(m.messageTime))) return true; + }); + if (res.length > 0) return false; + return true; + }); + + if (op == "update") { + // update the active user last message text and times for each user + const lastMessage = cVMsFiltered[cVMsFiltered.length - 1]; + cVMsFiltered.forEach((v) => { + if (v.fromUser == aVm.userName) { + aVm.lastMessageTime = lastMessage.messageTime; + aVm.lastMessageText = lastMessage.message.slice(0, 15) + "..."; + } + }); + } else { + this._messagePageMap.set( + aVm.userName!, + this._messagePageMap.get(aVm.userName!)! + 1 + ); + } + + this.storeUserMessages(aVm.userName!, cVMsFiltered, op); + this.notify({ userName: aVm.userName!, data: cVMsFiltered, op: op }); } - public async isPassphraseValid(passphrase: string, userName: string): Promise { - let valid = await this._chatModelHelper.isPassphraseValid(passphrase, userName); - return valid; - } -} \ No newline at end of file + return cVMsFiltered; + } + + public async isPassphraseValid( + passphrase: string, + userName: string + ): Promise { + let valid = await this._chatModelHelper.isPassphraseValid( + passphrase, + userName + ); + return valid; + } +}