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;