// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { ReactChild } from 'react'; import React from 'react'; import { LeftPaneHelper } from './LeftPaneHelper'; import type { Row } from '../ConversationList'; import { RowType } from '../ConversationList'; import type { ContactListItemConversationType } from '../conversationList/ContactListItem'; import { DisappearingTimerSelect } from '../DisappearingTimerSelect'; import type { LocalizerType } from '../../types/Util'; import type { DurationInSeconds } from '../../util/durations'; import { Alert } from '../Alert'; import { AvatarEditor } from '../AvatarEditor'; import { AvatarPreview } from '../AvatarPreview'; import { Spinner } from '../Spinner'; import { Button } from '../Button'; import { Modal } from '../Modal'; import { GroupTitleInput } from '../GroupTitleInput'; import type { AvatarDataType, DeleteAvatarFromDiskActionType, ReplaceAvatarActionType, SaveAvatarToDiskActionType, } from '../../types/Avatar'; import { AvatarColors } from '../../types/Colors'; export type LeftPaneSetGroupMetadataPropsType = { groupAvatar: undefined | Uint8Array; groupName: string; groupExpireTimer: DurationInSeconds; hasError: boolean; isCreating: boolean; isEditingAvatar: boolean; selectedContacts: ReadonlyArray; userAvatarData: ReadonlyArray; }; export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper { private readonly groupAvatar: undefined | Uint8Array; private readonly groupName: string; private readonly groupExpireTimer: DurationInSeconds; private readonly hasError: boolean; private readonly isCreating: boolean; private readonly isEditingAvatar: boolean; private readonly selectedContacts: ReadonlyArray; private readonly userAvatarData: ReadonlyArray; constructor({ groupAvatar, groupName, groupExpireTimer, hasError, isCreating, isEditingAvatar, selectedContacts, userAvatarData, }: Readonly) { super(); this.groupAvatar = groupAvatar; this.groupName = groupName; this.groupExpireTimer = groupExpireTimer; this.hasError = hasError; this.isCreating = isCreating; this.isEditingAvatar = isEditingAvatar; this.selectedContacts = selectedContacts; this.userAvatarData = userAvatarData; } override getHeaderContents({ i18n, showChooseGroupMembers, }: Readonly<{ i18n: LocalizerType; showChooseGroupMembers: () => void; }>): ReactChild { const backButtonLabel = i18n('setGroupMetadata__back-button'); return (
); } override getBackAction({ showChooseGroupMembers, }: { showChooseGroupMembers: () => void; }): undefined | (() => void) { return this.isCreating ? undefined : showChooseGroupMembers; } override getPreRowsNode({ clearGroupCreationError, composeDeleteAvatarFromDisk, composeReplaceAvatar, composeSaveAvatarToDisk, createGroup, i18n, setComposeGroupAvatar, setComposeGroupExpireTimer, setComposeGroupName, toggleComposeEditingAvatar, }: Readonly<{ clearGroupCreationError: () => unknown; composeDeleteAvatarFromDisk: DeleteAvatarFromDiskActionType; composeReplaceAvatar: ReplaceAvatarActionType; composeSaveAvatarToDisk: SaveAvatarToDiskActionType; createGroup: () => unknown; i18n: LocalizerType; setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown; setComposeGroupExpireTimer: (_: DurationInSeconds) => void; setComposeGroupName: (_: string) => unknown; toggleComposeEditingAvatar: () => unknown; }>): ReactChild { const [avatarColor] = AvatarColors; const disabled = this.isCreating; return (
{ event.preventDefault(); event.stopPropagation(); if (!this.canCreateGroup()) { return; } createGroup(); }} > {this.isEditingAvatar && ( { setComposeGroupAvatar(newAvatar); toggleComposeEditingAvatar(); }} userAvatarData={this.userAvatarData} replaceAvatar={composeReplaceAvatar} saveAvatarToDisk={composeSaveAvatarToDisk} /> )}
{i18n('icu:disappearingMessages')}
{this.hasError && ( )} ); } override getFooterContents({ createGroup, i18n, }: Readonly<{ createGroup: () => unknown; i18n: LocalizerType; }>): ReactChild { return ( ); } getRowCount(): number { if (!this.selectedContacts.length) { return 0; } return this.selectedContacts.length + 2; } getRow(rowIndex: number): undefined | Row { if (!this.selectedContacts.length) { return undefined; } if (rowIndex === 0) { return { type: RowType.Header, i18nKey: 'setGroupMetadata__members-header', }; } // This puts a blank row for the footer. if (rowIndex === this.selectedContacts.length + 1) { return { type: RowType.Blank }; } const contact = this.selectedContacts[rowIndex - 1]; return contact ? { type: RowType.Contact, contact, isClickable: false, } : undefined; } // This is deliberately unimplemented because these keyboard shortcuts shouldn't work in // the composer. The same is true for the "in direction" function below. getConversationAndMessageAtIndex( ..._args: ReadonlyArray ): undefined { return undefined; } getConversationAndMessageInDirection( ..._args: ReadonlyArray ): undefined { return undefined; } shouldRecomputeRowHeights(_old: unknown): boolean { return false; } private canCreateGroup(): boolean { return !this.isCreating && Boolean(this.groupName.trim()); } } function focusRef(el: HTMLElement | null) { if (el) { el.focus(); } }