Blur avatars of unapproved conversations
This commit is contained in:
parent
bbd7fd3854
commit
05703c2719
28 changed files with 474 additions and 124 deletions
|
@ -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`}>
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue