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.
198 lines
7.6 KiB
198 lines
7.6 KiB
import * as DOMPurify from 'dompurify';
|
|
import * as log from 'loglevel';
|
|
import { ChatMessageDTO } from "../dto/ChatMessageDTO";
|
|
import { MessageCipherDTO } from "../dto/MessageCipherDTO";
|
|
import { ChatModel } from "../model/ChatModel";
|
|
import { Observer } from "../observe/Observer";
|
|
import { EncryptionService } from "../service/EncryptionService";
|
|
import { MarkDownService } from "../service/MarkDownService";
|
|
import { JsonAPI } from "../singleton/JsonAPI";
|
|
import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel";
|
|
import { ChatViewDeps } from "./ChatViewDeps";
|
|
import { fetchHandler } from "./FetchHandler";
|
|
|
|
export class ChatView implements Observer {
|
|
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;
|
|
|
|
|
|
constructor(deps: ChatViewDeps) {
|
|
this._messageContainer = deps.messageContainer;
|
|
this._chatModel = deps.chatModel;
|
|
this._messageSendTemplate = deps.messageSendTemplate;
|
|
this._messageReceiveTemplate = deps.messageReceiveTemplate;
|
|
this._markdownService = deps.markdownService;
|
|
this._encryptionService = deps.encryptionService;
|
|
this.addEventListeners();
|
|
|
|
$(document).ready(function () {
|
|
$('#action_menu_btn').click(function () {
|
|
$('.action_menu').toggle();
|
|
});
|
|
});
|
|
|
|
this.chatMessagePageLoadAjax();
|
|
}
|
|
|
|
update(data: 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));
|
|
|
|
}
|
|
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 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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private createChatMessageDTO(e: Event, chatForm: HTMLSelectElement): void {
|
|
e.preventDefault();
|
|
|
|
let contactName = JsonAPI.contactName;
|
|
|
|
if (contactName == null) {
|
|
log.error("Contact name is null");
|
|
return;
|
|
}
|
|
|
|
if (!chatForm.checkValidity()) {
|
|
console.log("error");
|
|
chatForm.classList.add('was-validated');
|
|
return;
|
|
}
|
|
chatForm.classList.add('was-validated');
|
|
|
|
|
|
const chatInput = document.getElementById('chatInput') as HTMLInputElement;
|
|
const passphraseInput = document.getElementById('passphrase') as HTMLInputElement;
|
|
|
|
if (chatInput.value == '' || chatInput.value == null) {
|
|
log.error("Chat input is null.");
|
|
return;
|
|
}
|
|
|
|
if (passphraseInput.value == '' || passphraseInput.value == null) {
|
|
log.error("Chat input is null.");
|
|
return;
|
|
}
|
|
|
|
// @ts-ignore
|
|
const messageContent = chatInput.value;
|
|
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));
|
|
// scrollChatAreaAnimated(2400);
|
|
// let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
|
let messageCipher: MessageCipherDTO = this._encryptionService.encrypt(passphraseInput.value, messageContent)
|
|
// let messageCipherJson = JSON.parse(messageCipher);
|
|
let chatMessageDTO = {
|
|
"fromUser": JsonAPI.principleName,
|
|
"toUser": contactName,
|
|
"messageCipher": messageCipher,
|
|
// "messageTime": null
|
|
}
|
|
// @ts-ignore
|
|
this.sendMessageAJAX(chatMessageDTO);
|
|
}
|
|
|
|
private sendMessageAJAX(chatMessageDTO: ChatMessageDTO): void {
|
|
let headers = new Headers();
|
|
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
|
|
|
|
// headers.append('Accept','application/json')
|
|
headers.append('Content-Type', 'application/json');
|
|
// headers.append('Authorization', basicAuthToken);
|
|
// @ts-ignore
|
|
headers.append('X-AUTH-TOKEN', JsonAPI.authToken);
|
|
fetch(JsonAPI.MESSAGE_POST, {
|
|
method: 'POST',
|
|
headers: headers,
|
|
})
|
|
.then(response => {
|
|
log.debug(response);
|
|
return response.clone();
|
|
})
|
|
.then(response => fetchHandler(response));
|
|
|
|
}
|
|
|
|
chatMessagePageLoadAjax() {
|
|
this._messageContainer.addEventListener('scroll', (e) => {
|
|
if ($(this._messageContainer).scrollTop() == 0) {
|
|
let currentMsg = $('.msg:first');
|
|
log.debug('Reached top')
|
|
// @ts-ignore
|
|
let passphrase: string;
|
|
let passphraseInput = document.getElementById('passphrase') as HTMLInputElement;
|
|
|
|
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;
|
|
}
|
|
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)
|
|
});
|
|
}
|
|
})
|
|
}
|
|
}
|