Don't render links (or link previews) for blocked or unapproved conversations

This commit is contained in:
Evan Hahn 2021-02-02 11:09:53 -06:00 committed by GitHub
parent 267ae80442
commit 8f1bb6f087
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 105 additions and 33 deletions

View file

@ -858,6 +858,14 @@
.module-message__link-preview { .module-message__link-preview {
@include button-reset; @include button-reset;
&--nonclickable {
cursor: inherit;
.module-image__image {
cursor: inherit;
}
}
display: block; display: block;
margin-left: -12px; margin-left: -12px;

View file

@ -2,6 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react'; import * as React from 'react';
import { isBoolean } from 'lodash';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import { boolean, number, text } from '@storybook/addon-knobs'; import { boolean, number, text } from '@storybook/addon-knobs';
@ -72,6 +73,12 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
i18n, i18n,
id: text('id', overrideProps.id || ''), id: text('id', overrideProps.id || ''),
interactionMode: overrideProps.interactionMode || 'keyboard', interactionMode: overrideProps.interactionMode || 'keyboard',
isBlocked: isBoolean(overrideProps.isBlocked)
? overrideProps.isBlocked
: false,
isMessageRequestAccepted: isBoolean(overrideProps.isMessageRequestAccepted)
? overrideProps.isMessageRequestAccepted
: true,
isTapToView: overrideProps.isTapToView, isTapToView: overrideProps.isTapToView,
isTapToViewError: overrideProps.isTapToViewError, isTapToViewError: overrideProps.isTapToViewError,
isTapToViewExpired: overrideProps.isTapToViewExpired, isTapToViewExpired: overrideProps.isTapToViewExpired,
@ -885,3 +892,31 @@ story.add('All the context menus', () => {
return <Message {...props} direction="outgoing" />; return <Message {...props} direction="outgoing" />;
}); });
story.add('Not approved, with link preview', () => {
const props = createProps({
previews: [
{
domain: 'signal.org',
image: {
contentType: IMAGE_PNG,
fileName: 'the-sax.png',
height: 240,
url: pngUrl,
width: 320,
},
isStickerPack: false,
title: 'Signal',
description:
'Say "hello" to a different messaging experience. An unexpected focus on privacy, combined with all of the features you expect.',
url: 'https://www.signal.org',
date: new Date(2020, 2, 10).valueOf(),
},
],
status: 'sent',
text: 'Be sure to look at https://www.signal.org',
isMessageRequestAccepted: false,
});
return renderBothDirections(props);
});

View file

@ -134,6 +134,8 @@ export type PropsData = {
canReply: boolean; canReply: boolean;
canDownload: boolean; canDownload: boolean;
canDeleteForEveryone: boolean; canDeleteForEveryone: boolean;
isBlocked: boolean;
isMessageRequestAccepted: boolean;
bodyRanges?: BodyRangesType; bodyRanges?: BodyRangesType;
}; };
@ -466,6 +468,11 @@ export class Message extends React.PureComponent<Props, State> {
} }
} }
private areLinksEnabled(): boolean {
const { isMessageRequestAccepted, isBlocked } = this.props;
return isMessageRequestAccepted && !isBlocked;
}
public renderTimestamp(): JSX.Element { public renderTimestamp(): JSX.Element {
const { const {
direction, direction,
@ -859,31 +866,18 @@ export class Message extends React.PureComponent<Props, State> {
const linkPreviewDate = first.date || null; const linkPreviewDate = first.date || null;
return ( const isClickable = this.areLinksEnabled();
<button
type="button"
className={classNames(
'module-message__link-preview',
`module-message__link-preview--${direction}`,
withContentAbove
? 'module-message__link-preview--with-content-above'
: null
)}
onKeyDown={(event: React.KeyboardEvent) => {
if (event.key === 'Enter' || event.key === 'Space') {
event.stopPropagation();
event.preventDefault();
openLink(first.url); const className = classNames(
} 'module-message__link-preview',
}} `module-message__link-preview--${direction}`,
onClick={(event: React.MouseEvent) => { {
event.stopPropagation(); 'module-message__link-preview--with-content-above': withContentAbove,
event.preventDefault(); 'module-message__link-preview--nonclickable': !isClickable,
}
openLink(first.url); );
}} const contents = (
> <>
{first.image && previewHasImage && isFullSizeImage ? ( {first.image && previewHasImage && isFullSizeImage ? (
<ImageGrid <ImageGrid
attachments={[first.image]} attachments={[first.image]}
@ -938,7 +932,32 @@ export class Message extends React.PureComponent<Props, State> {
</div> </div>
</div> </div>
</div> </div>
</>
);
return isClickable ? (
<button
type="button"
className={className}
onKeyDown={(event: React.KeyboardEvent) => {
if (event.key === 'Enter' || event.key === 'Space') {
event.stopPropagation();
event.preventDefault();
openLink(first.url);
}
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
event.preventDefault();
openLink(first.url);
}}
>
{contents}
</button> </button>
) : (
<div className={className}>{contents}</div>
); );
} }
@ -1138,6 +1157,7 @@ export class Message extends React.PureComponent<Props, State> {
> >
<MessageBody <MessageBody
bodyRanges={bodyRanges} bodyRanges={bodyRanges}
disableLinks={!this.areLinksEnabled()}
direction={direction} direction={direction}
i18n={i18n} i18n={i18n}
openConversation={openConversation} openConversation={openConversation}

View file

@ -33,6 +33,8 @@ const defaultMessage: MessageProps = {
i18n, i18n,
id: 'my-message', id: 'my-message',
interactionMode: 'keyboard', interactionMode: 'keyboard',
isBlocked: false,
isMessageRequestAccepted: true,
kickOffAttachmentDownload: action('kickOffAttachmentDownload'), kickOffAttachmentDownload: action('kickOffAttachmentDownload'),
openConversation: () => null, openConversation: () => null,
openLink: () => null, openLink: () => null,

View file

@ -36,6 +36,8 @@ const defaultMessageProps: MessagesProps = {
i18n, i18n,
id: 'messageId', id: 'messageId',
interactionMode: 'keyboard', interactionMode: 'keyboard',
isBlocked: false,
isMessageRequestAccepted: true,
kickOffAttachmentDownload: () => null, kickOffAttachmentDownload: () => null,
openConversation: () => null, openConversation: () => null,
openLink: () => null, openLink: () => null,

View file

@ -876,6 +876,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
deletedForEveryone: this.get('deletedForEveryone') || false, deletedForEveryone: this.get('deletedForEveryone') || false,
bodyRanges: this.processBodyRanges(), bodyRanges: this.processBodyRanges(),
isMessageRequestAccepted: conversation
? conversation.getAccepted()
: true,
isBlocked: Boolean(conversation?.isBlocked()),
}; };
} }

View file

@ -14841,23 +14841,23 @@
"rule": "React-createRef", "rule": "React-createRef",
"path": "ts/components/conversation/Message.tsx", "path": "ts/components/conversation/Message.tsx",
"line": " public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();", "line": " public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();",
"lineNumber": 220,
"reasonCategory": "usageTrusted",
"updated": "2020-09-08T20:19:01.913Z"
},
{
"rule": "React-createRef",
"path": "ts/components/conversation/Message.tsx",
"line": " public focusRef: React.RefObject<HTMLDivElement> = React.createRef();",
"lineNumber": 222, "lineNumber": 222,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-09-08T20:19:01.913Z" "updated": "2020-09-08T20:19:01.913Z"
}, },
{
"rule": "React-createRef",
"path": "ts/components/conversation/Message.tsx",
"line": " public focusRef: React.RefObject<HTMLDivElement> = React.createRef();",
"lineNumber": 224,
"reasonCategory": "usageTrusted",
"updated": "2020-09-08T20:19:01.913Z"
},
{ {
"rule": "React-createRef", "rule": "React-createRef",
"path": "ts/components/conversation/Message.tsx", "path": "ts/components/conversation/Message.tsx",
"line": " > = React.createRef();", "line": " > = React.createRef();",
"lineNumber": 226, "lineNumber": 228,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-08-28T19:36:40.817Z" "updated": "2020-08-28T19:36:40.817Z"
}, },