fix: pending deletion working again (#185)
Some checks are pending
Build / 🚀 Deploy to test env (fly.io) (push) Waiting to run
Build / Manual Approval (push) Blocked by required conditions
Build / 🛠 Build (1.17, 18.x, 27) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/amd64) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/arm64) (push) Blocked by required conditions
Build / merge (push) Blocked by required conditions
Build / 🏷 Create Release (push) Blocked by required conditions

This commit is contained in:
guarzo
2025-02-18 17:24:15 -05:00
committed by GitHub
parent f965461820
commit 3d54783a3e
6 changed files with 70 additions and 52 deletions

View File

@@ -55,6 +55,22 @@ export function schedulePendingAdditionForSig(
); );
} }
export function mergeLocalPendingAdditions(
serverSigs: ExtendedSystemSignature[],
localSigs: ExtendedSystemSignature[],
): ExtendedSystemSignature[] {
const now = Date.now();
const pendingAdditions = localSigs.filter(sig => sig.pendingAddition && sig.pendingUntil && sig.pendingUntil > now);
const mergedMap = new Map<string, ExtendedSystemSignature>();
serverSigs.forEach(sig => mergedMap.set(sig.eve_id, sig));
pendingAdditions.forEach(sig => {
if (!mergedMap.has(sig.eve_id)) {
mergedMap.set(sig.eve_id, sig);
}
});
return Array.from(mergedMap.values());
}
export function scheduleLazyDeletionTimers( export function scheduleLazyDeletionTimers(
toRemove: ExtendedSystemSignature[], toRemove: ExtendedSystemSignature[],
setPendingMap: React.Dispatch<React.SetStateAction<Record<string, { finalUntil: number; finalTimeoutId: number }>>>, setPendingMap: React.Dispatch<React.SetStateAction<Record<string, { finalUntil: number; finalTimeoutId: number }>>>,

View File

@@ -1,10 +1,5 @@
// types.ts
import { ExtendedSystemSignature } from '../helpers/contentHelpers'; import { ExtendedSystemSignature } from '../helpers/contentHelpers';
import { OutCommandHandler } from '@/hooks/Mapper/types/mapHandlers'; // or your function type
/**
* The aggregators props
*/
export interface UseSystemSignaturesDataProps { export interface UseSystemSignaturesDataProps {
systemId: string; systemId: string;
settings: { key: string; value: boolean }[]; settings: { key: string; value: boolean }[];
@@ -14,9 +9,6 @@ export interface UseSystemSignaturesDataProps {
onLazyDeleteChange?: (value: boolean) => void; onLazyDeleteChange?: (value: boolean) => void;
} }
/**
* The minimal fetch logic
*/
export interface UseFetchingParams { export interface UseFetchingParams {
systemId: string; systemId: string;
signaturesRef: React.MutableRefObject<ExtendedSystemSignature[]>; signaturesRef: React.MutableRefObject<ExtendedSystemSignature[]>;
@@ -24,17 +16,11 @@ export interface UseFetchingParams {
localPendingDeletions: ExtendedSystemSignature[]; localPendingDeletions: ExtendedSystemSignature[];
} }
/**
* For the deletion sub-hook
*/
export interface UsePendingDeletionParams { export interface UsePendingDeletionParams {
systemId: string; systemId: string;
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>; setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
} }
/**
* For the additions sub-hook
*/
export interface UsePendingAdditionParams { export interface UsePendingAdditionParams {
setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>; setSignatures: React.Dispatch<React.SetStateAction<ExtendedSystemSignature[]>>;
} }

View File

@@ -5,12 +5,20 @@ import { FINAL_DURATION_MS } from '../constants';
export function usePendingAdditions({ setSignatures }: UsePendingAdditionParams) { export function usePendingAdditions({ setSignatures }: UsePendingAdditionParams) {
const [pendingUndoAdditions, setPendingUndoAdditions] = useState<ExtendedSystemSignature[]>([]); const [pendingUndoAdditions, setPendingUndoAdditions] = useState<ExtendedSystemSignature[]>([]);
const pendingAdditionMapRef = useRef<Record<string, { finalUntil: number; finalTimeoutId: number }>>({}); const pendingAdditionMapRef = useRef<Record<string, { finalUntil: number; finalTimeoutId: number }>>({});
const processAddedSignatures = useCallback( const processAddedSignatures = useCallback(
(added: ExtendedSystemSignature[]) => { (added: ExtendedSystemSignature[]) => {
if (!added.length) return; if (!added.length) return;
const now = Date.now();
setSignatures(prev => [
...prev,
...added.map(sig => ({
...sig,
pendingAddition: true,
pendingUntil: now + FINAL_DURATION_MS,
})),
]);
added.forEach(sig => { added.forEach(sig => {
schedulePendingAdditionForSig( schedulePendingAdditionForSig(
sig, sig,
@@ -29,7 +37,6 @@ export function usePendingAdditions({ setSignatures }: UsePendingAdditionParams)
clearTimeout(finalTimeoutId); clearTimeout(finalTimeoutId);
}); });
pendingAdditionMapRef.current = {}; pendingAdditionMapRef.current = {};
setSignatures(prev => setSignatures(prev =>
prev.map(x => (x.pendingAddition ? { ...x, pendingAddition: false, pendingUntil: undefined } : x)), prev.map(x => (x.pendingAddition ? { ...x, pendingAddition: false, pendingUntil: undefined } : x)),
); );

View File

@@ -19,14 +19,28 @@ export function usePendingDeletions({ systemId, setSignatures }: UsePendingDelet
updated: ExtendedSystemSignature[], updated: ExtendedSystemSignature[],
) => { ) => {
if (!removed.length) return; if (!removed.length) return;
const processedRemoved = removed.map(r => ({ ...r, pendingDeletion: true, pendingAddition: false })); const now = Date.now();
const processedRemoved = removed.map(r => ({
...r,
pendingDeletion: true,
pendingAddition: false,
pendingUntil: now + FINAL_DURATION_MS,
}));
setLocalPendingDeletions(prev => [...prev, ...processedRemoved]); setLocalPendingDeletions(prev => [...prev, ...processedRemoved]);
const resp = await outCommand({ outCommand({
type: OutCommand.updateSignatures, type: OutCommand.updateSignatures,
data: prepareUpdatePayload(systemId, added, updated, []), data: prepareUpdatePayload(systemId, added, updated, []),
}); });
const updatedFromServer = resp.signatures as ExtendedSystemSignature[];
setSignatures(prev =>
prev.map(sig => {
if (processedRemoved.find(r => r.eve_id === sig.eve_id)) {
return { ...sig, pendingDeletion: true, pendingUntil: now + FINAL_DURATION_MS };
}
return sig;
}),
);
scheduleLazyDeletionTimers( scheduleLazyDeletionTimers(
processedRemoved, processedRemoved,
@@ -41,18 +55,6 @@ export function usePendingDeletions({ systemId, setSignatures }: UsePendingDelet
}, },
FINAL_DURATION_MS, FINAL_DURATION_MS,
); );
const now = Date.now();
const updatedWithRemoval = updatedFromServer.map(sig => {
const wasRemoved = processedRemoved.find(r => r.eve_id === sig.eve_id);
return wasRemoved ? { ...sig, pendingDeletion: true, pendingUntil: now + FINAL_DURATION_MS } : sig;
});
const extras = processedRemoved
.map(r => ({ ...r, pendingDeletion: true, pendingUntil: now + FINAL_DURATION_MS }))
.filter(r => !updatedWithRemoval.some(m => m.eve_id === r.eve_id));
setSignatures([...updatedWithRemoval, ...extras]);
}, },
[systemId, outCommand, setSignatures], [systemId, outCommand, setSignatures],
); );
@@ -60,7 +62,6 @@ export function usePendingDeletions({ systemId, setSignatures }: UsePendingDelet
const clearPendingDeletions = useCallback(() => { const clearPendingDeletions = useCallback(() => {
Object.values(pendingDeletionMap).forEach(({ finalTimeoutId }) => clearTimeout(finalTimeoutId)); Object.values(pendingDeletionMap).forEach(({ finalTimeoutId }) => clearTimeout(finalTimeoutId));
setPendingDeletionMap({}); setPendingDeletionMap({});
setSignatures(prev => setSignatures(prev =>
prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false, pendingUntil: undefined } : x)), prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false, pendingUntil: undefined } : x)),
); );
@@ -72,7 +73,6 @@ export function usePendingDeletions({ systemId, setSignatures }: UsePendingDelet
setLocalPendingDeletions, setLocalPendingDeletions,
pendingDeletionMap, pendingDeletionMap,
setPendingDeletionMap, setPendingDeletionMap,
processRemovedSignatures, processRemovedSignatures,
clearPendingDeletions, clearPendingDeletions,
}; };

View File

@@ -1,8 +1,9 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { SystemSignature } from '@/hooks/Mapper/types'; import { SystemSignature } from '@/hooks/Mapper/types';
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers'; import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
import { ExtendedSystemSignature, prepareUpdatePayload, getActualSigs } from '../helpers'; import { ExtendedSystemSignature, prepareUpdatePayload, getActualSigs, mergeLocalPendingAdditions } 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 function useSignatureFetching({ export function useSignatureFetching({
@@ -33,7 +34,7 @@ export function useSignatureFetching({
...s, ...s,
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(extended); setSignatures(prev => mergeLocalPendingAdditions(extended, prev));
}, [characters, systemId, localPendingDeletions, outCommand, setSignatures]); }, [characters, systemId, localPendingDeletions, outCommand, setSignatures]);
const handleUpdateSignatures = useCallback( const handleUpdateSignatures = useCallback(
@@ -45,12 +46,24 @@ export function 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, signaturesRef, outCommand], [systemId, outCommand, signaturesRef, setSignatures],
); );
return { return {

View File

@@ -1,6 +1,5 @@
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import useRefState from 'react-usestateref'; import useRefState from 'react-usestateref';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { useMapEventListener } from '@/hooks/Mapper/events'; import { useMapEventListener } from '@/hooks/Mapper/events';
import { Commands, SystemSignature } from '@/hooks/Mapper/types'; import { Commands, SystemSignature } from '@/hooks/Mapper/types';
import { OutCommand } from '@/hooks/Mapper/types/mapHandlers'; import { OutCommand } from '@/hooks/Mapper/types/mapHandlers';
@@ -9,13 +8,14 @@ import {
KEEP_LAZY_DELETE_SETTING, KEEP_LAZY_DELETE_SETTING,
LAZY_DELETE_SIGNATURES_SETTING, LAZY_DELETE_SIGNATURES_SETTING,
} from '@/hooks/Mapper/components/mapInterface/widgets'; } from '@/hooks/Mapper/components/mapInterface/widgets';
import { ExtendedSystemSignature, getActualSigs } from '../helpers'; import { ExtendedSystemSignature, getActualSigs, mergeLocalPendingAdditions } from '../helpers';
import { useSignatureFetching } from './useSignatureFetching'; import { useSignatureFetching } from './useSignatureFetching';
import { usePendingAdditions } from './usePendingAdditions'; import { usePendingAdditions } from './usePendingAdditions';
import { usePendingDeletions } from './usePendingDeletions'; import { usePendingDeletions } from './usePendingDeletions';
import { UseSystemSignaturesDataProps } from './types'; import { UseSystemSignaturesDataProps } from './types';
import { TIME_ONE_DAY, TIME_ONE_WEEK } from '../constants'; import { TIME_ONE_DAY, TIME_ONE_WEEK } from '../constants';
import { SignatureGroup } from '@/hooks/Mapper/types'; import { SignatureGroup } from '@/hooks/Mapper/types';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
export function useSystemSignaturesData({ export function useSystemSignaturesData({
systemId, systemId,
@@ -25,9 +25,7 @@ export function useSystemSignaturesData({
onLazyDeleteChange, onLazyDeleteChange,
}: UseSystemSignaturesDataProps) { }: UseSystemSignaturesDataProps) {
const { outCommand } = useMapRootState(); const { outCommand } = useMapRootState();
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 { localPendingDeletions, setLocalPendingDeletions, processRemovedSignatures, clearPendingDeletions } =
@@ -51,7 +49,6 @@ export function useSystemSignaturesData({
const handlePaste = useCallback( const handlePaste = useCallback(
async (clipboardString: string) => { async (clipboardString: string) => {
const lazyDeleteValue = settings.find(s => s.key === LAZY_DELETE_SIGNATURES_SETTING)?.value ?? false; const lazyDeleteValue = settings.find(s => s.key === LAZY_DELETE_SIGNATURES_SETTING)?.value ?? false;
const incomingSignatures = parseSignatures( const incomingSignatures = parseSignatures(
clipboardString, clipboardString,
settings.map(s => s.key), settings.map(s => s.key),
@@ -79,8 +76,15 @@ export function useSystemSignaturesData({
removed: [], removed: [],
}, },
}); });
if (resp) {
const finalSigs = (resp.signatures ?? []) as SystemSignature[]; const finalSigs = (resp.signatures ?? []) as SystemSignature[];
setSignatures(finalSigs.map(x => ({ ...x }))); setSignatures(prev =>
mergeLocalPendingAdditions(
finalSigs.map(x => ({ ...x })),
prev,
),
);
}
} }
const keepLazy = settings.find(s => s.key === KEEP_LAZY_DELETE_SETTING)?.value ?? false; const keepLazy = settings.find(s => s.key === KEEP_LAZY_DELETE_SETTING)?.value ?? false;
@@ -115,16 +119,9 @@ export function useSystemSignaturesData({
const undoPending = useCallback(() => { const undoPending = useCallback(() => {
clearPendingDeletions(); clearPendingDeletions();
clearPendingAdditions(); clearPendingAdditions();
setSignatures(prev => setSignatures(prev =>
prev.map(x => { prev.map(x => (x.pendingDeletion ? { ...x, pendingDeletion: false, pendingUntil: undefined } : x)),
if (x.pendingDeletion) {
return { ...x, pendingDeletion: false, pendingUntil: undefined };
}
return x;
}),
); );
if (pendingUndoAdditions.length) { if (pendingUndoAdditions.length) {
pendingUndoAdditions.forEach(async sig => { pendingUndoAdditions.forEach(async sig => {
await outCommand({ await outCommand({
@@ -140,7 +137,6 @@ export function useSystemSignaturesData({
setSignatures(prev => prev.filter(x => !pendingUndoAdditions.some(u => u.eve_id === x.eve_id))); setSignatures(prev => prev.filter(x => !pendingUndoAdditions.some(u => u.eve_id === x.eve_id)));
setPendingUndoAdditions([]); setPendingUndoAdditions([]);
} }
setLocalPendingDeletions([]); setLocalPendingDeletions([]);
}, [ }, [
clearPendingDeletions, clearPendingDeletions,