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.
205 lines
7.3 KiB
205 lines
7.3 KiB
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";
|
|
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
|
|
|
export class UserView implements Observer<ActiveUserViewModel> {
|
|
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<ActiveUserViewModel>;
|
|
private readonly _userContactOnlineTemplate: Handlebars.TemplateDelegate<
|
|
ActiveUserViewModel
|
|
>;
|
|
private readonly _userContactOfflineTemplate: Handlebars.TemplateDelegate<
|
|
ActiveUserViewModel
|
|
>;
|
|
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<ActiveUserViewModel>): 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");
|
|
|
|
if (current.length > 0) {
|
|
current[0].className = current[0].className.replace(" active", "");
|
|
}
|
|
// Add the active class to the current/clicked button
|
|
else if (current.length == 0) {
|
|
// @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;
|
|
}
|
|
// 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 currentUser = this._model.activeUsersList.find((vm) => vm.userName === userName) || new ActiveUserViewModel();
|
|
currentUser.userName = userName;
|
|
|
|
if (!currentUser?.passphrase) {
|
|
this._notificationService.passphrasePrompt(
|
|
async (result) => {
|
|
if (result) {
|
|
|
|
const valid = await this._chatModel.isPassphraseValid(result, currentUser.userName!);
|
|
if (!valid) {
|
|
bootbox.alert("Some error occured. Please check your password");
|
|
log.error("invalid password");
|
|
return;
|
|
}
|
|
currentUser.unlocked = true;
|
|
currentUser.passphrase = result;
|
|
const chatMessages: ChatMessageViewModel[] = await this._chatModel.getMessages(currentUser, "new");
|
|
|
|
this._model.activeUsersList
|
|
.filter((v) => v.userName == currentUser!.userName)
|
|
.forEach((v) => {
|
|
v.passphrase = result;
|
|
v.unlocked = true;
|
|
if (chatMessages.length > 0) {
|
|
v.lastMessageTime = new Date(
|
|
chatMessages[chatMessages.length - 1].messageTime
|
|
);
|
|
const lastMessageText = (v.lastMessageText =
|
|
chatMessages[chatMessages.length - 1].message);
|
|
if (lastMessageText.length > 15) {
|
|
v.lastMessageText =
|
|
chatMessages[chatMessages.length - 1].message.slice(
|
|
0,
|
|
15
|
|
) + "...";
|
|
}
|
|
}
|
|
});
|
|
this._promptHandler(currentUser);
|
|
|
|
}
|
|
}
|
|
);
|
|
}
|
|
else {
|
|
this._chatModel.getMessages(currentUser, "new");
|
|
}
|
|
|
|
el.className += " active";
|
|
if (currentUser.unlocked && currentUser.lastMessageTime) {
|
|
this._newMessagesLoop = setInterval(
|
|
this._chatModel.getMessages.bind(this._chatModel, currentUser, "update"),
|
|
10_000
|
|
);
|
|
this._model.notify();
|
|
}
|
|
}
|
|
|
|
private _promptHandler(vm: ActiveUserViewModel) {
|
|
// vms.filter(v => v.userName == vm.userName).map(v => v.userName = vm.userName)
|
|
// log.debug(vms);
|
|
|
|
if (vm.lastMessageTime) {
|
|
this._newMessagesLoop = setInterval(
|
|
this._chatModel.getMessages.bind(this._chatModel, vm, "update"),
|
|
10_000
|
|
);
|
|
this._model.notify();
|
|
}
|
|
}
|
|
|
|
private _addSearchButtonEL() {
|
|
this._userSearchButton.addEventListener("submit", (e) => {
|
|
e.preventDefault();
|
|
// log.trace(temp);
|
|
const searchTerm = this._userSearchInputElement.value;
|
|
if (searchTerm.length > 0) {
|
|
log.debug("search term value = " + searchTerm);
|
|
const list = this._model.activeUsersList;
|
|
log.debug("active users");
|
|
log.debug(list);
|
|
if (!list) {
|
|
log.error("Users list is null");
|
|
return;
|
|
}
|
|
let searchResult = this._searchService.search(list, searchTerm);
|
|
this.update({ data: searchResult, op: "" });
|
|
log.debug(searchResult);
|
|
}
|
|
else {
|
|
this._notificationService.error("Please enter a name")
|
|
}
|
|
});
|
|
}
|
|
|
|
private _addSearchInputEL() {
|
|
this._userSearchInputElement.addEventListener("input", (e) => {
|
|
e.preventDefault();
|
|
if (this._userSearchInputElement.value.length < 2) {
|
|
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: "" });
|
|
});
|
|
}
|
|
}
|