mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-11-14 13:16:10 +00:00
220 lines
6.3 KiB
TypeScript
220 lines
6.3 KiB
TypeScript
import { useCallback, useState, useEffect, useRef, useMemo } 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 useLocalStorageState from 'use-local-storage-state';
|
|
import { useHotkey } from '@/hooks/Mapper/hooks/useHotkey';
|
|
import {
|
|
SETTINGS_KEYS,
|
|
SETTINGS_VALUES,
|
|
SIGNATURE_SETTING_STORE_KEY,
|
|
SIGNATURE_WINDOW_ID,
|
|
SignatureSettingsType,
|
|
getDeletionTimeoutMs,
|
|
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
|
|
import { OutCommand, OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers';
|
|
import { ExtendedSystemSignature } from '@/hooks/Mapper/types';
|
|
|
|
/**
|
|
* Custom hook for managing pending signature deletions and undo countdown.
|
|
*/
|
|
function useSignatureUndo(
|
|
systemId: string | undefined,
|
|
settings: SignatureSettingsType,
|
|
outCommand: OutCommandHandler,
|
|
) {
|
|
const [countdown, setCountdown] = useState<number>(0);
|
|
const [pendingIds, setPendingIds] = useState<Set<string>>(new Set());
|
|
const [deletedSignatures, setDeletedSignatures] = useState<ExtendedSystemSignature[]>([]);
|
|
const intervalRef = useRef<number | null>(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);
|
|
|
|
setCountdown(Math.ceil(timeoutMs / 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,
|
|
} = useMapRootState();
|
|
|
|
const [currentSettings, setCurrentSettings] = useLocalStorageState<SignatureSettingsType>(
|
|
SIGNATURE_SETTING_STORE_KEY,
|
|
{
|
|
defaultValue: SETTINGS_VALUES,
|
|
},
|
|
);
|
|
|
|
const [systemId] = selectedSystems;
|
|
const isSystemSelected = useMemo(() => selectedSystems.length === 1, [selectedSystems.length]);
|
|
const { pendingIds, countdown, deletedSignatures, addDeleted, handleUndo } = useSignatureUndo(
|
|
systemId,
|
|
currentSettings,
|
|
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) => {
|
|
setCurrentSettings(newSettings);
|
|
setVisible(false);
|
|
},
|
|
[setCurrentSettings],
|
|
);
|
|
|
|
const handleLazyDeleteToggle = useCallback(
|
|
(value: boolean) => {
|
|
setCurrentSettings(prev => ({
|
|
...prev,
|
|
[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES]: value,
|
|
}));
|
|
},
|
|
[setCurrentSettings],
|
|
);
|
|
|
|
const openSettings = useCallback(() => setVisible(true), []);
|
|
|
|
return (
|
|
<Widget
|
|
label={
|
|
<SystemSignaturesHeader
|
|
sigCount={sigCount}
|
|
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
|
|
pendingCount={pendingIds.size}
|
|
undoCountdown={countdown}
|
|
onLazyDeleteChange={handleLazyDeleteToggle}
|
|
onUndoClick={handleUndo}
|
|
onSettingsClick={openSettings}
|
|
/>
|
|
}
|
|
windowId={SIGNATURE_WINDOW_ID}
|
|
>
|
|
{!isSystemSelected ? (
|
|
<div className="w-full h-full flex justify-center items-center select-none text-center text-stone-400/80 text-sm">
|
|
System is not selected
|
|
</div>
|
|
) : (
|
|
<SystemSignaturesContent
|
|
systemId={systemId}
|
|
settings={currentSettings}
|
|
deletedSignatures={deletedSignatures}
|
|
onLazyDeleteChange={handleLazyDeleteToggle}
|
|
onCountChange={handleCountChange}
|
|
onSignatureDeleted={addDeleted}
|
|
/>
|
|
)}
|
|
|
|
{visible && (
|
|
<SystemSignatureSettingsDialog
|
|
settings={currentSettings}
|
|
onCancel={() => setVisible(false)}
|
|
onSave={handleSettingsSave}
|
|
/>
|
|
)}
|
|
</Widget>
|
|
);
|
|
};
|
|
|
|
export default SystemSignatures;
|