Refactor ConversationHeader into function component
This commit is contained in:
parent
9533796c81
commit
33d30c6e74
6 changed files with 1273 additions and 1112 deletions
|
@ -46,32 +46,32 @@ const commonProps = {
|
||||||
|
|
||||||
i18n,
|
i18n,
|
||||||
|
|
||||||
setDisappearingMessages: action('setDisappearingMessages'),
|
onConversationAccept: action('onConversationAccept'),
|
||||||
destroyMessages: action('destroyMessages'),
|
onConversationArchive: action('onConversationArchive'),
|
||||||
leaveGroup: action('leaveGroup'),
|
onConversationBlock: action('onConversationBlock'),
|
||||||
onOutgoingAudioCallInConversation: action(
|
onConversationBlockAndReportSpam: action('onConversationBlockAndReportSpam'),
|
||||||
'onOutgoingAudioCallInConversation'
|
onConversationDelete: action('onConversationDelete'),
|
||||||
|
onConversationDeleteMessages: action('onConversationDeleteMessages'),
|
||||||
|
onConversationDisappearingMessagesChange: action(
|
||||||
|
'onConversationDisappearingMessagesChange'
|
||||||
),
|
),
|
||||||
onOutgoingVideoCallInConversation: action(
|
onConversationLeaveGroup: action('onConversationLeaveGroup'),
|
||||||
'onOutgoingVideoCallInConversation'
|
onConversationMarkUnread: action('onConversationMarkUnread'),
|
||||||
|
onConversationMuteExpirationChange: action(
|
||||||
|
'onConversationMuteExpirationChange'
|
||||||
),
|
),
|
||||||
|
onConversationPin: action('onConversationPin'),
|
||||||
onArchive: action('onArchive'),
|
onConversationReportSpam: action('onConversationReportSpam'),
|
||||||
onMarkUnread: action('onMarkUnread'),
|
onConversationUnarchive: action('onConversationUnarchive'),
|
||||||
toggleSelectMode: action('toggleSelectMode'),
|
onConversationUnpin: action('onConversationUnpin'),
|
||||||
onMoveToInbox: action('onMoveToInbox'),
|
onOutgoingAudioCall: action('onOutgoingAudioCall'),
|
||||||
pushPanelForConversation: action('pushPanelForConversation'),
|
onOutgoingVideoCall: action('onOutgoingVideoCall'),
|
||||||
popPanelForConversation: action('popPanelForConversation'),
|
onSearchInConversation: action('onSearchInConversation'),
|
||||||
searchInConversation: action('searchInConversation'),
|
onSelectModeEnter: action('onSelectModeEnter'),
|
||||||
setMuteExpiration: action('onSetMuteNotifications'),
|
onShowMembers: action('onShowMembers'),
|
||||||
setPinned: action('setPinned'),
|
onViewConversationDetails: action('onViewConversationDetails'),
|
||||||
viewUserStories: action('viewUserStories'),
|
onViewRecentMedia: action('onViewRecentMedia'),
|
||||||
|
onViewUserStories: action('onViewUserStories'),
|
||||||
acceptConversation: action('acceptConversation'),
|
|
||||||
blockAndReportSpam: action('blockAndReportSpam'),
|
|
||||||
blockConversation: action('blockConversation'),
|
|
||||||
reportSpam: action('reportSpam'),
|
|
||||||
deleteConversation: action('deleteConversation'),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PrivateConvo(): JSX.Element {
|
export function PrivateConvo(): JSX.Element {
|
||||||
|
@ -80,69 +80,79 @@ export function PrivateConvo(): JSX.Element {
|
||||||
title: 'With name and profile, verified',
|
title: 'With name and profile, verified',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
isVerified: true,
|
color: getRandomColor(),
|
||||||
avatarPath: gifUrl,
|
isVerified: true,
|
||||||
title: 'Someone 🔥 Somewhere',
|
avatarPath: gifUrl,
|
||||||
name: 'Someone 🔥 Somewhere',
|
title: 'Someone 🔥 Somewhere',
|
||||||
phoneNumber: '(202) 555-0001',
|
name: 'Someone 🔥 Somewhere',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0001',
|
||||||
id: '1',
|
type: 'direct',
|
||||||
profileName: '🔥Flames🔥',
|
id: '1',
|
||||||
acceptedMessageRequest: true,
|
profileName: '🔥Flames🔥',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'With name, not verified, no avatar',
|
title: 'With name, not verified, no avatar',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
isVerified: false,
|
color: getRandomColor(),
|
||||||
title: 'Someone 🔥 Somewhere',
|
isVerified: false,
|
||||||
name: 'Someone 🔥 Somewhere',
|
title: 'Someone 🔥 Somewhere',
|
||||||
phoneNumber: '(202) 555-0002',
|
name: 'Someone 🔥 Somewhere',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0002',
|
||||||
id: '2',
|
type: 'direct',
|
||||||
acceptedMessageRequest: true,
|
id: '2',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'With name, not verified, descenders',
|
title: 'With name, not verified, descenders',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
isVerified: false,
|
color: getRandomColor(),
|
||||||
title: 'Joyrey 🔥 Leppey',
|
isVerified: false,
|
||||||
name: 'Joyrey 🔥 Leppey',
|
title: 'Joyrey 🔥 Leppey',
|
||||||
phoneNumber: '(202) 555-0002',
|
name: 'Joyrey 🔥 Leppey',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0002',
|
||||||
id: '3',
|
type: 'direct',
|
||||||
acceptedMessageRequest: true,
|
id: '3',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Profile, no name',
|
title: 'Profile, no name',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
isVerified: false,
|
color: getRandomColor(),
|
||||||
phoneNumber: '(202) 555-0003',
|
isVerified: false,
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0003',
|
||||||
id: '4',
|
type: 'direct',
|
||||||
title: '🔥Flames🔥',
|
id: '4',
|
||||||
profileName: '🔥Flames🔥',
|
title: '🔥Flames🔥',
|
||||||
acceptedMessageRequest: true,
|
profileName: '🔥Flames🔥',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'No name, no profile, no color',
|
title: 'No name, no profile, no color',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
title: '(202) 555-0011',
|
conversation: getDefaultConversation({
|
||||||
phoneNumber: '(202) 555-0011',
|
title: '(202) 555-0011',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0011',
|
||||||
id: '5',
|
type: 'direct',
|
||||||
acceptedMessageRequest: true,
|
id: '5',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -150,66 +160,76 @@ export function PrivateConvo(): JSX.Element {
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
phoneNumber: '(202) 555-0004',
|
color: getRandomColor(),
|
||||||
title: '(202) 555-0004',
|
phoneNumber: '(202) 555-0004',
|
||||||
type: 'direct',
|
title: '(202) 555-0004',
|
||||||
id: '6',
|
type: 'direct',
|
||||||
acceptedMessageRequest: true,
|
id: '6',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Disappearing messages set',
|
title: 'Disappearing messages set',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
title: '(202) 555-0005',
|
color: getRandomColor(),
|
||||||
phoneNumber: '(202) 555-0005',
|
title: '(202) 555-0005',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0005',
|
||||||
id: '7',
|
type: 'direct',
|
||||||
expireTimer: DurationInSeconds.fromSeconds(10),
|
id: '7',
|
||||||
acceptedMessageRequest: true,
|
expireTimer: DurationInSeconds.fromSeconds(10),
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Disappearing messages + verified',
|
title: 'Disappearing messages + verified',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
title: '(202) 555-0005',
|
color: getRandomColor(),
|
||||||
phoneNumber: '(202) 555-0005',
|
title: '(202) 555-0005',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0005',
|
||||||
id: '8',
|
type: 'direct',
|
||||||
expireTimer: DurationInSeconds.fromSeconds(300),
|
id: '8',
|
||||||
acceptedMessageRequest: true,
|
expireTimer: DurationInSeconds.fromSeconds(300),
|
||||||
isVerified: true,
|
acceptedMessageRequest: true,
|
||||||
canChangeTimer: true,
|
isVerified: true,
|
||||||
|
canChangeTimer: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Muting Conversation',
|
title: 'Muting Conversation',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
conversation: getDefaultConversation({
|
||||||
title: '(202) 555-0006',
|
color: getRandomColor(),
|
||||||
phoneNumber: '(202) 555-0006',
|
title: '(202) 555-0006',
|
||||||
type: 'direct',
|
phoneNumber: '(202) 555-0006',
|
||||||
id: '9',
|
type: 'direct',
|
||||||
acceptedMessageRequest: true,
|
id: '9',
|
||||||
muteExpiresAt: new Date('3000-10-18T11:11:11Z').valueOf(),
|
acceptedMessageRequest: true,
|
||||||
|
muteExpiresAt: new Date('3000-10-18T11:11:11Z').valueOf(),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'SMS-only conversation',
|
title: 'SMS-only conversation',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: '(202) 555-0006',
|
|
||||||
phoneNumber: '(202) 555-0006',
|
|
||||||
type: 'direct',
|
|
||||||
id: '10',
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
isSMSOnly: true,
|
isSMSOnly: true,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: '(202) 555-0006',
|
||||||
|
phoneNumber: '(202) 555-0006',
|
||||||
|
type: 'direct',
|
||||||
|
id: '10',
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -236,62 +256,71 @@ export function Group(): JSX.Element {
|
||||||
title: 'Basic',
|
title: 'Basic',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: 'Typescript support group',
|
|
||||||
name: 'Typescript support group',
|
|
||||||
phoneNumber: '',
|
|
||||||
id: '11',
|
|
||||||
type: 'group',
|
|
||||||
expireTimer: DurationInSeconds.fromSeconds(10),
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: 'Typescript support group',
|
||||||
|
name: 'Typescript support group',
|
||||||
|
phoneNumber: '',
|
||||||
|
id: '11',
|
||||||
|
type: 'group',
|
||||||
|
expireTimer: DurationInSeconds.fromSeconds(10),
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'In a group you left - no disappearing messages',
|
title: 'In a group you left - no disappearing messages',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: 'Typescript support group',
|
|
||||||
name: 'Typescript support group',
|
|
||||||
phoneNumber: '',
|
|
||||||
id: '12',
|
|
||||||
type: 'group',
|
|
||||||
left: true,
|
|
||||||
expireTimer: DurationInSeconds.fromSeconds(10),
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: 'Typescript support group',
|
||||||
|
name: 'Typescript support group',
|
||||||
|
phoneNumber: '',
|
||||||
|
id: '12',
|
||||||
|
type: 'group',
|
||||||
|
left: true,
|
||||||
|
expireTimer: DurationInSeconds.fromSeconds(10),
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'In a group with an active group call',
|
title: 'In a group with an active group call',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: 'Typescript support group',
|
|
||||||
name: 'Typescript support group',
|
|
||||||
phoneNumber: '',
|
|
||||||
id: '13',
|
|
||||||
type: 'group',
|
|
||||||
expireTimer: DurationInSeconds.fromSeconds(10),
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.Join,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.Join,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: 'Typescript support group',
|
||||||
|
name: 'Typescript support group',
|
||||||
|
phoneNumber: '',
|
||||||
|
id: '13',
|
||||||
|
type: 'group',
|
||||||
|
expireTimer: DurationInSeconds.fromSeconds(10),
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'In a forever muted group',
|
title: 'In a forever muted group',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: 'Way too many messages',
|
|
||||||
name: 'Way too many messages',
|
|
||||||
phoneNumber: '',
|
|
||||||
id: '14',
|
|
||||||
type: 'group',
|
|
||||||
expireTimer: DurationInSeconds.fromSeconds(10),
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.JustVideo,
|
||||||
muteExpiresAt: Infinity,
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: 'Way too many messages',
|
||||||
|
name: 'Way too many messages',
|
||||||
|
phoneNumber: '',
|
||||||
|
id: '14',
|
||||||
|
type: 'group',
|
||||||
|
expireTimer: DurationInSeconds.fromSeconds(10),
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
|
||||||
|
muteExpiresAt: Infinity,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -318,14 +347,16 @@ export function NoteToSelf(): JSX.Element {
|
||||||
title: 'In chat with yourself',
|
title: 'In chat with yourself',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: '(202) 555-0007',
|
|
||||||
phoneNumber: '(202) 555-0007',
|
|
||||||
id: '15',
|
|
||||||
type: 'direct',
|
|
||||||
isMe: true,
|
|
||||||
acceptedMessageRequest: true,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.None,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.None,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: '(202) 555-0007',
|
||||||
|
phoneNumber: '(202) 555-0007',
|
||||||
|
id: '15',
|
||||||
|
type: 'direct',
|
||||||
|
isMe: true,
|
||||||
|
acceptedMessageRequest: true,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -352,14 +383,16 @@ export function Unaccepted(): JSX.Element {
|
||||||
title: '1:1 conversation',
|
title: '1:1 conversation',
|
||||||
props: {
|
props: {
|
||||||
...commonProps,
|
...commonProps,
|
||||||
color: getRandomColor(),
|
|
||||||
title: '(202) 555-0007',
|
|
||||||
phoneNumber: '(202) 555-0007',
|
|
||||||
id: '16',
|
|
||||||
type: 'direct',
|
|
||||||
isMe: false,
|
|
||||||
acceptedMessageRequest: false,
|
|
||||||
outgoingCallButtonStyle: OutgoingCallButtonStyle.None,
|
outgoingCallButtonStyle: OutgoingCallButtonStyle.None,
|
||||||
|
conversation: getDefaultConversation({
|
||||||
|
color: getRandomColor(),
|
||||||
|
title: '(202) 555-0007',
|
||||||
|
phoneNumber: '(202) 555-0007',
|
||||||
|
id: '16',
|
||||||
|
type: 'direct',
|
||||||
|
isMe: false,
|
||||||
|
acceptedMessageRequest: false,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
File diff suppressed because it is too large
Load diff
132
ts/hooks/useMinimalConversation.ts
Normal file
132
ts/hooks/useMinimalConversation.ts
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright 2024 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import type { ConversationType } from '../state/ducks/conversations';
|
||||||
|
|
||||||
|
type Primitive = undefined | null | boolean | number | bigint | string;
|
||||||
|
type PrimitiveObject = Record<string, Primitive>;
|
||||||
|
type Satisfies<Expected, Actual extends Expected> = Actual;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type is a subset of ConversationType that includes only the fields that
|
||||||
|
* are not updated frequently and can be shallow compared. This is useful for
|
||||||
|
* memoization, because it allows us to avoid re-rendering when the conversation
|
||||||
|
* changes in ways that don't affect the UI.
|
||||||
|
*
|
||||||
|
* You are welcome to add to this type, as long as the value is a primitive
|
||||||
|
* type (no objects or arrays), and it is not updated frequently.
|
||||||
|
*/
|
||||||
|
export type MinimalConversation = Satisfies<
|
||||||
|
PrimitiveObject,
|
||||||
|
Pick<
|
||||||
|
ConversationType,
|
||||||
|
| 'acceptedMessageRequest'
|
||||||
|
| 'announcementsOnly'
|
||||||
|
| 'areWeAdmin'
|
||||||
|
| 'avatarPath'
|
||||||
|
| 'canChangeTimer'
|
||||||
|
| 'color'
|
||||||
|
| 'expireTimer'
|
||||||
|
| 'groupVersion'
|
||||||
|
| 'id'
|
||||||
|
| 'isArchived'
|
||||||
|
| 'isBlocked'
|
||||||
|
| 'isMe'
|
||||||
|
| 'isPinned'
|
||||||
|
| 'isReported'
|
||||||
|
| 'isVerified'
|
||||||
|
| 'left'
|
||||||
|
| 'markedUnread'
|
||||||
|
| 'muteExpiresAt'
|
||||||
|
| 'name'
|
||||||
|
| 'phoneNumber'
|
||||||
|
| 'profileName'
|
||||||
|
| 'title'
|
||||||
|
| 'type'
|
||||||
|
| 'unblurredAvatarPath'
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
|
||||||
|
export function useMinimalConversation(
|
||||||
|
conversation: ConversationType
|
||||||
|
): MinimalConversation {
|
||||||
|
const {
|
||||||
|
acceptedMessageRequest,
|
||||||
|
announcementsOnly,
|
||||||
|
areWeAdmin,
|
||||||
|
avatarPath,
|
||||||
|
canChangeTimer,
|
||||||
|
color,
|
||||||
|
expireTimer,
|
||||||
|
groupVersion,
|
||||||
|
id,
|
||||||
|
isArchived,
|
||||||
|
isBlocked,
|
||||||
|
isMe,
|
||||||
|
isPinned,
|
||||||
|
isReported,
|
||||||
|
isVerified,
|
||||||
|
left,
|
||||||
|
markedUnread,
|
||||||
|
muteExpiresAt,
|
||||||
|
name,
|
||||||
|
phoneNumber,
|
||||||
|
profileName,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
unblurredAvatarPath,
|
||||||
|
} = conversation;
|
||||||
|
return useMemo(() => {
|
||||||
|
return {
|
||||||
|
acceptedMessageRequest,
|
||||||
|
announcementsOnly,
|
||||||
|
areWeAdmin,
|
||||||
|
avatarPath,
|
||||||
|
canChangeTimer,
|
||||||
|
color,
|
||||||
|
expireTimer,
|
||||||
|
groupVersion,
|
||||||
|
id,
|
||||||
|
isArchived,
|
||||||
|
isBlocked,
|
||||||
|
isMe,
|
||||||
|
isPinned,
|
||||||
|
isReported,
|
||||||
|
isVerified,
|
||||||
|
left,
|
||||||
|
markedUnread,
|
||||||
|
muteExpiresAt,
|
||||||
|
name,
|
||||||
|
phoneNumber,
|
||||||
|
profileName,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
unblurredAvatarPath,
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
acceptedMessageRequest,
|
||||||
|
announcementsOnly,
|
||||||
|
areWeAdmin,
|
||||||
|
avatarPath,
|
||||||
|
canChangeTimer,
|
||||||
|
color,
|
||||||
|
expireTimer,
|
||||||
|
groupVersion,
|
||||||
|
id,
|
||||||
|
isArchived,
|
||||||
|
isBlocked,
|
||||||
|
isMe,
|
||||||
|
isPinned,
|
||||||
|
isReported,
|
||||||
|
isVerified,
|
||||||
|
left,
|
||||||
|
markedUnread,
|
||||||
|
muteExpiresAt,
|
||||||
|
name,
|
||||||
|
phoneNumber,
|
||||||
|
profileName,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
unblurredAvatarPath,
|
||||||
|
]);
|
||||||
|
}
|
|
@ -1,43 +1,45 @@
|
||||||
// Copyright 2020 Signal Messenger, LLC
|
// Copyright 2020 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { memo, useMemo } from 'react';
|
import React, { memo, useCallback, useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { pick } from 'lodash';
|
import { useContactNameData } from '../../components/conversation/ContactName';
|
||||||
import type { ConversationType } from '../ducks/conversations';
|
|
||||||
import {
|
import {
|
||||||
ConversationHeader,
|
ConversationHeader,
|
||||||
OutgoingCallButtonStyle,
|
OutgoingCallButtonStyle,
|
||||||
} from '../../components/conversation/ConversationHeader';
|
} from '../../components/conversation/ConversationHeader';
|
||||||
import { getPreferredBadgeSelector } from '../selectors/badges';
|
import { getCannotLeaveBecauseYouAreLastAdmin } from '../../components/conversation/conversation-details/ConversationDetails';
|
||||||
import {
|
import { useMinimalConversation } from '../../hooks/useMinimalConversation';
|
||||||
getConversationByServiceIdSelector,
|
|
||||||
getConversationSelector,
|
|
||||||
getHasPanelOpen,
|
|
||||||
getSelectedMessageIds,
|
|
||||||
isMissingRequiredProfileSharing,
|
|
||||||
} from '../selectors/conversations';
|
|
||||||
import { CallMode } from '../../types/Calling';
|
import { CallMode } from '../../types/Calling';
|
||||||
|
import { PanelType } from '../../types/Panels';
|
||||||
|
import { StoryViewModeType } from '../../types/Stories';
|
||||||
|
import { strictAssert } from '../../util/assert';
|
||||||
|
import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPendingInvitation';
|
||||||
|
import { getGroupMemberships } from '../../util/getGroupMemberships';
|
||||||
|
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
||||||
|
import { isGroupOrAdhocCallState } from '../../util/isGroupOrAdhocCall';
|
||||||
|
import { isSignalConversation } from '../../util/isSignalConversation';
|
||||||
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import { useCallingActions } from '../ducks/calling';
|
import { useCallingActions } from '../ducks/calling';
|
||||||
import { isAnybodyElseInGroupCall } from '../ducks/callingHelpers';
|
import { isAnybodyElseInGroupCall } from '../ducks/callingHelpers';
|
||||||
|
import type { ConversationType } from '../ducks/conversations';
|
||||||
import {
|
import {
|
||||||
getConversationCallMode,
|
getConversationCallMode,
|
||||||
useConversationsActions,
|
useConversationsActions,
|
||||||
} from '../ducks/conversations';
|
} from '../ducks/conversations';
|
||||||
import { getHasStoriesSelector } from '../selectors/stories2';
|
|
||||||
import { getUserACI, getIntl, getTheme } from '../selectors/user';
|
|
||||||
import { isConversationSMSOnly } from '../../util/isConversationSMSOnly';
|
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
|
||||||
import { strictAssert } from '../../util/assert';
|
|
||||||
import { isSignalConversation } from '../../util/isSignalConversation';
|
|
||||||
import { useSearchActions } from '../ducks/search';
|
import { useSearchActions } from '../ducks/search';
|
||||||
import { useStoriesActions } from '../ducks/stories';
|
import { useStoriesActions } from '../ducks/stories';
|
||||||
import { getCannotLeaveBecauseYouAreLastAdmin } from '../../components/conversation/conversation-details/ConversationDetails';
|
import { getPreferredBadgeSelector } from '../selectors/badges';
|
||||||
import { getGroupMemberships } from '../../util/getGroupMemberships';
|
|
||||||
import { isGroupOrAdhocCallState } from '../../util/isGroupOrAdhocCall';
|
|
||||||
import { useContactNameData } from '../../components/conversation/ContactName';
|
|
||||||
import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPendingInvitation';
|
|
||||||
import { getActiveCallState, getCallSelector } from '../selectors/calling';
|
import { getActiveCallState, getCallSelector } from '../selectors/calling';
|
||||||
|
import {
|
||||||
|
getConversationByServiceIdSelector,
|
||||||
|
getConversationSelector,
|
||||||
|
getHasPanelOpen,
|
||||||
|
isMissingRequiredProfileSharing as getIsMissingRequiredProfileSharing,
|
||||||
|
getSelectedMessageIds,
|
||||||
|
} from '../selectors/conversations';
|
||||||
|
import { getHasStoriesSelector } from '../selectors/stories2';
|
||||||
|
import { getIntl, getTheme, getUserACI } from '../selectors/user';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -102,7 +104,6 @@ export const SmartConversationHeader = memo(function SmartConversationHeader({
|
||||||
onArchive,
|
onArchive,
|
||||||
onMarkUnread,
|
onMarkUnread,
|
||||||
onMoveToInbox,
|
onMoveToInbox,
|
||||||
popPanelForConversation,
|
|
||||||
pushPanelForConversation,
|
pushPanelForConversation,
|
||||||
setDisappearingMessages,
|
setDisappearingMessages,
|
||||||
setMuteExpiration,
|
setMuteExpiration,
|
||||||
|
@ -145,73 +146,149 @@ export const SmartConversationHeader = memo(function SmartConversationHeader({
|
||||||
const conversationName = useContactNameData(conversation);
|
const conversationName = useContactNameData(conversation);
|
||||||
strictAssert(conversationName, 'conversationName is required');
|
strictAssert(conversationName, 'conversationName is required');
|
||||||
|
|
||||||
|
const isMissingMandatoryProfileSharing =
|
||||||
|
getIsMissingRequiredProfileSharing(conversation);
|
||||||
|
|
||||||
|
const onConversationAccept = useCallback(() => {
|
||||||
|
acceptConversation(conversation.id);
|
||||||
|
}, [acceptConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationArchive = useCallback(() => {
|
||||||
|
onArchive(conversation.id);
|
||||||
|
}, [onArchive, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationBlock = useCallback(() => {
|
||||||
|
blockConversation(conversation.id);
|
||||||
|
}, [blockConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationBlockAndReportSpam = useCallback(() => {
|
||||||
|
blockAndReportSpam(conversation.id);
|
||||||
|
}, [blockAndReportSpam, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationDelete = useCallback(() => {
|
||||||
|
deleteConversation(conversation.id);
|
||||||
|
}, [deleteConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationDeleteMessages = useCallback(() => {
|
||||||
|
destroyMessages(conversation.id);
|
||||||
|
}, [destroyMessages, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationDisappearingMessagesChange = useCallback(
|
||||||
|
seconds => {
|
||||||
|
setDisappearingMessages(conversation.id, seconds);
|
||||||
|
},
|
||||||
|
[setDisappearingMessages, conversation.id]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onConversationLeaveGroup = useCallback(() => {
|
||||||
|
leaveGroup(conversation.id);
|
||||||
|
}, [leaveGroup, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationMarkUnread = useCallback(() => {
|
||||||
|
onMarkUnread(conversation.id);
|
||||||
|
}, [onMarkUnread, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationMuteExpirationChange = useCallback(
|
||||||
|
seconds => {
|
||||||
|
setMuteExpiration(conversation.id, seconds);
|
||||||
|
},
|
||||||
|
[setMuteExpiration, conversation.id]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onConversationPin = useCallback(() => {
|
||||||
|
setPinned(conversation.id, true);
|
||||||
|
}, [setPinned, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationReportSpam = useCallback(() => {
|
||||||
|
reportSpam(conversation.id);
|
||||||
|
}, [reportSpam, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationUnarchive = useCallback(() => {
|
||||||
|
onMoveToInbox(conversation.id);
|
||||||
|
}, [onMoveToInbox, conversation.id]);
|
||||||
|
|
||||||
|
const onConversationUnpin = useCallback(() => {
|
||||||
|
setPinned(conversation.id, false);
|
||||||
|
}, [setPinned, conversation.id]);
|
||||||
|
|
||||||
|
const onOutgoingAudioCall = useCallback(() => {
|
||||||
|
onOutgoingAudioCallInConversation(conversation.id);
|
||||||
|
}, [onOutgoingAudioCallInConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onOutgoingVideoCall = useCallback(() => {
|
||||||
|
onOutgoingVideoCallInConversation(conversation.id);
|
||||||
|
}, [onOutgoingVideoCallInConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onSearchInConversation = useCallback(() => {
|
||||||
|
searchInConversation(conversation.id);
|
||||||
|
}, [searchInConversation, conversation.id]);
|
||||||
|
|
||||||
|
const onSelectModeEnter = useCallback(() => {
|
||||||
|
toggleSelectMode(true);
|
||||||
|
}, [toggleSelectMode]);
|
||||||
|
|
||||||
|
const onShowMembers = useCallback(() => {
|
||||||
|
pushPanelForConversation({ type: PanelType.GroupV1Members });
|
||||||
|
}, [pushPanelForConversation]);
|
||||||
|
|
||||||
|
const onViewConversationDetails = useCallback(() => {
|
||||||
|
pushPanelForConversation({ type: PanelType.ConversationDetails });
|
||||||
|
}, [pushPanelForConversation]);
|
||||||
|
|
||||||
|
const onViewRecentMedia = useCallback(() => {
|
||||||
|
pushPanelForConversation({ type: PanelType.AllMedia });
|
||||||
|
}, [pushPanelForConversation]);
|
||||||
|
|
||||||
|
const onViewUserStories = useCallback(() => {
|
||||||
|
viewUserStories({
|
||||||
|
conversationId: conversation.id,
|
||||||
|
storyViewMode: StoryViewModeType.User,
|
||||||
|
});
|
||||||
|
}, [viewUserStories, conversation.id]);
|
||||||
|
|
||||||
|
const minimalConversation = useMinimalConversation(conversation);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConversationHeader
|
<ConversationHeader
|
||||||
{...pick(conversation, [
|
addedByName={addedByName}
|
||||||
'acceptedMessageRequest',
|
|
||||||
'announcementsOnly',
|
|
||||||
'areWeAdmin',
|
|
||||||
'avatarPath',
|
|
||||||
'canChangeTimer',
|
|
||||||
'color',
|
|
||||||
'expireTimer',
|
|
||||||
'groupVersion',
|
|
||||||
'isArchived',
|
|
||||||
'isMe',
|
|
||||||
'isPinned',
|
|
||||||
'isVerified',
|
|
||||||
'left',
|
|
||||||
'markedUnread',
|
|
||||||
'muteExpiresAt',
|
|
||||||
'name',
|
|
||||||
'phoneNumber',
|
|
||||||
'profileName',
|
|
||||||
'sharedGroupNames',
|
|
||||||
'title',
|
|
||||||
'type',
|
|
||||||
'unblurredAvatarPath',
|
|
||||||
])}
|
|
||||||
badge={badge}
|
badge={badge}
|
||||||
cannotLeaveBecauseYouAreLastAdmin={cannotLeaveBecauseYouAreLastAdmin}
|
cannotLeaveBecauseYouAreLastAdmin={cannotLeaveBecauseYouAreLastAdmin}
|
||||||
destroyMessages={destroyMessages}
|
conversation={minimalConversation}
|
||||||
|
conversationName={conversationName}
|
||||||
hasPanelShowing={hasPanelShowing}
|
hasPanelShowing={hasPanelShowing}
|
||||||
hasStories={hasStories}
|
hasStories={hasStories}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
id={id}
|
isMissingMandatoryProfileSharing={isMissingMandatoryProfileSharing}
|
||||||
isMissingMandatoryProfileSharing={isMissingRequiredProfileSharing(
|
isSelectMode={isSelectMode}
|
||||||
conversation
|
|
||||||
)}
|
|
||||||
isSignalConversation={isSignalConversation(conversation)}
|
isSignalConversation={isSignalConversation(conversation)}
|
||||||
isSMSOnly={isConversationSMSOnly(conversation)}
|
isSMSOnly={isConversationSMSOnly(conversation)}
|
||||||
leaveGroup={leaveGroup}
|
onConversationAccept={onConversationAccept}
|
||||||
onArchive={onArchive}
|
onConversationArchive={onConversationArchive}
|
||||||
onMarkUnread={onMarkUnread}
|
onConversationBlock={onConversationBlock}
|
||||||
onMoveToInbox={onMoveToInbox}
|
onConversationBlockAndReportSpam={onConversationBlockAndReportSpam}
|
||||||
onOutgoingAudioCallInConversation={onOutgoingAudioCallInConversation}
|
onConversationDelete={onConversationDelete}
|
||||||
onOutgoingVideoCallInConversation={onOutgoingVideoCallInConversation}
|
onConversationDeleteMessages={onConversationDeleteMessages}
|
||||||
|
onConversationDisappearingMessagesChange={
|
||||||
|
onConversationDisappearingMessagesChange
|
||||||
|
}
|
||||||
|
onConversationLeaveGroup={onConversationLeaveGroup}
|
||||||
|
onConversationMarkUnread={onConversationMarkUnread}
|
||||||
|
onConversationMuteExpirationChange={onConversationMuteExpirationChange}
|
||||||
|
onConversationPin={onConversationPin}
|
||||||
|
onConversationReportSpam={onConversationReportSpam}
|
||||||
|
onConversationUnarchive={onConversationUnarchive}
|
||||||
|
onConversationUnpin={onConversationUnpin}
|
||||||
|
onOutgoingAudioCall={onOutgoingAudioCall}
|
||||||
|
onOutgoingVideoCall={onOutgoingVideoCall}
|
||||||
|
onSearchInConversation={onSearchInConversation}
|
||||||
|
onSelectModeEnter={onSelectModeEnter}
|
||||||
|
onShowMembers={onShowMembers}
|
||||||
|
onViewConversationDetails={onViewConversationDetails}
|
||||||
|
onViewRecentMedia={onViewRecentMedia}
|
||||||
|
onViewUserStories={onViewUserStories}
|
||||||
outgoingCallButtonStyle={outgoingCallButtonStyle}
|
outgoingCallButtonStyle={outgoingCallButtonStyle}
|
||||||
popPanelForConversation={popPanelForConversation}
|
sharedGroupNames={conversation.sharedGroupNames}
|
||||||
pushPanelForConversation={pushPanelForConversation}
|
|
||||||
searchInConversation={searchInConversation}
|
|
||||||
setDisappearingMessages={setDisappearingMessages}
|
|
||||||
setMuteExpiration={setMuteExpiration}
|
|
||||||
setPinned={setPinned}
|
|
||||||
theme={theme}
|
theme={theme}
|
||||||
isSelectMode={isSelectMode}
|
|
||||||
toggleSelectMode={toggleSelectMode}
|
|
||||||
viewUserStories={viewUserStories}
|
|
||||||
// MessageRequestActionsConfirmation
|
|
||||||
addedByName={addedByName}
|
|
||||||
conversationId={id}
|
|
||||||
conversationType={conversation.type}
|
|
||||||
conversationName={conversationName}
|
|
||||||
isBlocked={conversation.isBlocked ?? false}
|
|
||||||
isReported={conversation.isReported ?? false}
|
|
||||||
acceptConversation={acceptConversation}
|
|
||||||
blockAndReportSpam={blockAndReportSpam}
|
|
||||||
blockConversation={blockConversation}
|
|
||||||
reportSpam={reportSpam}
|
|
||||||
deleteConversation={deleteConversation}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ export type MuteOption = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getMuteOptions(
|
export function getMuteOptions(
|
||||||
muteExpiresAt: undefined | number,
|
muteExpiresAt: null | undefined | number,
|
||||||
i18n: LocalizerType
|
i18n: LocalizerType
|
||||||
): Array<MuteOption> {
|
): Array<MuteOption> {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -3520,20 +3520,18 @@
|
||||||
"updated": "2023-12-08T20:28:57.595Z"
|
"updated": "2023-12-08T20:28:57.595Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-createRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||||
"line": " this.menuTriggerRef = React.createRef();",
|
"line": " const menuTriggerRef = useRef<any>(null);",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-05-20T20:10:43.540Z",
|
"updated": "2024-03-15T18:29:48.327Z"
|
||||||
"reasonDetail": "Used to reference popup menu"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-createRef",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||||
"line": " this.headerRef = React.createRef();",
|
"line": " const headerRef = useRef<HTMLDivElement>(null);",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-01-18T22:24:05.937Z",
|
"updated": "2024-03-15T18:29:48.327Z"
|
||||||
"reasonDetail": "Used to reference popup menu boundaries element"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rule": "React-useRef",
|
"rule": "React-useRef",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue