v2.2.0
v2.2.0
Achievement Badges can now fit each user's Jellyfin layout and notification preferences
Added
- Optional Custom Tabs and Plugin Pages hosts (#37). Admins can enable either integration independently under Page integrations. Both hosts reuse the same Achievements surface as the stock page; there is no second implementation to drift out of sync. Plugin Pages registration uses an optional runtime bridge, so a missing or incompatible host cannot prevent Jellyfin or Achievement Badges from starting.
- Per-user navigation controls (#37). Every user can independently show or hide the Custom Tabs entry, Plugin Pages entry, and header/profile trophy shortcut. The controls appear inside Achievement settings and Jellyfin's native user settings. Hiding an entry affects only that navigation surface — tracking, notifications, and the stock page continue normally.
- Grouped or individual unlock bursts (#38). The new grouped mode (default) collapses simultaneous unlocks into one summary with the count, combined score, highest rarity, and first few badge names. Individual mode preserves the one-animation-per-achievement queue.
- Device-scoped unlock notifications (#38). Users can keep the default All signed-in devices behavior or choose Unlocking device only. New live unlocks are stamped with Jellyfin's originating device ID, and the server filters polling results so a client cannot bypass the preference by omitting or changing its own query locally.
- Clickable unlock toasts. A real single-achievement toast can be clicked or activated with Enter/Space. It opens My Badges, clears the active search/category/filter/sort state, scrolls to the exact achievement, focuses it, and briefly highlights the card. A grouped summary opens Recently unlocked instead. Synthetic admin previews intentionally remain non-navigating.
- Batch notification preview. Test 10 unlocks sits next to the existing toast preview controls and exercises the current user's saved grouping preference without creating achievements or writing to a profile.
- Build-specific client cache keys. Injected client assets now include the compiled module ID as well as the assembly version, preventing stale same-version JavaScript after a test deployment or rebuild.
- Full 8-language UI coverage. All new integration, navigation, notification, testing, and toast-action strings are translated in English, French, Spanish, German, Italian, Portuguese, Chinese, and Japanese.
Behaviour and compatibility notes
- Custom Tabs and Plugin Pages are admin opt-in and disabled by default. The stock Achievements page remains registered regardless of either setting.
- Existing users default to showing enabled navigation entries, grouped summaries, and all-device notification delivery, preserving discoverability and cross-client behavior.
- Originating-device mode applies cleanly to newly earned live unlocks. Unlocks without a recorded origin (for example, silent history backfills) intentionally do not produce a toast in that mode.
- Enabling either optional page-host integration requires saving the admin setting and restarting Jellyfin so the external host can install or register the page.
Verification
- 67/67 automated tests pass on .NET 9 / Jellyfin 10.11.x.
- Both browser bundles pass JavaScript syntax validation; all UI translation JSON parses successfully.
- Live headed Playwright smoke testing covered the stock page, native user settings, optional navigation visibility, single-toast mouse navigation, Enter-key activation, exact-card focus, grouped-summary routing, and inert/no-write synthetic previews.
- Deployed and smoke-tested against a healthy Jellyfin 10.11.x instance before release.
Upgrade
Drop-in upgrade from v2.1.x / v2.0.x. Existing profiles deserialize with safe defaults; no manual migration or schema reset is required. The release ZIP is Sigstore-signed and carries GitHub SLSA build provenance.