CSS selectors in CustomCss (a[href*=mypreferencesmenu], :has(...) wrappers)
weren't reliably hiding the entry — bundle renders it via MUI ListItemButton
+ React Router NavLink and the rendered DOM didn't match the wrapper rules.
Add nukeSettings() to the runtime shim: queries any
a[href*=mypreferencesmenu] / [to*=mypreferencesmenu], walks up to closest
li/.MuiListItem-root/[role=menuitem] and sets display:none. Wired into
start(), a new MutationObserver on document.body, and the existing 1s
setInterval. CustomCss rules left in place as belt-and-braces.
Doc: extend 10-spa-runtime-shim.md with the diagnosis, the bind-mount inode
gotcha (single-file binds + os.replace orphans the container's view), and
the nsenter-based recovery path.
The static <title>ARRFLIX</title> patch wasn't enough - Jellyfin's bundle
calls document.title=... on hydrate and per-route, so the tab kept showing
'Jellyfin'. Add a self-contained inline IIFE in <head> that:
- Replaces 'Jellyfin' with 'ARRFLIX' on the title (incl. ' - Jellyfin' suffix)
- Pins favicon hrefs to the existing data: URL already in the page
- Watches <head> via MutationObserver for SPA churn
- Has a 1s setInterval safety net for late-binding navigations
- One-shot unregisters the Jellyfin service worker so old clients reload fresh
bin/inject-shim.py is the source of truth - idempotent (replaces marker block).
docs/10-spa-runtime-shim.md covers root cause, deploy flow, SW eviction, and
how to extend the shim on Jellyfin upgrade.
- EnableUserPreferenceAccess=false on guest + 5 (hides Display, Home,
Playback, Subtitles pref pages — owner controls UX centrally).
- Wrapper bin/add-jellyfin-user.sh updated to bake this into all future
non-admin user creations.
- ROADMAP entries (added by sibling import agents):
- Imported: The Incredible Hulk (2008), TMDB 1724, 4 images
- Imported: Idiocracy (2006), TMDB 7512 (NOT 1542 = Office Space)
- Imported: American Dad! (2005) S01-S04, 58 eps, TMDB 1433
- WAN exposure docs added (doc 09, 256 lines): Gandi A record live,
no-guest middleware dropped, lockout=5 baked in. Owner still must
port-forward 80/443 on home router for actual public access.
Owner flipped libraries to PreferredMetadataLanguage=en, MetadataCountryCode=US.
New-user defaults must match. Wrapper now sets:
AudioLanguagePreference=eng (was pol)
SubtitleLanguagePreference=eng
SubtitleMode=Default (was Always — let player decide based on audio)
Jellyfin has no native global default for new-user DisplayPreferences;
home-layout defaults are baked into the web bundle. This wrapper layers
the s8n canonical prefs on top after user creation:
- Home sections: resume, resumeaudio, nextup, latestmedia, none x6
(drops the 'My Media' tile row — sidebar already exposes libraries)
- SubtitleMode=Always, SubtitleLanguagePreference=eng
- AudioLanguagePreference=pol
Use for every new user from now on; achieves the 'global default' the
admin wanted without patching the web bundle.
Already retroactively applied to s8n + guest.