Commit Graph
13 Commits
Author SHA1 Message Date
dtourolle 93d198ce21 domain: primaryImageTag -> imageId end-to-end (phase 4a/4b)
Rust: PlayerMediaItem and MergedMediaItem gain image_id (dual-carry),
populated from primary_image_tag at every construction/conversion site.
Regenerated bindings.

Frontend: all catalog + player + merged readers now use imageId. The
NowPlayingItem->MediaItem bridge (player.ts) properly maps the remote
session's Jellyfin fields (Type, runTimeTicks, primaryImageTag) onto the
neutral kind/durationMs/imageId. Types that are genuinely out of scope
(Person, NowPlayingItem, PlayItemRequest) keep primaryImageTag.

Rust 456, frontend 644, check clean.
2026-07-23 21:40:58 +02:00
dtourolle 7660a33dfc domain: catalog frontend off Jellyfin ticks -> milliseconds (phase 3a)
The catalog surface now speaks milliseconds, the app's neutral time unit.
Ticks no longer reach library/home components.

Rust:
- UserData gains playback_position_ms (dual-carry), populated from ticks
  at the offline mapping seam via domain::ticks_to_ms.

Frontend:
- formatDuration(duration.ts) and the two local copies now take ms, not
  ticks; all callers pass item.durationMs.
- Progress bars (EpisodeRow, EpisodeFocusView, MediaCard, LibraryListView)
  compute playbackPositionMs / durationMs — unit-consistent, no tick math.
- PlaylistDetailView totalDuration sums durationMs.
- duration.test.ts + TrackList.test.ts fixtures updated to ms.

Deferred: player/session/reporting tick math (Queue, SessionCard,
RemoteControls, playbackReporting, playerEvents) — those cross the
storage/Jellyfin command boundary in ticks and need command-signature
changes (phase 3b). Display {item.type} badge -> kind label (phase 4).

Rust 456, frontend 644, check + check:boundary clean.
2026-07-23 21:30:04 +02:00
dtourolle 772e9ca6d5 domain: flip catalog frontend off Jellyfin item-type strings (phase 2a)
Migrate catalog MediaItem consumers from stringly item.type ("Audio",
"MusicAlbum", …) to the neutral item.kind enum across all classification
logic: home, library detail, player routing, artist/person/related/genre
components, tv store.

Model refinements found during migration (each a real distinction the
flat item_type collapsed):
- MediaKind::LiveChannel — live TV (playable, non-seekable) vs
- MediaKind::ChannelItem — channel VOD leaf (playable, seekable) vs
- MediaKind::Channel — channel container (drill-in).
  TvChannel->LiveChannel, non-folder ChannelFolderItem->ChannelItem.

RelatedItemsSection and GenreTags props migrated from Jellyfin type
strings to MediaKind; MediaKind re-exported from api/types.

Deferred by design: display {item.type} text, ResultsCounter labels,
Person.type (role), stream.type (phase 4), and all runTimeTicks/tick math
(coupled to playbackPositionTicks — phase 3). Old fields still dual-carried
so nothing breaks.

Rust 456 + 7 domain tests, frontend 644 tests, check clean.
2026-07-23 21:12:20 +02:00
dtourolle f25deba824 feat(downloads): browsable downloaded library with on-disk usage
Replace the flat download list with a Downloaded browse surface that
reuses the online grids/cards/detail pages, filtered to on-device media,
plus a demoted Transfers tab. Add repository browse commands
(getDownloadedLibraries/Items, disk usage) with offline/hybrid
implementations, a downloadedCatalog service, formatBytes helper, and
per-item/device disk-usage labels on cards and grids. Regenerated
bindings.

Also carries the inseparable UR-052 offline-filter hunks in
offline.rs/hybrid.rs.

TRACES: UR-055 | DR-081, DR-082, DR-083, DR-084; UR-056 | DR-085
2026-07-23 20:02:55 +02:00
dtourolle acb7e5f221 fix offline mode and layout bugs
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 4m32s
Traceability Validation / Check Requirement Traces (push) Successful in 22s
Build & Release / Run Tests (push) Successful in 5m21s
🏗️ Build and Test JellyTau / Android Compile Check (push) Successful in 4m25s
Build & Release / Build Linux (push) Successful in 17m31s
Build & Release / Build Android (push) Successful in 22m5s
Build & Release / Create Release (push) Successful in 16s
2026-07-06 20:24:46 +02:00
dtourolleandClaude Opus 4.8 342f95cac1 Wire up playback reporting, fix duration flash, hide video from audio mini player
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 4m14s
Traceability Validation / Check Requirement Traces (push) Successful in 21s
🏗️ Build and Test JellyTau / Build Android APK (push) Successful in 19m3s
Playback reporting (position sync / resume-on-another-device):
- player_configure_jellyfin now builds a PlaybackReporter sharing the player
  controller's Arc, so Start/Progress/Stopped actually reach Jellyfin on every
  auth path (login/restore/reauth); previously they never did.
- The PlaybackReporterWrapper now shares the same Arc the controller and MPV
  progress loop report through, instead of a dead parallel Option.
- Android position callbacks now emit throttled progress reports (30s/item),
  mirroring the MPV backend.

Duration flash on pause:
- resolveDuration() prefers the live store duration for the already-loaded
  track over the runTimeTicks estimate, so pausing no longer clobbers the
  slider's max to 0 when runTimeTicks is missing.

Video leaking into audio mini player:
- isVideoItem() also checks the backend PlayerMediaItem mediaType
  discriminator, so a video started via player_play_item (no Jellyfin `type`,
  mediaType "video") no longer surfaces in the audio mini player.

Middle-truncation of long media names:
- New truncateMiddle util applied to track/episode/card/mini-player titles so
  distinguishing tails (episode numbers, suffixes) stay visible.

Adds regression tests for the duration and mini-player fixes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:52:27 +02:00
dtourolle 14e9d7e03a E frontend reconciliation (2/2): align consumers to generated bindings; svelte-check clean
Traceability Validation / Check Requirement Traces (push) Failing after 21s
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 13m21s
🏗️ Build and Test JellyTau / Build Android APK (push) Failing after 2m14s
Reconcile the ~50 frontend files that consumed the old hand-written types against
the stricter generated bindings (141 -> 0 svelte-check errors):

- Nullable strictness: null-coalesce/guard at consumer sites; widen shared helpers
  (CachedImage.tag, ticksToSeconds, formatDuration, getSessionIcon, session store
  send*/transferToRemote) to accept null.
- Field-name fixes exposed by codegen: userData.played -> isPlayed; remote
  NowPlayingItem uses album (not albumName); ArtistItem id/name.
- player.ts: normalize remote NowPlayingItem -> MediaItem in mergedMedia.
- ArtistItem now serializes camelCase (PascalCase alias retained for Jellyfin
  deserialize); update its serialize test.
- Update downloads.test.ts to the bundled { request } shape; complete the
  sessions.test.ts NowPlayingItem mock.

Frontend: svelte-check 0 errors, vitest 448 passing. Backend: 387 passing.
2026-06-20 20:49:20 +02:00
dtourolle c959c07ab4 Fixes for tests
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 31s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 3s
2026-06-20 15:28:15 +02:00
dtourolle e8e37649fa Many improvemtns and fixes related to decoupling of svelte and rust on android.
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 18s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 2s
2026-02-28 19:50:47 +01:00
dtourolle e3797f32ca many changes
Traceability Validation / Check Requirement Traces (push) Failing after 1m18s
🏗️ Build and Test JellyTau / Build APK and Run Tests (push) Has been cancelled
2026-02-14 00:09:47 +01:00
dtourolleandClaude Haiku 4.5 6d1c618a3a Implement Phase 1-2 of backend migration refactoring
CRITICAL FIXES (Previous):
- Fix nextEpisode event handlers (was calling undefined methods)
- Replace queue polling with event-based updates (90% reduction in backend calls)
- Move device ID to Tauri secure storage (security fix)
- Fix event listener memory leaks with proper cleanup
- Replace browser alerts with toast notifications
- Remove silent error handlers and improve logging
- Fix race condition in downloads store with request queuing
- Centralize duration formatting utility
- Add input validation to image URLs (prevent injection attacks)

PHASE 1: BACKEND SORTING & FILTERING 
- Created Jellyfin field mapping utility (src/lib/utils/jellyfinFieldMapping.ts)
  - Maps frontend sort keys to Jellyfin API field names
  - Provides item type constants and groups
  - Includes 20+ test cases for comprehensive coverage
- Updated route components to use backend sorting:
  - src/routes/library/music/tracks/+page.svelte
  - src/routes/library/music/albums/+page.svelte
  - src/routes/library/music/artists/+page.svelte
- Refactored GenericMediaListPage.svelte:
  - Removed client-side sorting/filtering logic
  - Removed filteredItems and applySortAndFilter()
  - Now passes sort parameters to backend
  - Uses backend search instead of client-side filtering
  - Added sortOrder state for Ascending/Descending toggle

PHASE 3: SEARCH (Already Implemented) 
- Search now uses backend repository_search command
- Replaced client-side filtering with backend calls
- Set up for debouncing implementation

PHASE 2: BACKEND URL CONSTRUCTION (Started)
- Converted getImageUrl() to async backend call
- Removed sync URL construction with credentials
- Next: Update 12+ components to handle async image URLs

UNIT TESTS ADDED:
- jellyfinFieldMapping.test.ts (20+ test cases)
- duration.test.ts (15+ test cases)
- validation.test.ts (25+ test cases)
- deviceId.test.ts (8+ test cases)
- playerEvents.test.ts (event initialization tests)

SUMMARY:
- Eliminated all client-side sorting/filtering logic
- Improved security by removing frontend URL construction
- Reduced backend polling load significantly
- Fixed critical bugs (nextEpisode, race conditions, memory leaks)
- 80+ new unit tests across utilities and services
- Comprehensive infrastructure for future phases

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-13 23:34:18 +01:00
dtourolleandClaude Haiku 4.5 544ea43a84 Fix Android navigation and improve UI responsiveness
- Convert music category buttons from <button> to native <a> links for better Android compatibility
- Convert artist/album nested buttons in TrackList to <a> links to fix HTML validation issues
- Add event handlers with proper stopPropagation to maintain click behavior
- Increase library overview card sizes from medium to large (50% bigger)
- Increase thumbnail sizes in list view from 10x10 to 16x16
- Add console logging for debugging click events on mobile
- Remove preventDefault() handlers that were blocking Android touch events

These changes resolve navigation issues on Android devices where buttons weren't responding to taps. Native <a> links provide better cross-platform compatibility and allow SvelteKit to handle navigation more reliably.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-27 16:04:57 +01:00
dtourolle cfddc1edea First working POC 2026-01-26 22:21:54 +01:00