Linthra

io.github.thezupzup.linthra
by Zapstore _@zapstore.dev

Republished from GitHub / F-Droid by the Zapstore main account.

First release: Aug 3, 2026, 12 total releases.

Most recent release: Sep 19, 2026.

Repo

Appears in 0 app stacks.

0 sats / 0 zaps received in the past year.

Sats Received

Underlying data available via MCP: app_zaps, app_releases.

Zap Count

Underlying data available via MCP: app_zaps, app_releases.

Releases

  • Sep 19, 2026 0.2.7
    # Linthra v0.2.7 Linthra 0.2.7 is a large Android and Linux quality release. It fixes the Android Auto track-change regression reported in 0.2.6, makes the Linux local-library experience much more resilient, expands the desktop UI, and turns the GitHub Linux release into something users can install as a standalone Flatpak bundle. This release is cut from the current `main` work rather than waiting for the remaining feature PRs. Those continue toward the next release. ## Highlights ### Android Auto
    More…
    - **Next and Previous work again in Android Auto.** The media-session path now carries car controls all the way through Linthra's shared playback controller instead of letting the command disappear before the queue changes. - The regression coverage includes playing and paused states, reconnects, queue boundaries, shuffle/repeat interactions and exactly-once dispatch, so one steering-wheel/head-unit press cannot accidentally skip twice. - Track metadata remains synchronized after a car-originated track change. ### Android and accessibility - Local Android metadata now reads **disc numbers**, including common values such as `1` and `1/2`, so the data needed for proper multi-disc ordering is preserved. - TalkBack/accessibility semantics were audited and tightened across the main app surfaces, especially icon-only and stateful controls. - Selection mode keeps its scroll position instead of jumping a large library back to the top. ### Local music on Linux The local-library path received a substantial reliability pass: - **Multiple music folders** can make up one local library. - Linthra can **watch configured folders** and refresh automatically when files change. - Incremental scans avoid reparsing files that did not change. - Moved and deleted tracks are handled without treating every scan as a brand-new library. - A removable USB/SSD music library is kept when the drive is temporarily unplugged instead of being mistaken for deleted data. - Missing folders, permission errors and temporarily unavailable mounts now produce a recoverable state instead of silently looking like an empty library. - Embedded local cover art is extracted and cached, with follow-up fixes for scaling and cache invalidation. - The **Add folder** action now lives in **Folders**, where local-library management belongs, instead of the Library browsing header. ### Desktop experience Linthra's Linux UI is much closer to a first-class desktop player: - A persistent **queue side panel** can stay beside the main content on wide windows. - Queue items can be reordered with mouse or keyboard. - Playlists can be reordered and tracks can be dragged onto playlists. - A global **quick search** overlay is available from the desktop. - Compact and Comfortable density modes are available. - The Now Playing bar/view, panes, hover states, context menus and multi-select behavior received a large desktop polish pass. - Full keyboard navigation was added, followed by **configurable keyboard shortcuts**. - Mouse-wheel and trackpad behavior was tuned for desktop use. - Configured self-hosted sources can show their current availability state in the sidebar. - Optional desktop notifications can announce real track changes without exposing provider credentials or private paths. ### Playback and audio on Linux - Linthra can select the Linux audio output device. - Audio-device hotplug is handled cleanly when devices appear or disappear. - A broken/missing libmpv runtime is reported as a Linux runtime problem instead of being mislabeled as an ordinary track failure. - A failed track now has a shared recovery path for retry, skip and provider fallback where available. - Native playback diagnostics can be copied from Settings for troubleshooting. - Playback work that was being performed unnecessarily in the background was reduced. ### Library, queue and downloads - Entire albums and playlists can be downloaded for offline use. - Search now folds accents more consistently. - Recently played history is available in the desktop queue pane and received follow-up correctness fixes. - Queue operations and desktop interactions received additional regression coverage for large libraries and long-running sessions. ### Audiobookshelf groundwork - Linthra can connect to an Audiobookshelf server from Settings. - The initial browse/library foundation is present. - This is groundwork only; it should not be read as a claim that the complete Audiobookshelf playback experience is finished. ### Linux packaging - Stable GitHub releases can now publish a **standalone `.flatpak` bundle** in addition to the native Linux archive. - Flatpak audio and selected-folder library smokes run inside the packaged sandbox. - Smoke cleanup was hardened so local contributor app data is not removed by destructive test cleanup. - Flatpak permissions have written rationale and automated checks. - The Flathub linter is part of the packaging checks. - For this release, the Flatpak build moves to **GNOME Platform 51 / freedesktop-sdk 26.08** and the matching LLVM 22 SDK extension. Linthra is **not on Flathub yet**. The standalone Flatpak is a GitHub Release artifact. ## Privacy and project guardrails - The repository now has an independently runnable dependency-level audit for known advertising, analytics, attribution, telemetry and third-party crash-reporting SDKs. - The current expected result remains: no known advertising, analytics, attribution, telemetry/session-replay/APM or automatic third-party crash-reporting SDK is present in the shipped dependency graph. - This is deliberately a narrow claim: it does not replace review of Linthra's own network behavior. ## Casting Casting remains **temporarily unavailable in production** while the receiver-trust remediation tracked in #575 is still under review. Several Cast hardening pieces landed after 0.2.6, including receiver pinning/remembering groundwork and additional containment verification, but this release does **not** restore production Cast. There is no insecure fallback or user-facing bypass. ## Licensing Linthra's **current project license is AGPL-3.0-or-later**. The license transition happened after v0.2.4: - releases through **v0.2.4** remain under the MPL-2.0 terms under which they were published; - **v0.2.5 and later**, including v0.2.7, are released under **AGPL-3.0-or-later**. The Linthra repository metadata, AppStream metadata and the F-Droid metadata kept in this repository all declare `AGPL-3.0-or-later`. Historical MPL-2.0 text remains preserved for the releases to which it applies. F-Droid's separate canonical `fdroiddata` entry and some third-party listings may still show MPL-2.0 until their metadata is updated or refreshed; that synchronization is tracked in #659. That lag does not change the license of this release. ## Android and F-Droid Canonical Android version: - versionName: `0.2.7` - base versionCode: `207999` F-Droid split-ABI version codes: - armeabi-v7a: `2079991` - arm64-v8a: `2079992` - x86_64: `2079993` F-Droid builds from source at the release tag on its own infrastructure and signs with its own key. GitHub APKs and F-Droid packages use different signing keys, so continue updating from the same source you originally installed from. Linthra is not publicly available on Google Play. ## Linux artifacts The stable GitHub Release is expected to publish: - the native Linux x64 archive; - the standalone Flatpak bundle; - the signed Android APK/AAB artifacts handled by the release workflow. The Flatpak bundle targets GNOME Platform 51. Installing the bundle can fetch that runtime from Flathub when it is not already present. ## Upgrade notes No manual data migration is required. Your configured libraries, queue, downloads, server sessions and playback settings are intended to remain in place across the update. Temporarily unavailable local folders/drives are preserved rather than treated as deleted. ## Community Thank you to everyone testing Linthra, reporting regressions, suggesting features and contributing code. The Android Auto report that led to #638/#643 is exactly the kind of real-device feedback that makes the app more reliable.
  • Sep 8, 2026 0.2.6
    # Linthra v0.2.6 Linthra 0.2.6 is a security maintenance release. Casting is temporarily turned off while a security fix is finished, and the release also carries the Linux desktop and Android library work that landed since 0.2.5. Updating is recommended for anyone who has used or might use casting. ## What's new ### Casting
    More…
    - **Casting is temporarily unavailable.** Linthra will not hand a track to a Cast receiver in this build. The cast control is still there, but it is muted and the device sheet explains that casting is off for now rather than offering devices. This is a deliberate, temporary safeguard while a reported security issue is resolved, not a removal of the feature. See below. ### Android - **A large music folder no longer freezes the app while it scans.** Picking a folder used to walk the whole tree on Android's main thread, one query per folder plus metadata and artwork extraction per file. On a real library that froze the UI and could end in an ANR. The scan now runs on a background thread and replies once when it is done, so the app stays responsive. Picking a second folder supersedes the first: the older scan stops rather than making you wait out a folder you already moved on from. No change to the permission model: the same folder grant, no MediaStore, no broad storage access. ### Linux - **Media keys and desktop media controls work.** Linthra now exports an MPRIS media session, so it shows up in GNOME's lock screen and top bar, KDE's media applet, and `playerctl`, and hardware media keys drive it. Play, pause, stop, next, previous, seek and absolute position are all wired, along with shuffle, repeat and the track's title, artist, album and duration. - Two things are deliberately not published on the session bus: the track's URL (for a streamed track that is an authenticated URL, for a local one it is your file path) and any cover reference that is not a plain loadable image. The track identifier is a counter, not your library's own id. - **Local files show their real tags.** A local Linux library used to show filenames. Linthra now reads title, artist, album, album artist and duration from the files themselves, parsing tags rather than loading whole files, and without pulling cover images out of every file during a scan. A file with missing, unsupported or broken tags still appears under its filename instead of vanishing. Embedded artwork is still to come. - **No more stray mpv cache file.** The audio backend was letting mpv keep an on-disk packet cache, which is the right default for a video player and the wrong one here, and which logged "Failed to create cache temporary file" on every stream where it could not write. That cache is now off. Memory and network buffering are unchanged, and Linthra's own offline downloads are a separate mechanism this does not touch. ### Project - **A security policy and a private reporting route.** The repository now has a `SECURITY.md` and GitHub private vulnerability reporting is enabled, so a security issue has somewhere to go that is not a public issue. Everything else behaves as it did in 0.2.5. Your queue, playback settings, saved servers, downloads and library are untouched by the update. ## Why casting is off A security researcher reported an issue in Linthra's Cast path through [private vulnerability reporting](https://github.com/TheZupZup/Linthra/security/advisories). The report is being handled in a private advisory, and the technical details stay there until a fix is ready and disclosure is coordinated with the reporter. There is no evidence that anyone was affected, and this release makes no such claim. The honest position until receiver identity can be verified properly is to not cast at all, so this release disables the path rather than papering over it. That containment is enforced in three independent places in the code, so a UI change or a single reverted line cannot quietly re-enable it. Public tracking issues: [#572](https://github.com/TheZupZup/Linthra/issues/572) (this containment), [#575](https://github.com/TheZupZup/Linthra/issues/575) (restoring casting properly) and [#576](https://github.com/TheZupZup/Linthra/issues/576) (reducing what any external playback device is given in the first place). Casting will come back in a later release, in a separate reviewed change. It is not restored by this one. ## Android and F-Droid The canonical Android version for this release is: - versionName: `0.2.6` - base versionCode: `206999` F-Droid's split-ABI scheme: - armeabi-v7a: `2069991` - arm64-v8a: `2069992` - x86_64: `2069993` F-Droid builds from source at this tag on its own infrastructure, so its build will follow once it picks the tag up. GitHub APKs and F-Droid packages are signed by different keys, so keep updating from the same install source you originally chose. They cannot update each other. Linthra is **not** publicly available on Google Play. ## Linux The native Linux x64 archive is published as usual: `Linthra-v0.2.6-linux-x64.tar.gz` Casting was never wired up on Linux, so that part of this release changes nothing there. Linthra is not on Flathub yet. ## Upgrade notes No manual migration is required. Update normally from the source you installed from. Your library, queue, downloads and saved servers stay exactly where they are. If you were using casting, it will stop being offered after this update. That is expected, and it is temporary. ## Reporting security issues If you have found something, please use [private vulnerability reporting](https://github.com/TheZupZup/Linthra/security/advisories/new) rather than a public issue. See [SECURITY.md](https://github.com/TheZupZup/Linthra/blob/main/SECURITY.md). ## Community Thank you to the reporter for a careful, responsibly disclosed report, and for coordinating privately while this was prepared. Thanks as always to everyone testing Linthra, filing issues, and contributing the desktop and library work in this release.
  • Sep 6, 2026 0.2.5
    # Linthra v0.2.5 Linthra 0.2.5 is the desktop release. It turns the Linux build from a phone layout stretched across a monitor into something that behaves like a desktop music player: a persistent navigation shell, layouts that adapt to the width they are actually given, and a window that finally identifies itself correctly to the desktop. Android gets a clearer local-music story, an Android Auto fix for large libraries, and more honest Jellyfin connection state. ## What's new - **Persistent desktop navigation.** Wide Linux windows get a navigation rail that stays put beside the content instead of a bottom bar. Each destination keeps its own stack, so switching tabs and coming back lands where you left off. Keyboard traversal reads the rail as one group rather than interleaving it with the page. - **Layouts adapt to the window, not to the platform.** Breakpoints are driven by the width a view is actually given, so a screen inside the rail measures the space it really has. Everything below 600 px is unchanged from the phone layout. - **Denser album and artist grids.** Album cards stay between 200 and 260 px and the grid adds columns instead of inflating covers: 5 across in a 1280-wide window, 7 at 1920, 9 at 2560, and more beyond. Artists flow into 3, 4 and 5 columns at the same widths instead of one row per monitor width. - **Album and artist detail get a side pane.** At expanded widths the cover or portrait, the counts, and Play/Shuffle sit in a persistent left pane beside the scrolling track list. Selection mode falls back to the single column.
    More…
    - **Now Playing and lyrics use the whole window.** The cover sits beside the metadata and transport at expanded widths, and lyrics open next to the cover instead of replacing it, sharing the same toggle and playback state. - **Single-column views stop stretching.** Songs, playlists, downloads and settings cap and centre their column, so a title and its trailing action never end up a screen apart. - **Resizing preserves state.** Crossing a breakpoint moves the navigation without rebuilding it, and inactive branch stacks survive the resize. - **Transport controls on the now-playing bar.** When the bar has room it carries favorite, previous, play/pause, next and a queue button. Previous and next follow the live queue and grey out at its ends. It is the same widget on a phone, so it sheds controls as the window narrows and below 360 px it is the bar we had before. - **Folders is a top-level destination.** It moved out of the Library tab strip and sits next to Library, Playlists, Downloads and Settings, so the folder trail survives a trip to another tab. - **The Linux window identifies itself correctly.** WM_CLASS now matches the app id exactly instead of the capitalised variant GDK derived by default, so shells that compare it exactly can group the window with its own launcher. This comes from the runner, so it applies to both Linux builds. - **The packaged Flatpak carries a real window icon.** The desktop entry declares the matching `StartupWMClass`, and the manifest installs raster icons alongside the scalable one so GTK's icon lookup resolves inside the sandbox and the window ships a `_NET_WM_ICON` for panels and task switchers. This is Flatpak-only: `linux/CMakeLists.txt` builds the executable, libraries and Flutter assets, so the native x64 archive still ships no desktop entry or icon and a user placing it on their system supplies those themselves. - **Music folders open through the desktop portal on Linux.** The runner registers its own folder picker backed by `GtkFileChooserNative`, which draws in process on a native build and routes to `xdg-desktop-portal` inside the sandbox. One code path serves both, and the Flatpak still ships without host filesystem access. - **Secure credential storage works inside the Flatpak.** Provider credentials go through the Secret portal, which every Flatpak may talk to, so this needs no extra sandbox permission at all: no session-bus socket, no D-Bus name grant. GNOME (gnome-keyring) and KDE Plasma 6 (KWallet's ksecretd) both provide that portal backend. On a desktop that provides none, Linthra reports a recoverable storage error and stays signed out rather than inventing storage of its own; a user who wants the Secret Service fallback can grant it themselves with `flatpak override --user`. - **Configured servers reach the network from the Flatpak.** The sandbox now permits the networking a configured server needs, and the finish-args parser handles quoted and commented entries correctly. - **Device-wide music access on Android is explicit.** Choosing your whole device library is now its own visible choice, separate from picking a folder, with its own permission flow and its own empty-state and error wording. Switching is transactional: a denied permission or a failed first scan leaves the previous folder and the indexed catalog exactly as they were. - **Android Auto no longer spins on the Songs list.** Songs is served in bounded browse pages, so large libraries load instead of overrunning the media browser's transaction buffer and never returning. - **Jellyfin connection state is real.** Configuration and reachability are tracked separately, so a LAN-only server you are away from reports as unavailable instead of "connected" while every stream fails. The catalog, playlists, favourites and downloads stay put. - **AppStream metainfo for software centres.** Linthra ships an AppStream component so Linux software centres can describe and list it. ## Linux and Flatpak status The GitHub Release still publishes the native Linux x64 archive: `Linthra-v0.2.5-linux-x64.tar.gz` Flatpak packaging in this repository is now building end to end on clean runners, with sandbox coverage for filesystem access and offline sources. Linthra is **not** published on Flathub yet, and this release does not claim a Flathub submission. The desktop work above is validated on the native Linux build and the packaged Flatpak. Runtime requirements and the current Linux support matrix are documented in `docs/linux-desktop.md`. ## Android and F-Droid Android remains a first-class target. The canonical Android version for this release is: - versionName: `0.2.5` - base versionCode: `205999` F-Droid's split-ABI scheme remains: - armeabi-v7a: `2059991` - arm64-v8a: `2059992` - x86_64: `2059993` GitHub APKs and F-Droid packages remain signed by different keys, so users should keep updating from the same install source they originally chose. Linthra is **not** publicly available on Google Play. CI can publish signed builds to a Google Play testing track; that is a distribution pipeline, not a public listing. ## Licensing This is the first release cut after the relicensing to **AGPL-3.0-or-later** (#535). Releases up to and including v0.2.4 remain under the MPL-2.0 terms they were published under, and that text is preserved at `docs/licenses/MPL-2.0.txt`. See `docs/license-transition.md`. v0.2.5 is therefore the F-Droid license cutover. Its `CurrentVersion` is the first cut from an AGPL source commit, so the F-Droid metadata's `License:` field moves to `AGPL-3.0-or-later` in this same change, as `docs/license-transition.md` requires. The historical `Builds` entries keep their pre-transition versions and are not relabelled. The matching update in the external `fdroiddata` repository still has to be made separately, along with the submission text, per `docs/fdroid-submission.md` §9. ## Upgrade notes No manual migration is required. Existing Android library and settings data remain in place during a normal same-source update, and Linux users can replace the previous native archive with the new one. Android users who previously pointed Linthra at a folder keep that folder. Device-wide music access is an opt-in choice, not a default. ## Community Thank you to everyone testing Linthra, reporting issues, reviewing changes, and contributing fixes. This release includes community work on desktop layout, Linux packaging, and playback robustness alongside the desktop shell and adaptive-layout work.
  • Aug 27, 2026 0.2.4
    # Linthra v0.2.4 Linthra 0.2.4 is a Linux packaging, desktop polish, accessibility, and project-safety release. It moves the Linux port closer to a packageable desktop application while tightening shutdown behavior and repository trust boundaries. ## What's new - **Flatpak packaging has moved from plan to a working foundation.** Linthra now carries the initial manifest/offline source pipeline, bundles the Linux audio runtime it needs, installs a desktop entry and scalable app icon, and documents local Flatpak development. This is packaging groundwork; Linthra is not yet published on Flathub. - **Desktop shutdown is deterministic.** Linthra waits for app-owned asynchronous teardown — including database, playback, control services, and caches — before shutdown completes, reducing exit/restart races. - **Keyboard and accessibility support is broader.** The custom seek bar can be operated from the keyboard, icon-only controls expose clearer semantics, cast/queue/source controls report their state better, and destructive dialogs default focus to Cancel. - **Large text no longer breaks the mini-player.** The compact player remains usable when text scaling is increased.
    More…
    - **Linux integration is more complete.** The application has a proper desktop launcher identity and scalable icon, while the packaged audio path is designed to be self-contained. - **Repository trust boundaries are substantially stronger.** PR security scanning and repository-integrity checks cover more sensitive surfaces and commit history, while trusted reporting can explain findings on fork PRs without executing contributor code. - **CI dependencies were refreshed.** `actions/setup-java` and `actions/github-script` moved to their current major versions after successful build validation. ## Linux / Flatpak status The GitHub Release still publishes the native Linux x64 archive: `Linthra-v0.2.4-linux-x64.tar.gz` Flatpak packaging is now present in the repository and suitable for local development/testing, but this release does **not** claim a Flathub publication yet. ## Android and F-Droid Android remains a first-class target. The canonical Android version for this release is: - versionName: `0.2.4` - base versionCode: `204999` F-Droid's split-ABI scheme remains: - armeabi-v7a: `2049991` - arm64-v8a: `2049992` - x86_64: `2049993` GitHub APKs and F-Droid packages remain signed by different keys, so users should keep updating from the same install source they originally chose. ## Upgrade notes No special user action is expected beyond a normal same-source update. Existing Android library/settings data remain in place during a normal update, and Linux users can replace the previous native archive with the new one. ## Community Thank you to everyone testing Linthra, reporting issues, reviewing changes, and contributing fixes. This release includes community work around desktop accessibility and UI robustness alongside the Linux packaging and project-hardening work.
  • Aug 20, 2026 0.2.3
    # Linthra v0.2.3 Linthra 0.2.3 is a community-driven stability and Linux desktop release, with stronger playback recovery, safer session restoration, better self-hosted server handling, and the first Audiobookshelf integration foundation. ## What's new - **Linux playback recovers instead of getting stuck.** Mid-stream server and network failures now use bounded recovery, a buffering watchdog, sibling-source fallback when available, and a clear Retry path instead of looping forever. - **Temporary network drops have a real reconnect state.** Now Playing can show **Reconnecting…** while Linthra re-resolves a fresh authenticated stream URL and resumes near the preserved position. - **Suspend/resume is much safer on Linux.** A track that was actively playing before system sleep can be re-resolved and reloaded after wake on the same player, while a track the user paused stays paused. - **Crash-safe Linux playback restoration.** After an unexpected restart, Linthra can restore the logical queue, current item, repeat/shuffle state, and position as a **paused** session. It never persists authenticated stream URLs or provider tokens, and remote tracks re-resolve normally when playback resumes.
    More…
    - **Audiobookshelf support has started.** This release adds the connection, authentication, server validation, session model, and library-listing foundation. Audiobook playback, chapters, progress sync, bookmarks, and offline audiobook support remain follow-up milestones. - **Self-hosted server URLs are more robust.** Jellyfin, Plex, and Subsonic/Navidrome now share one URL-normalization path, including correct handling for IPv6 literal hosts. - **Large source re-syncs are cheaper.** The local database now indexes `tracks.source_id`, avoiding a full catalog scan when one source is refreshed. Existing databases migrate automatically. - **Linux library defaults fit the desktop better.** The folder chooser can start from the user's XDG Music directory instead of assuming `~/Music`, including localized or relocated Music folders. - **System theme behavior is documented and guarded across desktop/mobile.** Linthra keeps one shared Flutter `ThemeMode.system` path rather than adding GNOME/KDE-specific theme code. - **Player accessibility improved.** The custom play/pause control now exposes the proper button role and enabled state to assistive technologies. ## Linux reliability The recent Linux playback work intentionally reuses Linthra's existing playback controller rather than creating provider-specific retry systems or extra players. Recovery is bounded, concurrent recovery triggers are coalesced, and failure still ends in a normal user-visible error/Retry state. Real hardware timing can vary after suspend — especially with Bluetooth, PipeWire/PulseAudio, or networking that returns after the Flutter lifecycle signal — so `docs/linux-desktop.md` includes the manual matrix used for milestone testing. ## Audiobookshelf status Audiobookshelf in v0.2.3 is the **first integration milestone**, not the complete audiobook player. The foundation validates the server before credentials are sent, uses the server's supported login/token flow, and keeps session parsing defensive against corrupt persisted data. The next milestones can build browsing/domain models, chapters/playback, progress sync, bookmarks, and offline behavior on top of this base without mixing audiobook behavior into the existing music providers. ## Android and F-Droid Android remains a first-class target. The Linux-specific recovery/restore paths are gated so Android screen-on and normal mobile lifecycle behavior do not begin auto-restarting playback. The canonical Android version for this release is: - versionName: `0.2.3` - base versionCode: `203999` F-Droid's split-ABI scheme remains: - armeabi-v7a: `2039991` - arm64-v8a: `2039992` - x86_64: `2039993` GitHub APKs and F-Droid packages remain signed by different keys, so users should keep updating from the same install source they originally chose. ## Linux download The GitHub Release workflow can attach: `Linthra-v0.2.3-linux-x64.tar.gz` This is the native Flutter Linux bundle, not the future Flatpak. Runtime requirements and the current Linux support matrix are documented in `docs/linux-desktop.md`. ## Upgrade notes No manual migration is required. The SQLite schema upgrade that adds the source index is handled automatically, and crash-safe playback state uses defensive versioned persistence. Existing Android library/settings data remain in place during a normal same-source update. ## Community A big part of v0.2.3 came from community contributions across self-hosted server support, Audiobookshelf, accessibility, database performance, Linux desktop integration, and playback reliability. Special thanks to **@jpdexter101-lang** and **@Borhan2004** for their contributions to this release. These acknowledgements are release-level thanks, not a one-to-one mapping between each nearby feature bullet and a specific commit author. Thank you to everyone testing Linthra, reporting edge cases, reviewing changes, and helping the project grow.
  • Aug 16, 2026 0.2.2
    # Linthra v0.2.2 Linthra 0.2.2 is a feature and stability release for Android, with the first official native Linux release path alongside it. ## What's new - **Now Playing feels smoother.** The playback progress control now uses Linthra's wavy seek bar, with a stable seek handoff so the marker does not snap back while the player catches up. - **Synced lyrics got a full presentation pass.** The active line follows cleanly in-place on Now Playing, surrounding lines use progressive emphasis, and the layout stays stable while the active line changes. - **Artwork survives restarts.** Remote artwork can be kept in Linthra's managed disk cache instead of being downloaded again every time the app opens. - **Automatic song precaching is optional.** It can be disabled independently; normal streaming and explicit/manual downloads keep working.
    More…
    - **Linux now has real native playback.** Linthra can build and run as a native Flutter Linux app using the Linux media backend, and official releases can publish an x64 Linux bundle from GitHub Actions. ## Stability and accessibility This release also includes fixes around seek acknowledgement, short lyrics layouts, timed-lyrics geometry, reduced-motion behavior, keyboard/screen-reader semantics in the updated player controls, and stronger Linux lifecycle/build validation. ## Android and F-Droid Android remains a first-class target and the normal F-Droid source-build path stays separate from GitHub release signing. The canonical Android version for this release is: - versionName: `0.2.2` - base versionCode: `202999` F-Droid's split-ABI build keeps Linthra's established `base * 10 + ABI rank` scheme: - armeabi-v7a: `2029991` - arm64-v8a: `2029992` - x86_64: `2029993` The release tooling now preserves that transformed F-Droid `CurrentVersionCode` instead of accidentally writing the untransformed base code. The committed `pubspec.lock`, Rust `Cargo.lock`, per-ABI Gradle override, and canonical GitHub per-ABI asset names remain part of the reproducible-build guardrails. F-Droid builds from source and can appear later than the GitHub Release while its own update/build/review pipeline runs. ## Linux download The GitHub Release workflow can attach: `Linthra-v0.2.2-linux-x64.tar.gz` This is the native Flutter Linux bundle, not the future Flatpak. It may still require the Linux runtime libraries documented in `docs/linux-desktop.md`. Flatpak/Flathub packaging and deeper desktop integration such as MPRIS remain separate roadmap work. ## Upgrade notes No migration step is required. Existing Android installs keep their library/settings data during a normal same-source update. As always, GitHub APKs and F-Droid packages are signed by different keys, so do not switch install sources on top of an existing installation.
  • Aug 10, 2026 0.2.1
    # Linthra v0.2.1 — release notes **Linthra v0.2.1 is a maintenance release focused on reproducible source builds and F-Droid compatibility.** It keeps the v0.2.0 player behavior intact while fixing the Rust dependency-locking issue that blocked F-Droid's source build pipeline. - **Version:** `0.2.1` (`versionName`), `versionCode` `201999` - **Platform:** Android - **Application ID:** `io.github.thezupzup.linthra` - **License:** MPL-2.0 ## What's new
    More…
    ### F-Droid source-build fix - Commits `native/linthra_core/Cargo.lock` so the Rust dependency manifest has a matching lockfile in the tagged source tree. - This resolves the dependency-scanner failure introduced when the standalone Rust core was added in v0.2.0. - Rust Clippy, unit tests, and the 200k-track benchmark now run with `--locked`, preventing CI from silently changing dependency resolution. ### No player behavior changes - Playback, local library behavior, Jellyfin, Navidrome / Subsonic, Plex, offline cache, casting, Android Auto, playlists, favorites, and onboarding remain functionally unchanged from v0.2.0. - This patch exists so the next immutable release tag contains the complete dependency-locking state F-Droid expects. ## Upgrade and distribution notes - Normal in-place updates preserve accounts, settings, playlists, catalog, favorites, and cache. - Do not mix GitHub and F-Droid installations because the APKs use different signing keys and cannot update one another. - F-Droid builds and signs its own APKs from the source tag; GitHub Release APKs are signed by the upstream project. - The existing `v0.2.0` tag remains untouched and immutable; v0.2.1 carries the source-build correction forward. No ads, no tracking, no analytics, no telemetry. Linthra plays music you already own or that your own server provides.
  • Aug 8, 2026 0.2.0
    # Linthra v0.2.0 release notes **Linthra is an Android music player for local files and self-hosted music servers.** v0.2.0 introduces a proper first-run experience for new installs and expands the project foundations for future performance work and broader open-source contributions. - **Version:** `0.2.0` (`versionName`), `versionCode` `200999` - **Platform:** Android - **Application ID:** `io.github.thezupzup.linthra` - **License:** MPL-2.0 ## What's new
    More…
    ### A real first-run welcome - New installs now open a guided welcome instead of dropping directly into an empty library. - The source chooser helps users start with local music, Jellyfin, Navidrome / Subsonic, or Plex. - Notification permission is deferred until the welcome has completed so first launch stays focused on setup. - The welcome can be replayed later from Settings. ### Existing installs stay out of the way - Linthra now records onboarding completion and detects Android install history during startup. - Existing users upgrading from an earlier version continue into the normal app instead of being treated like a fresh install. - The startup state is resolved before the router is built, preventing a temporary jump into the wrong screen. ### More resilient onboarding UI - The welcome layout now uses the actual SafeArea constraints and handles very short viewports without producing invalid layout constraints. - Regression coverage protects first-run routing, upgrade classification, onboarding persistence, and short-screen layout behavior. ## Project foundations for v0.2.x This release also opens more of Linthra to contributors working outside Dart while keeping these components deliberately separate from the shipped playback path until they are ready to be integrated. - A Rust `linthra_core` prototype provides a deterministic large-library search index and a 200k-track benchmark. - A native C++ audio DSP project defines an allocation-free processing chain, stable C ABI, EQ/preamp/limiter tests, and a realtime-safety benchmark. - Python and SQL tooling can generate and benchmark a deterministic 200k-track SQLite library. - CI now validates the Rust core, C++ DSP work, and large-library SQL benchmark independently. - Contributor documentation maps real areas where Dart, Kotlin, Rust, C++, Python, and SQL can be used in Linthra. These native and tooling projects are foundations for future work; v0.2.0 does not claim that Rust search or the C++ DSP chain has replaced the current Flutter playback/search implementation yet. ## Upgrade and distribution notes - Normal in-place updates preserve accounts, settings, playlists, catalog, favorites, and cache. - Existing installs should bypass the new first-run welcome automatically. - Do not mix GitHub and F-Droid installations because the APKs use different signing keys and cannot update one another. - F-Droid builds and signs its own APKs from the source tag; GitHub Release APKs are signed by the upstream project. No ads, no tracking, no analytics, no telemetry. Linthra plays music you already own or that your own server provides.
  • Aug 6, 2026 0.1.15
    # Linthra v0.1.15 — release notes **Linthra is an Android music player for local files and self-hosted music servers.** v0.1.15 is a focused player-interface stability release for Navidrome, Jellyfin, Plex, local music, offline cache, and casting. - **Version:** `0.1.15` (`versionName`), `versionCode` `115999` - **Platform:** Android - **Application ID:** `io.github.thezupzup.linthra` - **License:** MPL-2.0 ## What's new
    More…
    ### A steadier Now Playing screen - The Now Playing screen no longer jumps when playback moves between source, buffering, cache, casting, and error indicators. - The fix applies to Navidrome/Subsonic, Jellyfin, Plex, local music, offline cache, and casting because they share the same player status area. - The status area now reserves one stable height, keeping track metadata, the progress bar, and transport controls in place. - Long playback errors stay on one line with an ellipsis instead of expanding the layout. ### Better large-text support - The stable status area grows with the system text scale. - Larger accessibility text remains readable without overlapping or moving the controls. - A widget regression test verifies the transition from `Playing from Navidrome` to `Buffering…` to `Playing from Cache` without vertical movement. ## Upgrade and distribution notes - Normal in-place updates preserve accounts, settings, playlists, catalog, favorites, and cache. - No playback routing, seeking, provider, cache, or streaming behavior changed in this release. - Do not mix GitHub and F-Droid installations because the APKs use different signing keys and cannot update one another. - F-Droid builds and signs its own APKs from the source tag; GitHub Release APKs are signed by the upstream project. No ads, no tracking, no analytics, no telemetry. Linthra plays music you already own or that your own server provides.
  • Aug 5, 2026 0.1.14
    # Linthra v0.1.14 release notes **Linthra is an Android music player for local files and self-hosted music servers.** v0.1.14 improves album browsing, fixes compilation and collaboration grouping, adds full light/dark appearance support, and makes first-time server synchronization clearer. - **Version:** `0.1.14` (`versionName`), `versionCode` `114999` - **Platform:** Android - **Application ID:** `io.github.thezupzup.linthra` - **License:** MPL-2.0 ## What's new
    More…
    ### Compilation and collaboration albums stay together - Linthra now prefers a provider-namespaced album ID when grouping tracks. - Tracks from the same album remain grouped even when each track credits a different artist or collaborator. - Jellyfin and Plex also use their album-artist metadata when available; local files use an embedded album-artist tag when present. - Navidrome/Subsonic albums use the server-provided album ID without guessing an album artist. - Existing catalogs and settings are preserved by an additive database migration. - Allow or start a library sync after updating so existing tracks receive the new album metadata. ### A responsive album grid - The Albums tab now shows two cover-focused columns on phones instead of one full-width row per album. - Wider screens gain additional columns only when enough space is available. - Album artwork remains square, while long titles and artist names are safely truncated. - Tap and long-press behavior remains unchanged, including album navigation and bulk playlist actions. - Layout and semantics adapt to larger text sizes and accessibility tools. ### System, Light, and Dark appearance modes - Linthra now follows the phone's light or dark setting by default. - Settings → Appearance includes explicit System, Light, and Dark choices. - The selected mode is restored before the first frame, avoiding a theme flash at startup. - Light palettes were retuned and tested for readable contrast while preserving Linthra's visual identity. ### Clearer first synchronization - Empty-library screens now recognize active Jellyfin, Navidrome/Subsonic, and Plex synchronization. - Linthra names the source being synchronized when one source is active, and uses a general message when several are active. - Plex users are no longer shown the unrelated local-folder prompt while their server library is scanning. - Navidrome/Subsonic users no longer see a misleading empty-catalog message while the first sync is still filling the library. ## Release and F-Droid reliability - The release version remains fully defined in `pubspec.yaml`, with the matching in-app version enforced by tests. - F-Droid can detect the `v0.1.14` tag automatically and derive the three per-ABI version codes: `1149991`, `1149992`, and `1149993`. - Dependency resolution remains locked through the committed `pubspec.lock` and `flutter pub get --enforce-lockfile`. - Pull-request CI validates the Android release lint path before the immutable stable tag is created. - The stable publisher verifies the universal APK, AAB, and all three signed per-ABI APKs on the GitHub Release. ## Upgrade and distribution notes - Normal in-place updates preserve accounts, settings, playlists, catalog, favorites, and cache. - Run or allow one server-library sync after updating to populate the new album identifiers for existing tracks. - Do not mix GitHub and F-Droid installations because the APKs use different signing keys and cannot update one another. - F-Droid builds and signs its own APKs from the source tag; GitHub Release APKs are signed by the upstream project. No ads, no tracking, no analytics, no telemetry. Linthra plays music you already own or that your own server provides.
  • Aug 4, 2026 0.1.13
    ## F-Droid release reliability fix Linthra v0.1.13 carries forward the clean-reinstall protection intended for v0.1.12 while fixing the Android release-only lint failure that prevented v0.1.12 from producing APK and AAB artifacts. ### What’s new * Fixed the `lintVitalRelease` failure that blocked Android and F-Droid release builds. * Updated Android backup rules to use only storage domains supported by the pinned Android lint schema. * Added `lintVitalRelease` to pull-request CI so release-only Android resource errors are caught before a stable tag is created. * Preserved clean reinstall behavior: uninstalling and reinstalling Linthra no longer restores obsolete songs, settings, server state, or inaccessible folder references.
    More…
    * Normal in-place updates continue to preserve accounts, playlists, settings, catalog, and cache. * No database migration, UI feature, or playback behavior change is included in this release. ### Technical details * Removed unsupported `device_root`, `device_file`, `device_database`, and `device_sharedpref` backup domains. * Retained the supported `root`, `file`, `database`, `sharedpref`, and `external` exclusions. * Retained `android:allowBackup="false"` for debug, profile, and release builds. * Strengthened regression tests to prevent unsupported `device_*` domains from being reintroduced. * Implemented in PR #304. ### Upgrade notes Existing users can update normally without losing their data. Users who uninstall Linthra before reinstalling will receive a clean library rather than stale state restored by Android. GitHub and F-Droid builds use different signing keys and cannot update one another. Continue using the same installation source you currently use. No ads, no tracking, no analytics, no telemetry.
  • Aug 3, 2026 0.1.11
    # Linthra v0.1.11 — release notes **Linthra is an Android music player for local files and self-hosted music servers.** v0.1.11 is a **folder-browsing and Android navigation release**. It adds a real server-folder view for Jellyfin and Navidrome/Subsonic and makes the Android system Back button follow Linthra's navigation before exiting the app. - **Version:** `0.1.11` (`versionName`), `versionCode` `111999` - **Platform:** Android - **Application ID:** `io.github.thezupzup.linthra`
    More…
    - **License:** [MPL-2.0](../../LICENSE) - **Get it:** Available from the [GitHub Releases page](https://github.com/TheZupZup/Linthra/releases) first (signed APKs); [Obtainium](https://github.com/ImranR98/Obtainium) can track this repository for updates. The [F-Droid](https://f-droid.org/packages/io.github.thezupzup.linthra/) build follows after F-Droid detects the tag and completes its build process. ## What's new ### Browse by folder hierarchy - **New Folders tab.** Library now includes a Folders tab when a compatible Jellyfin or Navidrome/Subsonic server is connected. - **Real server structure.** Browse the hierarchy exposed by the server instead of relying only on Linthra's flat Songs, Albums, and Artists views. - **Direct playback.** Songs found inside a folder can be started immediately using Linthra's existing playback queue and track actions. - **Separate connected sources.** Jellyfin and Navidrome/Subsonic roots are shown independently when both are connected. - **Lightweight navigation.** Linthra requests one folder level at a time rather than recursively downloading the complete directory tree. - **Friendly states.** Loading, empty-folder, error, and retry states are handled inside the folder browser. ### Android Back navigation - **Nested folders return correctly.** Android Back moves to the previous folder before leaving the Folders tab. - **Detail screens return normally.** Album, artist, playlist, player, support, and settings-detail screens return to their parent screen. - **Main tabs return to Library.** Back from the root of Playlists, Downloads, or Settings returns to Library instead of closing Linthra immediately. - **Exit only from the true root.** Linthra closes normally only when Back is pressed from the root of Library with no internal state left to dismiss. - **Existing tab history is preserved.** The independent navigation stack and scroll position of each bottom-navigation tab remain intact. ## Technical summary - **Provider-neutral folder capability** ([PR #289](https://github.com/TheZupZup/Linthra/pull/289), closes [#282](https://github.com/TheZupZup/Linthra/issues/282)): a small optional folder-browsing contract lets supported providers expose root folders and one immediate child level without changing the normal music-source interface. - **Jellyfin folder browser:** reads music roots from `/Library/MediaFolders` and direct child folders/tracks from `/Items` with non-recursive requests. - **Navidrome/Subsonic folder browser:** reads music roots through `getMusicFolders`, indexes through `getIndexes`, and nested directories through `getMusicDirectory`. - **Credential-safe identifiers:** folder IDs stay opaque and never include an authenticated URL, password, token, or other secret. - **Central Android Back handling** ([PR #289](https://github.com/TheZupZup/Linthra/pull/289), closes [#285](https://github.com/TheZupZup/Linthra/issues/285)): root and branch navigators now cooperate so internal state is handled before the app exits. No dependency, Drift schema, account, playlist, download, cache, or media-library data migration is included in this release. ## Manual QA completed - [x] Browse a real Jellyfin folder hierarchy. - [x] Open nested folders and start a song directly from Folders. - [x] Use Android Back to return through nested folders. - [x] Use Android Back across Linthra detail screens and main tabs. - [x] Exit normally from the Library root. - [x] Dart formatting, Flutter analysis, full tests, privacy scan, Android debug build, and GitHub Sponsor simulation passed on the feature PR. ## Upgrade and distribution notes - No settings reset or database migration is required. - **Don't mix install sources.** A GitHub-release APK is signed with Linthra's key, while the F-Droid build is signed with F-Droid's key; the two cannot update each other. Stay with one source. - F-Droid detects stable tags automatically and builds from source. The local metadata mirror can be updated after tagging with the final tag commit SHA and per-ABI version codes. No ads, no tracking, no analytics, no telemetry. Linthra plays music you already own or that your own server provides.