import type { ChangeEvent } from 'react'; import type { FC } from '../../../lib/teact/teact'; import React, { memo, useEffect, useMemo, useRef, useState, } from '../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../global'; import type { ApiBotInfo, ApiUser } from '../../../api/types'; import { ApiMediaFormat } from '../../../api/types'; import { ManagementProgress } from '../../../types'; import { getChatAvatarHash, getMainUsername, getUserFirstOrLastName, } from '../../../global/helpers'; import { selectBot, selectTabState, selectUserFullInfo, } from '../../../global/selectors'; import { selectCurrentLimit } from '../../../global/selectors/limits'; import renderText from '../../common/helpers/renderText'; import useFlag from '../../../hooks/useFlag'; import useHistoryBack from '../../../hooks/useHistoryBack'; import useLastCallback from '../../../hooks/useLastCallback'; import useMedia from '../../../hooks/useMedia'; import useOldLang from '../../../hooks/useOldLang'; import Icon from '../../common/icons/Icon'; import AvatarEditable from '../../ui/AvatarEditable'; import FloatingActionButton from '../../ui/FloatingActionButton'; import InputText from '../../ui/InputText'; import ListItem from '../../ui/ListItem'; import SelectAvatar from '../../ui/SelectAvatar'; import Spinner from '../../ui/Spinner'; import TextArea from '../../ui/TextArea'; import './Management.scss'; type OwnProps = { userId: string; onClose: NoneToVoidFunction; isActive: boolean; }; type StateProps = { userId?: string; user?: ApiUser; chatBot?: ApiBotInfo; currentBio?: string; progress?: ManagementProgress; isMuted?: boolean; maxBioLength: number; }; const ERROR_NAME_MISSING = 'Please provide name'; const ManageBot: FC = ({ userId, user, progress, onClose, currentBio, isActive, maxBioLength, }) => { const { setBotInfo, uploadProfilePhoto, uploadContactProfilePhoto, startBotFatherConversation, } = getActions(); const [isFieldTouched, markFieldTouched, unmarkProfileTouched] = useFlag(false); const [isAvatarTouched, markAvatarTouched, unmarkAvatarTouched] = useFlag(false); const [error, setError] = useState(); const lang = useOldLang(); const username = useMemo(() => (user ? getMainUsername(user) : undefined), [user]); useHistoryBack({ isActive, onBack: onClose, }); const currentName = user ? getUserFirstOrLastName(user) : ''; const [photo, setPhoto] = useState(); const [name, setName] = useState(currentName || ''); const [bio, setBio] = useState(currentBio || ''); const currentAvatarHash = user && getChatAvatarHash(user); const currentAvatarBlobUrl = useMedia(currentAvatarHash, false, ApiMediaFormat.BlobUrl); useEffect(() => { unmarkProfileTouched(); unmarkAvatarTouched(); }, [userId]); useEffect(() => { setName(currentName || ''); setBio(currentBio || ''); }, [currentName, currentBio, user]); useEffect(() => { setPhoto(undefined); }, [currentAvatarBlobUrl]); useEffect(() => { if (progress === ManagementProgress.Complete) { unmarkProfileTouched(); unmarkAvatarTouched(); setError(undefined); } }, [progress]); const handleNameChange = useLastCallback((e: ChangeEvent) => { setName(e.target.value); markFieldTouched(); if (error === ERROR_NAME_MISSING) { setError(undefined); } }); const handleBioChange = useLastCallback((e: ChangeEvent) => { setBio(e.target.value); markFieldTouched(); }); const handlePhotoChange = useLastCallback((newPhoto: File) => { setPhoto(newPhoto); markAvatarTouched(); }); const handleProfileSave = useLastCallback(() => { const trimmedName = name.trim(); const trimmedBio = bio.trim(); if (!trimmedName.length) { setError(ERROR_NAME_MISSING); return; } setBotInfo({ ...(isFieldTouched && { bot: user, name: trimmedName, description: trimmedBio, }), }); if (photo) { uploadProfilePhoto({ file: photo, ...(isAvatarTouched && { bot: user }), }); } }); const handleChangeEditIntro = useLastCallback(() => { startBotFatherConversation({ param: `${username}-intro` }); }); const handleChangeEditCommands = useLastCallback(() => { startBotFatherConversation({ param: `${username}-commands` }); }); const handleChangeSettings = useLastCallback(() => { startBotFatherConversation({ param: `${username}` }); }); // eslint-disable-next-line no-null/no-null const inputRef = useRef(null); const isSuggestRef = useRef(false); const handleSelectAvatar = useLastCallback((file: File) => { markAvatarTouched(); uploadContactProfilePhoto({ userId, file, isSuggest: isSuggestRef.current }); }); if (!user) { return undefined; } const isLoading = progress === ManagementProgress.InProgress; return (