Blur avatars of unapproved conversations

This commit is contained in:
Evan Hahn 2021-04-30 14:40:25 -05:00 committed by GitHub
parent bbd7fd3854
commit 05703c2719
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 474 additions and 124 deletions

View file

@ -9,8 +9,8 @@ import { Avatar, AvatarSize } from '../Avatar';
import { Timestamp } from '../conversation/Timestamp';
import { isConversationUnread } from '../../util/isConversationUnread';
import { cleanId } from '../_util';
import { ColorType } from '../../types/Colors';
import { LocalizerType } from '../../types/Util';
import { ConversationType } from '../../state/ducks/conversations';
const BASE_CLASS_NAME =
'module-conversation-list__item--contact-or-conversation';
@ -23,33 +23,40 @@ export const MESSAGE_TEXT_CLASS_NAME = `${MESSAGE_CLASS_NAME}__text`;
const CHECKBOX_CLASS_NAME = `${BASE_CLASS_NAME}__checkbox`;
type PropsType = {
avatarPath?: string;
checked?: boolean;
color?: ColorType;
conversationType: 'group' | 'direct';
disabled?: boolean;
headerDate?: number;
headerName: ReactNode;
i18n: LocalizerType;
id?: string;
isMe?: boolean;
i18n: LocalizerType;
isNoteToSelf?: boolean;
isSelected: boolean;
markedUnread?: boolean;
messageId?: string;
messageStatusIcon?: ReactNode;
messageText?: ReactNode;
name?: string;
onClick?: () => void;
phoneNumber?: string;
profileName?: string;
style: CSSProperties;
title: string;
unreadCount?: number;
};
} & Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'markedUnread'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
| 'unblurredAvatarPath'
>;
export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo(
({
acceptedMessageRequest,
avatarPath,
checked,
color,
@ -69,8 +76,10 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
onClick,
phoneNumber,
profileName,
sharedGroupNames,
style,
title,
unblurredAvatarPath,
unreadCount,
}) => {
const isUnread = isConversationUnread({ markedUnread, unreadCount });
@ -112,6 +121,7 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
<>
<div className={`${BASE_CLASS_NAME}__avatar-container`}>
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color}
noteToSelf={isAvatarNoteToSelf}
@ -121,7 +131,9 @@ export const BaseConversationListItem: FunctionComponent<PropsType> = React.memo
phoneNumber={phoneNumber}
profileName={profileName}
title={title}
sharedGroupNames={sharedGroupNames}
size={AvatarSize.FIFTY_TWO}
unblurredAvatarPath={unblurredAvatarPath}
/>
{isUnread && (
<div className={`${BASE_CLASS_NAME}__unread-count`}>

View file

@ -4,7 +4,7 @@
import React, { CSSProperties, FunctionComponent, ReactNode } from 'react';
import { BaseConversationListItem } from './BaseConversationListItem';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
import { LocalizerType } from '../../types/Util';
import { ContactName } from '../conversation/ContactName';
import { About } from '../conversation/About';
@ -17,18 +17,23 @@ export enum ContactCheckboxDisabledReason {
}
export type PropsDataType = {
about?: string;
avatarPath?: string;
color?: ColorType;
disabledReason?: ContactCheckboxDisabledReason;
id: string;
isMe?: boolean;
isChecked: boolean;
name?: string;
phoneNumber?: string;
profileName?: string;
title: string;
};
} & Pick<
ConversationType,
| 'about'
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'id'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
| 'unblurredAvatarPath'
>;
type PropsHousekeepingType = {
i18n: LocalizerType;
@ -44,6 +49,7 @@ type PropsType = PropsDataType & PropsHousekeepingType;
export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
({
about,
acceptedMessageRequest,
avatarPath,
color,
disabledReason,
@ -55,8 +61,10 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
onClick,
phoneNumber,
profileName,
sharedGroupNames,
style,
title,
unblurredAvatarPath,
}) => {
const disabled = Boolean(disabledReason);
@ -87,6 +95,7 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
checked={isChecked}
color={color}
@ -102,8 +111,10 @@ export const ContactCheckbox: FunctionComponent<PropsType> = React.memo(
onClick={onClickItem}
phoneNumber={phoneNumber}
profileName={profileName}
sharedGroupNames={sharedGroupNames}
style={style}
title={title}
unblurredAvatarPath={unblurredAvatarPath}
/>
);
}

View file

@ -4,23 +4,27 @@
import React, { CSSProperties, FunctionComponent } from 'react';
import { BaseConversationListItem } from './BaseConversationListItem';
import { ColorType } from '../../types/Colors';
import { ConversationType } from '../../state/ducks/conversations';
import { LocalizerType } from '../../types/Util';
import { ContactName } from '../conversation/ContactName';
import { About } from '../conversation/About';
export type PropsDataType = {
about?: string;
avatarPath?: string;
color?: ColorType;
id: string;
isMe?: boolean;
name?: string;
phoneNumber?: string;
profileName?: string;
title: string;
type: 'group' | 'direct';
};
export type PropsDataType = Pick<
ConversationType,
| 'about'
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'id'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
| 'type'
| 'unblurredAvatarPath'
>;
type PropsHousekeepingType = {
i18n: LocalizerType;
@ -33,6 +37,7 @@ type PropsType = PropsDataType & PropsHousekeepingType;
export const ContactListItem: FunctionComponent<PropsType> = React.memo(
({
about,
acceptedMessageRequest,
avatarPath,
color,
i18n,
@ -42,9 +47,11 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
onClick,
phoneNumber,
profileName,
sharedGroupNames,
style,
title,
type,
unblurredAvatarPath,
}) => {
const headerName = isMe ? (
i18n('noteToSelf')
@ -63,6 +70,7 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color}
conversationType={type}
@ -76,8 +84,10 @@ export const ContactListItem: FunctionComponent<PropsType> = React.memo(
onClick={onClick ? () => onClick(id) : undefined}
phoneNumber={phoneNumber}
profileName={profileName}
sharedGroupNames={sharedGroupNames}
style={style}
title={title}
unblurredAvatarPath={unblurredAvatarPath}
/>
);
}

View file

@ -44,6 +44,8 @@ export type PropsData = {
avatarPath?: string;
isMe?: boolean;
muteExpiresAt?: number;
sharedGroupNames?: Array<string>;
unblurredAvatarPath?: string;
lastUpdated?: number;
unreadCount?: number;
@ -89,11 +91,13 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
onClick,
phoneNumber,
profileName,
sharedGroupNames,
shouldShowDraft,
style,
title,
type,
typingContact,
unblurredAvatarPath,
unreadCount,
}) => {
const headerName = isMe ? (
@ -180,6 +184,7 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
color={color}
conversationType={type}
@ -196,9 +201,11 @@ export const ConversationListItem: FunctionComponent<Props> = React.memo(
onClick={onClickItem}
phoneNumber={phoneNumber}
profileName={profileName}
sharedGroupNames={sharedGroupNames}
style={style}
title={title}
unreadCount={unreadCount}
unblurredAvatarPath={unblurredAvatarPath}
/>
);
}

View file

@ -1,4 +1,4 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, {
@ -14,8 +14,8 @@ import { ContactName } from '../conversation/ContactName';
import { assert } from '../../util/assert';
import { BodyRangesType, LocalizerType } from '../../types/Util';
import { ColorType } from '../../types/Colors';
import { BaseConversationListItem } from './BaseConversationListItem';
import { ConversationType } from '../../state/ducks/conversations';
export type PropsDataType = {
isSelected?: boolean;
@ -29,15 +29,19 @@ export type PropsDataType = {
body: string;
bodyRanges: BodyRangesType;
from: {
phoneNumber?: string;
title: string;
isMe?: boolean;
name?: string;
color?: ColorType;
profileName?: string;
avatarPath?: string;
};
from: Pick<
ConversationType,
| 'acceptedMessageRequest'
| 'avatarPath'
| 'color'
| 'isMe'
| 'name'
| 'phoneNumber'
| 'profileName'
| 'sharedGroupNames'
| 'title'
| 'unblurredAvatarPath'
>;
to: {
groupName?: string;
@ -192,6 +196,7 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
return (
<BaseConversationListItem
acceptedMessageRequest={from.acceptedMessageRequest}
avatarPath={from.avatarPath}
color={from.color}
conversationType="direct"
@ -207,8 +212,10 @@ export const MessageSearchResult: FunctionComponent<PropsType> = React.memo(
onClick={onClickItem}
phoneNumber={from.phoneNumber}
profileName={from.profileName}
sharedGroupNames={from.sharedGroupNames}
style={style}
title={from.title}
unblurredAvatarPath={from.unblurredAvatarPath}
/>
);
}