From 0878cbf30857aa5dfab9354c86a07a18bf0ae0a8 Mon Sep 17 00:00:00 2001 From: Psychotoxical <171614930+Psychotoxical@users.noreply.github.com> Date: Mon, 8 Jun 2026 22:05:41 +0200 Subject: [PATCH] feat(themes): Theme Store install counts, downloads & sort (#1036) * feat(themes): install counts, downloads, popularity & sort in the Theme Store Each registry theme now carries an install count and a last-changed date. Store rows show them in a dedicated meta panel (author, popularity bar, total downloads, last changed), plus a sort dropdown (most popular / newest / name), zebra-striped rows, a numbered pager, and a note that the stats refresh daily. Adds a shared formatRelativeTime helper (formatLastSeen now delegates to it). * test(themes): cover sort modes, pager jump and relative-time formatting * fix(build): gate nvidia_quirk_active to Linux Its only caller is the Linux branch of theme_animation_risk, so on Windows and macOS the function was dead code and tripped clippy's -D warnings. * docs: CHANGELOG + credits for theme store download stats & sort (#1036) --- CHANGELOG.md | 3 +- src-tauri/src/theme_animation.rs | 7 +- src/components/settings/PopularityBar.tsx | 24 ++++ .../settings/ThemeStoreSection.test.tsx | 88 +++++++++++- src/components/settings/ThemeStoreSection.tsx | 134 +++++++++++++++--- src/config/settingsCredits.ts | 2 +- src/locales/de/settings.ts | 9 +- src/locales/en/settings.ts | 9 +- src/locales/es/settings.ts | 9 +- src/locales/fr/settings.ts | 9 +- src/locales/nb/settings.ts | 9 +- src/locales/nl/settings.ts | 9 +- src/locales/ro/settings.ts | 9 +- src/locales/ru/settings.ts | 9 +- src/locales/zh/settings.ts | 9 +- src/utils/componentHelpers/userMgmtHelpers.ts | 13 +- src/utils/format/relativeTime.test.ts | 21 +++ src/utils/format/relativeTime.ts | 17 +++ src/utils/themes/themeRegistry.ts | 4 + 19 files changed, 346 insertions(+), 48 deletions(-) create mode 100644 src/components/settings/PopularityBar.tsx create mode 100644 src/utils/format/relativeTime.test.ts create mode 100644 src/utils/format/relativeTime.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 0348abba..71016277 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,13 +56,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Themes — community Theme Store -**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#1009](https://github.com/Psychotoxical/psysonic/pull/1009), [#1011](https://github.com/Psychotoxical/psysonic/pull/1011), [#1012](https://github.com/Psychotoxical/psysonic/pull/1012), [#1013](https://github.com/Psychotoxical/psysonic/pull/1013), [#1014](https://github.com/Psychotoxical/psysonic/pull/1014), [#1015](https://github.com/Psychotoxical/psysonic/pull/1015), [#1016](https://github.com/Psychotoxical/psysonic/pull/1016), [#1018](https://github.com/Psychotoxical/psysonic/pull/1018), [#1020](https://github.com/Psychotoxical/psysonic/pull/1020)** +**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#1009](https://github.com/Psychotoxical/psysonic/pull/1009), [#1011](https://github.com/Psychotoxical/psysonic/pull/1011), [#1012](https://github.com/Psychotoxical/psysonic/pull/1012), [#1013](https://github.com/Psychotoxical/psysonic/pull/1013), [#1014](https://github.com/Psychotoxical/psysonic/pull/1014), [#1015](https://github.com/Psychotoxical/psysonic/pull/1015), [#1016](https://github.com/Psychotoxical/psysonic/pull/1016), [#1018](https://github.com/Psychotoxical/psysonic/pull/1018), [#1020](https://github.com/Psychotoxical/psysonic/pull/1020), [#1036](https://github.com/Psychotoxical/psysonic/pull/1036)** * New **Settings → Themes** tab: pick a theme, set the day/night scheduler, and browse a built-in **Theme Store** to install, update and uninstall community themes — with search, a dark/light filter, and full-size thumbnail previews. * The app now bundles six core themes (Catppuccin Mocha & Latte, Kanagawa Wave, Stark HUD, and the colour-blind-safe Vision Dark / Vision Navy); every other palette installs on demand from the [psysonic-themes](https://github.com/Psysonic/psysonic-themes) repo. Installed themes are saved locally and apply instantly at startup, even offline. * **Import a theme from a local `.zip`** (manifest.json + theme.css): the package is validated, you confirm its name and author, then it installs like any other community theme. * Themes are **free-form** — beyond recolouring, they can add their own styling and animations and react to playback / fullscreen / sidebar / lyrics state. A safety floor (no network, no scripts) is always enforced; store themes are reviewed, and imported themes install at your own risk. * The store paginates large catalogues, and refreshing the list no longer jumps back to the top. +* Each store theme shows its **total downloads** and a **last-changed** date, and can be sorted by most popular, newest or name; the catalogue now has numbered page navigation. These stats refresh once a day. * Upgrading from an older build: an active or scheduled theme that has moved to the store and isn't installed falls back to Mocha (dark) / Latte (light). diff --git a/src-tauri/src/theme_animation.rs b/src-tauri/src/theme_animation.rs index 6e165e02..4ed3afcb 100644 --- a/src-tauri/src/theme_animation.rs +++ b/src-tauri/src/theme_animation.rs @@ -15,8 +15,11 @@ pub fn set_nvidia_quirk_active(active: bool) { let _ = NVIDIA_QUIRK_ACTIVE.set(active); } -/// Whether the Nvidia WebKit quirk was needed at startup. False when unrecorded -/// (non-Linux, or GPU acceleration opted in via `PSYSONIC_WEBKIT_GPU_ACCEL`). +/// Whether the Nvidia WebKit quirk was needed at startup. Linux-only: read +/// solely by the Linux branch of `theme_animation_risk`. False when unrecorded +/// (GPU acceleration opted in via `PSYSONIC_WEBKIT_GPU_ACCEL`). Gated so it is +/// not dead code on Windows/macOS, where the quirk never applies. +#[cfg(target_os = "linux")] pub(crate) fn nvidia_quirk_active() -> bool { NVIDIA_QUIRK_ACTIVE.get().copied().unwrap_or(false) } diff --git a/src/components/settings/PopularityBar.tsx b/src/components/settings/PopularityBar.tsx new file mode 100644 index 00000000..2ba53344 --- /dev/null +++ b/src/components/settings/PopularityBar.tsx @@ -0,0 +1,24 @@ +/** + * Five-segment popularity bar, filled relative to the most-downloaded theme in + * the catalogue (so the leader reads full and the rest scale against it). With + * few downloads it sits near-empty and fills in organically as counts grow. + * Decorative — the exact download number sits next to it as the real value. + */ +export function PopularityBar({ value, max }: { value: number; max: number }) { + const filled = max > 0 ? Math.round((Math.max(0, value) / max) * 5) : 0; + return ( +