desktop: five sections by job (Release, Store page, Revenue, Players, Health), Game services view, sidebar by attention
- app view: 12 tabs become 5 sections, each with a header (what it is for, the one next step from state already read) and its sub views in a segmented control; 1-5 jump, Ctrl+Shift+[ ] cycle, Ctrl+K and the context menu list sections and sub views; old tab ids, section and section/sub links all resolve - Players > Game services (games only): both stores, one row per leaderboard / achievement with its languages and each store's state, Game Center locale map, Play API-disabled state with the console plan - games status --json: items, localeMap, playApiDisabled; inspect summary: games - sidebar: apps grouped by attention / in progress / live / not on a store, one status line each, studio filter, workspace as a footer icon row - boot check opens places like a person (section, then sub view)
This commit is contained in:
parent
98cd1d3c92
commit
0ef27cf2e4
22 changed files with 918 additions and 115 deletions
|
|
@ -750,3 +750,21 @@ export function useRead<T>(target: string, method: string, o: { network: boolean
|
|||
|
||||
return { ...s, loading: !o.skip && (s.loading || st.busy), justNow: st.justNow, pausedUntil: st.pausedUntil, refresh };
|
||||
}
|
||||
|
||||
/** The cached value of one read (and every later result of it), without ever starting a read: for summaries such as a
|
||||
* section's "what's next" line that must not cost a store call. Null until the read ran once. */
|
||||
export function useCachedRead<T>(target: string | null, method: string, args: Record<string, unknown> = {}): T | null {
|
||||
const d = useData();
|
||||
const argsKey = JSON.stringify(args);
|
||||
const [v, set] = useState<T | null>(null);
|
||||
useEffect(() => {
|
||||
set(null);
|
||||
if (!target) return;
|
||||
let alive = true;
|
||||
const a = JSON.parse(argsKey) as Record<string, unknown>;
|
||||
api.cached<ToolResult>(method, target, a).then(c => { if (alive && c && c.value.data !== undefined && usable(method, c.value)) set(c.value.data as T); }, () => {});
|
||||
const un = d.onRead(readKey(target, method, a), e => { if (e.kind === 'done' && usable(method, e.result)) set(e.result.data as T); });
|
||||
return () => { alive = false; un(); };
|
||||
}, [target, method, argsKey]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue