desktop reads: a card that joins a read or gets the 'read just now' answer applies it (no bus event for those: a tab opened again stayed on its skeleton); invalidate before a write's after-refresh, editor save re-reads with force
This commit is contained in:
parent
fa081666ec
commit
f3e7c98994
2 changed files with 10 additions and 6 deletions
|
|
@ -23,7 +23,7 @@ export function TabEditor({ tab, project }: { tab: AppTab; project: Project }) {
|
|||
const r = useEditable(project);
|
||||
if (!EDIT_TABS[tab]) return null;
|
||||
if (!r.data) return r.error ? <ErrorNotice error={t('ed.loadFailed', { error: r.error })} tone="bad" /> : <Section><Skeleton lines={4} block /></Section>;
|
||||
const p = { project, data: r.data, onSaved: () => { r.refresh(); } };
|
||||
const p = { project, data: r.data, onSaved: () => { r.refresh(true); } };
|
||||
switch (tab) {
|
||||
case 'listings': return <ListingEditor {...p} />;
|
||||
case 'appinfo': return <AppInfoEditor {...p} />;
|
||||
|
|
|
|||
|
|
@ -608,7 +608,8 @@ export interface ReadState<T> {
|
|||
justNow?: boolean;
|
||||
/** Its store account waits on a quota pause or 429 backoff until then (epoch ms). */
|
||||
pausedUntil?: number | null;
|
||||
refresh: () => Promise<void>;
|
||||
/** Reads again (joins / memo); `true` skips the "read just now" memo. */
|
||||
refresh: (force?: unknown) => Promise<void>;
|
||||
}
|
||||
|
||||
/** preview: false when the screen already showed this dry run (the editors' Review step); the native dialog still follows. */
|
||||
|
|
@ -638,7 +639,7 @@ export function useWrite(projectId: string | null) {
|
|||
const o = await api.writeWithConfirm(w.method, projectId, w.args, job);
|
||||
if (o.stage === 'dry-run') d.updateToast(tid, { kind: 'bad', title: t('write.dryFailed'), detail: withHint(failureText(o.dryRun)), progress: undefined, job: undefined });
|
||||
else if (o.stage === 'dialog') d.updateToast(tid, { kind: 'info', title: t('write.notApplied'), detail: t('write.notAppliedDetail'), progress: undefined, job: undefined });
|
||||
else if (o.result?.ok) { d.updateToast(tid, { kind: 'ok', title: w.done, detail: lastLine(o.result.output) || undefined, progress: undefined, job: undefined }); w.after?.(); d.invalidate(projectId, w.method); }
|
||||
else if (o.result?.ok) { d.updateToast(tid, { kind: 'ok', title: w.done, detail: lastLine(o.result.output) || undefined, progress: undefined, job: undefined }); d.invalidate(projectId, w.method); w.after?.(); }
|
||||
// exit 3: the command stopped for an owner decision it did not get (a price change of a live product: the
|
||||
// Catalog tab's owner action applies it); everything else it could do was done
|
||||
else if (o.result?.exitCode === 3) { d.updateToast(tid, { kind: 'info', title: t('write.declined'), detail: lastLine(o.result.output) || undefined, progress: undefined, job: undefined }); w.after?.(); }
|
||||
|
|
@ -702,11 +703,14 @@ export function useRead<T>(target: string, method: string, o: { network: boolean
|
|||
const skipRef = useRef(o.skip);
|
||||
skipRef.current = o.skip;
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
const refresh = useCallback(async (force?: unknown) => {
|
||||
if (skipRef.current) return;
|
||||
set(x => ({ ...x, loading: false }));
|
||||
// a click: highest priority, joins a read in flight, answered from the memo when it finished just now
|
||||
await dRef.current.schedule(target, method, JSON.parse(argsKey) as Record<string, unknown>, 0).catch(() => {});
|
||||
// a click: highest priority, joins a read in flight, answered from the memo when it finished just now. The answer
|
||||
// is applied here too: a join or a memo answer sends no bus event, and a card that mounted after the read (a tab
|
||||
// opened again) would otherwise wait forever. `force === true` (after a save of this app's files) skips the memo.
|
||||
const r = await dRef.current.schedule(target, method, JSON.parse(argsKey) as Record<string, unknown>, 0, force === true).catch(() => null);
|
||||
if (r && usable(method, r)) set(x => (x.data === r.data ? x : { data: r.data as T, at: new Date().toISOString(), fromCache: false, loading: false, stale: false, error: null, command: r.command }));
|
||||
}, [target, method, argsKey]);
|
||||
|
||||
// results of this key, whoever asked for them (this card, the background reader, a write's invalidation)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue