What a switch or a section explains, rather than what is the person's
own, is one tap away: `HelpTitle`, a tile's title with halkyon_ui's
`HelpButton` beside it, in place of the explaining subtitles of Moving
more's reminders and suggestions, the music's playlists and smaller
copies, and the Loop's detection, firmware check and firmware through
the instance. Health Connect's short hints stay (they name what each
switch does, and its "taken back" state takes their place), as do its
rationale, the Loop's warnings before an update or a reset and the
settings' one-line hints.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
An http address to another machine is refused as typed, saying why: over it the password, the token and what the person listens to went through the network in clear, and the music job, held by Android to https, retried for ever without a track. A Jellyfin on the phone (localhost, 127.0.0.1) stays reachable over http, the network security config allowing those two alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Smaller copies, on by default on the music screen, has the music job
fetch a file above 256 kbps as Opus at 128 kbps in WebM, but for the
lossy codecs (MP3, AAC, Vorbis, Opus) at any rate. Each track keeps
which copy its file is; switching fetches the other copy without
working out the tempo again, the file kept until the new one is whole.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The app reads the playlists as before and hands the missing tracks to
MusicWorker.kt, which runs every 6 hours and once whenever the list
changes, on unmetered networks with the battery and storage not low.
MusicFetcher.kt downloads each with the token from JellyfinTokens, works
out its tempo and appends a line to fetched.txt, which the app takes in
as it opens and as each track comes. The app's own download is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
The token moves from flutter_secure_storage into JellyfinTokens.kt: a
file per person in the no-backup folder, sealed with AES-GCM under a key
of Android's Keystore, the person's ID as associated data, so that the
music job to come can read it as the app does. A token the keyring held
is moved over as it is first read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
A workout keeps its cadence as a series of its own (steps a minute, every
10 s while moving). The Record sheet offers Music, Metronome or Off on
foot, remembered; Music once a kept track has a tempo. The recorder
measures the cadence over the last 30 s and plays a fitting track (its
tempo, half or double, within 6 %) through Media3's ExoPlayer, retuning
the track playing where it still fits, else crossfading over 3 s; a
plan's new step picks anew. A run starts at the cadence learnt from the
person's runs, which also gives a plan's steps their cadence.
Media3 1.10.1, pinned by Gradle's checksums (trusted on first download
from Google's Maven, 29 Oct 2026), for review:
media3-common aar 39686f54ff6baf8cbc841199afd55619533eaef2ab6cd0efc32b8a3c55dd88c3
module a81b2f0ebc256fe0e09f05d93c5259ade5bf44707748b9295343bee67575d9c2
media3-container aar a198b62c577fa434941282fbfa31eb66ff0ff308a6573edf0b5dd01f4e38445d
module e2a1c62c7e5d1013b906bc6ff5056db3e797cda4505e2d7d229524b24ca67a0e
media3-database aar 520e6f814e42a7d428db187ac073b453c0fcba0f4f5f4edd1cf33fafd2cfb740
module c380fea161e80d8074215a20e86e3dc2c2d825de964ca87aee66c8331f5ae252
media3-datasource aar e22f9f779047ce951152c793af094593e7cbb52475a82d56fa4f869fd319e700
module 9d32d2ec6a983ee9f418bcc05777aa23eee4db37bf794f44fb66a05d6f22e963
media3-decoder aar a9fb2b8fa1d54b4a8d6bda98a1c655b04d59c74b3ace7e2503e9e39830f13aee
module 388d5226366edd1facf8eec42cb5420871a46032d545286e90eaea8454789580
media3-exoplayer aar 19090f829afbbb595d67618f59c212f72b433ac01dc72b47594cf42552c8ed61
module ba0b9ef325fa114baa0f2fbdb4caf54029606924be1999f4af02bed5f079756b
media3-extractor aar 3c823279356b64f4215a8c6cb1e6bfa60c533351a651786ad6fa69ad001ef1b1
module b3eb755d7373e4fd199ff80814005f3b303693dfb8ace16b5b9482655d49d493
Not tried on a phone yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Music's second part: the marked playlists' tracks are downloaded as
Jellyfin keeps them, on unmetered networks only, while the app is open
or resumes, and deleted once no marked playlist holds them. Each
track's tempo is worked out once on the phone: a BPM tag where the file
has one, else a minute decoded with MediaCodec and its spectral flux
autocorrelated (Tempo.kt, tested on the JVM). The music screen shows
what is kept and deletes it after asking.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Music's decisions as D47, and its first part: the music screen from the
account sheet, on Android, signs in to the person's Jellyfin with Quick
Connect, else a password, and lists their playlists of music to mark
for running. The token is in the keyring, the server and the marks in
the person's music.json, nothing on Train's server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>