Episodes missing season/identity fields from Jellyfin previously crashed
the converter due to non-null assertions. Introduce an Uncategorized
sentinel season appended to a series via Series.allSeasons so these
episodes are selectable in the season tabs on both phone and TV.
- Add UNCATEGORIZED_SEASON_ID/SERIES_ID/LABEL constants in core-model
- Make BaseItemDtoConverter null-safe and partition uncategorized episodes
- InMemoryLocalMediaRepository collects uncategorized episodes per series
- OfflineRoomMediaLocalDataSource persists and reconstructs the sentinel
- SeriesScreen and TvSeriesScreen use allSeasons for tab rendering
- Bump compileSdk/targetSdk from 36 to 37 across all modules
- Upgrade gradle wrapper to 9.6.1
- Upgrade agp to 9.3.0, kotlin to 2.4.10, ksp to 2.3.10
- Upgrade composeBom to 2026.06.01 and compose libs
- Upgrade hilt to 2.60.1, room to 2.8.4, media3 to 1.10.1
- Upgrade okhttp to 5.4.0, coil to 3.5.0, datastore to 1.2.1
- Upgrade lifecycle to 2.11.0, activity-compose to 1.13.0
- Upgrade firebase crashlytics to 20.1.0, gms services to 4.5.0
Move playback-related media state into shared model types and make the player consume a single PlayableMedia object instead of separately loading MediaItems, track preferences, resume positions, and media segments.
This updates PlayableMediaRepository to return playable media bundles, seeds the player playlist with the current item, keeps next-up entries in the same model, restores resume/segment handling, and fixes current queue highlighting.
The change also moves track preference models into core-model, centralizes Jellyfin BaseItemDto conversion, removes placeholder movie audio/subtitle fields, bumps the offline Room schema, and updates mobile/TV queue UI code for the playlist model.
Verification:
./gradlew --no-daemon :core-model:compileDebugKotlin :core:compileDebugKotlin :data:compileDebugKotlin :app:compileDebugKotlin