mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 18:56:01 +00:00
fix(Core): fixed lazy delete timeouts
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
import { useCallback, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { Widget } from '@/hooks/Mapper/components/mapInterface/components';
|
import { Widget } from '@/hooks/Mapper/components/mapInterface/components';
|
||||||
import { SystemSignaturesContent } from './SystemSignaturesContent';
|
import { SystemSignaturesContent } from './SystemSignaturesContent';
|
||||||
import { SystemSignatureSettingsDialog } from './SystemSignatureSettingsDialog';
|
import { SystemSignatureSettingsDialog } from './SystemSignatureSettingsDialog';
|
||||||
import { SystemSignature } from '@/hooks/Mapper/types';
|
import { ExtendedSystemSignature, SystemSignature } from '@/hooks/Mapper/types';
|
||||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
import { useHotkey } from '@/hooks/Mapper/hooks';
|
import { useHotkey } from '@/hooks/Mapper/hooks';
|
||||||
import { SystemSignaturesHeader } from './SystemSignatureHeader';
|
import { SystemSignaturesHeader } from './SystemSignatureHeader';
|
||||||
@@ -10,15 +10,19 @@ import useLocalStorageState from 'use-local-storage-state';
|
|||||||
import {
|
import {
|
||||||
SETTINGS_KEYS,
|
SETTINGS_KEYS,
|
||||||
SETTINGS_VALUES,
|
SETTINGS_VALUES,
|
||||||
|
SIGNATURE_DELETION_TIMEOUTS,
|
||||||
SIGNATURE_SETTING_STORE_KEY,
|
SIGNATURE_SETTING_STORE_KEY,
|
||||||
SIGNATURE_WINDOW_ID,
|
SIGNATURE_WINDOW_ID,
|
||||||
|
SIGNATURES_DELETION_TIMING,
|
||||||
SignatureSettingsType,
|
SignatureSettingsType,
|
||||||
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
|
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
|
||||||
|
import { calculateTimeRemaining } from './helpers';
|
||||||
|
|
||||||
export const SystemSignatures = () => {
|
export const SystemSignatures = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [sigCount, setSigCount] = useState<number>(0);
|
const [sigCount, setSigCount] = useState<number>(0);
|
||||||
const [pendingSigs, setPendingSigs] = useState<SystemSignature[]>([]);
|
const [pendingSigs, setPendingSigs] = useState<SystemSignature[]>([]);
|
||||||
|
const [pendingTimeRemaining, setPendingTimeRemaining] = useState<number | undefined>();
|
||||||
const undoPendingFnRef = useRef<() => void>(() => {});
|
const undoPendingFnRef = useRef<() => void>(() => {});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -51,27 +55,45 @@ export const SystemSignatures = () => {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
undoPendingFnRef.current();
|
undoPendingFnRef.current();
|
||||||
setPendingSigs([]);
|
setPendingSigs([]);
|
||||||
|
setPendingTimeRemaining(undefined);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleUndoClick = useCallback(() => {
|
const handleUndoClick = useCallback(() => {
|
||||||
undoPendingFnRef.current();
|
undoPendingFnRef.current();
|
||||||
setPendingSigs([]);
|
setPendingSigs([]);
|
||||||
|
setPendingTimeRemaining(undefined);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSettingsButtonClick = useCallback(() => {
|
const handleSettingsButtonClick = useCallback(() => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handlePendingChange = useCallback((newPending: SystemSignature[], newUndo: () => void) => {
|
const handlePendingChange = useCallback(
|
||||||
setPendingSigs(prev => {
|
(pending: React.MutableRefObject<Record<string, ExtendedSystemSignature>>, newUndo: () => void) => {
|
||||||
if (newPending.length === prev.length && newPending.every(np => prev.some(pp => pp.eve_id === np.eve_id))) {
|
setPendingSigs(() => {
|
||||||
return prev;
|
return Object.values(pending.current).filter(sig => sig.pendingDeletion);
|
||||||
}
|
|
||||||
return newPending;
|
|
||||||
});
|
});
|
||||||
undoPendingFnRef.current = newUndo;
|
undoPendingFnRef.current = newUndo;
|
||||||
}, []);
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calculate the minimum time remaining for any pending signature
|
||||||
|
useEffect(() => {
|
||||||
|
if (pendingSigs.length === 0) {
|
||||||
|
setPendingTimeRemaining(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculate = () => {
|
||||||
|
setPendingTimeRemaining(() => calculateTimeRemaining(pendingSigs));
|
||||||
|
};
|
||||||
|
|
||||||
|
calculate();
|
||||||
|
const interval = setInterval(calculate, 1000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [pendingSigs]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Widget
|
<Widget
|
||||||
@@ -79,8 +101,8 @@ export const SystemSignatures = () => {
|
|||||||
<SystemSignaturesHeader
|
<SystemSignaturesHeader
|
||||||
sigCount={sigCount}
|
sigCount={sigCount}
|
||||||
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
|
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
|
||||||
// lazyDeleteValue={lazyDeleteValue}
|
|
||||||
pendingCount={pendingSigs.length}
|
pendingCount={pendingSigs.length}
|
||||||
|
pendingTimeRemaining={pendingTimeRemaining}
|
||||||
onLazyDeleteChange={handleLazyDeleteChange}
|
onLazyDeleteChange={handleLazyDeleteChange}
|
||||||
onUndoClick={handleUndoClick}
|
onUndoClick={handleUndoClick}
|
||||||
onSettingsClick={handleSettingsButtonClick}
|
onSettingsClick={handleSettingsButtonClick}
|
||||||
@@ -96,6 +118,12 @@ export const SystemSignatures = () => {
|
|||||||
<SystemSignaturesContent
|
<SystemSignaturesContent
|
||||||
systemId={systemId}
|
systemId={systemId}
|
||||||
settings={currentSettings}
|
settings={currentSettings}
|
||||||
|
deletionTiming={
|
||||||
|
SIGNATURE_DELETION_TIMEOUTS[
|
||||||
|
(currentSettings[SETTINGS_KEYS.DELETION_TIMING] as keyof typeof SIGNATURE_DELETION_TIMEOUTS) ||
|
||||||
|
SIGNATURES_DELETION_TIMING.DEFAULT
|
||||||
|
] as number
|
||||||
|
}
|
||||||
onLazyDeleteChange={handleLazyDeleteChange}
|
onLazyDeleteChange={handleLazyDeleteChange}
|
||||||
onCountChange={handleSigCountChange}
|
onCountChange={handleSigCountChange}
|
||||||
onPendingChange={handlePendingChange}
|
onPendingChange={handlePendingChange}
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ export enum SIGNATURES_DELETION_TIMING {
|
|||||||
EXTENDED,
|
EXTENDED,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SignatureDeletionTimingType = { [key in SIGNATURES_DELETION_TIMING]?: unknown };
|
||||||
|
|
||||||
export const SIGNATURE_SETTINGS = {
|
export const SIGNATURE_SETTINGS = {
|
||||||
filterFlags: [
|
filterFlags: [
|
||||||
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.COSMIC_ANOMALY, name: 'Show Anomalies' },
|
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.COSMIC_ANOMALY, name: 'Show Anomalies' },
|
||||||
@@ -200,3 +202,9 @@ export const SETTINGS_VALUES: SignatureSettingsType = {
|
|||||||
[SETTINGS_KEYS.GAS_SITE]: true,
|
[SETTINGS_KEYS.GAS_SITE]: true,
|
||||||
[SETTINGS_KEYS.COMBAT_SITE]: true,
|
[SETTINGS_KEYS.COMBAT_SITE]: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SIGNATURE_DELETION_TIMEOUTS: SignatureDeletionTimingType = {
|
||||||
|
[SIGNATURES_DELETION_TIMING.DEFAULT]: 10_000,
|
||||||
|
[SIGNATURES_DELETION_TIMING.IMMEDIATE]: 0,
|
||||||
|
[SIGNATURES_DELETION_TIMING.EXTENDED]: 30_000,
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ExtendedSystemSignature } from '@/hooks/Mapper/types';
|
import { ExtendedSystemSignature, SystemSignature } from '@/hooks/Mapper/types';
|
||||||
import { FINAL_DURATION_MS } from '../constants';
|
import { FINAL_DURATION_MS } from '../constants';
|
||||||
|
|
||||||
export function prepareUpdatePayload(
|
export function prepareUpdatePayload(
|
||||||
@@ -49,40 +49,56 @@ export function schedulePendingAdditionForSig(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeLocalPendingAdditions(
|
export function mergeLocalPending(
|
||||||
|
pendingMapRef: React.MutableRefObject<Record<string, ExtendedSystemSignature>>,
|
||||||
serverSigs: ExtendedSystemSignature[],
|
serverSigs: ExtendedSystemSignature[],
|
||||||
localSigs: ExtendedSystemSignature[],
|
|
||||||
): ExtendedSystemSignature[] {
|
): ExtendedSystemSignature[] {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const pendingAdditions = localSigs.filter(sig => sig.pendingAddition && sig.pendingUntil && sig.pendingUntil > now);
|
const pendingDeletions = Object.values(pendingMapRef.current).filter(
|
||||||
|
sig => sig.pendingDeletion && sig.pendingUntil && sig.pendingUntil > now,
|
||||||
|
);
|
||||||
const mergedMap = new Map<string, ExtendedSystemSignature>();
|
const mergedMap = new Map<string, ExtendedSystemSignature>();
|
||||||
serverSigs.forEach(sig => mergedMap.set(sig.eve_id, sig));
|
serverSigs.forEach(sig => mergedMap.set(sig.eve_id, sig));
|
||||||
pendingAdditions.forEach(sig => {
|
|
||||||
if (!mergedMap.has(sig.eve_id)) {
|
pendingDeletions.forEach(sig => {
|
||||||
|
if (mergedMap.has(sig.eve_id)) {
|
||||||
mergedMap.set(sig.eve_id, sig);
|
mergedMap.set(sig.eve_id, sig);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return Array.from(mergedMap.values());
|
return Array.from(mergedMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scheduleLazyDeletionTimers(
|
export function scheduleLazyTimers(
|
||||||
toRemove: ExtendedSystemSignature[],
|
signatures: ExtendedSystemSignature[],
|
||||||
setPendingMap: React.Dispatch<React.SetStateAction<Record<string, { finalUntil: number; finalTimeoutId: number }>>>,
|
pendingMapRef: React.MutableRefObject<Record<string, ExtendedSystemSignature>>,
|
||||||
finalizeRemoval: (sig: ExtendedSystemSignature) => Promise<void>,
|
finalizeFn: (sig: ExtendedSystemSignature) => Promise<void>,
|
||||||
finalDuration = FINAL_DURATION_MS,
|
finalDuration = FINAL_DURATION_MS,
|
||||||
) {
|
) {
|
||||||
const now = Date.now();
|
signatures.forEach(sig => {
|
||||||
toRemove.forEach(sig => {
|
|
||||||
const finalTimeoutId = window.setTimeout(async () => {
|
const finalTimeoutId = window.setTimeout(async () => {
|
||||||
await finalizeRemoval(sig);
|
await finalizeFn(sig);
|
||||||
}, finalDuration);
|
}, finalDuration);
|
||||||
|
|
||||||
setPendingMap(prev => ({
|
pendingMapRef.current = {
|
||||||
...prev,
|
...pendingMapRef.current,
|
||||||
[sig.eve_id]: {
|
[sig.eve_id]: {
|
||||||
finalUntil: now + finalDuration,
|
...sig,
|
||||||
finalTimeoutId,
|
finalTimeoutId,
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const calculateTimeRemaining = (pendingSigs: SystemSignature[]) => {
|
||||||
|
const now = Date.now();
|
||||||
|
let minTime: number | undefined = undefined;
|
||||||
|
|
||||||
|
pendingSigs.forEach(sig => {
|
||||||
|
const extendedSig = sig as unknown as { pendingUntil?: number };
|
||||||
|
if (extendedSig.pendingUntil && (minTime === undefined || extendedSig.pendingUntil - now < minTime)) {
|
||||||
|
minTime = extendedSig.pendingUntil - now;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return minTime && minTime > 0 ? minTime : undefined;
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ export interface UseSystemSignaturesDataProps {
|
|||||||
settings: SignatureSettingsType;
|
settings: SignatureSettingsType;
|
||||||
hideLinkedSignatures?: boolean;
|
hideLinkedSignatures?: boolean;
|
||||||
onCountChange?: (count: number) => void;
|
onCountChange?: (count: number) => void;
|
||||||
onPendingChange?: (pending: ExtendedSystemSignature[], undo: () => void) => void;
|
onPendingChange?: (
|
||||||
|
pending: React.MutableRefObject<Record<string, ExtendedSystemSignature>>,
|
||||||
|
undo: () => void,
|
||||||
|
) => void;
|
||||||
onLazyDeleteChange?: (value: boolean) => void;
|
onLazyDeleteChange?: (value: boolean) => void;
|
||||||
deletionTiming?: number;
|
deletionTiming?: number;
|
||||||
}
|
}
|
||||||
@@ -15,16 +18,21 @@ export interface UseFetchingParams {
|
|||||||
systemId: string;
|
systemId: string;
|
||||||
signaturesRef: React.MutableRefObject<ExtendedSystemSignature[]>;
|
signaturesRef: React.MutableRefObject<ExtendedSystemSignature[]>;
|
||||||
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
||||||
localPendingDeletions: ExtendedSystemSignature[];
|
pendingDeletionMapRef: React.MutableRefObject<Record<string, ExtendedSystemSignature>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UsePendingDeletionParams {
|
export interface UsePendingDeletionParams {
|
||||||
systemId: string;
|
systemId: string;
|
||||||
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
|
||||||
deletionTiming?: number;
|
deletionTiming?: number;
|
||||||
|
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
||||||
|
onPendingChange?: (
|
||||||
|
pending: React.MutableRefObject<Record<string, ExtendedSystemSignature>>,
|
||||||
|
undo: () => void,
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UsePendingAdditionParams {
|
export interface UsePendingAdditionParams {
|
||||||
|
systemId: string;
|
||||||
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
|
||||||
deletionTiming?: number;
|
deletionTiming?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
import { useCallback, useRef, useState } from 'react';
|
|
||||||
import { UsePendingAdditionParams } from './types';
|
|
||||||
import { FINAL_DURATION_MS } from '../constants';
|
|
||||||
import { ExtendedSystemSignature } from '@/hooks/Mapper/types';
|
|
||||||
import { schedulePendingAdditionForSig } from '../helpers/contentHelpers';
|
|
||||||
|
|
||||||
export const usePendingAdditions = ({ setSignatures, deletionTiming }: UsePendingAdditionParams) => {
|
|
||||||
const [pendingUndoAdditions, setPendingUndoAdditions] = useState<ExtendedSystemSignature[]>([]);
|
|
||||||
const pendingAdditionMapRef = useRef<Record<string, { finalUntil: number; finalTimeoutId: number }>>({});
|
|
||||||
|
|
||||||
// Use the provided deletion timing or fall back to the default
|
|
||||||
const finalDuration = deletionTiming !== undefined ? deletionTiming : FINAL_DURATION_MS;
|
|
||||||
|
|
||||||
const processAddedSignatures = useCallback(
|
|
||||||
(added: ExtendedSystemSignature[]) => {
|
|
||||||
if (!added.length) return;
|
|
||||||
|
|
||||||
// If duration is 0, don't show pending state
|
|
||||||
if (finalDuration === 0) {
|
|
||||||
setSignatures(prev => [
|
|
||||||
...prev,
|
|
||||||
...added.map(sig => ({
|
|
||||||
...sig,
|
|
||||||
pendingAddition: false,
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = Date.now();
|
|
||||||
setSignatures(prev => [
|
|
||||||
...prev,
|
|
||||||
...added.map(sig => ({
|
|
||||||
...sig,
|
|
||||||
pendingAddition: true,
|
|
||||||
pendingUntil: now + finalDuration,
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
added.forEach(sig => {
|
|
||||||
schedulePendingAdditionForSig(
|
|
||||||
sig,
|
|
||||||
finalDuration,
|
|
||||||
setSignatures,
|
|
||||||
pendingAdditionMapRef,
|
|
||||||
setPendingUndoAdditions,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[setSignatures, finalDuration],
|
|
||||||
);
|
|
||||||
|
|
||||||
const clearPendingAdditions = useCallback(() => {
|
|
||||||
Object.values(pendingAdditionMapRef.current).forEach(({ finalTimeoutId }) => {
|
|
||||||
clearTimeout(finalTimeoutId);
|
|
||||||
});
|
|
||||||
pendingAdditionMapRef.current = {};
|
|
||||||
setSignatures(prev =>
|
|
||||||
prev.map(x => (x.pendingAddition ? { ...x, pendingAddition: false, pendingUntil: undefined } : x)),
|
|
||||||
);
|
|
||||||
setPendingUndoAdditions([]);
|
|
||||||
}, [setSignatures]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
pendingUndoAdditions,
|
|
||||||
setPendingUndoAdditions,
|
|
||||||
pendingAdditionMapRef,
|
|
||||||
processAddedSignatures,
|
|
||||||
clearPendingAdditions,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
import { useState, useCallback } from 'react';
|
import { useCallback, useRef, useEffect } from 'react';
|
||||||
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
||||||
import { prepareUpdatePayload, scheduleLazyDeletionTimers } from '../helpers';
|
import { prepareUpdatePayload, scheduleLazyTimers } from '../helpers';
|
||||||
import { UsePendingDeletionParams } from './types';
|
import { UsePendingDeletionParams } from './types';
|
||||||
import { FINAL_DURATION_MS } from '../constants';
|
import { FINAL_DURATION_MS } from '../constants';
|
||||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
import { ExtendedSystemSignature } from '@/hooks/Mapper/types';
|
import { ExtendedSystemSignature } from '@/hooks/Mapper/types';
|
||||||
|
|
||||||
export function usePendingDeletions({ systemId, setSignatures, deletionTiming }: UsePendingDeletionParams) {
|
export function usePendingDeletions({
|
||||||
|
systemId,
|
||||||
|
setSignatures,
|
||||||
|
deletionTiming,
|
||||||
|
onPendingChange,
|
||||||
|
}: UsePendingDeletionParams) {
|
||||||
const { outCommand } = useMapRootState();
|
const { outCommand } = useMapRootState();
|
||||||
const [localPendingDeletions, setLocalPendingDeletions] = useState<ExtendedSystemSignature[]>([]);
|
const pendingDeletionMapRef = useRef<Record<string, ExtendedSystemSignature>>({});
|
||||||
const [pendingDeletionMap, setPendingDeletionMap] = useState<
|
|
||||||
Record<string, { finalUntil: number; finalTimeoutId: number }>
|
|
||||||
>({});
|
|
||||||
|
|
||||||
// Use the provided deletion timing or fall back to the default
|
// Use the provided deletion timing or fall back to the default
|
||||||
const finalDuration = deletionTiming !== undefined ? deletionTiming : FINAL_DURATION_MS;
|
const finalDuration = deletionTiming !== undefined ? deletionTiming : FINAL_DURATION_MS;
|
||||||
@@ -37,15 +39,17 @@ export function usePendingDeletions({ systemId, setSignatures, deletionTiming }:
|
|||||||
const processedRemoved = removed.map(r => ({
|
const processedRemoved = removed.map(r => ({
|
||||||
...r,
|
...r,
|
||||||
pendingDeletion: true,
|
pendingDeletion: true,
|
||||||
pendingAddition: false,
|
|
||||||
pendingUntil: now + finalDuration,
|
pendingUntil: now + finalDuration,
|
||||||
}));
|
}));
|
||||||
setLocalPendingDeletions(prev => [...prev, ...processedRemoved]);
|
pendingDeletionMapRef.current = {
|
||||||
|
...pendingDeletionMapRef.current,
|
||||||
|
...processedRemoved.reduce((acc: any, sig) => {
|
||||||
|
acc[sig.eve_id] = sig;
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
};
|
||||||
|
|
||||||
outCommand({
|
onPendingChange?.(pendingDeletionMapRef, clearPendingDeletions);
|
||||||
type: OutCommand.updateSignatures,
|
|
||||||
data: prepareUpdatePayload(systemId, added, updated, []),
|
|
||||||
});
|
|
||||||
|
|
||||||
setSignatures(prev =>
|
setSignatures(prev =>
|
||||||
prev.map(sig => {
|
prev.map(sig => {
|
||||||
@@ -56,37 +60,34 @@ export function usePendingDeletions({ systemId, setSignatures, deletionTiming }:
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
scheduleLazyDeletionTimers(
|
scheduleLazyTimers(
|
||||||
processedRemoved,
|
processedRemoved,
|
||||||
setPendingDeletionMap,
|
pendingDeletionMapRef,
|
||||||
async sig => {
|
async sig => {
|
||||||
await outCommand({
|
await outCommand({
|
||||||
type: OutCommand.updateSignatures,
|
type: OutCommand.updateSignatures,
|
||||||
data: prepareUpdatePayload(systemId, [], [], [sig]),
|
data: prepareUpdatePayload(systemId, [], [], [sig]),
|
||||||
});
|
});
|
||||||
setLocalPendingDeletions(prev => prev.filter(x => x.eve_id !== sig.eve_id));
|
delete pendingDeletionMapRef.current[sig.eve_id];
|
||||||
setSignatures(prev => prev.filter(x => x.eve_id !== sig.eve_id));
|
setSignatures(prev => prev.filter(x => x.eve_id !== sig.eve_id));
|
||||||
},
|
},
|
||||||
finalDuration,
|
finalDuration,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[systemId, outCommand, setSignatures, finalDuration],
|
[systemId, outCommand, finalDuration],
|
||||||
);
|
);
|
||||||
|
|
||||||
const clearPendingDeletions = useCallback(() => {
|
const clearPendingDeletions = useCallback(() => {
|
||||||
Object.values(pendingDeletionMap).forEach(({ finalTimeoutId }) => clearTimeout(finalTimeoutId));
|
Object.values(pendingDeletionMapRef.current).forEach(({ finalTimeoutId }) => {
|
||||||
setPendingDeletionMap({});
|
clearTimeout(finalTimeoutId);
|
||||||
setSignatures(prev =>
|
});
|
||||||
prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false, pendingUntil: undefined } : x)),
|
pendingDeletionMapRef.current = {};
|
||||||
);
|
setSignatures(prev => prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false } : x)));
|
||||||
setLocalPendingDeletions([]);
|
onPendingChange?.(pendingDeletionMapRef, clearPendingDeletions);
|
||||||
}, [pendingDeletionMap, setSignatures]);
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
localPendingDeletions,
|
pendingDeletionMapRef,
|
||||||
setLocalPendingDeletions,
|
|
||||||
pendingDeletionMap,
|
|
||||||
setPendingDeletionMap,
|
|
||||||
processRemovedSignatures,
|
processRemovedSignatures,
|
||||||
clearPendingDeletions,
|
clearPendingDeletions,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { ExtendedSystemSignature, SystemSignature } from '@/hooks/Mapper/types';
|
import { ExtendedSystemSignature, SystemSignature } from '@/hooks/Mapper/types';
|
||||||
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
||||||
import { prepareUpdatePayload, getActualSigs, mergeLocalPendingAdditions } from '../helpers';
|
import { prepareUpdatePayload, getActualSigs, mergeLocalPending } from '../helpers';
|
||||||
import { UseFetchingParams } from './types';
|
import { UseFetchingParams } from './types';
|
||||||
import { FINAL_DURATION_MS } from '../constants';
|
|
||||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
|
|
||||||
export const useSignatureFetching = ({
|
export const useSignatureFetching = ({
|
||||||
systemId,
|
systemId,
|
||||||
signaturesRef,
|
signaturesRef,
|
||||||
setSignatures,
|
setSignatures,
|
||||||
localPendingDeletions,
|
pendingDeletionMapRef,
|
||||||
}: UseFetchingParams) => {
|
}: UseFetchingParams) => {
|
||||||
const {
|
const {
|
||||||
data: { characters },
|
data: { characters },
|
||||||
@@ -22,9 +21,6 @@ export const useSignatureFetching = ({
|
|||||||
setSignatures([]);
|
setSignatures([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (localPendingDeletions.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const resp = await outCommand({
|
const resp = await outCommand({
|
||||||
type: OutCommand.getSignatures,
|
type: OutCommand.getSignatures,
|
||||||
data: { system_id: systemId },
|
data: { system_id: systemId },
|
||||||
@@ -36,8 +32,8 @@ export const useSignatureFetching = ({
|
|||||||
character_name: characters.find(c => c.eve_id === s.character_eve_id)?.name,
|
character_name: characters.find(c => c.eve_id === s.character_eve_id)?.name,
|
||||||
})) as ExtendedSystemSignature[];
|
})) as ExtendedSystemSignature[];
|
||||||
|
|
||||||
setSignatures(prev => mergeLocalPendingAdditions(extended, prev));
|
setSignatures(() => mergeLocalPending(pendingDeletionMapRef, extended));
|
||||||
}, [characters, systemId, localPendingDeletions, outCommand, setSignatures]);
|
}, [characters, systemId, outCommand]);
|
||||||
|
|
||||||
const handleUpdateSignatures = useCallback(
|
const handleUpdateSignatures = useCallback(
|
||||||
async (newList: ExtendedSystemSignature[], updateOnly: boolean, skipUpdateUntouched?: boolean) => {
|
async (newList: ExtendedSystemSignature[], updateOnly: boolean, skipUpdateUntouched?: boolean) => {
|
||||||
@@ -48,24 +44,12 @@ export const useSignatureFetching = ({
|
|||||||
skipUpdateUntouched,
|
skipUpdateUntouched,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (added.length > 0) {
|
|
||||||
const now = Date.now();
|
|
||||||
setSignatures(prev => [
|
|
||||||
...prev,
|
|
||||||
...added.map(a => ({
|
|
||||||
...a,
|
|
||||||
pendingAddition: true,
|
|
||||||
pendingUntil: now + FINAL_DURATION_MS,
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
await outCommand({
|
await outCommand({
|
||||||
type: OutCommand.updateSignatures,
|
type: OutCommand.updateSignatures,
|
||||||
data: prepareUpdatePayload(systemId, added, updated, removed),
|
data: prepareUpdatePayload(systemId, added, updated, removed),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[systemId, outCommand, signaturesRef, setSignatures],
|
[systemId, outCommand, signaturesRef],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import useRefState from 'react-usestateref';
|
import useRefState from 'react-usestateref';
|
||||||
import { useMapEventListener } from '@/hooks/Mapper/events';
|
import { useMapEventListener } from '@/hooks/Mapper/events';
|
||||||
import { Commands, ExtendedSystemSignature, SignatureKind, SystemSignature } from '@/hooks/Mapper/types';
|
import { Commands, ExtendedSystemSignature, SignatureKind } from '@/hooks/Mapper/types';
|
||||||
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
|
||||||
import { parseSignatures } from '@/hooks/Mapper/helpers';
|
import { parseSignatures } from '@/hooks/Mapper/helpers';
|
||||||
|
|
||||||
import { getActualSigs, mergeLocalPendingAdditions } from '../helpers';
|
import { getActualSigs } from '../helpers';
|
||||||
import { useSignatureFetching } from './useSignatureFetching';
|
import { useSignatureFetching } from './useSignatureFetching';
|
||||||
import { usePendingAdditions } from './usePendingAdditions';
|
|
||||||
import { usePendingDeletions } from './usePendingDeletions';
|
import { usePendingDeletions } from './usePendingDeletions';
|
||||||
import { UseSystemSignaturesDataProps } from './types';
|
import { UseSystemSignaturesDataProps } from './types';
|
||||||
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
|
||||||
@@ -25,24 +24,18 @@ export const useSystemSignaturesData = ({
|
|||||||
const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]);
|
const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]);
|
||||||
const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]);
|
const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]);
|
||||||
|
|
||||||
const { localPendingDeletions, setLocalPendingDeletions, processRemovedSignatures, clearPendingDeletions } =
|
const { pendingDeletionMapRef, processRemovedSignatures, clearPendingDeletions } = usePendingDeletions({
|
||||||
usePendingDeletions({
|
|
||||||
systemId,
|
systemId,
|
||||||
setSignatures,
|
setSignatures,
|
||||||
deletionTiming,
|
deletionTiming,
|
||||||
});
|
onPendingChange,
|
||||||
|
|
||||||
const { pendingUndoAdditions, setPendingUndoAdditions, processAddedSignatures, clearPendingAdditions } =
|
|
||||||
usePendingAdditions({
|
|
||||||
setSignatures,
|
|
||||||
deletionTiming,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleGetSignatures, handleUpdateSignatures } = useSignatureFetching({
|
const { handleGetSignatures, handleUpdateSignatures } = useSignatureFetching({
|
||||||
systemId,
|
systemId,
|
||||||
signaturesRef,
|
signaturesRef,
|
||||||
setSignatures,
|
setSignatures,
|
||||||
localPendingDeletions,
|
pendingDeletionMapRef,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handlePaste = useCallback(
|
const handlePaste = useCallback(
|
||||||
@@ -56,18 +49,16 @@ export const useSystemSignaturesData = ({
|
|||||||
|
|
||||||
const currentNonPending = lazyDeleteValue
|
const currentNonPending = lazyDeleteValue
|
||||||
? signaturesRef.current.filter(sig => !sig.pendingDeletion)
|
? signaturesRef.current.filter(sig => !sig.pendingDeletion)
|
||||||
: signaturesRef.current.filter(sig => !sig.pendingDeletion && !sig.pendingAddition);
|
: signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition);
|
||||||
|
|
||||||
const { added, updated, removed } = getActualSigs(currentNonPending, incomingSignatures, !lazyDeleteValue, true);
|
const { added, updated, removed } = getActualSigs(currentNonPending, incomingSignatures, !lazyDeleteValue, true);
|
||||||
|
|
||||||
if (added.length > 0) {
|
|
||||||
processAddedSignatures(added);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removed.length > 0) {
|
if (removed.length > 0) {
|
||||||
await processRemovedSignatures(removed, added, updated);
|
await processRemovedSignatures(removed, added, updated);
|
||||||
} else {
|
}
|
||||||
const resp = await outCommand({
|
|
||||||
|
if (updated.length !== 0 || added.length !== 0) {
|
||||||
|
await outCommand({
|
||||||
type: OutCommand.updateSignatures,
|
type: OutCommand.updateSignatures,
|
||||||
data: {
|
data: {
|
||||||
system_id: systemId,
|
system_id: systemId,
|
||||||
@@ -76,16 +67,6 @@ export const useSystemSignaturesData = ({
|
|||||||
removed: [],
|
removed: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (resp) {
|
|
||||||
const finalSigs = (resp.signatures ?? []) as SystemSignature[];
|
|
||||||
setSignatures(prev =>
|
|
||||||
mergeLocalPendingAdditions(
|
|
||||||
finalSigs.map(x => ({ ...x })),
|
|
||||||
prev,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const keepLazy = settings[SETTINGS_KEYS.KEEP_LAZY_DELETE] as boolean;
|
const keepLazy = settings[SETTINGS_KEYS.KEEP_LAZY_DELETE] as boolean;
|
||||||
@@ -93,16 +74,7 @@ export const useSystemSignaturesData = ({
|
|||||||
onLazyDeleteChange?.(false);
|
onLazyDeleteChange?.(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[settings, signaturesRef, processRemovedSignatures, outCommand, systemId, onLazyDeleteChange],
|
||||||
settings,
|
|
||||||
signaturesRef,
|
|
||||||
processAddedSignatures,
|
|
||||||
processRemovedSignatures,
|
|
||||||
outCommand,
|
|
||||||
systemId,
|
|
||||||
setSignatures,
|
|
||||||
onLazyDeleteChange,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDeleteSelected = useCallback(async () => {
|
const handleDeleteSelected = useCallback(async () => {
|
||||||
@@ -112,7 +84,7 @@ export const useSystemSignaturesData = ({
|
|||||||
|
|
||||||
await handleUpdateSignatures(finalList, false, true);
|
await handleUpdateSignatures(finalList, false, true);
|
||||||
setSelectedSignatures([]);
|
setSelectedSignatures([]);
|
||||||
}, [selectedSignatures, signatures, handleUpdateSignatures]);
|
}, [selectedSignatures, signatures]);
|
||||||
|
|
||||||
const handleSelectAll = useCallback(() => {
|
const handleSelectAll = useCallback(() => {
|
||||||
setSelectedSignatures(signatures);
|
setSelectedSignatures(signatures);
|
||||||
@@ -120,42 +92,7 @@ export const useSystemSignaturesData = ({
|
|||||||
|
|
||||||
const undoPending = useCallback(() => {
|
const undoPending = useCallback(() => {
|
||||||
clearPendingDeletions();
|
clearPendingDeletions();
|
||||||
clearPendingAdditions();
|
}, [clearPendingDeletions]);
|
||||||
setSignatures(prev =>
|
|
||||||
prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false, pendingUntil: undefined } : x)),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pendingUndoAdditions.length) {
|
|
||||||
pendingUndoAdditions.forEach(async sig => {
|
|
||||||
await outCommand({
|
|
||||||
type: OutCommand.updateSignatures,
|
|
||||||
data: {
|
|
||||||
system_id: systemId,
|
|
||||||
added: [],
|
|
||||||
updated: [],
|
|
||||||
removed: [sig],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setSignatures(prev => prev.filter(x => !pendingUndoAdditions.some(u => u.eve_id === x.eve_id)));
|
|
||||||
setPendingUndoAdditions([]);
|
|
||||||
}
|
|
||||||
setLocalPendingDeletions([]);
|
|
||||||
}, [
|
|
||||||
clearPendingDeletions,
|
|
||||||
clearPendingAdditions,
|
|
||||||
pendingUndoAdditions,
|
|
||||||
setPendingUndoAdditions,
|
|
||||||
setLocalPendingDeletions,
|
|
||||||
setSignatures,
|
|
||||||
outCommand,
|
|
||||||
systemId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const combined = [...localPendingDeletions, ...pendingUndoAdditions];
|
|
||||||
onPendingChange?.(combined, undoPending);
|
|
||||||
}, [localPendingDeletions, pendingUndoAdditions, onPendingChange, undoPending]);
|
|
||||||
|
|
||||||
useMapEventListener(event => {
|
useMapEventListener(event => {
|
||||||
if (event.name === Commands.signaturesUpdated && String(event.data) === String(systemId)) {
|
if (event.name === Commands.signaturesUpdated && String(event.data) === String(systemId)) {
|
||||||
@@ -167,14 +104,15 @@ export const useSystemSignaturesData = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!systemId) {
|
if (!systemId) {
|
||||||
setSignatures([]);
|
setSignatures([]);
|
||||||
|
undoPending();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleGetSignatures();
|
handleGetSignatures();
|
||||||
}, [systemId, handleGetSignatures, setSignatures]);
|
}, [systemId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onCountChange?.(signatures.length);
|
onCountChange?.(signatures.length);
|
||||||
}, [signatures, onCountChange]);
|
}, [signatures]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
signatures,
|
signatures,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export interface ExtendedSystemSignature extends SystemSignature {
|
|||||||
pendingDeletion?: boolean;
|
pendingDeletion?: boolean;
|
||||||
pendingAddition?: boolean;
|
pendingAddition?: boolean;
|
||||||
pendingUntil?: number;
|
pendingUntil?: number;
|
||||||
|
finalTimeoutId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SignatureKindENG {
|
export enum SignatureKindENG {
|
||||||
|
|||||||
@@ -3850,6 +3850,11 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
|
morphdom@2.7.4:
|
||||||
|
version "2.7.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.7.4.tgz#c61d511e935cc25ca588dfaa752461f27865865e"
|
||||||
|
integrity sha512-ATTbWMgGa+FaMU3FhnFYB6WgulCqwf6opOll4CBzmVDTLvPMmUPrEv8CudmLPK0MESa64+6B89fWOxP3+YIlxQ==
|
||||||
|
|
||||||
ms@2.1.2:
|
ms@2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
||||||
@@ -4061,7 +4066,9 @@ path-type@^5.0.0:
|
|||||||
version "4.2.1"
|
version "4.2.1"
|
||||||
|
|
||||||
"phoenix_live_view@file:../deps/phoenix_live_view":
|
"phoenix_live_view@file:../deps/phoenix_live_view":
|
||||||
version "0.20.17"
|
version "1.0.5"
|
||||||
|
dependencies:
|
||||||
|
morphdom "2.7.4"
|
||||||
|
|
||||||
picocolors@^1, picocolors@^1.0.0:
|
picocolors@^1, picocolors@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user