🏗️ Build and Test JellyTau / Run Tests (push) Skipped
🏗️ Build and Test JellyTau / Android Compile Check (push) Skipped
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 3m57s
📱 Test APK / Build test APK (push) Successful in 20m27s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 3m45s
Traceability Validation / Check Requirement Traces (push) Successful in 11s
Build & Release / Run Tests (push) Successful in 10m38s
Build & Release / Build Linux (push) Successful in 14m21s
Build & Release / Build Windows (push) Successful in 10m47s
Build & Release / Build Android (push) Successful in 20m26s
Build & Release / Create Release (push) Successful in 43s
Resuming the app after time in the background no longer replaces the page on screen with "Failed to load item".
172 lines
7.1 KiB
TOML
172 lines
7.1 KiB
TOML
[package]
|
|
name = "jellytau"
|
|
# The app. Named explicitly because the crate also builds
|
|
# `player-conformance`, and a second binary makes a bare `cargo run` —
|
|
# which `tauri dev` issues — ambiguous.
|
|
default-run = "jellytau"
|
|
version = "0.13.3"
|
|
description = "A cross-platform Jellyfin client"
|
|
authors = ["Duncan Tourolle <duncan@tourolle.paris>"]
|
|
license = "MIT"
|
|
repository = "https://gitea.tourolle.paris/dtourolle/jellytau"
|
|
edition = "2021"
|
|
|
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
|
|
[lib]
|
|
# The `_lib` suffix may seem redundant but it is necessary
|
|
# to make the lib name unique and wouldn't conflict with the bin name.
|
|
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
|
name = "jellytau_lib"
|
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
|
|
# Keep debug info minimal to reduce target/ size in CI (line numbers in
|
|
# backtraces are preserved; the bulky full debuginfo is dropped).
|
|
[profile.dev]
|
|
debug = "line-tables-only"
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
# protocol-asset serves cached thumbnails to the webview (asset://localhost on
|
|
# Linux/macOS, http://asset.localhost on Windows/Android); without it
|
|
# convertFileSrc yields a URL nothing answers. Paired with
|
|
# app.security.assetProtocol in tauri.conf.json, which scopes it to
|
|
# $APPDATA/thumbnails/** — the one directory still read through this protocol.
|
|
# Downloaded media went the same way until DR-137 moved it to the loopback media
|
|
# server, so the database, the encrypted-token fallback file and downloads/ are
|
|
# all outside the grant now.
|
|
# TRACES: UR-012, UR-071 | DR-134, DR-137, DR-198
|
|
tauri = { version = "2", features = ["protocol-asset"] }
|
|
tauri-plugin-opener = "2"
|
|
tauri-plugin-os = "2"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
uuid = { version = "1", features = ["v4", "v5"] }
|
|
rand = "0.8"
|
|
tokio = { version = "1", features = ["sync", "rt-multi-thread", "time", "fs", "io-util", "macros"] }
|
|
tokio-util = "0.7"
|
|
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream", "json"] }
|
|
urlencoding = "2"
|
|
futures-util = "0.3"
|
|
async-trait = "0.1"
|
|
|
|
# SQLite for offline storage
|
|
rusqlite = { version = "0.32", features = ["bundled"] }
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
directories = "5"
|
|
|
|
# Secure credential storage (system keyring with encrypted file fallback)
|
|
keyring = "3"
|
|
aes-gcm = "0.10"
|
|
base64 = "0.22"
|
|
sha2 = "0.10"
|
|
getrandom = "0.2"
|
|
|
|
# Profile PIN hashing (DR-268). A switching gate against a member of the
|
|
# household, not at-rest protection -- but a hash is the right primitive for a
|
|
# gate, and Argon2id costs nothing extra over a weaker one.
|
|
argon2 = "0.5"
|
|
password-hash = { version = "0.5", features = ["alloc", "rand_core"] }
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
|
|
# Persistent, rotating, redacted logging on every platform -- and on Android the
|
|
# only thing that puts Rust output into logcat at all (env_logger writes to
|
|
# stdout, which Android discards, which is why the backend was invisible on the
|
|
# platform where the hardest bugs live).
|
|
#
|
|
# TRACES: UR-078 | DR-218
|
|
tauri-plugin-log = "2"
|
|
|
|
# Zip for the diagnostics export bundle.
|
|
zip = { version = "2", default-features = false, features = ["deflate"] }
|
|
tauri-specta = { version = "=2.0.0-rc.21", features = ["derive", "typescript"] }
|
|
specta-typescript = "=0.0.9"
|
|
specta = { version = "=2.0.0-rc.22", features = ["chrono", "derive"] }
|
|
tiny_http = { version = "0.12.0", default-features = false }
|
|
|
|
# In-app update, desktop only.
|
|
#
|
|
# `cfg(desktop)` is not decoration: tauri-plugin-updater does not support
|
|
# Android at all -- an APK cannot replace itself, that is the package manager's
|
|
# job -- and building it for the Android target fails. Android is offered the
|
|
# releases page through tauri-plugin-opener instead (see the frontend's
|
|
# updateCheck module). tauri-plugin-process supplies the relaunch that has to
|
|
# follow a desktop install.
|
|
#
|
|
# The cfg is spelled out as "not android, not iOS" rather than `cfg(desktop)`:
|
|
# Cargo evaluates a [target.'cfg(...)'] table against *target-triple* cfgs only
|
|
# (target_os, target_arch, target_family, unix/windows). `desktop` is a cfg
|
|
# Tauri's build script emits for use in Rust source, so `cfg(desktop)` here
|
|
# matches nothing, silently drops the dependency, and the build then fails much
|
|
# later with "Permission updater:default not found".
|
|
#
|
|
# TRACES: UR-077 | DR-217
|
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
|
tauri-plugin-updater = "2"
|
|
tauri-plugin-process = "2"
|
|
|
|
# Linux-specific dependencies
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
hostname = "0.4"
|
|
libc = "0.2"
|
|
# The crates.io release of libmpv predates the MPV versions we support, so this
|
|
# tracks the upstream git repo.
|
|
#
|
|
# Pinned by `rev`, not `branch = "master"`. With a branch, the revision is
|
|
# whatever Cargo.lock happens to hold and any `cargo update` silently swaps in
|
|
# new upstream code -- for the one dependency here that is not from crates.io,
|
|
# is not signed, and links a C library into the player. The rev below is the
|
|
# commit the lockfile already resolved to, so this pins current behaviour rather
|
|
# than changing it. To take upstream fixes, bump this deliberately.
|
|
libmpv = { git = "https://github.com/ParadoxSpiral/libmpv-rs.git", rev = "3e6c389b716f52a595cc5e8e3fa1f96cb76b3de7" }
|
|
|
|
# The raw FFI bindings behind `libmpv`, pinned to the *same* revision so the two
|
|
# can never describe different ABIs.
|
|
#
|
|
# Needed because the safe crate's `render` module is an empty stub at this
|
|
# revision — the render API (`mpv_render_context_create` and friends) exists only
|
|
# in the sys bindings, which do carry all of it. `Mpv::ctx` is public, so the
|
|
# render context can be built over the same handle the safe wrapper drives. This
|
|
# is what makes native video reachable *without* first completing the libmpv2
|
|
# migration, which the spike's use of `libmpv2-sys` had implied was a
|
|
# prerequisite.
|
|
#
|
|
# TRACES: UR-080 | DR-230, IR-033
|
|
libmpv-sys = { git = "https://github.com/ParadoxSpiral/libmpv-rs.git", rev = "3e6c389b716f52a595cc5e8e3fa1f96cb76b3de7" }
|
|
|
|
# Same major as the one Tauri/wry already resolve, so `gtk_window()` and
|
|
# `default_vbox()` hand back types this crate can name rather than a second,
|
|
# incompatible GTK.
|
|
gtk = "0.18"
|
|
|
|
# JNI for Android ExoPlayer integration
|
|
[target.'cfg(target_os = "android")'.dependencies]
|
|
jni = "0.21"
|
|
ndk-context = "0.1"
|
|
|
|
[dev-dependencies]
|
|
tempfile = "3.24.0"
|
|
# `net` for the loopback server in `download::worker::timeout_tests`; reqwest
|
|
# enables it transitively, but a test must not depend on that.
|
|
tokio = { version = "1", features = ["net"] }
|
|
wiremock = "0.6.5"
|
|
|
|
[features]
|
|
# Exposes the MediaPlayer conformance suite and the `player-conformance` binary
|
|
# to non-test builds, so an engine that cannot run in-process — ExoPlayer on a
|
|
# device — is driven by the same cases as the ones that can, rather than by a
|
|
# second checklist that drifts.
|
|
conformance = []
|
|
|
|
# A standalone runner for the conformance suite. Deliberately a separate binary:
|
|
# it links libmpv and nothing else, so a wrapper can be verified without building
|
|
# or launching the app.
|
|
[[bin]]
|
|
name = "player-conformance"
|
|
path = "src/bin/player_conformance.rs"
|
|
required-features = ["conformance"]
|
|
|