Chat area is cleared when changing user
Also frontend code has een refactored significantly
This commit is contained in:
parent
52af8f39ba
commit
f34a5524fd
@ -9,7 +9,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Configuration
|
||||
|
@ -3,7 +3,6 @@ package org.ros.chatto.service;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
@ -45,6 +45,6 @@
|
||||
"alertifyjs": "global:alertify"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "watchify ts/src/main.ts -p [ tsify --target es2017 --noImplicitAny ] --debug -o ../resources/static/js/bundle.js"
|
||||
"watch": "watchify ts/src/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o ../resources/static/js/bundle.js"
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +1,58 @@
|
||||
import { Controller } from "./controller/AbstractController";
|
||||
import { UserModel } from "./model/UserModel"
|
||||
import { Model } from "./model/AbstractModel";
|
||||
import { View } from "./view/AbstractView";
|
||||
import { UserView } from "./view/UserView";
|
||||
import { UserController } from "./controller/UserController";
|
||||
import { ModelFactory } from "./model/ModelFactory";
|
||||
import { ActiveUserViewModel } from "./viewmodel/ActiveUserViewModel";
|
||||
import { ChatMessageViewModel } from "./viewmodel/ChatMessageViewModel";
|
||||
import * as Handlebars from "handlebars";
|
||||
import { ChatModel } from "./model/ChatModel";
|
||||
import { ChatView } from "./view/ChatView";
|
||||
import { ChatController } from "./controller/ChatController";
|
||||
import { JsonAPI } from "./singleton/JsonAPI";
|
||||
import * as log from 'loglevel';
|
||||
import { EncryptionService } from "./service/EncryptionService";
|
||||
import { SJCLEncryptionService } from "./service/SJCLEncryptionService";
|
||||
import { MessageCipherDTO } from "./dto/MessageCipherDTO";
|
||||
import { SearchService } from "./service/SearchService";
|
||||
import { FuseSearchService } from "./service/FuseSearchService";
|
||||
import { ChatMessageDTO } from "./dto/ChatMessageDTO";
|
||||
import { NotificationService } from "./service/NotificationService";
|
||||
import { AlertifyNotificationService } from "./service/AlertifyNotificationService";
|
||||
import { Builder } from "builder-pattern";
|
||||
|
||||
// import "./SprintfTest.d.ts"
|
||||
// import { sprintf } from "sprintf-js";
|
||||
// import sprintf = require('sprintf-js');
|
||||
import { TemplateFactory } from "./template/TemplateFactory";
|
||||
import { UserViewDeps } from "./view/UserViewDeps";
|
||||
import { ChatViewDeps } from "./view/ChatViewDeps";
|
||||
import { MarkDownItMarkDownService } from "./service/MarkDownItMarkDownService";
|
||||
import { Sprintf } from "./singleton/Sprintf";
|
||||
import * as Handlebars from "handlebars";
|
||||
import * as log from 'loglevel';
|
||||
import { ChatController } from "./controller/ChatController";
|
||||
import { UserController } from "./controller/UserController";
|
||||
import { ChatModel } from "./model/ChatModel";
|
||||
import { ChatModelHelper } from "./model/ChatModelHelper";
|
||||
import { UserModel } from "./model/UserModel";
|
||||
import { AlertifyNotificationService } from "./service/AlertifyNotificationService";
|
||||
import { EncryptionServiceFactory } from "./service/EncryptionServiceFactory";
|
||||
import { FuseSearchService } from "./service/FuseSearchService";
|
||||
import { MarkDownItMarkDownService } from "./service/MarkDownItMarkDownService";
|
||||
import { NotificationService } from "./service/NotificationService";
|
||||
import { SearchService } from "./service/SearchService";
|
||||
import { TemplateFactory } from "./template/TemplateFactory";
|
||||
import { ChatView } from "./view/ChatView";
|
||||
import { ChatViewDeps } from "./view/ChatViewDeps";
|
||||
import { UserView } from "./view/UserView";
|
||||
import { UserViewDeps } from "./view/UserViewDeps";
|
||||
import { ActiveUserViewModel } from "./viewmodel/ActiveUserViewModel";
|
||||
|
||||
log.setLevel("TRACE");
|
||||
|
||||
const usersListElement = document.getElementById('contacts-box');
|
||||
const userSearchButton = document.getElementById('user-search');
|
||||
const userSearchInputElement = document.getElementById('user-search-term') as HTMLInputElement;
|
||||
const userSearchCancelButton = document.getElementById('user-search-cancel');
|
||||
const chatArea = document.getElementById('chat-area-new');
|
||||
|
||||
|
||||
const activeUserSearchService: SearchService<ActiveUserViewModel> = new FuseSearchService(["userName"]);
|
||||
const ns: NotificationService = new AlertifyNotificationService();
|
||||
const encryptionService = EncryptionServiceFactory.getEncryptionService();
|
||||
|
||||
log.setLevel("TRACE")
|
||||
|
||||
const chatModel = new ChatModel();
|
||||
|
||||
const userModel = new UserModel();
|
||||
// const userModel = ModelFactory.createModel("USER");
|
||||
const chatModelHelper = new ChatModelHelper(encryptionService, ns);
|
||||
const chatModel = new ChatModel(chatModelHelper);
|
||||
const cvDeps: ChatViewDeps = {
|
||||
chatModel: chatModel,
|
||||
// @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
|
||||
messageContainer: chatArea,
|
||||
messageSendTemplate: TemplateFactory.getTemplate('msg_container_send_template'),
|
||||
messageReceiveTemplate: TemplateFactory.getTemplate('msg_container_template'),
|
||||
markdownService: new MarkDownItMarkDownService,
|
||||
encryptionService: encryptionService,
|
||||
notificationService: ns
|
||||
}
|
||||
const chatView = new ChatView(cvDeps);
|
||||
chatModel.attach(chatView);
|
||||
const chatController = new ChatController(chatModel, chatView);
|
||||
|
||||
|
||||
|
||||
const userModel = new UserModel(ns);
|
||||
const uvDeps: UserViewDeps = {
|
||||
model: userModel,
|
||||
chatModel: chatModel,
|
||||
@ -61,82 +68,21 @@ const uvDeps: UserViewDeps = {
|
||||
userContactOfflineTemplate: TemplateFactory.getTemplate('user-contact-offline-template')
|
||||
}
|
||||
const userView = new UserView(uvDeps);
|
||||
|
||||
// console.log(userBox);
|
||||
|
||||
userModel.attach(userView);
|
||||
// userView.model
|
||||
|
||||
|
||||
const userController = new UserController(userModel, userView);
|
||||
// userController.test();
|
||||
|
||||
|
||||
|
||||
// userModel.someBusinessMethod(activeUsersMock);
|
||||
log.info("hello");
|
||||
|
||||
const chatArea = document.getElementById('chat-area-new');
|
||||
// @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
|
||||
const cvDeps: ChatViewDeps = {
|
||||
chatModel: chatModel,
|
||||
// @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
|
||||
messageContainer: chatArea,
|
||||
messageSendTemplate: TemplateFactory.getTemplate('msg_container_send_template'),
|
||||
messageReceiveTemplate: TemplateFactory.getTemplate('msg_container_template'),
|
||||
markdownService: new MarkDownItMarkDownService,
|
||||
encryptionService: EncryptionServiceFactory.getEncryptionService()
|
||||
|
||||
}
|
||||
const chatView = new ChatView(cvDeps);
|
||||
chatModel.attach(chatView);
|
||||
const chatController = new ChatController(chatModel, chatView);
|
||||
|
||||
|
||||
function someFunc(vm: ActiveUserViewModel): void {
|
||||
// log.info(vm);
|
||||
// logger.info(vm)
|
||||
}
|
||||
|
||||
userController.getActiveUsers();
|
||||
|
||||
log.info("test");
|
||||
// someFunc(activeUserViewModelMock);
|
||||
|
||||
// @ts-ignore: Object is possibly 'null'.
|
||||
var source = document.getElementById("msg_container_template").innerHTML;
|
||||
|
||||
var msgContainerTemplate = Handlebars.compile(source);
|
||||
|
||||
JsonAPI.ACTIVE_USERS_GET + 'aef';
|
||||
|
||||
const encryptionService: EncryptionService = EncryptionServiceFactory.getEncryptionService();
|
||||
let messageCipherDTO: MessageCipherDTO = encryptionService.encrypt("password", "data");
|
||||
console.log(encryptionService.decrypt("password", messageCipherDTO));
|
||||
|
||||
|
||||
async function func(): Promise<void> {
|
||||
const text = await encryptionService.decryptAsPromise("password", messageCipherDTO)
|
||||
log.debug(text);
|
||||
}
|
||||
|
||||
func();
|
||||
|
||||
Handlebars.registerHelper('avatar', function () {
|
||||
return '<div class="img_cont_msg"> <img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img_msg"> </div>';
|
||||
});
|
||||
|
||||
const testList: ChatMessageDTO[] = [];
|
||||
|
||||
// @ts-ignore
|
||||
console.log()
|
||||
log.info(Sprintf("test sprintf"))
|
||||
// log.info(sprintf2.sprintf("test sprintf"))
|
||||
const ns: NotificationService = new AlertifyNotificationService();
|
||||
|
||||
ns.success("Welcome");
|
||||
// ns.errorWithDelay("Hmm very long error notif", 10);
|
||||
|
||||
const ss = FuseSearchService.getInstance<ActiveUserViewModel>([""]);
|
||||
|
||||
const test = Builder<UserViewDeps>().build();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
|
||||
export interface Model extends Subject{
|
||||
export interface Model extends Subject<any> {
|
||||
someBusinessMethod(data: Object): void;
|
||||
|
||||
|
||||
}
|
@ -1,114 +1,126 @@
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { Model } from "./AbstractModel";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import log = require('loglevel');
|
||||
import { EncryptionService } from "../service/EncryptionService";
|
||||
import { SJCLEncryptionService } from "../service/SJCLEncryptionService";
|
||||
import { ChatMessageDTO } from "../dto/ChatMessageDTO";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatModelHelper } from "./ChatModelHelper";
|
||||
import log = require('loglevel');
|
||||
import { ObserverData } from "../observe/ObserverData";
|
||||
|
||||
export class ChatModel implements Subject {
|
||||
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[] = [];
|
||||
private state: ChatMessageViewModel[] | null;
|
||||
private readonly _observers: Observer<ChatMessageViewModel>[] = [];
|
||||
private readonly _messagePageMap: Map<string, number>;
|
||||
private readonly _messagesMap: Map<string, ChatMessageViewModel[]>;
|
||||
private readonly _chatModelHelper: ChatModelHelper;
|
||||
|
||||
constructor() {
|
||||
this.state = null;
|
||||
constructor(chatModelHelper: ChatModelHelper) {
|
||||
this._messagePageMap = new Map();
|
||||
this._messagesMap = new Map();
|
||||
this._chatModelHelper = chatModelHelper;
|
||||
}
|
||||
/**
|
||||
* The subscription management methods.
|
||||
*/
|
||||
public attach(observer: Observer): void {
|
||||
console.log('Subject: Attached an observer.');
|
||||
public attach(observer: Observer<ChatMessageViewModel>): void {
|
||||
log.info('Subject: Attached an observer.');
|
||||
this._observers.push(observer);
|
||||
}
|
||||
|
||||
public detach(observer: Observer): void {
|
||||
public detach(observer: Observer<ChatMessageViewModel>): void {
|
||||
const observerIndex = this._observers.indexOf(observer);
|
||||
this._observers.splice(observerIndex, 1);
|
||||
console.log('Subject: Detached an observer.');
|
||||
log.info('Subject: Detached an observer.');
|
||||
}
|
||||
|
||||
private storeUserMessages(username: string, messages: ChatMessageViewModel[]) {
|
||||
this._messagesMap.set(username, messages);
|
||||
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[] {
|
||||
return this._messagesMap.get(username)!;
|
||||
let temp = this._messagesMap.get(username);
|
||||
if (temp == null)
|
||||
return [];
|
||||
else {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an update in each subscriber.
|
||||
*/
|
||||
public notify(userName: string): void {
|
||||
console.log('Subject: Notifying observers...');
|
||||
for (const observer of this._observers) {
|
||||
observer.update(this._messagesMap.get(userName));
|
||||
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 {
|
||||
this.state = chatMessageList;
|
||||
console.log(`Subject: My state has just changed`);
|
||||
console.log(chatMessageList);
|
||||
this.notify("some user");
|
||||
}
|
||||
|
||||
public async getMessages(contactName: string, passphrase: string, lastMessageTime: string | null): Promise<ChatMessageViewModel[]> {
|
||||
public clear(): void {
|
||||
this._messagePageMap.set(JsonAPI.contactName!, 0);
|
||||
this.storeUserMessages(JsonAPI.contactName!, [], "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);
|
||||
// else {
|
||||
// log.debug('page number before = ' + this._messagePageMap.get(contactName)!)
|
||||
// this._messagePageMap.set(contactName, this._messagePageMap.get(contactName)! + 1);
|
||||
// log.debug('page number after = ' + this._messagePageMap.get(contactName)!)
|
||||
// }
|
||||
|
||||
const pageNumber = this._messagePageMap.get(contactName)
|
||||
const cVMs = await ChatModelHelper.getMessages(contactName, passphrase, pageNumber!, lastMessageTime);
|
||||
const cVMs = await this._chatModelHelper.getMessages(contactName, passphrase, pageNumber!, lastMessageTime, op);
|
||||
if (cVMs != null) {
|
||||
log.info('Subject: My state has just changed')
|
||||
|
||||
// this._messagesMap.set(userName, cVMs);
|
||||
const existingMessages = this.getStoredUserMessages(contactName);
|
||||
log.debug('existing message:')
|
||||
log.debug(existingMessages);
|
||||
log.debug('new messages:')
|
||||
log.debug(cVMs);
|
||||
if (existingMessages != null) {
|
||||
// existingMessages.forEach(function (elem) {
|
||||
// cVMs.push(elem);
|
||||
// })
|
||||
const newArr = cVMs.concat(existingMessages)
|
||||
// log.debug(newArr);
|
||||
this.storeUserMessages(contactName, cVMs);
|
||||
// this.storeUserMessages(contactName, cVMs);
|
||||
}
|
||||
else {
|
||||
this.storeUserMessages(contactName, cVMs);
|
||||
}
|
||||
JsonAPI.contactName = contactName;
|
||||
this.notify(contactName);
|
||||
this.storeUserMessages(contactName, cVMs, op);
|
||||
this.notify({ userName: contactName, data: cVMs, op: op });
|
||||
}
|
||||
else {
|
||||
log.error('Messages were null');
|
||||
}
|
||||
if(this._messagePageMap.get(contactName) == 0)
|
||||
{
|
||||
log.info(cVMs[cVMs.length - 1].messageTime)
|
||||
}
|
||||
|
||||
if (cVMs.length != 0) {
|
||||
// log.debug('page number before = ' + this._messagePageMap.get(contactName)!)
|
||||
this._messagePageMap.set(contactName, this._messagePageMap.get(contactName)! + 1);
|
||||
// log.debug('page number after = ' + this._messagePageMap.get(contactName)!)
|
||||
}
|
||||
|
||||
return cVMs;
|
||||
|
@ -1,30 +1,38 @@
|
||||
import * as log from "loglevel";
|
||||
import { ChatMessageDTO } from "../dto/ChatMessageDTO";
|
||||
import { EncryptionService } from "../service/EncryptionService";
|
||||
import { EncryptionServiceFactory } from "../service/EncryptionServiceFactory";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { Sprintf } from "../singleton/Sprintf";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
|
||||
export class ChatModelHelper {
|
||||
private static readonly _encryptionService: EncryptionService = EncryptionServiceFactory.getEncryptionService();
|
||||
private readonly _encryptionService: EncryptionService;
|
||||
private readonly _notificationService: NotificationService;
|
||||
|
||||
public static async getMessages(userName: string, passphrase: string, page: number | null, lastMessageTime: string | null): Promise<ChatMessageViewModel[]> {
|
||||
|
||||
constructor(encryptionService: EncryptionService, notificationService: NotificationService) {
|
||||
this._encryptionService = encryptionService;
|
||||
this._notificationService = notificationService;
|
||||
}
|
||||
|
||||
|
||||
public async getMessages(userName: string, passphrase: string, page: number | null, lastMessageTime: string | null, op: string): Promise<ChatMessageViewModel[]> {
|
||||
switch (lastMessageTime) {
|
||||
case null: {
|
||||
const data: ChatMessageDTO[] = await this.getPaginatedMessagesAjax(userName, page!);
|
||||
const cVMs = Promise.all(data.map(vm => this.toChatMessageVMAsync(vm, passphrase)).reverse());
|
||||
const data: ChatMessageDTO[] = await this._getPaginatedMessagesAjax(userName, page!);
|
||||
const cVMs = Promise.all(data.map(vm => this._toChatMessageVMAsync(vm, passphrase)).reverse());
|
||||
return cVMs;
|
||||
}
|
||||
default: {
|
||||
const data: ChatMessageDTO[] = await this.getNewMessagesAjax(userName, lastMessageTime);
|
||||
return data.map(vm => this.toChatMessageVM(vm, passphrase));
|
||||
const data: ChatMessageDTO[] = await this._getNewMessagesAjax(userName, lastMessageTime);
|
||||
return data.map(vm => this._toChatMessageVM(vm, passphrase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async toChatMessageVMAsync(chatMessageDTO: ChatMessageDTO, passphrase: string): Promise<ChatMessageViewModel> {
|
||||
private async _toChatMessageVMAsync(chatMessageDTO: ChatMessageDTO, passphrase: string): Promise<ChatMessageViewModel> {
|
||||
const vm = new ChatMessageViewModel();
|
||||
vm.fromUser = chatMessageDTO.fromUser;
|
||||
vm.toUser = chatMessageDTO.toUser;
|
||||
@ -34,7 +42,7 @@ export class ChatModelHelper {
|
||||
return vm;
|
||||
}
|
||||
|
||||
private static toChatMessageVM(chatMessageDTO: ChatMessageDTO, passphrase: string): ChatMessageViewModel {
|
||||
private _toChatMessageVM(chatMessageDTO: ChatMessageDTO, passphrase: string): ChatMessageViewModel {
|
||||
const vm = new ChatMessageViewModel();
|
||||
vm.fromUser = chatMessageDTO.fromUser;
|
||||
vm.toUser = chatMessageDTO.toUser;
|
||||
@ -44,7 +52,7 @@ export class ChatModelHelper {
|
||||
return vm;
|
||||
}
|
||||
|
||||
private static async getAllMessagesAjax(toUser: string): Promise<any> {
|
||||
private async _getAllMessagesAjax(toUser: string): Promise<any> {
|
||||
const headers = new Headers();
|
||||
if (JsonAPI.authToken == null) {
|
||||
log.error("authToken null");
|
||||
@ -52,51 +60,41 @@ export class ChatModelHelper {
|
||||
};
|
||||
headers.append('X-AUTH-TOKEN', JsonAPI.authToken);
|
||||
const url = Sprintf(JsonAPI.CHAT_MESSAGES_GET, toUser);
|
||||
// const url = Sprintf(JsonAPI.CHAT_MESSAGE_PAGE_GET, toUser,1,5);
|
||||
log.debug(url)
|
||||
// const response = await fetch(`${JsonAPI.CHAT_MESSAGES_GET}/${toUser}`, {
|
||||
// method: 'GET',
|
||||
// headers: headers
|
||||
// });
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
console.log(response.clone());
|
||||
if (fetchErrorHandler(response.clone())) {
|
||||
log.debug(response.clone());
|
||||
if (fetchErrorHandler(response.clone(), this._notificationService)) {
|
||||
return null;
|
||||
}
|
||||
const data: Promise<any> = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
private static async getPaginatedMessagesAjax(toUser: string, page: number): Promise<any> {
|
||||
private async _getPaginatedMessagesAjax(toUser: string, page: number): Promise<any> {
|
||||
const headers = new Headers();
|
||||
if (JsonAPI.authToken == null) {
|
||||
log.error("authToken null");
|
||||
return;
|
||||
};
|
||||
headers.append('X-AUTH-TOKEN', JsonAPI.authToken);
|
||||
// const url = Sprintf(JsonAPI.CHAT_MESSAGES_GET, toUser);
|
||||
const url = Sprintf(JsonAPI.CHAT_MESSAGE_PAGE_GET, toUser, page, 5);
|
||||
log.debug(url)
|
||||
// const response = await fetch(`${JsonAPI.CHAT_MESSAGES_GET}/${toUser}`, {
|
||||
// method: 'GET',
|
||||
// headers: headers
|
||||
// });
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
console.log(response.clone());
|
||||
if (fetchErrorHandler(response.clone())) {
|
||||
log.debug(response.clone());
|
||||
if (fetchErrorHandler(response.clone(), this._notificationService)) {
|
||||
return null;
|
||||
}
|
||||
const data: Promise<any> = await response.json();
|
||||
return data;
|
||||
}
|
||||
|
||||
private static async getNewMessagesAjax(toUser: string, lastMessageTimeStamp: string): Promise<any> {
|
||||
private async _getNewMessagesAjax(toUser: string, lastMessageTimeStamp: string): Promise<any> {
|
||||
const headers = new Headers();
|
||||
if (JsonAPI.authToken == null) {
|
||||
log.error("authToken null");
|
||||
@ -107,8 +105,8 @@ export class ChatModelHelper {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
console.log(response.clone());
|
||||
if (fetchErrorHandler(response.clone())) {
|
||||
log.debug(response.clone());
|
||||
if (fetchErrorHandler(response.clone(), this._notificationService)) {
|
||||
return null;
|
||||
}
|
||||
const data: Promise<any> = await response.json();
|
||||
|
@ -1,17 +1,19 @@
|
||||
import log = require("loglevel");
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { Sprintf } from "../singleton/Sprintf";
|
||||
// import { sprintf } from "sprintf-js";
|
||||
///<reference path="../SprintfTest.d.ts" />
|
||||
|
||||
// import sprintf = require('sprintf-js').sprintf;
|
||||
|
||||
export function fetchErrorHandler(response: Response) {
|
||||
export function fetchErrorHandler(response: Response, ns: NotificationService) {
|
||||
// alertify.success('Current position : ' + alertify.get('notifier', 'position'));
|
||||
if (!response.ok) {
|
||||
return response.text().catch(err => {
|
||||
// the status was not ok and there is no json body
|
||||
// throw new Error(response.statusText);
|
||||
// window.alert(sprintf('Some error occured. Http code is %s', response.status));
|
||||
// alertify.error(sprintf('Some error occured. Http code is %s', response.status));
|
||||
ns.error(Sprintf('Some error occured. Http code is %s', response.status));
|
||||
// @ts-ignore
|
||||
log.error(sprintf('Some error occured. Http code is %s', response.status));
|
||||
log.error();
|
||||
@ -20,7 +22,7 @@ export function fetchErrorHandler(response: Response) {
|
||||
// the status was not ok but there is a json body
|
||||
// throw new Error(json.error.message); // example error message returned by a REST API
|
||||
// window.alert(sprintf('Error: %s (Http code %s)', json, response.status));
|
||||
// alertify.error(sprintf('Some error occured. Http code is %s', response.status));
|
||||
ns.error(Sprintf('Some error occured. Http code is %s', response.status));
|
||||
// @ts-ignore
|
||||
log.error(sprintf('Some error occured. Http code is %s', response.status));
|
||||
log.error(json);
|
||||
|
@ -1,64 +1,66 @@
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { Model } from "./AbstractModel";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import * as log from "loglevel";
|
||||
import { Subject } from "../observe/Observable";
|
||||
import { Observer } from "../observe/Observer";
|
||||
import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||
import { fetchErrorHandler } from "./FetchErrorHandler";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
|
||||
export class UserModel implements Subject {
|
||||
export class UserModel implements Subject<ActiveUserViewModel> {
|
||||
/**
|
||||
* @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 observers: Observer<ActiveUserViewModel>[] = [];
|
||||
|
||||
|
||||
private _activeUsersList: ActiveUserViewModel[] | undefined;
|
||||
// @ts-ignore: Cannot find name 'hostAddress'.
|
||||
|
||||
constructor() { }
|
||||
private _activeUsersList: ActiveUserViewModel[];
|
||||
private readonly _notificationService: NotificationService;
|
||||
|
||||
/**
|
||||
* Getter activeUsersList
|
||||
* @return {ActiveUserViewModel[] }
|
||||
*/
|
||||
public get activeUsersList(): ActiveUserViewModel[] | undefined {
|
||||
return this._activeUsersList;
|
||||
constructor(notificationService: NotificationService) {
|
||||
this._activeUsersList = [];
|
||||
this._notificationService = notificationService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Getter activeUsersList
|
||||
* @return {ActiveUserViewModel[] }
|
||||
*/
|
||||
public get activeUsersList(): ActiveUserViewModel[] {
|
||||
return this._activeUsersList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The subscription management methods.
|
||||
*/
|
||||
public attach(observer: Observer): void {
|
||||
console.log('Subject: Attached an observer.');
|
||||
public attach(observer: Observer<ActiveUserViewModel>): void {
|
||||
log.info('Subject: Attached an observer.');
|
||||
this.observers.push(observer);
|
||||
}
|
||||
|
||||
public detach(observer: Observer): void {
|
||||
public detach(observer: Observer<ActiveUserViewModel>): void {
|
||||
const observerIndex = this.observers.indexOf(observer);
|
||||
this.observers.splice(observerIndex, 1);
|
||||
console.log('Subject: Detached an observer.');
|
||||
log.info('Subject: Detached an observer.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an update in each subscriber.
|
||||
*/
|
||||
public notify(): void {
|
||||
console.log('Subject: Notifying observers...');
|
||||
log.info('Subject: Notifying observers...');
|
||||
for (const observer of this.observers) {
|
||||
observer.update(this._activeUsersList);
|
||||
observer.update({ data: this._activeUsersList!, op: "" });
|
||||
}
|
||||
}
|
||||
|
||||
public someBusinessMethod(activeuserList: ActiveUserViewModel[]): void {
|
||||
this._activeUsersList = activeuserList;
|
||||
this.helperMethod();
|
||||
console.log(`Subject: My state has just changed`);
|
||||
console.log(activeuserList);
|
||||
log.info(`Subject: My state has just changed`);
|
||||
log.trace(activeuserList);
|
||||
this.notify();
|
||||
}
|
||||
|
||||
@ -66,31 +68,31 @@ export class UserModel implements Subject {
|
||||
* getActiveUsers
|
||||
*/
|
||||
public getActiveUsers(): void {
|
||||
if(JsonAPI.authToken!= null){
|
||||
this.getActiveUsersAjax(JsonAPI.authToken)
|
||||
.then(data => {
|
||||
// // activeUsers = data;
|
||||
// sessionStorage.setItem('activeUsers', JSON.stringify(data));
|
||||
// console.log(sessionStorage.getItem('activeUsers'));
|
||||
console.log(`Subject: received ajax active users`);
|
||||
this._activeUsersList = data;
|
||||
this.notify();
|
||||
})
|
||||
if (JsonAPI.authToken != null) {
|
||||
this._getActiveUsersAjax(JsonAPI.authToken)
|
||||
.then(data => {
|
||||
// // activeUsers = data;
|
||||
// sessionStorage.setItem('activeUsers', JSON.stringify(data));
|
||||
// log.trace(sessionStorage.getItem('activeUsers'));
|
||||
log.info(`Subject: received ajax active users`);
|
||||
this._activeUsersList = data;
|
||||
this.notify();
|
||||
})
|
||||
}
|
||||
else {
|
||||
log.error('Auth token is null');
|
||||
}
|
||||
}
|
||||
|
||||
async getActiveUsersAjax(authToken: string): Promise<any> {
|
||||
private async _getActiveUsersAjax(authToken: string): Promise<any> {
|
||||
let headers = new Headers();
|
||||
headers.append('X-AUTH-TOKEN', authToken);
|
||||
let response = await fetch(JsonAPI.ACTIVE_USERS_GET, {
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
});
|
||||
console.log(response.clone());
|
||||
if (fetchErrorHandler(response.clone())) {
|
||||
log.debug(response.clone());
|
||||
if (fetchErrorHandler(response.clone(), this._notificationService)) {
|
||||
return null;
|
||||
}
|
||||
let data = await response.json();
|
||||
|
@ -1,17 +1,18 @@
|
||||
import { Observer } from "./Observer";
|
||||
import { ObserverData } from "./ObserverData";
|
||||
|
||||
/**
|
||||
* The Subject interface declares a set of methods for managing subscribers.
|
||||
*/
|
||||
export interface Subject {
|
||||
export interface Subject<T> {
|
||||
// Attach an observer to the subject.
|
||||
attach(observer: Observer): void;
|
||||
attach(observer: Observer<T>): void;
|
||||
|
||||
// Detach an observer from the subject.
|
||||
detach(observer: Observer): void;
|
||||
detach(observer: Observer<T>): void;
|
||||
|
||||
// Notify all observers about an event.
|
||||
notify(param: any | null): void;
|
||||
notify(param: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Subject } from "./Observable";
|
||||
import { ObserverData } from "./ObserverData";
|
||||
|
||||
export interface Observer {
|
||||
export interface Observer<T> {
|
||||
// Receive update from subject.
|
||||
update(data: any): void;
|
||||
update(data: ObserverData<T>): void;
|
||||
}
|
||||
|
||||
// /**
|
||||
|
@ -0,0 +1,4 @@
|
||||
export interface ObserverData<T> {
|
||||
data: Array<T>
|
||||
op: string
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
import { Model } from "../model/AbstractModel";
|
||||
import { Controller } from "../controller/AbstractController";
|
||||
import { Observer } from "../observe/Observer";
|
||||
export interface View extends Observer {
|
||||
export interface View extends Observer<any> {
|
||||
readonly model: Model,
|
||||
readonly element: any
|
||||
}
|
@ -10,14 +10,17 @@ import { JsonAPI } from "../singleton/JsonAPI";
|
||||
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatViewDeps } from "./ChatViewDeps";
|
||||
import { fetchHandler } from "./FetchHandler";
|
||||
import { ObserverData } from '../observe/ObserverData';
|
||||
import { NotificationService } from '../service/NotificationService';
|
||||
|
||||
export class ChatView implements Observer {
|
||||
export class ChatView implements Observer<ChatMessageViewModel> {
|
||||
private readonly _chatModel: ChatModel;
|
||||
private readonly _messageContainer: HTMLElement;
|
||||
private readonly _messageSendTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
|
||||
private readonly _messageReceiveTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
|
||||
private readonly _markdownService: MarkDownService;
|
||||
private readonly _encryptionService: EncryptionService;
|
||||
private readonly _notificationService: NotificationService;
|
||||
|
||||
|
||||
constructor(deps: ChatViewDeps) {
|
||||
@ -27,7 +30,8 @@ export class ChatView implements Observer {
|
||||
this._messageReceiveTemplate = deps.messageReceiveTemplate;
|
||||
this._markdownService = deps.markdownService;
|
||||
this._encryptionService = deps.encryptionService;
|
||||
this.addEventListeners();
|
||||
this._notificationService = deps.notificationService;
|
||||
this._initEventListeners();
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#action_menu_btn').click(function () {
|
||||
@ -35,67 +39,83 @@ export class ChatView implements Observer {
|
||||
});
|
||||
});
|
||||
|
||||
this.chatMessagePageLoadAjax();
|
||||
this._chatMessagePageLoadAjax();
|
||||
}
|
||||
|
||||
update(data: ChatMessageViewModel[]): void {
|
||||
update(cd: ObserverData<ChatMessageViewModel>): void {
|
||||
log.info('ChatView: updating view');
|
||||
// let html: string = "";
|
||||
// let currentMsg = $('.msg:first');
|
||||
// this._messageContainer.innerHTML = "";
|
||||
const rev: ChatMessageViewModel[] = Object.create(data)
|
||||
rev.reverse();
|
||||
let arr: string[] = [];
|
||||
rev.forEach((vm: ChatMessageViewModel) => {
|
||||
const vmTemp: ChatMessageViewModel = { ...vm };
|
||||
vmTemp.message = this._markdownService.render(vm.message);
|
||||
/** Very Important!!!
|
||||
* Sanitizing HTML before displaying on webpage to prevent XSS attacks!!
|
||||
*/
|
||||
let rendered;
|
||||
if (vmTemp.fromUser == JsonAPI.principleName) {
|
||||
rendered = DOMPurify.sanitize(this._messageSendTemplate(vmTemp));
|
||||
|
||||
switch (cd.op) {
|
||||
case "clear": {
|
||||
$(this._messageContainer).html("");
|
||||
} break;
|
||||
case "new": {
|
||||
const rev: ChatMessageViewModel[] = Object.create(cd.data)
|
||||
rev.reverse();
|
||||
let arr: string[] = [];
|
||||
rev.forEach((vm: ChatMessageViewModel) => {
|
||||
const vmTemp: ChatMessageViewModel = { ...vm };
|
||||
vmTemp.message = this._markdownService.render(vm.message);
|
||||
/** Very Important!!!
|
||||
* Sanitizing HTML before displaying on webpage to prevent XSS attacks!!
|
||||
*/
|
||||
let rendered;
|
||||
if (vmTemp.fromUser == JsonAPI.principleName) {
|
||||
rendered = DOMPurify.sanitize(this._messageSendTemplate(vmTemp));
|
||||
|
||||
}
|
||||
else {
|
||||
rendered = DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp));
|
||||
}
|
||||
$(this._messageContainer).prepend(rendered);
|
||||
});
|
||||
$(this._messageContainer).stop().animate({
|
||||
scrollTop: $(this._messageContainer)[0].scrollHeight
|
||||
}, 1500);
|
||||
} break;
|
||||
default: {
|
||||
const rev: ChatMessageViewModel[] = Object.create(cd.data)
|
||||
rev.reverse();
|
||||
let arr: string[] = [];
|
||||
rev.forEach((vm: ChatMessageViewModel) => {
|
||||
const vmTemp: ChatMessageViewModel = { ...vm };
|
||||
vmTemp.message = this._markdownService.render(vm.message);
|
||||
/** Very Important!!!
|
||||
* Sanitizing HTML before displaying on webpage to prevent XSS attacks!!
|
||||
*/
|
||||
let rendered;
|
||||
if (vmTemp.fromUser == JsonAPI.principleName) {
|
||||
rendered = DOMPurify.sanitize(this._messageSendTemplate(vmTemp));
|
||||
|
||||
}
|
||||
else {
|
||||
rendered = DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp));
|
||||
}
|
||||
$(this._messageContainer).prepend(rendered);
|
||||
});
|
||||
}
|
||||
else {
|
||||
rendered = DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp));
|
||||
}
|
||||
$(this._messageContainer).prepend(rendered);
|
||||
// if (currentMsg.position() != null) {
|
||||
// $(this._messageContainer).scrollTop(currentMsg.position().top)
|
||||
// }
|
||||
}
|
||||
|
||||
// log.debug(vm)
|
||||
// log.debug(vmTemp)
|
||||
// html += this._messageSendTemplate(vm);
|
||||
});
|
||||
// if (currentMsg.position() != null) {
|
||||
// $(this._messageContainer).scrollTop(currentMsg.position().top)
|
||||
// }
|
||||
|
||||
// html = DOMPurify.sanitize(md.render(html));
|
||||
// this._element.innerHTML = html;
|
||||
// log.debug(this._element.innerHTML);
|
||||
}
|
||||
|
||||
private addEventListeners(): void {
|
||||
this.addChatFormEL();
|
||||
private _initEventListeners(): void {
|
||||
this._addChatFormEL();
|
||||
}
|
||||
|
||||
private addChatFormEL() {
|
||||
private _addChatFormEL() {
|
||||
const chatForm = document.getElementById('chatMessageForm') as HTMLSelectElement;
|
||||
|
||||
if (chatForm == null) {
|
||||
log.error("Chat form is null");
|
||||
}
|
||||
else {
|
||||
chatForm.addEventListener('submit', (e) => this.createChatMessageDTO(e, chatForm))
|
||||
chatForm.addEventListener('submit', (e) => this._createChatMessageDTO(e, chatForm))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private createChatMessageDTO(e: Event, chatForm: HTMLSelectElement): void {
|
||||
private _createChatMessageDTO(e: Event, chatForm: HTMLSelectElement): void {
|
||||
e.preventDefault();
|
||||
|
||||
let contactName = JsonAPI.contactName;
|
||||
@ -106,7 +126,7 @@ export class ChatView implements Observer {
|
||||
}
|
||||
|
||||
if (!chatForm.checkValidity()) {
|
||||
console.log("error");
|
||||
log.error("Form is not valid");
|
||||
chatForm.classList.add('was-validated');
|
||||
return;
|
||||
}
|
||||
@ -117,18 +137,24 @@ export class ChatView implements Observer {
|
||||
const passphraseInput = document.getElementById('passphrase') as HTMLInputElement;
|
||||
|
||||
if (chatInput.value == '' || chatInput.value == null) {
|
||||
this._notificationService.error("Please enter a message");
|
||||
log.error("Chat input is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (passphraseInput.value == '' || passphraseInput.value == null) {
|
||||
log.error("Chat input is null.");
|
||||
this._notificationService.error("Please enter a passphrase");
|
||||
log.error("Passphrase is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const messageContent = chatInput.value;
|
||||
const context = { fromUser: JsonAPI.principleName, toUser: "", message: this._markdownService.render(messageContent), messageTime: new Date().toLocaleString() };
|
||||
const context = {
|
||||
fromUser: JsonAPI.principleName, toUser: "",
|
||||
message: this._markdownService.render(messageContent),
|
||||
messageTime: new Date().toLocaleString()
|
||||
};
|
||||
// @ts-ignore
|
||||
const msgContainer: string = this._messageSendTemplate(context);
|
||||
$(this._messageContainer).append(DOMPurify.sanitize(msgContainer));
|
||||
@ -143,10 +169,10 @@ export class ChatView implements Observer {
|
||||
// "messageTime": null
|
||||
}
|
||||
// @ts-ignore
|
||||
this.sendMessageAJAX(chatMessageDTO);
|
||||
this._sendMessageAJAX(chatMessageDTO);
|
||||
}
|
||||
|
||||
private sendMessageAJAX(chatMessageDTO: ChatMessageDTO): void {
|
||||
private _sendMessageAJAX(chatMessageDTO: ChatMessageDTO): void {
|
||||
let headers = new Headers();
|
||||
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
|
||||
|
||||
@ -164,16 +190,15 @@ export class ChatView implements Observer {
|
||||
log.debug(response);
|
||||
return response.clone();
|
||||
})
|
||||
.then(response => fetchHandler(response));
|
||||
.then(response => fetchHandler(response, this._notificationService));
|
||||
|
||||
}
|
||||
|
||||
chatMessagePageLoadAjax() {
|
||||
private _chatMessagePageLoadAjax() {
|
||||
this._messageContainer.addEventListener('scroll', (e) => {
|
||||
if ($(this._messageContainer).scrollTop() == 0) {
|
||||
if ($(this._messageContainer).scrollTop() == 0 && $(this._messageContainer).html() != "") {
|
||||
let currentMsg = $('.msg:first');
|
||||
log.debug('Reached top')
|
||||
// @ts-ignore
|
||||
let passphrase: string;
|
||||
let passphraseInput = document.getElementById('passphrase') as HTMLInputElement;
|
||||
|
||||
@ -189,9 +214,11 @@ export class ChatView implements Observer {
|
||||
return;
|
||||
}
|
||||
if (JsonAPI.contactName != null)
|
||||
this._chatModel.getMessages(JsonAPI.contactName, passphrase, null).then(() => {
|
||||
log.debug(currentMsg.offset()!.top)
|
||||
$(this._messageContainer).scrollTop(currentMsg.position()!.top - $('.msg').position()!.top)
|
||||
this._chatModel.getMessages(JsonAPI.contactName, passphrase, null, "page").then(() => {
|
||||
if (currentMsg != null) {
|
||||
// log.debug(currentMsg.offset()!.top)
|
||||
$(this._messageContainer).scrollTop(currentMsg.position().top - $('.msg').position()!.top)
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
||||
import { ChatModel } from "../model/ChatModel";
|
||||
import { MarkDownService } from "../service/MarkDownService";
|
||||
import { EncryptionService } from "../service/EncryptionService";
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
|
||||
export interface ChatViewDeps {
|
||||
chatModel: ChatModel;
|
||||
@ -10,5 +11,5 @@ export interface ChatViewDeps {
|
||||
messageReceiveTemplate: Handlebars.TemplateDelegate<ChatMessageViewModel>;
|
||||
markdownService: MarkDownService;
|
||||
encryptionService: EncryptionService;
|
||||
|
||||
notificationService: NotificationService
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
import { NotificationService } from "../service/NotificationService";
|
||||
import { AlertifyNotificationService } from "../service/AlertifyNotificationService";
|
||||
import { Sprintf } from "../singleton/Sprintf";
|
||||
|
||||
export function fetchHandler(response: any) {
|
||||
const ns: NotificationService = new AlertifyNotificationService();
|
||||
export function fetchHandler(response: Response, ns: NotificationService) {
|
||||
if (response.ok) {
|
||||
return response.json().then((json: any) => {
|
||||
// the status was ok and there is a json body
|
||||
|
@ -6,8 +6,10 @@ 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";
|
||||
|
||||
export class UserView implements Observer {
|
||||
export class UserView implements Observer<ActiveUserViewModel> {
|
||||
|
||||
|
||||
private readonly _model: UserModel;
|
||||
@ -31,35 +33,35 @@ export class UserView implements Observer {
|
||||
this._userContactOnlineTemplate = deps.userContactOnlineTemplate;
|
||||
this._userContactOfflineTemplate = deps.userContactOfflineTemplate;
|
||||
|
||||
this.addSearchEventListeners();
|
||||
this._addSearchEventListeners();
|
||||
}
|
||||
|
||||
update(data: ActiveUserViewModel[]): void {
|
||||
update(d: ObserverData<ActiveUserViewModel>): void {
|
||||
let html: string = "";
|
||||
data.forEach((element: ActiveUserViewModel) => {
|
||||
d.data.forEach((element: ActiveUserViewModel) => {
|
||||
element.online ? html += this._userContactOnlineTemplate(element) : html += this._userContactOfflineTemplate(element);
|
||||
});
|
||||
$(this._usersListElement).html(DOMPurify.sanitize(html));
|
||||
this.addUserCallBacks();
|
||||
console.log(this._usersListElement.innerHTML);
|
||||
this._addUserCallBacks();
|
||||
}
|
||||
|
||||
private addSearchEventListeners(): void {
|
||||
this.addSearchButtonEL();
|
||||
this.addSearchCancelEL();
|
||||
this.addSearchInputEL();
|
||||
private _addSearchEventListeners(): void {
|
||||
this._addSearchButtonEL();
|
||||
this._addSearchCancelEL();
|
||||
this._addSearchInputEL();
|
||||
}
|
||||
|
||||
private addUserCallBacks(): void {
|
||||
private _addUserCallBacks(): void {
|
||||
let userBoxes = document.getElementsByClassName('user-box');
|
||||
for (let i = 0; i < userBoxes.length; i++) {
|
||||
let userBox = userBoxes[i];
|
||||
userBoxes[i].addEventListener('click', this.userCallBack.bind(this, userBox));
|
||||
userBoxes[i].addEventListener('click', this._userCallBack.bind(this, userBox));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private userCallBack(el: Element): void {
|
||||
private _userCallBack(el: Element): void {
|
||||
this._chatModel.clear();
|
||||
let current = document.getElementsByClassName('user-box active');
|
||||
|
||||
let passphrase: string = '';
|
||||
@ -104,13 +106,14 @@ export class UserView implements Observer {
|
||||
// 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;
|
||||
this._chatModel.getMessages(userName, passphrase, null);
|
||||
this._chatModel.getMessages(userName, passphrase, null, "new");
|
||||
el.className += " active";
|
||||
}
|
||||
|
||||
private addSearchButtonEL() {
|
||||
private _addSearchButtonEL() {
|
||||
this._userSearchButton.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
// log.trace(temp);
|
||||
@ -124,12 +127,12 @@ export class UserView implements Observer {
|
||||
return;
|
||||
}
|
||||
let searchResult = this._searchService.search(list, searchTerm);
|
||||
this.update(searchResult);
|
||||
this.update({data: searchResult, op: ""});
|
||||
log.debug(searchResult);
|
||||
})
|
||||
}
|
||||
|
||||
private addSearchInputEL() {
|
||||
private _addSearchInputEL() {
|
||||
this._userSearchInputElement.addEventListener('input', (e) => {
|
||||
e.preventDefault();
|
||||
if (this._userSearchInputElement.value.length < 2) {
|
||||
@ -139,14 +142,13 @@ export class UserView implements Observer {
|
||||
})
|
||||
}
|
||||
|
||||
private addSearchCancelEL() {
|
||||
private _addSearchCancelEL() {
|
||||
this._userSearchCancelButton.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this._userSearchInputElement.value = "";
|
||||
this._userSearchCancelButton.hidden = true;
|
||||
let list = this._model.activeUsersList;
|
||||
// @ts-ignore
|
||||
this.update(list)
|
||||
this.update({data: list, op: ""})
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user