@samitouri / QOSami-HFS / commits / 940f7df8

fix: plugin/list-uploader: was not refreshing info after logging in with an admin

Massimo Melina committed May 8, 2026 at 11:24 UTC 940f7df85caef83539098e6a67f6deb105bd810c
2 files changed +17 -11
plugins/list-uploader/public/main.js
+1 -1
@@ -6,7 +6,7 @@
6 HFS.h(Uploader, entry))
7
8 function Uploader({ uri }) {
9 - const { data } = HFS.useBatch(getDetails, uri)
9 + const { data } = HFS.useBatch(getDetails, uri, { depend: HFS.state.isAdmin })
10 const text = React.useMemo(() => {
11 if (!data || data === true) return ''
12 const { upload: x } = data
shared/react.ts
+16 -10
@@ -44,27 +44,33 @@ export function useRequestRender() {
44 return Object.assign(useCallback(() => setState(x => x + 1), [setState]), { state })
45 }
46
47 -/* the idea is that you need a job done by a worker, but the worker will execute only after it collected jobs for some time
48 - by other "users" of the same worker, like other instances of the same component, but potentially also different components.
49 - User of this hook will just be returned with the single result of its own job.
50 - As an additional feature, results are cached, but you can refresh()
51 -*/
47 +/* This is very useful when you need to make many requests for the content of a long list,
48 + especially if you want to limit such requests to the rendered part, for paginated lists.
49 + The requests will be automatically batched while you make calls the simple way.
50 + It collects jobs requested by every hook using the same worker, calls the worker once after a delay,
51 + and returns each caller only the result matching its own job.
52 + Results are cached per worker/job/depend until refresh() schedules that job again, or expireAfter clears it */
53 export function useBatch<Job=unknown,Result=unknown>(
54 worker: Falsy | ((jobs: Job[]) => Promise<Result[]>),
55 job: undefined | Job,
55 - { delay=0, expireAfter=0 }={}
56 + { delay=0, expireAfter=0, depend=0 }={}
57 ) {
58 interface Env {
59 batch: Set<Job>
60 cache: Map<Job, Result | null>
61 + depend: unknown
62 waiter?: Promise<void>
63 }
64 const worker2env = (useBatch as any).worker2env ||= worker && new Map<typeof worker, Env>()
63 - const env = worker2env && (worker2env.get(worker) || (() => {
64 - const ret = { batch: new Set<Job>(), cache: new Map<Job, Result>() } as Env
65 + let env = worker2env && worker2env.get(worker)
66 + if (env && !_.isEqual(env.depend, depend))
67 + env = undefined
68 + env ||= worker2env && (() => {
69 + // depend scopes the worker cache, so stale results from a previous context won't be reused
70 + const ret = { batch: new Set<Job>(), cache: new Map<Job, Result>(), depend } as Env
71 worker2env.set(worker, ret)
72 return ret
67 - })())
73 + })()
74 const requestRender = useRequestRender()
75 useEffect(() => {
76 worker && (env.waiter ||= new Promise<void>(resolve => {
@@ -96,7 +102,7 @@ export function useBatch<Job=unknown,Result=unknown>(
102 requestRender()
103 env.batch.add(job)
104 }
99 - }, [job, cached])
105 + }, [env, job, cached])
106 return {
107 data: cached,
108 refresh() {