A self hosted chat application with end-to-end encrypted messaging.
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.

154 lines
6.2 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import { Observer } from "../observe/Observer";
  2. import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
  3. import { ChatModel } from "../model/ChatModel";
  4. import log = require("loglevel");
  5. import * as DOMPurify from "dompurify";
  6. import { SearchService } from "../service/SearchService";
  7. import { UserModel } from "../model/UserModel";
  8. import { UserViewDeps } from "./UserViewDeps";
  9. export class UserView implements Observer {
  10. private readonly _model: UserModel;
  11. private readonly _chatModel: ChatModel;
  12. private readonly _usersListElement: HTMLElement;
  13. private readonly _userSearchInputElement: HTMLInputElement;
  14. private readonly _userSearchButton: HTMLElement;
  15. private readonly _userSearchCancelButton: HTMLElement;
  16. private readonly _searchService: SearchService<ActiveUserViewModel>;
  17. private readonly _userContactOnlineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
  18. private readonly _userContactOfflineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
  19. constructor(deps: UserViewDeps) {
  20. this._model = deps.model;
  21. this._chatModel = deps.chatModel;
  22. this._usersListElement = deps.usersListElement;
  23. this._userSearchInputElement = deps.userSearchInputElement;
  24. this._userSearchButton = deps.userSearchButton;
  25. this._userSearchCancelButton = deps.userSearchCancelButton;
  26. this._searchService = deps.searchService;
  27. this._userContactOnlineTemplate = deps.userContactOnlineTemplate;
  28. this._userContactOfflineTemplate = deps.userContactOfflineTemplate;
  29. this.addSearchEventListeners();
  30. }
  31. update(data: ActiveUserViewModel[]): void {
  32. let html: string = "";
  33. data.forEach((element: ActiveUserViewModel) => {
  34. element.online ? html += this._userContactOnlineTemplate(element) : html += this._userContactOfflineTemplate(element);
  35. });
  36. $(this._usersListElement).html(DOMPurify.sanitize(html));
  37. this.addUserCallBacks();
  38. console.log(this._usersListElement.innerHTML);
  39. }
  40. private addSearchEventListeners(): void {
  41. this.addSearchButtonEL();
  42. this.addSearchCancelEL();
  43. this.addSearchInputEL();
  44. }
  45. private addUserCallBacks(): void {
  46. let userBoxes = document.getElementsByClassName('user-box');
  47. for (let i = 0; i < userBoxes.length; i++) {
  48. let userBox = userBoxes[i];
  49. userBoxes[i].addEventListener('click', this.userCallBack.bind(this, userBox));
  50. }
  51. }
  52. private userCallBack(el: Element): void {
  53. let current = document.getElementsByClassName('user-box active');
  54. let passphrase: string = '';
  55. if (current.length > 0) {
  56. let passphraseInput = document.getElementById('passphrase') as any;
  57. if (passphraseInput == null) {
  58. log.error('passphraseInput element reference is null');
  59. return;
  60. }
  61. passphrase = passphraseInput.value
  62. if (passphrase == '' || passphrase == null) {
  63. // alert('Please input passphrase')
  64. // alertify.error('Please enter a passphrase');
  65. log.error('passphrase is empty or null');
  66. return;
  67. }
  68. current[0].className = current[0].className.replace(" active", "");
  69. }
  70. // Add the active class to the current/clicked button
  71. else if (current.length == 0) {
  72. let elem = document.getElementById('passphrase-initial') as any;
  73. if (elem == null) {
  74. log.error('passphraseInput element reference is null');
  75. return;
  76. }
  77. passphrase = elem.value;
  78. if (passphrase == '' || passphrase == null) {
  79. // // alert('Please input passphrase')
  80. // // alertify.error('Please enter a passphrase');
  81. log.error('passphrase is empty or null');
  82. return;
  83. }
  84. // @ts-ignore: Object is possibly 'null'.
  85. document.getElementById('no-user-selected').hidden = true;
  86. // @ts-ignore: Object is possibly 'null'.
  87. document.getElementById('chat-card').hidden = false;
  88. // @ts-ignore: Object is possibly 'null'.
  89. elem.hidden = true;
  90. }
  91. // console.log(this.getElementsByClassName('to-user-span'));
  92. let elem = el.getElementsByClassName('to-user-span')[0] as HTMLElement;
  93. let userName = elem.innerText;
  94. // @ts-ignore: Object is possibly 'null'.
  95. document.getElementById('user-name-span').innerText = userName;
  96. this._chatModel.getmessages(userName, passphrase, null);
  97. // populateMessages(userName, passphrase);
  98. sessionStorage.setItem('selectedUser', userName);
  99. el.className += " active";
  100. }
  101. private addSearchButtonEL() {
  102. this._userSearchButton.addEventListener('submit', (e) => {
  103. e.preventDefault();
  104. // log.trace(temp);
  105. const searchTerm = this._userSearchInputElement.value;
  106. log.debug("search term value = " + searchTerm);
  107. const list = this._model.activeUsersList;
  108. log.debug("active users");
  109. log.debug(list);
  110. if (list == null) {
  111. log.error("Users list is null");
  112. return;
  113. }
  114. let searchResult = this._searchService.search(list, searchTerm);
  115. this.update(searchResult);
  116. log.debug(searchResult);
  117. })
  118. }
  119. private addSearchInputEL() {
  120. this._userSearchInputElement.addEventListener('input', (e) => {
  121. e.preventDefault();
  122. if (this._userSearchInputElement.value.length < 2) {
  123. log.debug("inputted")
  124. this._userSearchCancelButton.hidden = false;
  125. }
  126. })
  127. }
  128. private addSearchCancelEL() {
  129. this._userSearchCancelButton.addEventListener('click', (e) => {
  130. e.preventDefault();
  131. this._userSearchInputElement.value = "";
  132. this._userSearchCancelButton.hidden = true;
  133. let list = this._model.activeUsersList;
  134. // @ts-ignore
  135. this.update(list)
  136. })
  137. }
  138. }