Files
SoulStream/src-tauri/Cargo.toml
T
KeelrLeek bb828ff2dc android: the phone, on the real core — the mockup shell, playback, the media card, the catalog, the resolver, Save, the dev flavour
The same Tauri 2 project builds for Android: mobile.html as a third Vite
entry (src/mobile/, the mockup on real data), tauri.android.conf.json, the
mobile stubs (updater, lyric alignment, vocal separation), rustls reqwest
on Android, the AAudio buffer, and a hand-driven detour build
(src-tauri/android/{env,build,deploy,dev}.sh) while Developer Mode is off.
ANDROID.md is the recipe.

Playback: the media-session plugin crate (lock-screen card, MediaStyle
notification, audio focus, headset buttons, a foreground service that
promotes itself first — Android 14 kills the app otherwise), session
restore across reload and restart, solid chrome after measuring the
backdrop-filter lag.

The catalog: Search is the desktop's top bar (the top-result rule, artist
cards), the artist page and the record page are the desktop's, Home is the
desktop's landing page, Gaps per followed shelf. Playing goes through the
desktop's own source rules, moved verbatim from state.svelte.js into
src/lib/sources.js so both apps share one resolver; the phone readies the
next three tracks and crosses boundaries gapless. Save fetches a record or
a track into the library by the download rules; Transfers shows the
burst. The raw Soulseek search stays, offered on request, a peer's copy
streaming with the lane rising as the bytes arrive. Community is the
Soulseek side (rooms, chat, buddies); the private layer waits.

The opener and storage plugins (social links, the picked library folder,
all-files access), the volume normalization switch, and the harness:
tests/mobile/smoke.mjs walks the mock (a fake network behind
src/lib/events.js) and the real phone over CDP, perf.mjs measures frames.
2026-09-13 09:30:06 -05:00

105 lines
3.8 KiB
TOML

[package]
name = "app"
version.workspace = true
description = "SoulStream — music player, downloader and streamer for the Soulseek network"
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dev-dependencies]
# Import-apply tests build a whole source/pen/library bed on disk; already in
# the lock file via the dependency tree, so this adds no download.
tempfile = "3"
[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-log = "2"
tauri-plugin-dialog = "2"
serde.workspace = true
serde_json.workspace = true
log.workspace = true
image.workspace = true
tokio.workspace = true
base64 = "0.22"
bincode = "1"
bs58 = "0.5"
rand = "0.8"
# Shazam signature packets (shazam.rs) carry a CRC-32 of their body.
crc32fast = "1"
# Inflate for the deno release zip (ytdlp.rs) — already in the lock via the
# image stack, so this adds no download.
flate2 = "1"
# STFT/iSTFT for the vocal separator (vocal_sep.rs) — pure Rust, so the
# no-child-processes charter holds; wraps rustfft with real transforms.
realfft = "3"
# XSPF playlist import (playlist_formats.rs). quick-xml never resolves DTDs
# or external entities, which is exactly the safety posture the importer wants.
quick-xml = "0.37"
keyring = { version = "3", features = ["windows-native"] }
sysinfo = "0.33"
soulseek-proto = { path = "../crates/soulseek-proto" }
soulseek-client = { path = "../crates/soulseek-client" }
freenet-adapter = { path = "../crates/freenet-adapter" }
persona-state = { path = "../crates/persona-state" }
player = { path = "../crates/player" }
tagger = { path = "../crates/tagger" }
metadata = { path = "../crates/metadata" }
library = { path = "../crates/library" }
audio-formats = { path = "../crates/audio-formats" }
# The phone's lock-screen card and background playback (a Kotlin foreground
# service). Registered everywhere so the permission set resolves on every
# platform; on the desktop its commands answer "not here".
tauri-plugin-media-session = { path = "../crates/tauri-plugin-media-session" }
tauri-plugin-storage = { path = "../crates/tauri-plugin-storage" }
semver = "1"
tauri-plugin-opener = "2.5.5"
# LRCLIB lyrics client (lyrics.rs). Already in the tree via the metadata crate.
# Desktop keeps the platform TLS (schannel on Windows); Android has no OpenSSL
# to build against, so it takes rustls with the bundled roots instead.
[target.'cfg(not(target_os = "android"))'.dependencies]
reqwest = { version = "0.12", features = ["json"] }
# Release checks and the silent install are a desktop story; the phone gets
# its builds from the store or a sideload, and the plugin is desktop-only.
tauri-plugin-updater = "2"
[target.'cfg(target_os = "android")'.dependencies]
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
# JNI_OnLoad (android_glue.rs): hands the JavaVM and the app Context to
# ndk-context, which cpal's AAudio backend reads and tao 0.35 never fills.
jni = "0.21"
ndk-context = "0.1"
[target.'cfg(windows)'.dependencies]
windows = { version = "0.61.3", features = [
"AI_MachineLearning",
"Foundation_Collections",
"Globalization",
"Graphics_Imaging",
# SystemMediaTransportControls — the OS media card (see src/smtc.rs).
"Media",
"Media_FaceAnalysis",
"Media_Ocr",
"Storage_Streams",
"Win32_Foundation",
# Taskbar thumbnail toolbar — ITaskbarList3 + the window subclass that
# hears its clicks, and the GDI/registry bits that draw its icons.
"Win32_Graphics_Gdi",
"Win32_System_Com",
"Win32_System_Registry",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
"Win32_System_Performance",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
"Win32_System_WinRT",
] }