Durable hide/show for the VidPlex popup "instructions" panel.
What
The "Hide instructions" toggle now PERSISTS. Clicking it writes the choice to chrome.storage.local['goon_instructions_visible']; on every popup (and viewer
window) mount the stored value is read and applied. Absent key => SHOWN, which
preserves the current first-time "expanded on mount" behavior (zero regression).
The only thing that reverses a hide is the user clicking "Show" again — reloads,
session end, and service-worker termination no longer resurrect the panel.
Mechanism
New key INSTRUCTIONS_VISIBLE_KEY = 'goon_instructions_visible' in src/viewer/index.js, alongside the existing goon_* storage keys.
On mount: chrome.storage.local.get(KEY).then(stored => setInstructionsExpanded(stored[KEY] === undefined ? true : stored[KEY])),
with a .catch fallback to SHOWN on any read error.
On every toggle click: apply in-DOM via setInstructionsExpanded(next) and
persist chrome.storage.local.set({ [KEY]: next }) in both directions.
viewer.js has no instructions panel, so it needs no change. storage was
already a declared permission — no manifest change, no new dependency.
"Application-wide" respect comes for free because chrome.storage.local is
extension-wide.
__tests__/instructions_ui.test.mjs — +85/- (3 new tests):
stored-hidden honored on mount; persist on both toggle directions;
first-time (absent key) defaults to SHOWN.
Verification (QA lane — this is the verify step)
node --check src/viewer/index.js → OK.
Targeted instructions suite __tests__/instructions_ui.test.mjs → 5/5 passed.
npm run build → exit 0; dist/viewerIndex.js carries the new logic.
(web_accessible_resources still [interceptors.js, hlds.js]; icons present.)
tsc --noEmit → only the pre-existing vite.config.ts__dirname
errors (missing @types/node in this env); none on changed files.
Full node __tests__/run.mjs NOT used as a gate: it hangs on the hls_qa
deep-probe under jsdom (known pre-existing pitfall in vidplex-test-ci skill),
unrelated to this change — so the targeted suite is the trustworthy signal.
Behavioral simulation driving the real src/viewer/index.js in jsdom with a
persistent ext-wide store, all PASS:
first-time (empty store) => SHOWN
Hide => store=false; refresh/re-open => STILL HIDDEN
"Clear cache" (cache cleared, chrome.storage.local intact) => STILL HIDDEN
Show => store=true; refresh => SHOWN
explicit chrome.storage.local.clear() => back to first-time SHOWN default
Branch / commit
branch: feature/durable-instructions-visibility
commit: 42c1ad75c8ebbdf2a55a52c4301c95143a775064
"feat(viewer): persist hide/show instructions state in chrome.storage.local"
base: master
Durable hide/show for the VidPlex popup "instructions" panel.
## What
The "Hide instructions" toggle now PERSISTS. Clicking it writes the choice to
`chrome.storage.local['goon_instructions_visible']`; on every popup (and viewer
window) mount the stored value is read and applied. Absent key => SHOWN, which
preserves the current first-time "expanded on mount" behavior (zero regression).
The only thing that reverses a hide is the user clicking "Show" again — reloads,
session end, and service-worker termination no longer resurrect the panel.
## Mechanism
- New key `INSTRUCTIONS_VISIBLE_KEY = 'goon_instructions_visible'` in
`src/viewer/index.js`, alongside the existing `goon_*` storage keys.
- On mount: `chrome.storage.local.get(KEY).then(stored =>
setInstructionsExpanded(stored[KEY] === undefined ? true : stored[KEY]))`,
with a `.catch` fallback to SHOWN on any read error.
- On every toggle click: apply in-DOM via `setInstructionsExpanded(next)` and
persist `chrome.storage.local.set({ [KEY]: next })` in both directions.
- `viewer.js` has no instructions panel, so it needs no change. `storage` was
already a declared permission — no manifest change, no new dependency.
"Application-wide" respect comes for free because `chrome.storage.local` is
extension-wide.
## Files
- `src/viewer/index.js` — +10/-2 (key + read-on-mount + persist-on-toggle)
- `__tests__/instructions_ui.test.mjs` — +85/- (3 new tests):
stored-hidden honored on mount; persist on both toggle directions;
first-time (absent key) defaults to SHOWN.
## Verification (QA lane — this is the verify step)
- `node --check src/viewer/index.js` → OK.
- Targeted instructions suite `__tests__/instructions_ui.test.mjs` → 5/5 passed.
- `npm run build` → exit 0; `dist/viewerIndex.js` carries the new logic.
(`web_accessible_resources` still `[interceptors.js, hlds.js]`; icons present.)
- `eslint src/viewer/index.js` → 0 errors (pre-existing `no-unused-vars`
warnings in unrelated catch blocks only).
- `tsc --noEmit` → only the pre-existing `vite.config.ts` `__dirname`
errors (missing `@types/node` in this env); none on changed files.
- Full `node __tests__/run.mjs` NOT used as a gate: it hangs on the hls_qa
deep-probe under jsdom (known pre-existing pitfall in vidplex-test-ci skill),
unrelated to this change — so the targeted suite is the trustworthy signal.
- Behavioral simulation driving the real `src/viewer/index.js` in jsdom with a
persistent ext-wide store, all PASS:
1. first-time (empty store) => SHOWN
2. Hide => store=false; refresh/re-open => STILL HIDDEN
3. "Clear cache" (cache cleared, chrome.storage.local intact) => STILL HIDDEN
4. Show => store=true; refresh => SHOWN
5. explicit chrome.storage.local.clear() => back to first-time SHOWN default
## Branch / commit
- branch: `feature/durable-instructions-visibility`
- commit: `42c1ad75c8ebbdf2a55a52c4301c95143a775064`
"feat(viewer): persist hide/show instructions state in chrome.storage.local"
- base: `master`
Read the instructions panel's visibility on mount from
chrome.storage.local['goon_instructions_visible'] (absent => shown, the
first-time default) and persist the new value on every user toggle, so a
'hide instructions' choice survives popup reloads and service-worker
termination and is respected across the app via the shared storage key.
Adds unit tests: stored-hidden honored on mount, persistence on both toggle
directions, and first-time (absent key) defaulting to shown.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Durable hide/show for the VidPlex popup "instructions" panel.
What
The "Hide instructions" toggle now PERSISTS. Clicking it writes the choice to
chrome.storage.local['goon_instructions_visible']; on every popup (and viewerwindow) mount the stored value is read and applied. Absent key => SHOWN, which
preserves the current first-time "expanded on mount" behavior (zero regression).
The only thing that reverses a hide is the user clicking "Show" again — reloads,
session end, and service-worker termination no longer resurrect the panel.
Mechanism
INSTRUCTIONS_VISIBLE_KEY = 'goon_instructions_visible'insrc/viewer/index.js, alongside the existinggoon_*storage keys.chrome.storage.local.get(KEY).then(stored => setInstructionsExpanded(stored[KEY] === undefined ? true : stored[KEY])),with a
.catchfallback to SHOWN on any read error.setInstructionsExpanded(next)andpersist
chrome.storage.local.set({ [KEY]: next })in both directions.viewer.jshas no instructions panel, so it needs no change.storagewasalready a declared permission — no manifest change, no new dependency.
"Application-wide" respect comes for free because
chrome.storage.localisextension-wide.
Files
src/viewer/index.js— +10/-2 (key + read-on-mount + persist-on-toggle)__tests__/instructions_ui.test.mjs— +85/- (3 new tests):stored-hidden honored on mount; persist on both toggle directions;
first-time (absent key) defaults to SHOWN.
Verification (QA lane — this is the verify step)
node --check src/viewer/index.js→ OK.__tests__/instructions_ui.test.mjs→ 5/5 passed.npm run build→ exit 0;dist/viewerIndex.jscarries the new logic.(
web_accessible_resourcesstill[interceptors.js, hlds.js]; icons present.)eslint src/viewer/index.js→ 0 errors (pre-existingno-unused-varswarnings in unrelated catch blocks only).
tsc --noEmit→ only the pre-existingvite.config.ts__dirnameerrors (missing
@types/nodein this env); none on changed files.node __tests__/run.mjsNOT used as a gate: it hangs on the hls_qadeep-probe under jsdom (known pre-existing pitfall in vidplex-test-ci skill),
unrelated to this change — so the targeted suite is the trustworthy signal.
src/viewer/index.jsin jsdom with apersistent ext-wide store, all PASS:
Branch / commit
feature/durable-instructions-visibility42c1ad75c8ebbdf2a55a52c4301c95143a775064"feat(viewer): persist hide/show instructions state in chrome.storage.local"
master👍