4c9361d0200f48853fb26fbfd5f3023bd4ace755
The app's data dir was eligible for Google cloud backup: the manifest set neither allowBackup nor any extraction rules, so the SQLite catalogue (library metadata, watch history) and the jellytau_secure_prefs credential blob were shipped to the user's Google account. Restoring that is worse than not having it — SecureStorage encrypts under an Android Keystore key, and Keystore keys are never backed up, so a restored install gets ciphertext with nothing to open it and fails auth silently while looking signed in. Backup and device-to-device transfer are both turned off. allowBackup ="false" covers API 24-30 outright and kills cloud backup on 31+; it does NOT stop D2D there, so @xml/data_extraction_rules excludes every domain from both channels. Nothing is lost: the catalogue is a rebuildable mirror of the Jellyfin server, and watch state lives on the server. The credential-load path degrades instead of erroring, because a device can still arrive at undecryptable ciphertext (an older install's backup, a Keystore key invalidated by a lockscreen change). Both backends now distinguish "nothing stored" from "stored but unreadable" and answer the second as the first: CredentialStore::load_credentials_file logs and returns an empty map rather than CredentialError::Encryption — which storage_get_access_token was turning into a hard Err and storage_get_active_session into a warning — and SecureStorage.getCredential discards the dead blob so it cannot fail every subsequent read. The result is a login screen rather than a broken session, and the next successful sign-in rewrites the store. Also removes the half-declared Android TV support: the manifest offered LEANBACK_LAUNCHER and the leanback uses-feature with no D-pad focus model, no TV layouts, and neither of the two declarations Play's TV validation also requires (touchscreen required="false", android:banner). That fails review while advertising the app to TV launchers. All four go back together when a focus pass is actually done. And raises jvmTarget from 1.8 to 17 under compileSdk 36, with matching compileOptions — AGP 8.11 already requires a JDK 17 toolchain, so 1.8 was only capping emitted bytecode. Nothing else in the build assumed 1.8. TRACES: UR-012 | IR-014

JellyTau
A cross-platform Jellyfin client built with Tauri, SvelteKit, and TypeScript.
Business logic lives in a Rust backend; a UI-rich Svelte frontend handles presentation and talks to it over Tauri's IPC. Targets Linux (libmpv) and Android (ExoPlayer).
Getting Started
This project uses bun as its package manager.
# Activate the Rust environment (fish shell)
source "$HOME/.cargo/env.fish"
# Install dependencies
bun install
# Run in development
bun run tauri dev
# Type-check the frontend
bun run check
# Build for Linux
bun run tauri build
# Build for Android
bun run tauri android build
For the full set of build, test, and Android helper scripts, see scripts/README.md.
Documentation
| Topic | Location |
|---|---|
| Architecture overview & subsystem docs | docs/architecture/ |
| Requirements, traceability & technical debt | docs/requirements.md |
| Build & release process | docs/build-release.md |
| Docker builds | docs/build/docker.md |
| Traceability tooling & CI | docs/traceability.md, docs/traceability-ci.md |
| Release checklist | docs/release-checklist.md |
| UX flows | docs/ux-flows.md |
Recommended IDE Setup
VS Code + Svelte + Tauri + rust-analyzer.
License
MIT
Releases
37
JellyTau v0.10.1
Latest
Languages
Rust
49.1%
TypeScript
26.6%
Svelte
17.1%
Kotlin
4.9%
Shell
1.7%
Other
0.5%