Show info for permanently undownloadable file and audio attachments
Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com>
This commit is contained in:
parent
1fa7427ff4
commit
bd88f7558a
11 changed files with 244 additions and 6 deletions
|
@ -1522,10 +1522,22 @@
|
|||
"messageformat": "This media is no longer available.",
|
||||
"description": "Shown in info toast for messages with old image and video attachments which are no longer available for download. Also used for accessibility label for the download attachment button."
|
||||
},
|
||||
"icu:mediaNotAvailable": {
|
||||
"messageformat": "This media is not available",
|
||||
"description": "Shown in info toast for messages with old image and video attachments which are no longer available for download. Also used for accessibility label for the download attachment button."
|
||||
},
|
||||
"icu:attachmentNoLongerAvailable__learnMore": {
|
||||
"messageformat": "Learn more",
|
||||
"description": "Link in message placeholder and info toast for messages with old attachments which are no longer available for download."
|
||||
},
|
||||
"icu:fileNotAvailable": {
|
||||
"messageformat": "This file is not available",
|
||||
"description": "Shown in chat timeline for messages with old generic file attachments which are no longer available for download."
|
||||
},
|
||||
"icu:voiceMessageNotAvailable": {
|
||||
"messageformat": "This voice message is not available",
|
||||
"description": "Shown in chat timeline for messages with old audio attachments which are no longer available for download."
|
||||
},
|
||||
"icu:save": {
|
||||
"messageformat": "Save",
|
||||
"description": "Used on save buttons"
|
||||
|
|
5
images/icons/v3/file/file-slash.svg
Normal file
5
images/icons/v3/file/file-slash.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.61872 1.38128C2.27701 1.03957 1.72299 1.03957 1.38128 1.38128C1.03957 1.72299 1.03957 2.27701 1.38128 2.61872L21.3813 22.6187C21.723 22.9604 22.277 22.9604 22.6187 22.6187C22.9604 22.277 22.9604 21.723 22.6187 21.3813L2.61872 1.38128Z" fill="black"/>
|
||||
<path d="M3.62507 6.98384L3.625 16.7368C3.62499 17.5456 3.62498 18.2056 3.66878 18.7417C3.71407 19.296 3.81053 19.7944 4.04735 20.2592C4.41886 20.9884 5.01166 21.5812 5.74079 21.9527C6.20556 22.1895 6.70399 22.2859 7.25835 22.3312C7.79438 22.375 8.45431 22.375 9.2631 22.375H14.7368C15.5456 22.375 16.2056 22.375 16.7416 22.3312C17.296 22.2859 17.7944 22.1895 18.2592 21.9527C18.3326 21.9153 18.4046 21.8757 18.4751 21.8339L17.148 20.5068C17.0069 20.541 16.8304 20.5682 16.5991 20.587C16.1428 20.6243 15.5545 20.625 14.7 20.625H9.3C8.44548 20.625 7.85722 20.6243 7.40086 20.587C6.95471 20.5506 6.71223 20.4836 6.53527 20.3934C6.13543 20.1897 5.81034 19.8646 5.60661 19.4647C5.51645 19.2878 5.44942 19.0453 5.41297 18.5992C5.37568 18.1428 5.375 17.5545 5.375 16.7V8.73377L3.62507 6.98384Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.625 15.2663V10.375H17.2632C16.4544 10.375 15.7944 10.375 15.2584 10.3312C14.704 10.2859 14.2056 10.1895 13.7408 9.95265C13.0117 9.58114 12.4189 8.98834 12.0473 8.25921C11.8105 7.79444 11.7141 7.29601 11.6688 6.74165C11.625 6.2056 11.625 5.54562 11.625 4.73679V3.37501H9.3C8.44548 3.37501 7.85722 3.37569 7.40086 3.41298C7.16961 3.43187 6.99307 3.45898 6.85202 3.49327L5.5249 2.16615C5.59542 2.12437 5.66742 2.08475 5.74079 2.04736C6.20556 1.81055 6.70399 1.71409 7.25835 1.66879C7.7944 1.62499 8.45438 1.625 9.26322 1.62501L12.3224 1.62496C12.6229 1.6246 12.9067 1.62427 13.1831 1.69063C13.4254 1.74881 13.6571 1.84477 13.8696 1.97499C14.112 2.12354 14.3125 2.32445 14.5247 2.53717L19.4628 7.47534C19.6756 7.68755 19.8765 7.888 20.025 8.1304C20.1552 8.3429 20.2512 8.57456 20.3094 8.8169C20.3757 9.09334 20.3754 9.37714 20.3751 9.67762L20.3749 17.0162L18.625 15.2663ZM13.375 3.86245L18.1376 8.625H17.3C16.4455 8.625 15.8572 8.62432 15.4009 8.58703C14.9547 8.55058 14.7122 8.48355 14.5353 8.39339C14.1354 8.18966 13.8103 7.86457 13.6066 7.46473C13.5164 7.28777 13.4494 7.04529 13.413 6.59914C13.3757 6.14278 13.375 5.55452 13.375 4.7V3.86245Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
7
images/icons/v3/play/play-slash.svg
Normal file
7
images/icons/v3/play/play-slash.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.61872 1.38128C2.27701 1.03957 1.72299 1.03957 1.38128 1.38128C1.03957 1.72299 1.03957 2.27701 1.38128 2.61872L21.3813 22.6187C21.723 22.9604 22.277 22.9604 22.6187 22.6187C22.9604 22.277 22.9604 21.723 22.6187 21.3813L2.61872 1.38128Z" fill="black"/>
|
||||
<path d="M1.68922 6.67316C1.73053 6.16753 1.80012 5.70963 1.92522 5.28398L3.4352 6.79396L3.4334 6.81566C3.37568 7.52215 3.375 8.42544 3.375 9.7V14.3C3.375 15.5746 3.37568 16.4778 3.4334 17.1843C3.49029 17.8806 3.59819 18.3083 3.7701 18.6457C4.11764 19.3278 4.6722 19.8824 5.35428 20.2299C5.69168 20.4018 6.11939 20.5097 6.81566 20.5666C7.52215 20.6243 8.42544 20.625 9.7 20.625H14.3C15.5746 20.625 16.4778 20.6243 17.1843 20.5666L17.206 20.5648L18.716 22.0748C18.2904 22.1999 17.8325 22.2695 17.3268 22.3108C16.5407 22.375 15.566 22.375 14.3384 22.375H9.6616C8.43401 22.375 7.45926 22.375 6.67316 22.3108C5.86866 22.2451 5.18501 22.1077 4.5598 21.7892C3.54843 21.2738 2.72616 20.4516 2.21084 19.4402C1.89228 18.815 1.75495 18.1313 1.68922 17.3268C1.62499 16.5407 1.62499 15.566 1.625 14.3384V9.66162C1.62499 8.43403 1.62499 7.45926 1.68922 6.67316Z" fill="black"/>
|
||||
<path d="M8.75 15.4641V12.1088L11.9753 15.334L10.25 16.3301C9.58333 16.715 8.75 16.2339 8.75 15.4641Z" fill="black"/>
|
||||
<path d="M12.0922 8.7334L16.234 12.8752L16.25 12.866C16.9167 12.4811 16.9167 11.5188 16.25 11.1339L12.0922 8.7334Z" fill="black"/>
|
||||
<path d="M20.5666 17.1843L20.5648 17.206L22.0748 18.716C22.1999 18.2904 22.2695 17.8325 22.3108 17.3268C22.375 16.5407 22.375 15.566 22.375 14.3384V9.6616C22.375 8.43401 22.375 7.45926 22.3108 6.67316C22.2451 5.86866 22.1077 5.18501 21.7892 4.5598C21.2738 3.54843 20.4516 2.72616 19.4402 2.21084C18.815 1.89228 18.1313 1.75495 17.3268 1.68922C16.5407 1.62499 15.566 1.62499 14.3384 1.625H9.66162C8.43403 1.62499 7.45926 1.62499 6.67316 1.68922C6.16753 1.73053 5.70963 1.80012 5.28398 1.92522L6.79396 3.4352L6.81566 3.4334C7.52215 3.37568 8.42544 3.375 9.7 3.375H14.3C15.5746 3.375 16.4778 3.37568 17.1843 3.4334C17.8806 3.49029 18.3083 3.59819 18.6457 3.7701C19.3278 4.11764 19.8824 4.6722 20.2299 5.35428C20.4018 5.69168 20.5097 6.11939 20.5666 6.81566C20.6243 7.52215 20.625 8.42544 20.625 9.7V14.3C20.625 15.5746 20.6243 16.4778 20.5666 17.1843Z" fill="black"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
|
@ -744,6 +744,46 @@ $message-padding-horizontal: 12px;
|
|||
}
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment {
|
||||
@include mixins.font-body-1;
|
||||
|
||||
display: flex;
|
||||
|
||||
padding-block: 9px 8px;
|
||||
padding-inline: 12px;
|
||||
|
||||
margin-inline: -$message-padding-horizontal;
|
||||
margin-block-start: -$message-padding-vertical;
|
||||
margin-block-end: -$message-padding-vertical;
|
||||
|
||||
&--with-content-below {
|
||||
margin-block-end: 7px;
|
||||
border-bottom: 0.5px solid variables.$color-white-alpha-10;
|
||||
|
||||
@include mixins.light-theme {
|
||||
border-color: variables.$color-black-alpha-10;
|
||||
}
|
||||
|
||||
@include mixins.dark-theme {
|
||||
border-color: variables.$color-white-alpha-10;
|
||||
}
|
||||
}
|
||||
|
||||
&--with-content-above {
|
||||
margin-block-start: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.module-message__container--outgoing
|
||||
.module-message__undownloadable-attachment--with-content-below {
|
||||
border-color: variables.$color-white-alpha-30;
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment--no-text
|
||||
+ .module-message__metadata {
|
||||
margin-block-start: -25px;
|
||||
}
|
||||
|
||||
.module-message__sticker-container {
|
||||
// To ensure that images are centered if they aren't full width of bubble
|
||||
text-align: center;
|
||||
|
@ -918,6 +958,47 @@ $message-padding-horizontal: 12px;
|
|||
}
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment__icon-container {
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment__icon {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
|
||||
&--audio {
|
||||
@include mixins.color-svg(
|
||||
'../images/icons/v3/play/play-slash.svg',
|
||||
currentColor
|
||||
);
|
||||
}
|
||||
|
||||
&--generic {
|
||||
@include mixins.color-svg(
|
||||
'../images/icons/v3/file/file-slash.svg',
|
||||
currentColor
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment-info {
|
||||
margin-inline-end: 15px;
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment-learn-more-container {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.module-message__undownloadable-attachment-learn-more {
|
||||
@include mixins.button-reset;
|
||||
@include mixins.font-body-1-bold;
|
||||
@include mixins.keyboard-mode {
|
||||
&:focus {
|
||||
box-shadow: 0px 0px 0px 2px variables.$color-ultramarine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.module-message__link-preview {
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
@ -46,9 +46,11 @@ $color-black: #000000;
|
|||
|
||||
$color-white-alpha-06: rgba($color-white, 0.06);
|
||||
$color-white-alpha-08: rgba($color-white, 0.08);
|
||||
$color-white-alpha-10: rgba($color-white, 0.1);
|
||||
$color-white-alpha-12: rgba($color-white, 0.12);
|
||||
$color-white-alpha-16: rgba($color-white, 0.16);
|
||||
$color-white-alpha-20: rgba($color-white, 0.2);
|
||||
$color-white-alpha-30: rgba($color-white, 0.3);
|
||||
$color-white-alpha-40: rgba($color-white, 0.4);
|
||||
$color-white-alpha-60: rgba($color-white, 0.6);
|
||||
$color-white-alpha-70: rgba($color-white, 0.7);
|
||||
|
@ -60,6 +62,7 @@ $color-black-alpha-06: rgba($color-black, 0.06);
|
|||
$color-black-alpha-08: rgba($color-black, 0.08);
|
||||
// Equivalent to gray-05 on a white background
|
||||
$color-black-alpha-085: rgba($color-black, 0.085);
|
||||
$color-black-alpha-10: rgba($color-black, 0.1);
|
||||
$color-black-alpha-12: rgba($color-black, 0.12);
|
||||
$color-black-alpha-16: rgba($color-black, 0.16);
|
||||
$color-black-alpha-20: rgba($color-black, 0.2);
|
||||
|
|
|
@ -418,7 +418,7 @@ export function renderToast({
|
|||
onClick: () => openLinkInWebBrowser(LINKED_DEVICES_URL),
|
||||
}}
|
||||
>
|
||||
{i18n('icu:mediaNoLongerAvailable')}
|
||||
{i18n('icu:mediaNotAvailable')}
|
||||
</Toast>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ export function GIF(props: Props): JSX.Element {
|
|||
<button
|
||||
type="button"
|
||||
className="module-image__overlay-circle module-image__overlay-circle--undownloadable"
|
||||
aria-label={i18n('icu:mediaNoLongerAvailable')}
|
||||
aria-label={i18n('icu:mediaNotAvailable')}
|
||||
onClick={undownloadableClick}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
|
|
|
@ -212,7 +212,7 @@ export function Image({
|
|||
<button
|
||||
type="button"
|
||||
className="module-image__overlay-circle module-image__overlay-circle--undownloadable"
|
||||
aria-label={i18n('icu:mediaNoLongerAvailable')}
|
||||
aria-label={i18n('icu:mediaNotAvailable')}
|
||||
onClick={undownloadableClick}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
|
|
|
@ -71,6 +71,7 @@ import {
|
|||
isGIF,
|
||||
isPlayed,
|
||||
isPermanentlyUndownloadable,
|
||||
canRenderAudio,
|
||||
} from '../../types/Attachment';
|
||||
import type { EmbeddedContactType } from '../../types/EmbeddedContact';
|
||||
|
||||
|
@ -106,6 +107,7 @@ import { getColorForCallLink } from '../../util/getColorForCallLink';
|
|||
import { getKeyFromCallLink } from '../../util/callLinks';
|
||||
import { InAnotherCallTooltip } from './InAnotherCallTooltip';
|
||||
import { formatFileSize } from '../../util/formatFileSize';
|
||||
import { LINKED_DEVICES_URL } from '../../types/support';
|
||||
|
||||
const GUESS_METADATA_WIDTH_TIMESTAMP_SIZE = 16;
|
||||
const GUESS_METADATA_WIDTH_EXPIRE_TIMER_SIZE = 18;
|
||||
|
@ -630,7 +632,7 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
if (!text && !deletedForEveryone && !attachmentDroppedDueToSize) {
|
||||
return isAudio(attachments)
|
||||
return canRenderAudio(attachments)
|
||||
? MetadataPlacement.RenderedByMessageAudioComponent
|
||||
: MetadataPlacement.Bottom;
|
||||
}
|
||||
|
@ -1053,8 +1055,55 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
);
|
||||
}
|
||||
}
|
||||
const isAttachmentAudio = isAudio(attachments);
|
||||
|
||||
if (isAudio(attachments)) {
|
||||
// Undownloadable audio and generic files
|
||||
if (isPermanentlyUndownloadable(firstAttachment)) {
|
||||
const containerClassName = classNames(
|
||||
'module-message__undownloadable-attachment',
|
||||
withContentAbove
|
||||
? 'module-message__undownloadable-attachment--with-content-above'
|
||||
: null,
|
||||
withContentBelow
|
||||
? 'module-message__undownloadable-attachment--with-content-below'
|
||||
: null,
|
||||
text ? null : 'module-message__undownloadable-attachment--no-text'
|
||||
);
|
||||
const attachmentType = isAttachmentAudio ? 'audio' : 'generic';
|
||||
const iconClassName = classNames(
|
||||
'module-message__undownloadable-attachment__icon',
|
||||
`module-message__undownloadable-attachment__icon--${attachmentType}`
|
||||
);
|
||||
return (
|
||||
<div className={containerClassName}>
|
||||
<div className="module-message__undownloadable-attachment__icon-container">
|
||||
<div className={iconClassName} />
|
||||
</div>
|
||||
<div>
|
||||
<div className="module-message__undownloadable-attachment-info">
|
||||
{isAttachmentAudio
|
||||
? i18n('icu:voiceMessageNotAvailable')
|
||||
: i18n('icu:fileNotAvailable')}
|
||||
</div>
|
||||
<div className="module-message__undownloadable-attachment-learn-more-container">
|
||||
<button
|
||||
className="module-message__undownloadable-attachment-learn-more"
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
openLinkInWebBrowser(LINKED_DEVICES_URL);
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
{i18n('icu:attachmentNoLongerAvailable__learnMore')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isAttachmentAudio) {
|
||||
const played = isPlayed(direction, status, readStatus);
|
||||
|
||||
return renderAudioAttachment({
|
||||
|
|
|
@ -2212,6 +2212,7 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
|
@ -2227,6 +2228,7 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
fakeAttachment({
|
||||
contentType: IMAGE_JPEG,
|
||||
|
@ -2237,6 +2239,7 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
|
@ -2253,6 +2256,7 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
|
@ -2268,10 +2272,49 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
});
|
||||
const audioProps = createProps({
|
||||
attachments: [
|
||||
fakeAttachment({
|
||||
contentType: AUDIO_MP3,
|
||||
fileName: 'bird.mp3',
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
});
|
||||
const audioWithCaptionProps = {
|
||||
...audioProps,
|
||||
text: "Here's that file",
|
||||
};
|
||||
const textFileProps = createProps({
|
||||
attachments: [
|
||||
fakeAttachment({
|
||||
contentType: stringToMIMEType('text/plain'),
|
||||
fileName: 'why-i-love-birds.txt',
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
path: undefined,
|
||||
key: undefined,
|
||||
id: undefined,
|
||||
error: true,
|
||||
}),
|
||||
],
|
||||
status: 'sent',
|
||||
});
|
||||
const textFileWithCaptionProps = {
|
||||
...textFileProps,
|
||||
text: "Here's that file",
|
||||
};
|
||||
|
||||
const outgoingAuthor = {
|
||||
...imageProps.author,
|
||||
|
@ -2283,7 +2326,11 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
<TimelineMessage {...imageProps} shouldCollapseAbove />
|
||||
<TimelineMessage {...gifProps} />
|
||||
<TimelineMessage {...videoProps} />
|
||||
<TimelineMessage {...multipleImagesProps} shouldCollapseBelow />
|
||||
<TimelineMessage {...multipleImagesProps} />
|
||||
<TimelineMessage {...textFileProps} />
|
||||
<TimelineMessage {...textFileWithCaptionProps} />
|
||||
<TimelineMessage {...audioProps} />
|
||||
<TimelineMessage {...audioWithCaptionProps} shouldCollapseBelow />
|
||||
<TimelineMessage
|
||||
{...imageProps}
|
||||
author={outgoingAuthor}
|
||||
|
@ -2304,6 +2351,26 @@ export function PermanentlyUndownloadableAttachments(): JSX.Element {
|
|||
{...multipleImagesProps}
|
||||
author={outgoingAuthor}
|
||||
direction="outgoing"
|
||||
/>
|
||||
<TimelineMessage
|
||||
{...textFileProps}
|
||||
author={outgoingAuthor}
|
||||
direction="outgoing"
|
||||
/>
|
||||
<TimelineMessage
|
||||
{...textFileWithCaptionProps}
|
||||
author={outgoingAuthor}
|
||||
direction="outgoing"
|
||||
/>
|
||||
<TimelineMessage
|
||||
{...audioProps}
|
||||
author={outgoingAuthor}
|
||||
direction="outgoing"
|
||||
/>
|
||||
<TimelineMessage
|
||||
{...audioWithCaptionProps}
|
||||
author={outgoingAuthor}
|
||||
direction="outgoing"
|
||||
shouldCollapseBelow
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -655,6 +655,20 @@ export function isPlayed(
|
|||
return readStatus === ReadStatus.Viewed;
|
||||
}
|
||||
|
||||
export function canRenderAudio(
|
||||
attachments?: ReadonlyArray<AttachmentType>
|
||||
): boolean {
|
||||
const firstAttachment = attachments && attachments[0];
|
||||
if (!firstAttachment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
isAudio(attachments) &&
|
||||
(isDownloaded(firstAttachment) || isDownloadable(firstAttachment))
|
||||
);
|
||||
}
|
||||
|
||||
export function canDisplayImage(
|
||||
attachments?: ReadonlyArray<AttachmentType>
|
||||
): boolean {
|
||||
|
|
Loading…
Add table
Reference in a new issue