Commit Graph

150 Commits

Author SHA1 Message Date
36002e513e feat: implement focus management for Continue Watching section in TV player 2026-02-27 21:03:45 +01:00
96a9419746 feat: enable code optimization and resource shrinking in release build 2026-02-27 19:34:08 +01:00
d02e39b674 feat: add release directory to .gitignore 2026-02-27 19:01:20 +01:00
78f03096dd feat: make prerequisits for app publication 2026-02-27 18:52:14 +01:00
06272eb08a feat: Add D-pad seeking and auto-focus seek bar in TV player
D-pad left/right now seeks -10s/+10s both when controls are hidden
and when the seek bar is focused. Controls auto-focus the seek bar
when shown, removing the need to press OK first to interact.
2026-02-27 18:52:14 +01:00
71d2ef9534 feat: Show TV player controls on D-pad or OK button press 2026-02-27 18:12:28 +01:00
e4b99354f6 feat: Back gesture should hide controls in tv module 2026-02-27 17:42:05 +01:00
2b27ce946d feat: Add TV focus states and refactor content screens to LazyColumn
- Add animated focus feedback (scale, border, background) to all interactive
  TV UI components: PosterCard, GhostIconButton, MediaActionButton,
  MediaResumeButton, PurefinIconButton, TvHomeDrawer nav items,
  TvHomeSections cards, TvPlayerScreen track/queue panels
- Refactor EpisodeScreen, MovieScreen, and SeriesScreen from Scaffold +
  verticalScroll to LazyColumn layout with Box-overlaid top bar
- Switch MovieComponents and MovieScreen from MovieUiModel to core Movie model
- Conditionally render cast sections only when cast is non-empty
2026-02-27 17:24:05 +01:00
cccb20312b fix: Prevent tap gesture handler from interfering with seek drag
The detectTapGestures and drag awaitEachGesture handlers competed for
pointer events, causing drag() to sometimes end prematurely and the
seek to not fire. A shared dragActive flag now gates tap/double-tap
callbacks so they are suppressed during active drags.
2026-02-27 16:22:54 +01:00
318b190061 Code cleanup 2026-02-22 19:08:28 +01:00
fe699d7f99 refactor: Fix repository switch between offline and online. Now it switches seamlessly 2026-02-22 18:41:46 +01:00
d90612a056 feat: Remove quick play content on the Nextup section 2026-02-22 15:48:16 +01:00
8c7ddab9c2 feat: Implement Episode download functionality 2026-02-22 15:41:42 +01:00
9ec09a0e94 feat: Allow offline mode in Purefin 2026-02-22 15:41:08 +01:00
4ecb402e69 refactor: extract InMemoryMediaRepository from InMemoryAppContentRepository
- Create InMemoryMediaRepository to hold in-memory media state (movies,
  series, episodes), lazy series content loading, and watch progress updates
- InMemoryAppContentRepository delegates MediaRepository via Kotlin's by
  delegation, injecting InMemoryMediaRepository as a composite component
- CompositeMediaRepository now uses InMemoryMediaRepository directly as the
  online repository instead of AppContentRepository
2026-02-22 14:38:22 +01:00
69fda1fef2 refactor: add CompositeMediaRepository to switch between offline/online based on user session
Extract AppContentRepository interface from MediaRepository for home/library-specific features.
CompositeMediaRepository delegates to OfflineMediaRepository or AppContentRepository based on
UserSessionRepository.isOfflineMode, allowing content ViewModels to use a single MediaRepository
interface that automatically switches data source.
2026-02-22 14:18:27 +01:00
d5c0bbded6 feat: add DownloadsViewModel for managing offline media downloads 2026-02-22 13:41:52 +01:00
ce126988d9 feat: add images to libraries on LibrariesContent screen 2026-02-22 12:50:56 +01:00
843bd749b1 feat: remove offline state toggle button 2026-02-22 11:17:03 +01:00
67ef5c3edf Code cleanup 2026-02-22 11:14:57 +01:00
781d36cc99 refactor: replace Room backing store in InMemoryMediaRepository with MutableStateFlows
- Remove RoomMediaLocalDataSource dependency from InMemoryMediaRepository;
  libraries, movies, series, and episodes are now held in MutableStateFlows
- observeSeriesWithContent derives from _series flow via map {}
- updateWatchProgress mutates _movies / _episodes in-memory
- ensureSeriesContentLoaded checks and updates _series in-memory
- Reorganize Room package: move entities/DAOs from local/room to room/entity and room/dao
2026-02-22 11:05:28 +01:00
c72283c566 refactor: replace NavigationDrawer with NavigationBar on HomeScreen
Converts the mobile home screen from a ModalNavigationDrawer to a
bottom NavigationBar with three tabs: Home, Libraries, and Downloads.
2026-02-22 11:05:27 +01:00
6f34190ed0 feat: add player screen to TV app via compose navigation
- Add PlayerRoute to the Route sealed interface
- Refactor PlayerViewModel to expose loadMedia() for external callers
- Add onPlay() to EpisodeScreenViewModel and MovieScreenViewModel
- Wire play/resume buttons in TV episode and movie screens
- Create TvPlayerScreen with TV-optimized controls: seek bar, playback
  buttons, track selection panels, queue panel, and state cards
- Register PlayerRoute in TvRouteEntryBuilder and TvNavigationModule
- Add media3-ui dependency to app-tv module
2026-02-22 11:05:27 +01:00
f85ecc04c7 feat: add content screens to TV app (movies, series, episodes)
- Created MovieScreen, MovieComponents for movie detail view
- Created SeriesScreen, SeriesComponents for series detail with season selection
- Created EpisodeScreen, EpisodeComponents for episode detail view
- Copied all required common UI components from mobile app
- Updated TvNavigationModule with route entry builders
- Updated TvRouteEntryBuilder with new screen entries
- Added missing launcher resources for TV app build
- All screens reuse ViewModels from :feature:shared module
- TV app now supports browsing movies, series, and episodes
2026-02-22 11:05:27 +01:00
75f3313aa9 feat: add :app-tv module as Android TV starting point
Creates a new :app-tv application module that reuses shared business
logic from :core:model, :core:data, :core:player, and :feature:shared,
with its own TV-specific UI layer.

- TvApplication + TvActivity with full Hilt + Navigation3 wiring
- TvHomePage reusing HomePageViewModel from :feature:shared
- Copied common UI components (PosterCard, WaitingScreen, etc.)
- Copied login screen and form components
- TV navigation module with Home + Login route entry builders
- Material3 theme copied from mobile (ready for TV customization)
- AndroidManifest with LAUNCHER + LEANBACK_LAUNCHER intent filters
- Excludes :feature:download (downloads are mobile-only)
2026-02-22 11:05:27 +01:00
7333781f83 refactor: modularize app into multi-module architecture 2026-02-22 11:05:26 +01:00
8601ef0236 Added README.md 2026-02-22 11:05:26 +01:00
feb2bdd9e9 fix: do not show next up section header if no content available 2026-02-22 11:05:26 +01:00
455d8957fd fix: remove left in background for gesture testing 2026-02-22 11:05:26 +01:00
72982a0f48 fix: fix gesture layout 2026-02-22 11:05:26 +01:00
969f6dc5fd revert: restore separate ContinueWatching and NextUp sections
Manually reverts c5b613e which combined the two sections. Restores
the NextUp UI section, data flow, and dedicated API call.
2026-02-22 11:05:15 +01:00
a86d496ff9 fix: consume vertical drag events to prevent overlay toggle
Vertical drag gestures (brightness/volume) were not consuming pointer
events, causing detectTapGestures to fire onTap and toggle the player
overlay when the gesture ended.
2026-02-22 11:05:05 +01:00
6191098158 feat: use MediaResumeButton with progress in Movie and Episode screens
Replace MediaPlayButton with MediaResumeButton in both MovieComponents
and EpisodeComponents, converting Double progress (0-100) to Float (0-1).
2026-02-22 11:04:25 +01:00
17ddc0b160 feat: update WatchStateIndicator and UnwatchedEpisodeIndicator sizes and styles 2026-02-19 17:51:22 +01:00
f3dd2a0783 feat: remove quick play button from the ContinueWatchingCard on Homepage 2026-02-19 11:03:41 +01:00
62606fc7a4 cleanup: remove unused component 2026-02-19 11:01:20 +01:00
90a66ef7e3 fix: Change SearchField bg color so it is can be seen easier 2026-02-19 10:57:27 +01:00
7d564c2470 feat: Generated MUI3 Color scheme 2026-02-19 10:56:37 +01:00
ed7d0f23d6 fix: Prevent rendering empty Continue Watching section 2026-02-18 20:13:02 +01:00
c5b613e301 refactor: combine ContinueWatching and NextUp sections. 2026-02-18 19:55:51 +01:00
82547a781c feat: Add HomeData caching for faster application loading 2026-02-18 19:05:53 +01:00
198e40d1e8 fix: Prevent duplicate API calls on app startup
ensureReady() had a race condition where concurrent callers from init
block and ViewModels would all run the loading logic simultaneously.
Added Mutex to ensure only the first caller loads; others await.

Also added a cooldown to refreshHomeData() since LifecycleResumeEffect
fires immediately on first composition, triggering a redundant reload
right after the initial load completes.
2026-02-18 18:52:05 +01:00
9a9cb9c2e7 refactor: Do not use JellyfinApiClient in viewModels. Use MediaRepository for consistency 2026-02-18 18:37:57 +01:00
1a46247da0 feat: Integrate OfflineRoomMediaLocalDataSource into InMemoryMediaRepository for library management 2026-02-18 18:24:26 +01:00
a0dbef3dc1 feat: Added library to the database scheme and to the MediaRepository. LibraryViewModel now uses it. 2026-02-18 17:56:29 +01:00
e7d2fa3d62 feat: Use fraction for the size of MediaHero component 2026-02-18 15:53:24 +01:00
88a8f6f90d fix: Add default index if season wihtout index received from server 2026-02-18 12:08:15 +01:00
a4b28b1dc7 fix: prevent popping the last item from backStack if it's the only item 2026-02-18 12:07:30 +01:00
f215c93608 fix: restore subtitles after backward seek
Switch seek parameters from CLOSEST_SYNC to PREVIOUS_SYNC so seeks always
land at or before the requested position, preventing subtitle cues from
being skipped. On backward seek discontinuity, briefly disable and re-enable
the text track to flush TextRenderer state so the current cue is re-delivered.
2026-02-17 21:23:34 +01:00
19273d2cb9 feat: Added purefin logo 2026-02-17 21:07:08 +01:00