libmpv on Windows (DR-237):
- The builder image carries zhongfly's LGPL libmpv-2.dll, pinned by
asset name and sha256, plus an MSVC mpv.lib generated from the DLL's
own mpv_* exports (the archive ships only a MinGW .dll.a). LGPL, not
the GPL builds: no x264/x265, mpv -Dgpl=false; FFmpeg is version3, so
LGPL-3.0. THIRD_PARTY_NOTICES.md records it.
- build-windows-cross.sh stages both files into src-tauri/windows-libs/;
build.rs links mpv.lib from there and tauri.windows.conf.json bundles
the DLL beside jellytau.exe from there, with the licence texts under
licenses/. One directory, so the DLL shipped is the one linked.
- Workflows move to builder image 2026.09.1.
Windows audio:
- MpvBackend replaces WebviewAudioBackend on Windows (ao=wasapi), so
volume, EQ, normalization and gapless work there as on Linux. Local
files are passed to mpv as native paths, not file:// URLs.
Fixes found on the way:
- player_play_item decided "does the backend render video" with
cfg!(not(linux)), true on Windows, while get_player_status sent
Windows video to the <video> element. With mpv as the backend that
would decode every film's soundtrack twice. All three callers now
ask video_renders_natively() (UT-273).
- confine_queued_path rebuilt paths with PathBuf::push, so on Windows
a queued `downloads/x` was stored as `downloads\x`, no longer the
spelling the app built. It now keeps the caller's separator (UT-205,
which only ever ran on Linux, failed under Windows).
Verified: jellytau.exe imports libmpv-2.dll; the full unit suite
cross-compiled for Windows passes under wine against the shipped DLL
(943/943, including the mpv injection and TLS tests); the NSIS
installer contains the DLL and licence texts. Not yet run on real
Windows hardware.
check:boundary passed on the very leak it was written for. The pattern was
anchored to `includeItemTypes:` at the query site, so searchScope.ts
assigning the same array to a named const and dereferencing it one
indirection away was invisible — through every green CI run.
The check now matches an array literal naming two or more Jellyfin item
types anywhere in src/, catching a const, a Record value, a function
return, and an inline query alike. Deliberate limits kept: two adjacent
literals required (single-type presentation stays legal), string literals
required (item.type === "Audio" is display logic), explicit type list
(so ["High","Low"] produces no noise).
Verified all five cases: reintroducing the original SCOPE_ITEM_TYPES
fails; a new const ["Movie","Series"] fails; the same array in a
.test.ts passes; itemType: "Movie" / item.type === / ["High","Low"] pass;
a 5th allowlist entry fails on the new cap.
Allowlist 1→3 entries, capped at 4 so the next exception forces a
conversation rather than a one-line append:
- GenericMediaListPage: grid styling over a self-declared itemType —
presentation, changes only with a UI redesign.
- DownloadedBrowse: borderline, leans domain (the container set grows
when Jellyfin adds a container type). Allowlisted with a TODO for a
backend MediaItem.isContainer flag.
The header now names what the check still cannot see — run-time-built
sets, types split across variables, switch/|| taxonomy — and CLAUDE.md
states that a green check:boundary is not proof. That matters given this
check passed on its own founding violation for months.
Also: both gates wired into test-all.sh, which called `bun run test`
without --run and would have hung in watch mode. Corrected the Dockerfile
comment describing the Windows toolchain as mingw/GNU — it is MSVC via
cargo-xwin (GNU cannot bundle NSIS from Linux).
Adds Docker-based packaging for Linux desktop (deb/rpm), Arch
(.pkg.tar.zst via makepkg), and Windows. Windows cross-compiles from
Linux via the official Tauri path — the x86_64-pc-windows-msvc target
driven by cargo-xwin — and produces an NSIS installer (nsis via
tauri.conf.json targets, since the CLI rejects --bundles nsis on a Linux
host). Verified end to end: builds jellytau.exe + jellytau_x64-setup.exe.
Unifies everything on one registry builder image (Dockerfile.builder):
Android SDK/NDK, rpm/file, clang(+clang-cl)/lld/llvm/nsis, cargo-xwin and
the msvc target. Packaging tools sit in a trailing layer so tool changes
rebuild in ~1min instead of ~15. Desktop stages are thin FROM
${BUILDER_IMAGE} layers; Arch uses a separate archlinux image.
CLAUDE.md: CI must install no system toolchains — everything lives in the
image. Bumps version 0.0.18 -> 0.1.0 (Windows support + webview audio +
equalizer).
TRACES: UR-003, UR-005 | DR-004
- Convert music category buttons from <button> to native <a> links for better Android compatibility
- Convert artist/album nested buttons in TrackList to <a> links to fix HTML validation issues
- Add event handlers with proper stopPropagation to maintain click behavior
- Increase library overview card sizes from medium to large (50% bigger)
- Increase thumbnail sizes in list view from 10x10 to 16x16
- Add console logging for debugging click events on mobile
- Remove preventDefault() handlers that were blocking Android touch events
These changes resolve navigation issues on Android devices where buttons weren't responding to taps. Native <a> links provide better cross-platform compatibility and allow SvelteKit to handle navigation more reliably.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>