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() {