Spaces:
Sleeping
Sleeping
File size: 2,576 Bytes
709db16 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /** Shared pending-resolve queue: Home banner / Log after-save / Entry detail. */
import { createContext } from "preact";
import { useCallback, useContext, useMemo, useState } from "preact/hooks";
import type { ComponentChildren } from "preact";
import { listPending, type Entry } from "../api";
import { ResolvePendingSheet } from "./ResolvePendingSheet";
type PendingApi = {
openResolve: (entries?: Entry[]) => void;
openResolveId: (id: string, fallback?: Entry) => void;
refreshPendingSignal: number;
bumpRefresh: () => void;
};
const PendingContext = createContext<PendingApi | null>(null);
export function usePendingResolve(): PendingApi {
const ctx = useContext(PendingContext);
if (!ctx) throw new Error("usePendingResolve requires PendingResolveProvider");
return ctx;
}
export function PendingResolveProvider({ children }: { children: ComponentChildren }) {
const [queue, setQueue] = useState<Entry[]>([]);
const [open, setOpen] = useState(false);
const [refreshPendingSignal, setRefresh] = useState(0);
const bumpRefresh = useCallback(() => {
setRefresh((n) => n + 1);
}, []);
const openResolve = useCallback(async (entries?: Entry[]) => {
if (entries && entries.length) {
setQueue(entries);
setOpen(true);
return;
}
try {
const data = await listPending(50);
if (!data.items.length) return;
setQueue(data.items);
setOpen(true);
} catch {
// leave closed
}
}, []);
const openResolveId = useCallback(async (id: string, fallback?: Entry) => {
if (fallback && fallback.id === id) {
setQueue([fallback]);
setOpen(true);
return;
}
try {
const data = await listPending(50);
const hit = data.items.find((item) => item.id === id);
const rest = data.items.filter((item) => item.id !== id);
setQueue(hit ? [hit, ...rest] : fallback ? [fallback, ...rest] : rest);
setOpen(true);
} catch {
if (fallback) {
setQueue([fallback]);
setOpen(true);
}
}
}, []);
const api = useMemo(
() => ({ openResolve, openResolveId, refreshPendingSignal, bumpRefresh }),
[openResolve, openResolveId, refreshPendingSignal, bumpRefresh],
);
return (
<PendingContext.Provider value={api}>
{children}
<ResolvePendingSheet
open={open}
queue={queue}
onClose={() => {
setOpen(false);
setQueue([]);
}}
onQueueChange={setQueue}
onResolved={bumpRefresh}
/>
</PendingContext.Provider>
);
}
|