Skip to content

themeSwitch: fix theme picking, snippets switching off, and NSFW blur on the player (2.1.3) - #784

Merged
DogmaDragon merged 1 commit into
stashapp:mainfrom
nexalapp:themeswitch-first-pick-fix
Oct 15, 2026
Merged

DogmaDragon merged 1 commit into
stashapp:mainfrom
nexalapp:themeswitch-first-pick-fix

Conversation

@nexalapp

@nexalapp nexalapp commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Five problems in Theme Switch, all reproducible on Stash v0.31:

  1. First pick of a plugin theme does nothing. When a theme has never been picked, applyCSS takes the !theme branch and calls addStyleSheet(key, path). Plugin themes have no path, so it requests plugin/themeSwitch/assetsundefined and never installs or enables the plugin. The radio shows the theme as selected but the page stays default; picking it a second time works.
  2. Themes stack. Switching only disables the plugin Theme Switch remembers enabling (in localStorage). Theme plugins enabled from Settings → Plugins, or in another browser, stay on, so several themes load at once and fight.
  3. Snippets switch themselves off. init() runs on every stash:location event (any page change, including changing a filter or sort, and once more on load) and re-applies active snippets through applyCSS, which treats an already-attached snippet as a click and removes it, saving active: false. With "Blur NSFW images" on, every filter change and every refresh toggled the blur.
  4. "Blur NSFW images" doesn't cover the scene player. The snippet targets JW Player classes (.jw-video, .jw-preview) from before Stash switched to video.js, so the video, its poster and the scrubber thumbnails stay sharp. Group (formerly movie), studio, image and gallery images were also missing; the "Un-blur on mouse over" snippet already listed them.
  5. Updated snippets never reach the browser. Snippets are added after page load and Stash sends no cache headers for plugin assets, so browsers keep the old CSS even after a hard reload.

This change:

  • On a pick, installs the theme if needed (waiting for the install job to register it), then enables exactly that theme's plugin and disables every other theme plugin in the list in one setPluginsEnabled call. Picking Default disables them all.
  • CSS-only themes switch in place: the other themes' stylesheets are removed and the chosen one is added (cache-busted), with no page reload. Switching to or from a theme that ships JavaScript still reloads, since a script can't be unloaded.
  • On navigation, init() only attaches what is missing: path-based themes and active snippets. It never toggles anything and makes no GraphQL calls.
  • Removes path-based theme stylesheets when switching away from them.
  • Adds .video-js video, .video-js .vjs-tech, .video-js .vjs-poster, .video-js .vjs-poster img, .scrubber-item, .group-card-image, .studio-card-image, .image-image and .gallery-image to the blur snippet. The old JW Player selectors are kept. The player rules are !important so player styles and themes can't undo them.
  • Snippet URLs carry ?v=<plugin version>, so an update reaches users without clearing their cache.

Since this PR was opened

  • The menu opens off screen on phones. Stash moves the nav bar to the bottom on phones, so the menu, which always drops downward, opened below the viewport and nothing appeared. It now opens toward the side of the button with more room, is clamped to the screen width, and scrolls if it is taller than the space.
  • The icon ignores the theme. Its white parts were a fixed #fafafa, so on light themes the icon was invisible and on others it didn't match the nav icons beside it. Those parts now use currentColor, so the icon follows the nav colour; the coloured dots are unchanged. The icon's inline <style> (.s0–.s4) also leaked page-wide; the fills are now attributes.

Testing

Tested on Stash v0.31.1 (Docker) in Chrome:

  • With no Theme Switch history and an unrelated theme plugin enabled from Settings → Plugins, one pick of a theme enabled it and disabled the other; switching between themes always left exactly one enabled, with the page and the server agreeing; CSS-only themes switched without a reload, themes with JavaScript reloaded once; Default disabled them all.
  • With "Blur NSFW images" on, it stayed on across sort and filter changes, in-page searches and repeated refreshes (localStorage stayed active: true, stylesheet attached once).
  • On a scene page, the video, its poster and the scrubber thumbnails are blurred.
  • At 390×844 with the nav bar at the bottom, the menu opens above the button and stays on screen; at 1440×900 it opens below. The icon matches the nav icons in each of the community themes.
  • node validate.js --ci passes.

AI disclosure

This change was written with Claude (Anthropic) in Claude Code. I reviewed the code and tested it on my own Stash install before submitting.

🤖 Generated with Claude Code

@nexalapp
nexalapp force-pushed the themeswitch-first-pick-fix branch from 01482e3 to 2c408e5 Compare October 3, 2026 16:57
@nexalapp
nexalapp force-pushed the themeswitch-first-pick-fix branch from 2c408e5 to 4e355eb Compare October 15, 2026 20:47
@DogmaDragon DogmaDragon added the type:plugin Plugins label Oct 15, 2026
@discourse-stashapp

Copy link
Copy Markdown

This pull request has been mentioned on Stash Forum. There might be relevant details there:

https://discourse.stashapp.cc/t/theme-switch/1414/3

@DogmaDragon
DogmaDragon merged commit c50978e into stashapp:main Oct 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants