import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Widget } from '@/hooks/Mapper/components/mapInterface/components'; import { SystemSignaturesContent } from './SystemSignaturesContent'; import { SystemSignatureSettingsDialog } from './SystemSignatureSettingsDialog'; import { useMapRootState } from '@/hooks/Mapper/mapRootProvider'; import { SystemSignaturesHeader } from './SystemSignatureHeader'; import { useHotkey } from '@/hooks/Mapper/hooks/useHotkey'; import { getDeletionTimeoutMs } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts'; import { OutCommand, OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers'; import { ExtendedSystemSignature } from '@/hooks/Mapper/types'; import { SETTINGS_KEYS, SIGNATURE_WINDOW_ID, SignatureSettingsType } from '@/hooks/Mapper/constants/signatures'; /** * Custom hook for managing pending signature deletions and undo countdown. */ function useSignatureUndo( systemId: string | undefined, settings: SignatureSettingsType, outCommand: OutCommandHandler, ) { const [countdown, setCountdown] = useState(0); const [pendingIds, setPendingIds] = useState>(new Set()); const [deletedSignatures, setDeletedSignatures] = useState([]); const intervalRef = useRef(null); const addDeleted = useCallback((signatures: ExtendedSystemSignature[]) => { const newIds = signatures.map(sig => sig.eve_id); setPendingIds(prev => { const next = new Set(prev); newIds.forEach(id => next.add(id)); return next; }); setDeletedSignatures(prev => [...prev, ...signatures]); }, []); // Clear deleted signatures when system changes useEffect(() => { if (systemId) { setDeletedSignatures([]); setPendingIds(new Set()); setCountdown(0); if (intervalRef.current != null) { clearInterval(intervalRef.current); intervalRef.current = null; } } }, [systemId]); // kick off or clear countdown whenever pendingIds changes useEffect(() => { // clear any existing timer if (intervalRef.current != null) { clearInterval(intervalRef.current); intervalRef.current = null; } if (pendingIds.size === 0) { setCountdown(0); setDeletedSignatures([]); return; } // determine timeout from settings const timeoutMs = getDeletionTimeoutMs(settings); // Ensure a minimum of 1 second for immediate deletion so the UI shows const effectiveTimeoutMs = timeoutMs === 0 ? 1000 : timeoutMs; setCountdown(Math.ceil(effectiveTimeoutMs / 1000)); // start new interval intervalRef.current = window.setInterval(() => { setCountdown(prev => { if (prev <= 1) { clearInterval(intervalRef.current!); intervalRef.current = null; setPendingIds(new Set()); setDeletedSignatures([]); return 0; } return prev - 1; }); }, 1000); return () => { if (intervalRef.current != null) { clearInterval(intervalRef.current); intervalRef.current = null; } }; }, [pendingIds, settings]); // undo handler const handleUndo = useCallback(async () => { if (!systemId || pendingIds.size === 0) return; await outCommand({ type: OutCommand.undoDeleteSignatures, data: { system_id: systemId, eve_ids: Array.from(pendingIds) }, }); setPendingIds(new Set()); setDeletedSignatures([]); setCountdown(0); if (intervalRef.current != null) { clearInterval(intervalRef.current); intervalRef.current = null; } }, [systemId, pendingIds, outCommand]); return { pendingIds, countdown, deletedSignatures, addDeleted, handleUndo, }; } export const SystemSignatures = () => { const [visible, setVisible] = useState(false); const [sigCount, setSigCount] = useState(0); const { data: { selectedSystems }, outCommand, storedSettings: { settingsSignatures, settingsSignaturesUpdate }, } = useMapRootState(); const [systemId] = selectedSystems; const isSystemSelected = useMemo(() => selectedSystems.length === 1, [selectedSystems.length]); const { pendingIds, countdown, deletedSignatures, addDeleted, handleUndo } = useSignatureUndo( systemId, settingsSignatures, outCommand, ); useHotkey(true, ['z', 'Z'], (event: KeyboardEvent) => { if (pendingIds.size > 0 && countdown > 0) { event.preventDefault(); event.stopPropagation(); handleUndo(); } }); const handleCountChange = useCallback((count: number) => { setSigCount(count); }, []); const handleSettingsSave = useCallback( (newSettings: SignatureSettingsType) => { settingsSignaturesUpdate(newSettings); setVisible(false); }, [settingsSignaturesUpdate], ); const handleLazyDeleteToggle = useCallback( (value: boolean) => { settingsSignaturesUpdate(prev => ({ ...prev, [SETTINGS_KEYS.LAZY_DELETE_SIGNATURES]: value, })); }, [settingsSignaturesUpdate], ); const openSettings = useCallback(() => setVisible(true), []); return ( } windowId={SIGNATURE_WINDOW_ID} > {!isSystemSelected ? (
System is not selected
) : ( )} {visible && ( setVisible(false)} onSave={handleSettingsSave} /> )}
); }; export default SystemSignatures;