import { Observer } from "../observe/Observer"; import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel"; import { ChatModel } from "../model/ChatModel"; import log = require("loglevel"); import * as DOMPurify from "dompurify"; import { SearchService } from "../service/SearchService"; import { UserModel } from "../model/UserModel"; import { UserViewDeps } from "./UserViewDeps"; import { ObserverData } from "../observe/ObserverData"; import { JsonAPI } from "../singleton/JsonAPI"; import { NotificationService } from "../service/NotificationService"; export class UserView implements Observer { private readonly _model: UserModel; private readonly _chatModel: ChatModel; private readonly _usersListElement: HTMLElement; private readonly _userSearchInputElement: HTMLInputElement; private readonly _userSearchButton: HTMLElement; private readonly _userSearchCancelButton: HTMLElement; private readonly _searchService: SearchService; private readonly _userContactOnlineTemplate: Handlebars.TemplateDelegate; private readonly _userContactOfflineTemplate: Handlebars.TemplateDelegate; private readonly _notificationService: NotificationService; private _newMessagesLoop: any; constructor(deps: UserViewDeps) { this._model = deps.model; this._chatModel = deps.chatModel; this._usersListElement = deps.usersListElement; this._userSearchInputElement = deps.userSearchInputElement; this._userSearchButton = deps.userSearchButton; this._userSearchCancelButton = deps.userSearchCancelButton; this._searchService = deps.searchService; this._userContactOnlineTemplate = deps.userContactOnlineTemplate; this._userContactOfflineTemplate = deps.userContactOfflineTemplate; this._notificationService = deps.notificationService; this._addSearchEventListeners(); } update(d: ObserverData): void { let html: string = ""; d.data.forEach((element: ActiveUserViewModel) => { element.online ? html += this._userContactOnlineTemplate(element) : html += this._userContactOfflineTemplate(element); }); $(this._usersListElement).html(DOMPurify.sanitize(html)); this._addUserCallBacks(); } private _addSearchEventListeners(): void { this._addSearchButtonEL(); this._addSearchCancelEL(); this._addSearchInputEL(); } private _addUserCallBacks(): void { let userBoxes = document.getElementsByClassName('user-box'); Array.from(userBoxes).forEach((ub: Element) => ub.addEventListener('click', this._userCallBack.bind(this, ub))) } private _userCallBack(el: Element): void { this._chatModel.clear(); clearInterval(this._newMessagesLoop); let current = document.getElementsByClassName('user-box active'); let passphrase: string = ''; if (current.length > 0) { // let passphraseInput = document.getElementById('passphrase') as any; // if (passphraseInput == null) { // log.error('passphraseInput element reference is null'); // return; // } // passphrase = passphraseInput.value // if (passphrase == '' || passphrase == null) { // // alert('Please input passphrase') // // alertify.error('Please enter a passphrase'); // log.error('passphrase is empty or null'); // return; // } current[0].className = current[0].className.replace(" active", ""); } // Add the active class to the current/clicked button else if (current.length == 0) { let elem = document.getElementById('passphrase-initial') as any; if (elem == null) { log.error('passphraseInput element reference is null'); return; } // passphrase = elem.value; // if (passphrase == '' || passphrase == null) { // // // alert('Please input passphrase') // // // alertify.error('Please enter a passphrase'); // log.error('passphrase is empty or null'); // return; // } // @ts-ignore: Object is possibly 'null'. document.getElementById('no-user-selected').hidden = true; // @ts-ignore: Object is possibly 'null'. document.getElementById('chat-card').hidden = false; // @ts-ignore: Object is possibly 'null'. elem.hidden = true; } // console.log(this.getElementsByClassName('to-user-span')); let elem = el.getElementsByClassName('to-user-span')[0] as HTMLElement; let userName = elem.innerText; JsonAPI.contactName = userName; // @ts-ignore: Object is possibly 'null'. document.getElementById('user-name-span').innerText = userName; let vm = this._model.activeUsersList.find(vm => vm.userName === userName); if (!vm) { vm = new ActiveUserViewModel(); vm.userName = userName; } this._notificationService.passphrasePrompt(vm, this._model.activeUsersList, this._chatModel.getMessages.bind(this._chatModel), this._promptHandler.bind(this), this._chatModel.isPassphraseValid.bind(this._chatModel)); // this._chatModel.getMessages(userName, vm.passphrase, null, "new"); el.className += " active"; log.debug("loop", this._newMessagesLoop) if (this._newMessagesLoop != null) { this._newMessagesLoop = setInterval(this._chatModel.getMessages.bind(this._chatModel, vm, "update"), 2000); } } private _promptHandler(vm: ActiveUserViewModel, vms: ActiveUserViewModel[]) { // vms.filter(v => v.userName == vm.userName).map(v => v.userName = vm.userName) log.debug(vms) this._model.notify(); this._newMessagesLoop = setInterval(this._chatModel.getMessages.bind(this._chatModel, vm, "update"), 2000); } private _addSearchButtonEL() { this._userSearchButton.addEventListener('submit', (e) => { e.preventDefault(); // log.trace(temp); const searchTerm = this._userSearchInputElement.value; log.debug("search term value = " + searchTerm); const list = this._model.activeUsersList; log.debug("active users"); log.debug(list); if (list == null) { log.error("Users list is null"); return; } let searchResult = this._searchService.search(list, searchTerm); this.update({ data: searchResult, op: "" }); log.debug(searchResult); }) } private _addSearchInputEL() { this._userSearchInputElement.addEventListener('input', (e) => { e.preventDefault(); if (this._userSearchInputElement.value.length < 2) { log.debug("inputted") this._userSearchCancelButton.hidden = false; } }) } private _addSearchCancelEL() { this._userSearchCancelButton.addEventListener('click', (e) => { e.preventDefault(); this._userSearchInputElement.value = ""; this._userSearchCancelButton.hidden = true; let list = this._model.activeUsersList; this.update({ data: list, op: "" }) }) } }