signal-desktop/ts/hooks/useMinimalConversation.ts

132 lines
2.7 KiB
TypeScript

// 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,
]);
}