import { Box, Button, ButtonGroup, Margins, TextInput, Field, FieldGroup, FieldLabel, FieldRow, FieldError, IconButton, } from '@rocket.chat/fuselage'; import { GenericModal, ContextualbarScrollableContent, ContextualbarFooter } from '@rocket.chat/ui-client'; import { useSetModal, useAbsoluteUrl, useToastMessageDispatch } from '@rocket.chat/ui-contexts'; import { useQueryClient } from '@tanstack/react-query'; import type { ChangeEvent } from 'react'; import { useCallback, useState, useMemo, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useEndpointMutation } from '../../../hooks/useEndpointMutation'; import { useEndpointUploadMutation } from '../../../hooks/useEndpointUploadMutation'; import { useSingleFileInput } from '../../../hooks/useSingleFileInput'; export type EditCustomEmojiProps = { close: () => void; onChange: () => void; data: { _id: string; name: string; aliases: string[]; extension: string; etag?: string; }; }; const EditCustomEmoji = ({ close, onChange, data, ...props }: EditCustomEmojiProps) => { const { t } = useTranslation(); const setModal = useSetModal(); const absoluteUrl = useAbsoluteUrl(); const queryClient = useQueryClient(); const [errors, setErrors] = useState({ name: false, aliases: false }); const { _id, name: previousName, aliases: previousAliases } = data || {}; const [name, setName] = useState(() => data?.name ?? ''); const [aliases, setAliases] = useState(() => data?.aliases?.join(', ') ?? ''); const [emojiFile, setEmojiFile] = useState(); const newEmojiPreview = useMemo(() => { if (emojiFile) { return URL.createObjectURL(emojiFile); } if (data) { return absoluteUrl(`/emoji-custom/${encodeURIComponent(data.name)}.${data.extension}${data.etag ? `?etag=${data.etag}` : ''}`); } return null; }, [absoluteUrl, data, emojiFile]); useEffect(() => { setName(previousName || ''); setAliases(previousAliases?.join(', ') || ''); }, [previousName, previousAliases, _id]); const hasUnsavedChanges = useMemo( () => previousName !== name || aliases !== previousAliases.join(', ') || !!emojiFile, [previousName, name, aliases, previousAliases, emojiFile], ); const { mutateAsync: saveAction } = useEndpointUploadMutation('/v1/emoji-custom.update', { onSuccess: () => { dispatchToastMessage({ type: 'success', message: t('Custom_Emoji_Updated_Successfully') }); queryClient.invalidateQueries({ queryKey: ['emoji-custom.list'] }); onChange(); close(); }, }); const handleSave = useCallback(async () => { if (!name) { return setErrors((prevState) => ({ ...prevState, name: true })); } if (name === aliases) { return setErrors((prevState) => ({ ...prevState, aliases: true })); } if (!emojiFile && !newEmojiPreview) { return; } const formData = new FormData(); emojiFile && formData.append('emoji', emojiFile); formData.append('_id', _id); formData.append('name', name); formData.append('aliases', aliases); await saveAction(formData); }, [emojiFile, _id, name, aliases, saveAction, newEmojiPreview]); const dispatchToastMessage = useToastMessageDispatch(); const { mutateAsync: deleteAction } = useEndpointMutation('POST', '/v1/emoji-custom.delete', { onSuccess: () => { dispatchToastMessage({ type: 'success', message: t('Custom_Emoji_Has_Been_Deleted') }); queryClient.invalidateQueries({ queryKey: ['emoji-custom.list'] }); }, onSettled: () => { onChange(); setModal(null); close(); }, }); const handleDeleteButtonClick = useCallback(() => { const handleDelete = async () => { await deleteAction({ emojiId: _id }); }; const handleCancel = () => { setModal(null); }; setModal( {t('Custom_Emoji_Delete_Warning')} , ); }, [setModal, deleteAction, _id, t]); const handleChangeAliases = useCallback( (e: ChangeEvent) => { if (e.currentTarget.value !== name) { setErrors((prevState) => ({ ...prevState, aliases: false })); } return setAliases(e.currentTarget.value); }, [setAliases, name], ); const [clickUpload] = useSingleFileInput(setEmojiFile, 'emoji'); const handleChangeName = (e: ChangeEvent): void => { if (e.currentTarget.value !== '') { setErrors((prevState) => ({ ...prevState, name: false })); } return setName(e.currentTarget.value); }; return ( <> {t('Name')} {errors.name && {t('Required_field', { field: t('Name') })}} {t('Aliases')} {errors.aliases && {t('Custom_Emoji_Error_Same_Name_And_Alias')}} {t('Custom_Emoji')} {newEmojiPreview && ( )} ); }; export default EditCustomEmoji;