refactor(ui): every function compiles under the React Compiler but VirtualGrid, and react-hooks/refs is on
E32 S4 — the burn-down from 29 skipped functions to 1: - try/finally (26 sites): the cleanup runs after a try/catch; steps that return early moved into their own function (push, the setup wizard's next, the share page's unlock). - A conditional, loop or optional call inside a try skips the function too, and react-hooks/todo does not see it: the value is computed before the try, or the try lives in a module-level helper (config writes, clip queueing, clipboard, frame counts, seekable end, YouTube player times). - The two exhaustive-deps suppressions are gone. useYtProgress takes its per-item snapshot through one effect event, read once when the player is built; PlexPlayer's unmount relies on the leaving-the-item cleanup for the generation bump it duplicated. - What the skips hid: PlexPlayer's 17 render-phase ref writes (useLatest), its tracks popover alias, the loadSession self-reference (declared early, set after commit); PlayerModal's session-position read during render (now where the player starts), navRef/modeRef writes, and a description helper that ran a ref-carrying callback during render (now PlayerDescription); SavedViewsProvider's latest-cfg ref, and its setState in the seed effect (preferSticky now prefers the starred default among same-filter views, so the seed needs no sticky write — test seen red on the old helper). - A store's hook was called `use()`, which the compiler does not know as a hook: inside the newly compiled usePlaylistActions it was memoized, ran on the first render alone, and the playlist rail threw "rendered fewer hooks" on its second render. Renamed to `useValue()` everywhere; the old contract test claimed the call was safe inside any `use…` function, which was false — replaced by a render test that is red under the old name. - PlexPlayer's palette ref was written and never read since the Backspace guard moved to the layer stack: removed. react-hooks/refs is back at error with no exception. The ratchet lists only VirtualGrid (IncompatibleLibrary) and pins both players as compiled. No size or complexity ceiling was raised.
This commit is contained in:
@@ -416,7 +416,7 @@ const tokens: { scope: KeyScope }[] = [];
|
||||
|
||||
/** The live scopes, innermost first, always ending in `global`. Re-renders on change. */
|
||||
export function useActiveScopes(): KeyScope[] {
|
||||
const stack = scopeStack.use();
|
||||
const stack = scopeStack.useValue();
|
||||
// DEDUPED: a scope can be registered by more than one live component (the Playlists page and its
|
||||
// rail each mount a `useContextMenu`), and `helpLines` appends a row's chords once per occurrence —
|
||||
// so without this the sheet rendered "⇧ F10 Menu ⇧ F10 Menu" under a duplicated React key
|
||||
@@ -449,14 +449,14 @@ export const toggleKeyboardHelp = (): void => {
|
||||
helpOpen.set(next);
|
||||
};
|
||||
/** Subscribe to whether the sheet is showing (the Plex player suppresses wheel-volume under it). */
|
||||
export const useKeyboardHelpOpen = (): boolean => helpOpen.use();
|
||||
export const useKeyboardHelpOpen = (): boolean => helpOpen.useValue();
|
||||
/** Whether the sheet was opened over a keyboard-owning layer (see `helpOverLayer`). */
|
||||
export const useKeyboardHelpOverLayer = (): boolean => helpOverLayer.use();
|
||||
export const useKeyboardHelpOverLayer = (): boolean => helpOverLayer.useValue();
|
||||
|
||||
// The modules this account can reach — published by `useGlobalKeymap`, read by the `g` chords and
|
||||
// by the sheet (which drops the chord of a gated module rather than promise a page that isn't there).
|
||||
const navigablePages = createStore<readonly Page[]>([]);
|
||||
export const useNavigablePages = (): readonly Page[] => navigablePages.use();
|
||||
export const useNavigablePages = (): readonly Page[] => navigablePages.useValue();
|
||||
|
||||
// ── The command palette ───────────────────────────────────────────────────────────────────────
|
||||
const paletteOpen = createStore(false);
|
||||
@@ -464,7 +464,7 @@ const paletteOpen = createStore(false);
|
||||
export const closePalette = (): void => paletteOpen.set(false);
|
||||
/** Open it from a visible control (the header's key cap / launcher), not only from Ctrl/Cmd+K. */
|
||||
export const openPalette = (): void => paletteOpen.set(true);
|
||||
export const usePaletteOpen = (): boolean => paletteOpen.use();
|
||||
export const usePaletteOpen = (): boolean => paletteOpen.useValue();
|
||||
|
||||
/** Bind the `global` and `page` scopes, once, for the whole app. It lives here rather than inside
|
||||
* either overlay because both are opened by it: a listener that sat in one of them would have to
|
||||
@@ -576,7 +576,7 @@ export function useSearchFocusKey(input: RefObject<HTMLInputElement | null>): vo
|
||||
}, [input]);
|
||||
}
|
||||
|
||||
export const useHelpConditionValues = (): HelpConditions => helpConditions.use();
|
||||
export const useHelpConditionValues = (): HelpConditions => helpConditions.useValue();
|
||||
|
||||
// ── Display ───────────────────────────────────────────────────────────────────────────────────
|
||||
const GLYPHS: Record<string, string> = {
|
||||
|
||||
Reference in New Issue
Block a user