diff --git a/_locales/en/messages.json b/_locales/en/messages.json index ba7d5bb47..f9847a3d0 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1547,13 +1547,17 @@ "message": "Unsupported message", "description": "Shown in notifications and in the left pane when a message has features too new for this signal install." }, + "message--getDescription--disappearing-media": { + "message": "View-once Media", + "description": "Shown in notifications and in the left pane after view-once message is deleted." + }, "message--getDescription--disappearing-photo": { - "message": "Disappearing Photo", - "description": "Shown in notifications and in the left pane when a message is a disappearing photo." + "message": "View-once Photo", + "description": "Shown in notifications and in the left pane when a message is a view once photo." }, "message--getDescription--disappearing-video": { - "message": "Disappearing Video", - "description": "Shown in notifications and in the left pane when a message is a disappearing video." + "message": "View-once Video", + "description": "Shown in notifications and in the left pane when a message is a view once video." }, "stickers--toast--InstallFailed": { "message": "Sticker pack could not be installed", @@ -1697,12 +1701,20 @@ "message": "Media", "description": "Text shown on outgoing messages with with individual timers (inaccessble)" }, + "Message--tap-to-view--incoming--expired-toast": { + "message": "You already viewed this message.", + "description": "Shown when user clicks on an expired incoming view-once bubble" + }, + "Message--tap-to-view--outgoing--expired-toast": { + "message": "View-once messages are not stored in your conversation history.", + "description": "Shown when user clicks on an expired outgoing view-once bubble" + }, "Message--tap-to-view--incoming": { - "message": "Photo", + "message": "View Photo", "description": "Text shown on photo messages with with individual timers, before user has viewed it" }, "Message--tap-to-view--incoming-video": { - "message": "Video", + "message": "View Video", "description": "Text shown on video messages with with individual timers, before user has viewed it" }, "Conversation--getDraftPreview--attachment": { diff --git a/images/icons/v2/play-outline-20.svg b/images/icons/v2/play-outline-20.svg deleted file mode 100644 index 9dacad460..000000000 --- a/images/icons/v2/play-outline-20.svg +++ /dev/null @@ -1 +0,0 @@ -play-outline-20 \ No newline at end of file diff --git a/images/icons/v2/play-outline-24.svg b/images/icons/v2/play-outline-24.svg deleted file mode 100644 index 4733083ec..000000000 --- a/images/icons/v2/play-outline-24.svg +++ /dev/null @@ -1 +0,0 @@ -play-outline-24 \ No newline at end of file diff --git a/images/icons/v2/view-once-24.svg b/images/icons/v2/view-once-24.svg new file mode 100644 index 000000000..2bd91d62e --- /dev/null +++ b/images/icons/v2/view-once-24.svg @@ -0,0 +1 @@ +view-once-24 \ No newline at end of file diff --git a/images/icons/v2/viewed-once-24.svg b/images/icons/v2/viewed-once-24.svg new file mode 100644 index 000000000..f34caf212 --- /dev/null +++ b/images/icons/v2/viewed-once-24.svg @@ -0,0 +1 @@ +viewed-once-24 \ No newline at end of file diff --git a/js/models/messages.js b/js/models/messages.js index 249153947..0410f1ec7 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -741,7 +741,7 @@ } if (this.isTapToView()) { if (this.isErased()) { - return i18n('mediaMessage'); + return i18n('message--getDescription--disappearing-media'); } const attachments = this.get('attachments'); diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 367e35c15..00bdedcd7 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -90,6 +90,20 @@ return { toastMessage: i18n('conversationReturnedToInbox') }; }, }); + Whisper.TapToViewExpiredIncomingToast = Whisper.ToastView.extend({ + render_attributes() { + return { + toastMessage: i18n('Message--tap-to-view--incoming--expired-toast'), + }; + }, + }); + Whisper.TapToViewExpiredOutgoingToast = Whisper.ToastView.extend({ + render_attributes() { + return { + toastMessage: i18n('Message--tap-to-view--outgoing--expired-toast'), + }; + }, + }); Whisper.FileSavedToast = Whisper.ToastView.extend({ className: 'toast toast-clickable', initialize(options) { @@ -459,6 +473,12 @@ const downloadNewVersion = () => { this.downloadNewVersion(); }; + const showExpiredIncomingTapToViewToast = () => { + this.showToast(Whisper.TapToViewExpiredIncomingToast); + }; + const showExpiredOutgoingTapToViewToast = () => { + this.showToast(Whisper.TapToViewExpiredOutgoingToast); + }; const scrollToQuotedMessage = async options => { const { author, sentAt } = options; @@ -623,6 +643,8 @@ showIdentity, showMessageDetail, showVisualAttachment, + showExpiredIncomingTapToViewToast, + showExpiredOutgoingTapToViewToast, }), }); diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index b459f9a0d..87570e419 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -366,8 +366,6 @@ } .module-message__container--with-tap-to-view-expired { - cursor: default; - @include light-theme { border: 1px solid $color-gray-15; background-color: $color-white; @@ -440,16 +438,16 @@ height: 20px; @include light-theme { - @include color-svg('../images/icons/v2/play-solid-24.svg', $color-white); + @include color-svg('../images/icons/v2/view-once-24.svg', $color-white); } @include dark-theme { - @include color-svg('../images/icons/v2/play-solid-24.svg', $color-gray-05); + @include color-svg('../images/icons/v2/view-once-24.svg', $color-gray-05); } @include ios-theme { - @include color-svg('../images/icons/v2/play-solid-24.svg', $color-gray-90); + @include color-svg('../images/icons/v2/view-once-24.svg', $color-gray-90); } @include ios-dark-theme { - @include color-svg('../images/icons/v2/play-solid-24.svg', $color-gray-05); + @include color-svg('../images/icons/v2/view-once-24.svg', $color-gray-05); } } .module-message__tap-to-view__icon--outgoing { @@ -465,28 +463,16 @@ } .module-message__tap-to-view__icon--expired { @include light-theme { - @include color-svg( - '../images/icons/v2/play-outline-24.svg', - $color-gray-75 - ); + @include color-svg('../images/icons/v2/viewed-once-24.svg', $color-gray-75); } @include dark-theme { - @include color-svg( - '../images/icons/v2/play-outline-24.svg', - $color-gray-05 - ); + @include color-svg('../images/icons/v2/viewed-once-24.svg', $color-gray-05); } @include ios-theme { - @include color-svg( - '../images/icons/v2/play-outline-24.svg', - $color-gray-75 - ); + @include color-svg('../images/icons/v2/viewed-once-24.svg', $color-gray-75); } @include ios-dark-theme { - @include color-svg( - '../images/icons/v2/play-outline-24.svg', - $color-gray-05 - ); + @include color-svg('../images/icons/v2/viewed-once-24.svg', $color-gray-05); } } .module-message__tap-to-view__text { diff --git a/ts/components/conversation/Message.md b/ts/components/conversation/Message.md index 7e6464f72..fc6347ca5 100644 --- a/ts/components/conversation/Message.md +++ b/ts/components/conversation/Message.md @@ -3681,6 +3681,32 @@ Sticker link previews are forced to use the small link preview form, no matter t authorAvatarPath={util.gifObjectUrl} /> +
+ + console.log('displayTapToViewMessage', args) + } + authorAvatarPath={util.gifObjectUrl} + /> +
void; scrollToQuotedMessage: (options: { author: string; sentAt: number }) => void; selectMessage?: (messageId: string, conversationId: string) => unknown; + + showExpiredIncomingTapToViewToast: () => unknown; + showExpiredOutgoingTapToViewToast: () => unknown; }; export type Props = PropsData & PropsHousekeeping & PropsActions; @@ -1311,7 +1314,7 @@ export class Message extends React.PureComponent { ); } - // tslint:disable-next-line cyclomatic-complexity + // tslint:disable-next-line cyclomatic-complexity max-func-body-length public handleOpen = ( event: React.KeyboardEvent | React.MouseEvent ) => { @@ -1319,19 +1322,32 @@ export class Message extends React.PureComponent { attachments, contact, displayTapToViewMessage, + direction, id, isTapToView, isTapToViewExpired, openConversation, showContactDetail, showVisualAttachment, + showExpiredIncomingTapToViewToast, + showExpiredOutgoingTapToViewToast, } = this.props; const { imageBroken } = this.state; const isAttachmentPending = this.isAttachmentPending(); if (isTapToView) { - if (!isTapToViewExpired && !isAttachmentPending) { + if (isAttachmentPending) { + return; + } + + if (isTapToViewExpired) { + const action = + direction === 'outgoing' + ? showExpiredOutgoingTapToViewToast + : showExpiredIncomingTapToViewToast; + action(); + } else { event.preventDefault(); event.stopPropagation(); diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 7f2f753fa..71337a676 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -9234,7 +9234,7 @@ "rule": "React-createRef", "path": "ts/components/conversation/Message.tsx", "line": " public focusRef: React.RefObject = React.createRef();", - "lineNumber": 150, + "lineNumber": 153, "reasonCategory": "usageTrusted", "updated": "2020-01-06T17:05:33.013Z", "reasonDetail": "Used for setting focus only"