// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { FormEventHandler, FunctionComponent, useCallback, useRef, useState, } from 'react'; import { LocalizerType } from '../../../types/Util'; import { Modal } from '../../Modal'; import { AvatarInputContainer } from '../../AvatarInputContainer'; import { AvatarInputVariant } from '../../AvatarInput'; import { Button, ButtonVariant } from '../../Button'; import { Spinner } from '../../Spinner'; import { GroupDescriptionInput } from '../../GroupDescriptionInput'; import { GroupTitleInput } from '../../GroupTitleInput'; import { RequestState } from './util'; const TEMPORARY_AVATAR_VALUE = new ArrayBuffer(0); type PropsType = { avatarPath?: string; groupDescription?: string; i18n: LocalizerType; initiallyFocusDescription: boolean; makeRequest: ( _: Readonly<{ avatar?: undefined | ArrayBuffer; description?: string; title?: undefined | string; }> ) => void; onClose: () => void; requestState: RequestState; title: string; }; export const EditConversationAttributesModal: FunctionComponent = ({ avatarPath: externalAvatarPath, groupDescription: externalGroupDescription = '', i18n, initiallyFocusDescription, makeRequest, onClose, requestState, title: externalTitle, }) => { const focusDescriptionRef = useRef( initiallyFocusDescription ); const focusDescription = focusDescriptionRef.current; const startingTitleRef = useRef(externalTitle); const startingAvatarPathRef = useRef(externalAvatarPath); const [avatar, setAvatar] = useState( externalAvatarPath ? TEMPORARY_AVATAR_VALUE : undefined ); const [rawTitle, setRawTitle] = useState(externalTitle); const [rawGroupDescription, setRawGroupDescription] = useState( externalGroupDescription ); const [hasAvatarChanged, setHasAvatarChanged] = useState(false); const trimmedTitle = rawTitle.trim(); const trimmedDescription = rawGroupDescription.trim(); const focusRef = (el: null | HTMLElement) => { if (el) { el.focus(); focusDescriptionRef.current = undefined; } }; const hasChangedExternally = startingAvatarPathRef.current !== externalAvatarPath || startingTitleRef.current !== externalTitle; const hasTitleChanged = trimmedTitle !== externalTitle.trim(); const hasGroupDescriptionChanged = externalGroupDescription.trim() !== trimmedDescription; const isRequestActive = requestState === RequestState.Active; const canSubmit = !isRequestActive && (hasChangedExternally || hasTitleChanged || hasAvatarChanged || hasGroupDescriptionChanged) && trimmedTitle.length > 0; const onSubmit: FormEventHandler = event => { event.preventDefault(); const request: { avatar?: undefined | ArrayBuffer; description?: string; title?: string; } = {}; if (hasAvatarChanged) { request.avatar = avatar; } if (hasTitleChanged) { request.title = trimmedTitle; } if (hasGroupDescriptionChanged) { request.description = trimmedDescription; } makeRequest(request); }; const handleAvatarLoaded = useCallback( loadedAvatar => { setAvatar(loadedAvatar); }, [setAvatar] ); return (
{ setAvatar(newAvatar); setHasAvatarChanged(true); }} onAvatarLoaded={handleAvatarLoaded} variant={AvatarInputVariant.Dark} />
{i18n('EditConversationAttributesModal__description-warning')}
{requestState === RequestState.InactiveWithError && (
{i18n('updateGroupAttributes__error-message')}
)}
); };