From 12bf46e09ecd107ffe0f3bd88382b731727efd14 Mon Sep 17 00:00:00 2001
From: Audric Ackermann <audric@loki.network>
Date: Tue, 27 Oct 2020 12:56:32 +1100
Subject: [PATCH] use pushToast through ToastUtils when it's a static toast
 content

---
 js/background.js                              |  29 +--
 js/models/conversations.js                    |   6 +-
 js/models/messages.js                         |  24 +--
 js/views/conversation_view.js                 | 204 ------------------
 js/views/inbox_view.js                        |   6 -
 js/views/session_registration_view.js         |   8 -
 js/views/toast_view.js                        |   9 -
 ts/components/EditProfileDialog.tsx           |   7 +-
 ts/components/session/SessionSeedModal.tsx    |   6 +-
 .../conversation/SessionCompositionBox.tsx    |   7 +-
 .../conversation/SessionConversation.tsx      |  23 +-
 ts/session/utils/Toast.ts                     |  65 ++++++
 12 files changed, 88 insertions(+), 306 deletions(-)

diff --git a/js/background.js b/js/background.js
index 8c4d7b9a3..2a2aee303 100644
--- a/js/background.js
+++ b/js/background.js
@@ -203,11 +203,7 @@
     setTimeout(() => {
       localStorage.removeItem('restart-reason');
 
-      window.pushToast({
-        title: window.i18n('successUnlinked'),
-        type: 'info',
-        id: '123',
-      });
+      window.libsession.Utils.ToastUtils.pushForceUnlinked();
     }, 2000);
   }
 
@@ -841,11 +837,7 @@
       // if not undefined, we take the opposite
       const newValue = currentValue !== undefined ? !currentValue : false;
       window.Events.setSpellCheck(newValue);
-      window.pushToast({
-        description: window.i18n('spellCheckDirty'),
-        type: 'info',
-        id: 'spellCheckDirty',
-      });
+      window.libsession.Utils.ToastUtils.pushSpellCheckDirty();
     };
 
     window.toggleLinkPreview = () => {
@@ -979,11 +971,8 @@
         const conversationExists = ConversationController.get(conversationId);
         if (conversationExists) {
           window.log.warn('We are already a member of this public chat');
-          window.pushToast({
-            description: window.i18n('publicChatExists'),
-            type: 'info',
-            id: 'alreadyMemberPublicChat',
-          });
+          window.libsession.Utils.ToastUtils.pushAlreadyMemberOpenGroup();
+
           return;
         }
 
@@ -1066,16 +1055,6 @@
       }
     });
 
-    Whisper.events.on('showToast', options => {
-      if (
-        appView &&
-        appView.inboxView &&
-        appView.inboxView.conversation_stack
-      ) {
-        appView.inboxView.conversation_stack.showToast(options);
-      }
-    });
-
     Whisper.events.on('showConfirmationDialog', options => {
       if (
         appView &&
diff --git a/js/models/conversations.js b/js/models/conversations.js
index bdfccacd6..cdabcef52 100644
--- a/js/models/conversations.js
+++ b/js/models/conversations.js
@@ -2280,11 +2280,7 @@
     copyPublicKey() {
       clipboard.writeText(this.id);
 
-      window.pushToast({
-        title: i18n('copiedToClipboard'),
-        type: 'success',
-        id: 'copiedToClipboard',
-      });
+      window.libsession.Utils.ToastUtils.pushCopiedToClipBoard();
     },
 
     changeNickname() {
diff --git a/js/models/messages.js b/js/models/messages.js
index 3e04e9a32..bfc009ae1 100644
--- a/js/models/messages.js
+++ b/js/models/messages.js
@@ -904,11 +904,7 @@
         clipboard.writeText(this.OUR_NUMBER);
       }
 
-      window.pushToast({
-        title: i18n('copiedToClipboard'),
-        type: 'success',
-        id: 'copiedToClipboard',
-      });
+      window.libsession.Utils.ToastUtils.pushCopiedToClipBoard();
     },
 
     banUser() {
@@ -923,17 +919,9 @@
           const success = await channelAPI.banUser(source);
 
           if (success) {
-            window.pushToast({
-              title: i18n('userBanned'),
-              type: 'success',
-              id: 'userBanned',
-            });
+            window.libsession.Utils.ToastUtils.pushUserBanSuccess();
           } else {
-            window.pushToast({
-              title: i18n('userBanFailed'),
-              type: 'error',
-              id: 'userBanFailed',
-            });
+            window.libsession.Utils.ToastUtils.pushUserBanFailure();
           }
         },
       });
@@ -957,11 +945,7 @@
     copyText() {
       clipboard.writeText(this.get('body'));
 
-      window.pushToast({
-        title: i18n('copiedToClipboard'),
-        type: 'success',
-        id: 'copiedToClipboard',
-      });
+      window.libsession.Utils.ToastUtils.pushCopiedToClipBoard();
     },
 
     /**
diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js
index e5315cc23..aabeaaeb7 100644
--- a/js/views/conversation_view.js
+++ b/js/views/conversation_view.js
@@ -1231,210 +1231,6 @@
       });
     },
 
-    deleteSelectedMessages() {
-      const ourPubkey = textsecure.storage.user.getNumber();
-      const selected = Array.from(this.model.selectedMessages);
-      const isModerator = this.model.isModerator(ourPubkey);
-      const isAllOurs = selected.every(
-        message =>
-          message.propsForMessage.authorPhoneNumber === message.OUR_NUMBER
-      );
-
-      if (!isAllOurs && !isModerator) {
-        window.pushToast({
-          title: i18n('messageDeletionForbidden'),
-          type: 'error',
-          id: 'messageDeletionForbidden',
-        });
-
-        return;
-      }
-
-      this.deleteMessages(selected, () => {
-        this.resetMessageSelection();
-      });
-    },
-
-    deleteMessages(messages, onSuccess) {
-      const multiple = messages.length > 1;
-      const isPublic = this.model.isPublic();
-
-      // In future, we may be able to unsend private messages also
-      // isServerDeletable also defined in ConversationHeader.tsx for
-      // future reference
-      const isServerDeletable = isPublic;
-
-      const warningMessage = (() => {
-        if (isPublic) {
-          return multiple
-            ? i18n('deleteMultiplePublicWarning')
-            : i18n('deletePublicWarning');
-        }
-        return multiple ? i18n('deleteMultipleWarning') : i18n('deleteWarning');
-      })();
-
-      const doDelete = async () => {
-        let toDeleteLocally;
-
-        if (isPublic) {
-          toDeleteLocally = await this.model.deletePublicMessages(messages);
-          if (toDeleteLocally.length === 0) {
-            // Message failed to delete from server, show error?
-            return;
-          }
-        } else {
-          messages.forEach(m => this.model.messageCollection.remove(m.id));
-          toDeleteLocally = messages;
-        }
-
-        await Promise.all(
-          toDeleteLocally.map(async m => {
-            await window.Signal.Data.removeMessage(m.id, {
-              Message: Whisper.Message,
-            });
-            m.trigger('unload');
-          })
-        );
-
-        this.resetPanel();
-        this.updateHeader();
-
-        if (onSuccess) {
-          onSuccess();
-        }
-      };
-
-      // Only show a warning when at least one messages was successfully
-      // saved in on the server
-      if (!messages.some(m => !m.hasErrors())) {
-        doDelete();
-        return;
-      }
-
-      // If removable from server, we "Unsend" - otherwise "Delete"
-      let title;
-      if (isPublic) {
-        title = multiple
-          ? i18n('deleteMessagesForEveryone')
-          : i18n('deleteMessageForEveryone');
-      } else {
-        title = multiple ? i18n('deleteMessages') : i18n('deleteMessage');
-      }
-
-      const okText = isServerDeletable
-        ? i18n('deleteForEveryone')
-        : i18n('delete');
-
-      window.confirmationDialog({
-        title,
-        message: warningMessage,
-        okText,
-        okTheme: 'danger',
-        resolve: doDelete,
-      });
-    },
-
-    deleteMessage(message) {
-      this.deleteMessages([message]);
-    },
-
-    showChannelLightbox({ media, attachment, message }) {
-      const selectedIndex = media.findIndex(
-        mediaMessage => mediaMessage.attachment.path === attachment.path
-      );
-      this.lightboxGalleryView = new Whisper.ReactWrapperView({
-        className: 'lightbox-wrapper',
-        Component: Signal.Components.LightboxGallery,
-        props: {
-          media,
-          onSave: () => this.downloadAttachment({ attachment, message }),
-          selectedIndex,
-        },
-        onClose: () => Signal.Backbone.Views.Lightbox.hide(),
-      });
-      Signal.Backbone.Views.Lightbox.show(this.lightboxGalleryView.el);
-    },
-
-    showLightbox({ attachment, message }) {
-      const { contentType, path } = attachment;
-
-      if (
-        !Signal.Util.GoogleChrome.isImageTypeSupported(contentType) &&
-        !Signal.Util.GoogleChrome.isVideoTypeSupported(contentType)
-      ) {
-        this.downloadAttachment({ attachment, message });
-        return;
-      }
-
-      const attachments = message.get('attachments') || [];
-
-      const media = attachments
-        .filter(item => item.thumbnail && !item.pending && !item.error)
-        .map((item, index) => ({
-          objectURL: getAbsoluteAttachmentPath(item.path),
-          path: item.path,
-          contentType: item.contentType,
-          index,
-          message,
-          attachment: item,
-        }));
-
-      if (media.length === 1) {
-        const props = {
-          objectURL: getAbsoluteAttachmentPath(path),
-          contentType,
-          caption: attachment.caption,
-          onSave: () => this.downloadAttachment({ attachment, message }),
-        };
-        this.lightboxView = new Whisper.ReactWrapperView({
-          className: 'lightbox-wrapper',
-          Component: Signal.Components.Lightbox,
-          props,
-          onClose: () => {
-            Signal.Backbone.Views.Lightbox.hide();
-            this.stopListening(message);
-          },
-        });
-        this.listenTo(message, 'expired', () => this.lightboxView.remove());
-        Signal.Backbone.Views.Lightbox.show(this.lightboxView.el);
-        return;
-      }
-
-      const selectedIndex = _.findIndex(
-        media,
-        item => attachment.path === item.path
-      );
-
-      const onSave = async (options = {}) => {
-        Signal.Types.Attachment.save({
-          attachment: options.attachment,
-          document,
-          index: options.index + 1,
-          getAbsolutePath: getAbsoluteAttachmentPath,
-          timestamp: options.message.get('sent_at'),
-        });
-      };
-
-      const props = {
-        media,
-        selectedIndex: selectedIndex >= 0 ? selectedIndex : 0,
-        onSave,
-      };
-      this.lightboxGalleryView = new Whisper.ReactWrapperView({
-        className: 'lightbox-wrapper',
-        Component: Signal.Components.LightboxGallery,
-        props,
-        onClose: () => {
-          Signal.Backbone.Views.Lightbox.hide();
-          this.stopListening(message);
-        },
-      });
-      this.listenTo(message, 'expired', () =>
-        this.lightboxGalleryView.remove()
-      );
-      Signal.Backbone.Views.Lightbox.show(this.lightboxGalleryView.el);
-    },
-
     async showMessageDetail(message) {
       const onClose = () => {
         this.stopListening(message, 'change', update);
diff --git a/js/views/inbox_view.js b/js/views/inbox_view.js
index 83beb99dc..7c503fd24 100644
--- a/js/views/inbox_view.js
+++ b/js/views/inbox_view.js
@@ -39,12 +39,6 @@
         $el.remove();
       }
     },
-    showToast({ message }) {
-      window.pushToast({
-        title: message,
-        type: 'success',
-      });
-    },
     showConfirmationDialog({
       title,
       message,
diff --git a/js/views/session_registration_view.js b/js/views/session_registration_view.js
index b1ec89621..8fa51f5da 100644
--- a/js/views/session_registration_view.js
+++ b/js/views/session_registration_view.js
@@ -38,14 +38,6 @@
         .addClass('in')
         .fadeIn();
     },
-
-    showToast(message) {
-      const toast = new Whisper.MessageToastView({
-        message,
-      });
-      toast.$el.appendTo(this.$el);
-      toast.render();
-    },
   });
 
   class TextScramble {
diff --git a/js/views/toast_view.js b/js/views/toast_view.js
index 9d4d0b6ea..ae90feb25 100644
--- a/js/views/toast_view.js
+++ b/js/views/toast_view.js
@@ -28,13 +28,4 @@
       setTimeout(this.close.bind(this), 2000);
     },
   });
-
-  Whisper.MessageToastView = Whisper.ToastView.extend({
-    initialize(options) {
-      this.message = options.message || '-';
-    },
-    render_attributes() {
-      return { toastMessage: this.message };
-    },
-  });
 })();
diff --git a/ts/components/EditProfileDialog.tsx b/ts/components/EditProfileDialog.tsx
index 065490bcb..afeee4b0b 100644
--- a/ts/components/EditProfileDialog.tsx
+++ b/ts/components/EditProfileDialog.tsx
@@ -295,12 +295,7 @@ export class EditProfileDialog extends React.Component<Props, State> {
 
   private copySessionID(sessionID: string) {
     window.clipboard.writeText(sessionID);
-
-    ToastUtils.push({
-      title: window.i18n('copiedToClipboard'),
-      type: 'success',
-      id: 'copiedToClipboard',
-    });
+    ToastUtils.pushCopiedToClipBoard();
   }
 
   private onClickOK() {
diff --git a/ts/components/session/SessionSeedModal.tsx b/ts/components/session/SessionSeedModal.tsx
index 094a32258..2280273ed 100644
--- a/ts/components/session/SessionSeedModal.tsx
+++ b/ts/components/session/SessionSeedModal.tsx
@@ -210,11 +210,7 @@ export class SessionSeedModal extends React.Component<Props, State> {
   private copyRecoveryPhrase(recoveryPhrase: string) {
     window.clipboard.writeText(recoveryPhrase);
 
-    ToastUtils.push({
-      title: window.i18n('copiedToClipboard'),
-      type: 'success',
-      id: 'copyRecoveryPhraseToast',
-    });
+    ToastUtils.pushCopiedToClipBoard();
   }
 
   private onEnter(event: any) {
diff --git a/ts/components/session/conversation/SessionCompositionBox.tsx b/ts/components/session/conversation/SessionCompositionBox.tsx
index e8c226ab3..f8fc0351e 100644
--- a/ts/components/session/conversation/SessionCompositionBox.tsx
+++ b/ts/components/session/conversation/SessionCompositionBox.tsx
@@ -423,12 +423,7 @@ export class SessionCompositionBox extends React.Component<Props, State> {
       return;
     }
 
-    window.pushToast({
-      id: 'audioPermissionNeeded',
-      title: window.i18n('audioPermissionNeededTitle'),
-      description: window.i18n('audioPermissionNeeded'),
-      type: 'info',
-    });
+    ToastUtils.pushAudioPermissionNeeded();
   }
 
   private onExitVoiceNoteView() {
diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx
index 6cf5467e0..f72c021b1 100644
--- a/ts/components/session/conversation/SessionConversation.tsx
+++ b/ts/components/session/conversation/SessionConversation.tsx
@@ -656,10 +656,11 @@ export class SessionConversation extends React.Component<Props, State> {
     const conversationModel = window.ConversationController.getOrThrow(
       conversationKey
     );
-    const selectedMessages = conversationModel.messageCollection.models.filter(message =>
-      this.state.selectedMessages.find(
-        selectedMessage => selectedMessage === message.id
-      )
+    const selectedMessages = conversationModel.messageCollection.models.filter(
+      message =>
+        this.state.selectedMessages.find(
+          selectedMessage => selectedMessage === message.id
+        )
     );
 
     const multiple = selectedMessages.length > 1;
@@ -697,17 +698,15 @@ export class SessionConversation extends React.Component<Props, State> {
           await MultiDeviceProtocol.getPrimaryDevice(ourDevicePubkey)
         ).key;
         const isModerator = conversationModel.isModerator(ourPrimaryPubkey);
-        const ourNumbers = (await MultiDeviceProtocol.getOurDevices()).map(m => m.key);
-        const isAllOurs = selectedMessages.every(
-          message => ourNumbers.includes(message.get('source'))
+        const ourNumbers = (await MultiDeviceProtocol.getOurDevices()).map(
+          m => m.key
+        );
+        const isAllOurs = selectedMessages.every(message =>
+          ourNumbers.includes(message.get('source'))
         );
 
         if (!isAllOurs && !isModerator) {
-          window.pushToast({
-            title: window.i18n('messageDeletionForbidden'),
-            type: 'error',
-            id: 'messageDeletionForbidden',
-          });
+          ToastUtils.pushMessageDeleteForbidden();
 
           this.setState({ selectedMessages: [] });
           return;
diff --git a/ts/session/utils/Toast.ts b/ts/session/utils/Toast.ts
index 0c5d70413..dae0f9ae8 100644
--- a/ts/session/utils/Toast.ts
+++ b/ts/session/utils/Toast.ts
@@ -73,3 +73,68 @@ export function pushMessageBodyMissing() {
     id: 'messageBodyMissing',
   });
 }
+
+export function pushCopiedToClipBoard() {
+  window.pushToast({
+    title: window.i18n('copiedToClipboard'),
+    type: 'success',
+    id: 'copiedToClipboard',
+  });
+}
+
+export function pushForceUnlinked() {
+  window.pushToast({
+    title: window.i18n('successUnlinked'),
+    type: 'info',
+    id: 'successUnlinked',
+  });
+}
+
+export function pushSpellCheckDirty() {
+  window.pushToast({
+    title: window.i18n('spellCheckDirty'),
+    type: 'info',
+    id: 'spellCheckDirty',
+  });
+}
+
+export function pushAlreadyMemberOpenGroup() {
+  window.pushToast({
+    title: window.i18n('publicChatExists'),
+    type: 'info',
+    id: 'alreadyMemberPublicChat',
+  });
+}
+
+export function pushUserBanSuccess() {
+  window.pushToast({
+    title: window.i18n('userBanned'),
+    type: 'success',
+    id: 'userBanned',
+  });
+}
+
+export function pushUserBanFailure() {
+  window.pushToast({
+    title: window.i18n('userBanFailed'),
+    type: 'error',
+    id: 'userBanFailed',
+  });
+}
+
+export function pushMessageDeleteForbidden() {
+  window.pushToast({
+    title: window.i18n('messageDeletionForbidden'),
+    type: 'error',
+    id: 'messageDeletionForbidden',
+  });
+}
+
+export function pushAudioPermissionNeeded() {
+  window.pushToast({
+    id: 'audioPermissionNeeded',
+    title: window.i18n('audioPermissionNeededTitle'),
+    description: window.i18n('audioPermissionNeeded'),
+    type: 'info',
+  });
+}