import React, { useCallback, useState, useMemo, useEffect } from 'react'; import { Box, Button, ButtonGroup, Margins, TextInput, Field, Icon, Skeleton, Throbber, InputBox } from '@rocket.chat/fuselage'; import { useTranslation } from '../../contexts/TranslationContext'; import { useMethod } from '../../contexts/ServerContext'; import { useToastMessageDispatch } from '../../contexts/ToastMessagesContext'; import { Modal } from '../../components/basic/Modal'; import { useFileInput } from '../../hooks/useFileInput'; import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../hooks/useEndpointDataExperimental'; import { validate, createSoundData } from './lib'; import VerticalBar from '../../components/basic/VerticalBar'; const DeleteWarningModal = ({ onDelete, onCancel, ...props }) => { const t = useTranslation(); return {t('Are_you_sure')} {t('Custom_Sound_Delete_Warning')} ; }; const SuccessModal = ({ onClose, ...props }) => { const t = useTranslation(); return {t('Deleted')} {t('Custom_Sound_Has_Been_Deleted')} ; }; export function EditCustomSound({ _id, cache, ...props }) { const query = useMemo(() => ({ query: JSON.stringify({ _id }), }), [_id]); const { data, state, error } = useEndpointDataExperimental('custom-sounds.list', query); if (state === ENDPOINT_STATES.LOADING) { return ; } if (error || !data || data.sounds.length < 1) { return {error}; } return ; } function EditSound({ close, onChange, data, ...props }) { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); const { _id, name: previousName } = data || {}; const previousSound = data || {}; const [name, setName] = useState(''); const [sound, setSound] = useState(); const [modal, setModal] = useState(); useEffect(() => { setName(previousName || ''); setSound(previousSound || ''); }, [previousName, previousSound, _id]); const deleteCustomSound = useMethod('deleteCustomSound'); const uploadCustomSound = useMethod('uploadCustomSound'); const insertOrUpdateSound = useMethod('insertOrUpdateSound'); const handleChangeFile = useCallback((soundFile) => { setSound(soundFile); }, []); const hasUnsavedChanges = useMemo(() => previousName !== name || previousSound !== sound, [name, previousName, previousSound, sound]); const saveAction = useCallback(async (sound) => { const soundData = createSoundData(sound, name, { previousName, previousSound, _id }); const validation = validate(soundData, sound); if (validation.length === 0) { let soundId; try { soundId = await insertOrUpdateSound(soundData); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } soundData._id = soundId; soundData.random = Math.round(Math.random() * 1000); if (sound && sound !== previousSound) { dispatchToastMessage({ type: 'success', message: t('Uploading_file') }); const reader = new FileReader(); reader.readAsBinaryString(sound); reader.onloadend = () => { try { uploadCustomSound(reader.result, sound.type, soundData); return dispatchToastMessage({ type: 'success', message: t('File_uploaded') }); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } }; } } validation.forEach((error) => dispatchToastMessage({ type: 'error', message: t('error-the-field-is-required', { field: t(error) }) })); }, [_id, dispatchToastMessage, insertOrUpdateSound, name, previousName, previousSound, t, uploadCustomSound]); const handleSave = useCallback(async () => { saveAction(sound); onChange(); }, [saveAction, sound, onChange]); const onDeleteConfirm = useCallback(async () => { try { await deleteCustomSound(_id); setModal(() => { setModal(undefined); close(); onChange(); }}/>); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); onChange(); } }, [_id, close, deleteCustomSound, dispatchToastMessage, onChange]); const openConfirmDelete = () => setModal(() => setModal(undefined)}/>); const clickUpload = useFileInput(handleChangeFile, 'audio/mp3'); return <> {t('Name')} setName(e.currentTarget.value)} placeholder={t('Name')} /> {t('Sound_File_mp3')} {(sound && sound.name) || 'none'} { modal } ; }