Navigation up/back split, faster startup, and CI versionCode fix
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 4m57s
Traceability Validation / Check Requirement Traces (push) Successful in 22s
Build & Release / Run Tests (push) Successful in 5m13s
🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m30s
Build & Release / Build Linux (push) Successful in 17m52s
Build & Release / Build Android (push) Failing after 58s
Build & Release / Create Release (push) Has been skipped

Navigation:
- Split conflated "back" into navigateUp (deterministic route parent) and a
  history-safe navigateBack that tracks in-app depth via afterNavigate instead
  of history.length. Fixes the resume-from-background trap where a stale WebView
  stack left the header arrow stuck on the current page.
- /library self-corrects for music/tv/movies (which have dedicated landing
  pages): a leftover currentLibrary no longer forces the inline content-list
  view, so "up"/back shows the libraries overview. Live TV / channels / other
  types still render inline.

Startup (unblock first paint):
- auth.initialize() no longer awaits security-status, player-config, or session
  verification before flipping isInitialized. These run fire-and-forget after the
  session is restored, so the library overview paints without waiting on several
  serial IPC round-trips.

Versioning / CI:
- tauri.conf.json + package.json aligned to 0.0.15 (the tag series had drifted to
  0.1.0, whose formula-derived versionCode 1000 outran the v0.0.x tags).
- Release workflow now pins a monotonic Android versionCode
  (1000 + major*10000 + minor*100 + patch) so tagged builds never downgrade
  below prior installs and always increase in semver order.

Tests: navigation (4), auth (29), playbackMode (23) green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 21:12:36 +02:00
co-authored by Claude Opus 4.8
parent 1992a8187d
commit 2e479d05b3
13 changed files with 278 additions and 94 deletions
+7
View File
@@ -22,9 +22,16 @@
showGlobalMiniPlayer as computeShowGlobalMiniPlayer,
routeOwnsLayout as computeRouteOwnsLayout,
} from "$lib/utils/layoutShell";
import { registerNavigationTracking } from "$lib/utils/navigation";
let { children } = $props();
// Track in-app navigation depth so the header "back" affordance knows when a
// real in-app Back exists (vs. a stale WebView stack after a background /
// restore). Must run during component init — afterNavigate needs a component
// context, not the async onMount callback below.
registerNavigationTracking();
// Layout-shell visibility rules live in one pure, unit-tested module
// ($lib/utils/layoutShell) so they can't drift per route/platform.
//
+20 -3
View File
@@ -17,6 +17,23 @@
const isMusicLibrary = $derived($currentLibrary?.collectionType === "music");
// Music/TV/Movies libraries have their own dedicated landing pages
// (/library/music, /library/tv, /library/movies). When `currentLibrary` is one
// of those, any inline "library content" view here is a STALE leftover from
// navigating into that page — showing it makes "up"/back from that page render
// the library's item list instead of the libraries overview. Treat those types
// as "no inline content" so this page always shows the overview for them,
// whether we arrived via the header Up affordance or the hardware back button.
// Live TV / channels / other types still render their content inline here.
const currentLibraryHasDedicatedPage = $derived(
$currentLibrary?.collectionType === "music" ||
$currentLibrary?.collectionType === "tvshows" ||
$currentLibrary?.collectionType === "movies"
);
const showInlineLibraryContent = $derived(
!!$currentLibrary && !currentLibraryHasDedicatedPage
);
// Filter out Playlist libraries - they belong in Music sub-library
const visibleLibraries = $derived.by(() => {
return $libraries.filter(lib => lib.collectionType !== "playlists");
@@ -176,8 +193,8 @@
onItemClick={handleItemClick}
/>
</div>
{:else if $currentLibrary}
<!-- Library content -->
{:else if showInlineLibraryContent}
<!-- Library content (live TV / channels / other inline-rendered types) -->
<div class="space-y-6">
<div class="flex items-center gap-4">
<button
@@ -189,7 +206,7 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
</svg>
</button>
<h1 class="text-2xl font-bold text-white">{$currentLibrary.name}</h1>
<h1 class="text-2xl font-bold text-white">{$currentLibrary?.name}</h1>
</div>
{#if isMusicLibrary}
+3 -3
View File
@@ -2,8 +2,8 @@
<script lang="ts">
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { navigateBack } from "$lib/utils/navigation";
import { currentLibrary } from "$lib/stores/library";
import { navigateUp } from "$lib/utils/navigation";
import { library, currentLibrary } from "$lib/stores/library";
import { movies } from "$lib/stores/movies";
import { isServerReachable } from "$lib/stores/connectivity";
import { useServerReachabilityReload } from "$lib/composables/useServerReachabilityReload";
@@ -86,7 +86,7 @@
<div class="flex items-center justify-between px-4">
<h1 class="text-3xl font-bold text-white">{$currentLibrary?.name ?? "Movies"}</h1>
<button
onclick={() => navigateBack("/library")}
onclick={() => { library.setCurrentLibrary(null); navigateUp("/library"); }}
class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
title="Back to libraries"
aria-label="Back to libraries"
+3 -3
View File
@@ -2,9 +2,9 @@
<script lang="ts">
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { navigateBack } from "$lib/utils/navigation";
import { navigateUp } from "$lib/utils/navigation";
import { auth } from "$lib/stores/auth";
import { currentLibrary } from "$lib/stores/library";
import { library, currentLibrary } from "$lib/stores/library";
import { music } from "$lib/stores/music";
import { isServerReachable } from "$lib/stores/connectivity";
import { useServerReachabilityReload } from "$lib/composables/useServerReachabilityReload";
@@ -108,7 +108,7 @@
<div class="flex items-center justify-between px-4">
<h1 class="text-3xl font-bold text-white">Music</h1>
<button
onclick={() => navigateBack("/library")}
onclick={() => { library.setCurrentLibrary(null); navigateUp("/library"); }}
class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
title="Back to libraries"
aria-label="Back to libraries"
+3 -3
View File
@@ -2,8 +2,8 @@
<script lang="ts">
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { navigateBack } from "$lib/utils/navigation";
import { currentLibrary } from "$lib/stores/library";
import { navigateUp } from "$lib/utils/navigation";
import { library, currentLibrary } from "$lib/stores/library";
import { tv } from "$lib/stores/tv";
import { isServerReachable } from "$lib/stores/connectivity";
import { useServerReachabilityReload } from "$lib/composables/useServerReachabilityReload";
@@ -93,7 +93,7 @@
<div class="flex items-center justify-between px-4">
<h1 class="text-3xl font-bold text-white">{$currentLibrary?.name ?? "TV Shows"}</h1>
<button
onclick={() => navigateBack("/library")}
onclick={() => { library.setCurrentLibrary(null); navigateUp("/library"); }}
class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
title="Back to libraries"
aria-label="Back to libraries"