// Copyright 2024 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 { SearchInput } from '../SearchInput'; import type { LocalizerType } from '../../types/Util'; import type { ShowConversationType } from '../../state/ducks/conversations'; import type { ParsedE164Type } from '../../util/libphonenumberInstance'; import { parseAndFormatPhoneNumber } from '../../util/libphonenumberInstance'; import type { UUIDFetchStateType } from '../../util/uuidFetchState'; import type { CountryDataType } from '../../util/getCountryData'; import { isFetchingByE164 } from '../../util/uuidFetchState'; import { drop } from '../../util/drop'; import type { LookupConversationWithoutServiceIdActionsType } from '../../util/lookupConversationWithoutServiceId'; import { Spinner } from '../Spinner'; import { Button } from '../Button'; import { CountryCodeSelect } from '../CountryCodeSelect'; export type LeftPaneFindByPhoneNumberPropsType = { searchTerm: string; regionCode: string | undefined; uuidFetchState: UUIDFetchStateType; selectedRegion: string; countries: ReadonlyArray; }; type DoLookupActionsType = Readonly<{ showInbox: () => void; showConversation: ShowConversationType; }> & LookupConversationWithoutServiceIdActionsType; export class LeftPaneFindByPhoneNumberHelper extends LeftPaneHelper { private readonly searchTerm: string; private readonly phoneNumber: ParsedE164Type | undefined; private readonly regionCode: string | undefined; private readonly uuidFetchState: UUIDFetchStateType; private readonly countries: ReadonlyArray; private readonly selectedRegion: string; constructor({ searchTerm, regionCode, uuidFetchState, countries, selectedRegion, }: Readonly) { super(); this.searchTerm = searchTerm; this.uuidFetchState = uuidFetchState; this.regionCode = regionCode; this.countries = countries; this.selectedRegion = selectedRegion; this.phoneNumber = parseAndFormatPhoneNumber( this.searchTerm, selectedRegion || regionCode ); } override getHeaderContents({ i18n, startComposing, }: Readonly<{ i18n: LocalizerType; startComposing: () => void; }>): ReactChild { const backButtonLabel = i18n('icu:setGroupMetadata__back-button'); return (
); } override getBackAction({ startComposing, }: { startComposing: () => void; }): undefined | (() => void) { return this.isFetching() ? undefined : startComposing; } override getSearchInput({ i18n, onChangeComposeSearchTerm, onChangeComposeSelectedRegion, ...lookupActions }: Readonly<{ i18n: LocalizerType; onChangeComposeSearchTerm: ( event: React.ChangeEvent ) => unknown; onChangeComposeSelectedRegion: (newRegion: string) => void; }> & DoLookupActionsType): ReactChild { const placeholder = i18n( 'icu:LeftPaneFindByHelper__placeholder--findByPhoneNumber' ); return (
{ if (ev.key === 'Enter') { drop(this.doLookup(lookupActions)); } }} />
); } override getFooterContents({ i18n, ...lookupActions }: Readonly<{ i18n: LocalizerType; }> & DoLookupActionsType): ReactChild { return ( ); } getRowCount(): number { return 1; } getRow(): Row { // This puts a blank row for the footer. return { type: RowType.Blank }; } // 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 async doLookup({ lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, showInbox, showConversation, }: DoLookupActionsType): Promise { if (!this.phoneNumber || this.isLookupDisabled()) { return; } const conversationId = await lookupConversationWithoutServiceId({ showUserNotFoundModal, setIsFetchingUUID, type: 'e164', e164: this.phoneNumber.e164, phoneNumber: this.searchTerm, }); if (conversationId != null) { showConversation({ conversationId }); showInbox(); } } private isFetching(): boolean { if (this.phoneNumber != null) { return isFetchingByE164(this.uuidFetchState, this.phoneNumber.e164); } return false; } private isLookupDisabled(): boolean { if (this.isFetching()) { return true; } return !this.phoneNumber?.isValid; } } function focusRef(el: HTMLElement | null) { if (el) { el.focus(); } }