distributionList.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * This file is part of Threema Web.
  3. *
  4. * Threema Web is free software: you can redistribute it and/or modify it
  5. * under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or (at
  7. * your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. import {Logger} from 'ts-log';
  18. import {LogService} from '../services/log';
  19. import {WebClientService} from '../services/webclient';
  20. // Type aliases
  21. import ControllerModelMode = threema.ControllerModelMode;
  22. export class DistributionListControllerModel implements threema.ControllerModel<threema.DistributionListReceiver> {
  23. private $translate: ng.translate.ITranslateService;
  24. private $mdDialog: ng.material.IDialogService;
  25. private readonly log: Logger;
  26. public members: string[];
  27. public name: string;
  28. public subject: string;
  29. public isLoading = false;
  30. private addContactPlaceholder: string;
  31. private distributionList: threema.DistributionListReceiver | null;
  32. private webClientService: WebClientService;
  33. private mode: ControllerModelMode;
  34. private onRemovedCallback: threema.OnRemovedCallback;
  35. constructor($translate: ng.translate.ITranslateService, $mdDialog: ng.material.IDialogService,
  36. logService: LogService, webClientService: WebClientService,
  37. mode: ControllerModelMode,
  38. distributionList?: threema.DistributionListReceiver) {
  39. this.$translate = $translate;
  40. this.$mdDialog = $mdDialog;
  41. this.log = logService.getLogger('DistributionList-CM');
  42. if (distributionList === undefined) {
  43. if (mode !== ControllerModelMode.NEW) {
  44. throw new Error('DistributionListControllerModel: Distribution list ' +
  45. 'may not be undefined for mode ' + mode);
  46. }
  47. } else {
  48. this.distributionList = distributionList;
  49. }
  50. this.mode = mode;
  51. this.webClientService = webClientService;
  52. this.addContactPlaceholder = $translate.instant('messenger.DISTRIBUTION_LIST_SELECT_MEMBERS');
  53. switch (this.getMode()) {
  54. case ControllerModelMode.EDIT:
  55. this.subject = $translate.instant('messenger.EDIT_RECEIVER');
  56. this.name = this.distributionList!.displayName;
  57. this.members = this.distributionList!.members;
  58. break;
  59. case ControllerModelMode.VIEW:
  60. case ControllerModelMode.CHAT:
  61. this.subject = this.distributionList!.displayName;
  62. this.members = this.distributionList!.members;
  63. break;
  64. case ControllerModelMode.NEW:
  65. this.subject = $translate.instant('messenger.CREATE_DISTRIBUTION_LIST');
  66. this.members = [];
  67. break;
  68. default:
  69. this.log.error('Invalid controller model mode: ', this.getMode());
  70. }
  71. }
  72. public setOnRemoved(callback: threema.OnRemovedCallback): void {
  73. this.onRemovedCallback = callback;
  74. }
  75. public getMode(): ControllerModelMode {
  76. return this.mode;
  77. }
  78. public isValid(): boolean {
  79. return this.members.filter((identity: string) => {
  80. return identity !== this.webClientService.me.id;
  81. }).length > 0;
  82. }
  83. public canChat(): boolean {
  84. return true;
  85. }
  86. public canEdit(): boolean {
  87. // a distribution list can always be edited
  88. return true;
  89. }
  90. public canClean(): boolean {
  91. return true;
  92. }
  93. public clean(ev: any): any {
  94. const confirm = this.$mdDialog.confirm()
  95. .title(this.$translate.instant('messenger.DELETE_THREAD'))
  96. .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', {count: 1}))
  97. .targetEvent(ev)
  98. .ok(this.$translate.instant('common.YES'))
  99. .cancel(this.$translate.instant('common.CANCEL'));
  100. this.$mdDialog.show(confirm).then(() => {
  101. this.reallyClean();
  102. }, () => {
  103. this.log.debug('Clean cancelled');
  104. });
  105. }
  106. private reallyClean(): any {
  107. if (!this.distributionList) {
  108. this.log.error('reallyClean: Distribution list is null');
  109. return;
  110. }
  111. if (!this.canClean()) {
  112. this.log.error('Not allowed to clean this distribution list');
  113. return;
  114. }
  115. this.isLoading = true;
  116. this.webClientService.cleanReceiverConversation(this.distributionList)
  117. .then(() => {
  118. this.isLoading = false;
  119. })
  120. .catch((error) => {
  121. // TODO: Handle this properly / show an error message
  122. this.log.error(`Cleaning receiver conversation failed: ${error}`);
  123. this.isLoading = false;
  124. });
  125. }
  126. public canShowQr(): boolean {
  127. return false;
  128. }
  129. public delete(ev): void {
  130. const confirm = this.$mdDialog.confirm()
  131. .title(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE'))
  132. .textContent(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE_REALLY'))
  133. .targetEvent(ev)
  134. .ok(this.$translate.instant('common.OK'))
  135. .cancel(this.$translate.instant('common.CANCEL'));
  136. this.$mdDialog.show(confirm).then(() => {
  137. this.reallyDelete();
  138. }, () => {
  139. this.log.debug('Delete cancelled');
  140. });
  141. }
  142. private reallyDelete(): void {
  143. if (!this.distributionList) {
  144. this.log.error('reallyDelete: Distribution list is null');
  145. return;
  146. }
  147. if (!this.distributionList.access.canDelete) {
  148. this.log.error('Not allowed to delete this distribution list');
  149. return;
  150. }
  151. this.isLoading = true;
  152. this.webClientService.deleteDistributionList(this.distributionList).then(() => {
  153. this.isLoading = false;
  154. if (this.onRemovedCallback && this.distributionList !== null) {
  155. this.onRemovedCallback(this.distributionList.id);
  156. }
  157. }).catch((error) => {
  158. // TODO: Handle this properly / show an error message
  159. this.log.error(`Deleting distribution list failed: ${error}`);
  160. this.isLoading = false;
  161. });
  162. }
  163. public save(): Promise<threema.DistributionListReceiver> {
  164. switch (this.getMode()) {
  165. case ControllerModelMode.EDIT:
  166. return this.webClientService.modifyDistributionList(
  167. this.distributionList!.id,
  168. this.members,
  169. this.name,
  170. );
  171. case ControllerModelMode.NEW:
  172. return this.webClientService.createDistributionList(
  173. this.members,
  174. this.name);
  175. default:
  176. this.log.error('Cannot save distribution list, invalid mode');
  177. return Promise.reject('Cannot save distribution list, invalid mode');
  178. }
  179. }
  180. public onChangeMembers(identities: string[]): void {
  181. this.members = identities;
  182. }
  183. public getMembers(): string[] {
  184. return this.members;
  185. }
  186. }