import { isDirectMessageRoom } from '@rocket.chat/core-typings'; import { useStableCallback } from '@rocket.chat/fuselage-hooks'; import { GenericModal } from '@rocket.chat/ui-client'; import { useSetModal, useToastMessageDispatch, useEndpoint, useRoomToolbox } from '@rocket.chat/ui-contexts'; import { useCallback, useMemo, useState } from 'react'; import { useForm, FormProvider } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import PruneMessages from './PruneMessages'; import { formatDate } from '../../../../lib/utils/dateFormat'; import { useRoom } from '../../contexts/RoomContext'; const getTimeZoneOffset = (): string => { const offset = new Date().getTimezoneOffset(); const absOffset = Math.abs(offset); return `${offset < 0 ? '+' : '-'}${`00${Math.floor(absOffset / 60)}`.slice(-2)}:${`00${absOffset % 60}`.slice(-2)}`; }; export const initialValues = { newer: { date: '', time: '', }, older: { date: '', time: '', }, users: [], inclusive: false, pinned: false, discussion: false, threads: false, attached: false, }; const DEFAULT_PRUNE_LIMIT = 2000; const PruneMessagesWithData = () => { const { t } = useTranslation(); const room = useRoom(); const setModal = useSetModal(); const { closeTab: close } = useRoomToolbox(); const closeModal = useCallback(() => setModal(null), [setModal]); const dispatchToastMessage = useToastMessageDispatch(); const pruneMessagesAction = useEndpoint('POST', '/v1/rooms.cleanHistory'); const [counter, setCounter] = useState(0); const methods = useForm({ defaultValues: initialValues }); const { newer: { date: newerDate, time: newerTime }, older: { date: olderDate, time: olderTime }, users, inclusive, pinned, discussion, threads, attached, } = methods.watch(); const fromDate = useMemo(() => { return new Date(`${newerDate || '0001-01-01'}T${newerTime || '00:00'}:00${getTimeZoneOffset()}`); }, [newerDate, newerTime]); const toDate = useMemo(() => { return new Date(`${olderDate || '9999-12-31'}T${olderTime || '23:59'}:59${getTimeZoneOffset()}`); }, [olderDate, olderTime]); const handlePrune = useStableCallback((): void => { const handlePruneAction = async () => { const limit = DEFAULT_PRUNE_LIMIT; try { if (counter === limit) { return; } const { count } = await pruneMessagesAction({ roomId: room._id, latest: toDate.toISOString(), oldest: fromDate.toISOString(), inclusive, limit, excludePinned: pinned, filesOnly: attached, ignoreDiscussion: discussion, ignoreThreads: threads, users, }); setCounter(count); if (count < 1) { throw new Error(attached ? t('No_files_found_to_prune') : t('No_messages_found_to_prune')); } dispatchToastMessage({ type: 'success', message: attached ? t('__count__file_pruned', { count }) : t('__count__message_pruned', { count }), }); methods.reset(); } catch (error: unknown) { dispatchToastMessage({ type: 'error', message: error }); } finally { closeModal(); } }; return setModal( {t('Prune_Modal')} , ); }); const callOutText = useMemo(() => { const name = room && ((isDirectMessageRoom(room) && room.usernames?.join(' x ')) || room.fname || room.name); const exceptPinned = pinned ? ` ${t('except_pinned')}` : ''; const ifFrom = users.length ? ` ${t('if_they_are_from', { users: users.map((element) => element).join(', ') })}` : ''; const filesOrMessages = attached ? t('files') : t('messages'); if (newerDate && olderDate) { return ( t('Prune_Warning_between', { items: filesOrMessages, roomName: name, fromDate: formatDate(fromDate, 'L LT'), toDate: formatDate(toDate, 'L LT'), }) + exceptPinned + ifFrom ); } if (newerDate) { return ( t('Prune_Warning_after', { items: filesOrMessages, roomName: name, fromDate: formatDate(fromDate, 'L LT') }) + exceptPinned + ifFrom ); } if (olderDate) { return ( t('Prune_Warning_before', { items: filesOrMessages, roomName: name, toDate: formatDate(toDate, 'L LT') }) + exceptPinned + ifFrom ); } return t('Prune_Warning_all', { items: filesOrMessages, roomName: name }) + exceptPinned + ifFrom; }, [attached, fromDate, newerDate, olderDate, pinned, room, t, toDate, users]); const validateText = useMemo(() => { if (fromDate > toDate) { return t('Newer_than_may_not_exceed_Older_than'); } if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) { return t('error-invalid-date'); } return undefined; }, [fromDate, t, toDate]); return ( ); }; export default PruneMessagesWithData;