Commit Graph

2126 Commits

Author SHA1 Message Date
Uruk
1ea7f0f491 refactor(casting): extract useCastPlayerProgress hook 2026-05-22 01:32:21 +02:00
Uruk
79c2829444 refactor(casting): extract useCastDismissGesture hook 2026-05-22 01:22:21 +02:00
Uruk
87e0b0006b refactor(casting): extract useCastEpisodes hook 2026-05-22 01:18:08 +02:00
Uruk
3c71c08591 refactor(casting): extract useCastPlayerItem hook 2026-05-22 01:15:29 +02:00
Uruk
9f4f0fa7d1 refactor(casting): extract CastPlayerTransportControls 2026-05-22 01:10:30 +02:00
Uruk
0d922b75d6 refactor(casting): extract CastPlayerProgressBar 2026-05-22 01:08:04 +02:00
Uruk
0ee1d43d16 refactor(casting): extract CastPlayerEpisodeControls 2026-05-22 01:02:37 +02:00
Uruk
ec49d03cf1 refactor(casting): extract CastPlayerPoster 2026-05-22 00:59:57 +02:00
Uruk
02df2477d8 refactor(casting): extract CastPlayerHeader and CastPlayerTitle 2026-05-22 00:57:55 +02:00
Uruk
8c9506c7b5 docs(casting): add casting-player split implementation plan
10-task plan for sub-project C: extract 6 presentational components +
4 hooks from casting-player.tsx, leaving a thin orchestrator. Purely
mechanical, behaviour-neutral.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 00:56:21 +02:00
Uruk
b225286f57 docs(casting): add casting-player split design spec 2026-05-22 00:53:17 +02:00
Uruk
23b4f20d18 fix(casting): track menus from full item, keep quality on version switch, stable resume position
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 00:05:14 +02:00
Uruk
88d96603e4 feat(casting): reliable track switching with CastSelection truth 2026-05-21 23:58:22 +02:00
Uruk
6e513b8f9e feat(player): expand shared BITRATES ladder 2026-05-21 23:50:21 +02:00
Uruk
4f50ec6665 feat(casting): add useCastSelection hook 2026-05-21 23:49:23 +02:00
Uruk
0e25a5936c feat(casting): resolve and embed full CastSelection on load 2026-05-21 23:48:29 +02:00
Uruk
e9fee79130 feat(casting): embed CastSelection in cast customData 2026-05-21 23:47:23 +02:00
Uruk
3d65c3bb7a feat(casting): add CastSelection model and resolution helpers 2026-05-21 23:46:19 +02:00
Uruk
e5d61bf3ea docs(casting): add track switching implementation plan
6-task plan for sub-project B: CastSelection model, customData source of
truth, useCastSelection hook, expanded BITRATES, casting-player and
settings-menu rework.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:44:05 +02:00
Uruk
5eac91190e docs(casting): quality filter by media bitrate + device cap
Per review: filter quality tiers by both ceilings; correct the shared
BITRATES file reference to BitrateSelector.tsx.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:43:44 +02:00
Uruk
95d63e3c8a docs(casting): quality menu reuses expanded shared BITRATES
Per review: the cast quality selector reuses the app-wide BITRATES
constant (expanded to the Jellyfin Android TV ladder) instead of a
cast-specific list, filtered by device capability.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:30:18 +02:00
Uruk
6d0ca44308 docs(casting): add track switching & multi-version design spec
Design for sub-project B: a single CastSelection source of truth carried
in cast customData (approach A3), fixing audio/subtitle/quality desync,
plus a real multi-version selector.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 23:23:19 +02:00
Uruk
73214f5d45 fix(casting): apply conservative bitrate cap on downgrade retry
The status-2100 downgrade retry overrode only the device profile's
MaxStreamingBitrate. Jellyfin uses the explicit getStreamUrl maxBitrate
request param as the effective ceiling, so a quality-menu bitrate would
survive the retry. Clamp options.maxBitrate to the fallback cap too.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:36:25 +02:00
Uruk
5cfd110ad5 docs(casting): add Chromecast cast test matrix 2026-05-21 02:33:12 +02:00
Uruk
6e63afc61a feat(casting): replace H265 toggle with Chromecast profile selector 2026-05-21 02:32:18 +02:00
Uruk
bcf6b705e1 refactor(casting): route all cast loads through loadCastMedia
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:27:20 +02:00
Uruk
fb8c649f6f feat(casting): add unified loadCastMedia with downgrade-on-failure 2026-05-21 02:20:06 +02:00
Uruk
6ecadecb87 feat(casting): add chromecastProfile and chromecastMaxBitrate settings 2026-05-21 02:17:59 +02:00
Uruk
e3f105691b feat(casting): add Chromecast device profile builder 2026-05-21 02:16:29 +02:00
Uruk
bcfa8c6d63 feat(casting): add Chromecast capability detection 2026-05-21 02:13:31 +02:00
Uruk
17450e3811 docs(casting): add device profiles implementation plan
7-task TDD plan for sub-project A: capability detection, profile builder,
unified loadCastMedia, call-site rewiring, settings UI, test matrix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 02:09:44 +02:00
Uruk
9759d84aa2 docs(casting): drop settings migration from profiles design
Per review: break enableH265ForChromecast outright instead of carrying
migration code. Users reconfigure; chromecastProfile defaults to auto.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 01:46:57 +02:00
Uruk
28d8b28c73 docs(casting): add device profiles & capability detection design spec
Design for sub-project A of the Chromecast refactor: per-device capability
detection, profile builder replacing the two static profiles, unified cast
load, and load-path bug fixes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 01:42:04 +02:00
Uruk
a4e47e5cb7 feat(casting): improve track selection and session handling
implements automatic initialization of audio and subtitle tracks based on server-provided defaults. ensures subtitle selection persists correctly during stream reloads by resolving track indices more reliably.

replaces crypto-based uuid generation with a math-based fallback to ensure compatibility with environments lacking global crypto support. adds missing media source metadata to cast info to improve consistency between the client and receiver.
2026-05-21 00:48:37 +02:00
Uruk
fcd7e46599 fix: resolve 13 review issues across casting components
- casting-player: remove redundant self-navigation useEffect
- casting-player: derive Type from metadata instead of hardcoding 'Movie'
- casting-player: pass null to useTrickplay instead of empty BaseItemDto
- casting-player: use != null for skip time labels (allow 0 to render)
- Chromecast: case-insensitive m3u8 detection via regex
- Chromecast: fix UUID hyphen indices to 4,6,8,10 for proper v4 format
- CastingMiniPlayer: use SeriesPrimaryImageTag for series poster URL
- ChromecastConnectionMenu: send rounded volume to castSession.setVolume
- ChromecastConnectionMenu: use isMutedRef in onValueChange to avoid stale closure
- ChromecastDeviceSheet: skip volume sync during active sliding
- ChromecastDeviceSheet: move unmute logic from onValueChange to onSlidingStart
- useCasting: detect playback start via isPlaying/playerState, not just progress>0
- useCasting: derive isChromecastAvailable from castState instead of hardcoding true
- useTrickplay: accept BaseItemDto|null with null guards on Id access
2026-05-21 00:47:31 +02:00
Uruk
a841619d78 Fix: Generates UUID v4 for play session ID
Fixes the play session ID generation to use UUID v4 format.

This ensures a more robust and standard identifier for tracking play sessions.
2026-05-21 00:47:31 +02:00
Uruk
6c72a2803f fix(chromecast): replace Math.random with crypto.getRandomValues for session ID 2026-05-21 00:47:31 +02:00
Uruk
6bf00abb9b fix: Refactors casting player and components
Refactors the casting player screen and related components for improved code clarity, performance, and maintainability.

- Removes unused code and simplifies logic, especially around audio track selection and recommended stereo track handling.
- Improves the formatting of trickplay time displays for consistency.
- Streamlines UI elements and removes unnecessary conditional checks.
- Updates the Chromecast component to use hooks for side effects, ensuring the Chromecast session remains active.
- Improves the display of the language in the audio track display.
2026-05-21 00:47:31 +02:00
Uruk
ac405af3b2 Fix: Improves Chromecast casting experience
Fixes several issues and enhances the Chromecast casting experience:

- Prevents errors when loading media by slimming down the customData payload to avoid exceeding message size limits.
- Improves logic for selecting custom data from media status.
- Fixes an issue with subtitle track selection.
- Recommends stereo audio tracks for better Chromecast compatibility.
- Improves volume control and mute synchronization between the app and the Chromecast device.
- Adds error handling for `loadMedia` in `PlayButton`.
- Fixes image caching issue for season posters in mini player.
- Implements cleanup for scroll retry timeout in episode list.
- Ensures segment skipping functions are asynchronous.
- Resets `hasReportedStartRef` after stopping casting.
- Prevents seeking past the end of Outro segments.
- Reports playback progress more accurately by also taking player state changes into account.
2026-05-21 00:47:31 +02:00
Uruk
9ec81cfa1d Fix: Improves Chromecast casting experience
Fixes several issues and improves the overall Chromecast casting experience:

- Implements an AbortController for fetching item data to prevent race conditions.
- Syncs live progress in the mini player more accurately using elapsed real time.
- Prevents event propagation in the mini player's play/pause button.
- Ensures the disconnect callback in the connection menu is always called.
- Retries scrolling in the episode list on failure.
- Handles unmute failures gracefully in volume controls.
- Clamps seek positions to prevent exceeding duration.
- Fixes reporting playback start multiple times
- Improves segment calculation in `useChromecastSegments`
- Prevents race condition with `isPlaying` state in `Controls` component

Also includes minor UI and timing adjustments for a smoother user experience.
2026-05-21 00:47:31 +02:00
Uruk
28bf1489c1 Fix: Improve casting and segment skipping
Fixes several issues and improves the casting player experience.

- Adds the ability to disable segment skipping options based on plugin settings.
- Improves Chromecast integration by:
  - Adding PlaySessionId for better tracking.
  - Improves audio track selection
  - Uses mediaInfo builder for loading media.
  - Adds support for loading next/previous episodes
  - Translation support
- Updates progress reporting to Jellyfin to be more accurate and reliable.
- Fixes an error message in the direct player.
2026-05-21 00:47:31 +02:00
Uruk
68d64fec9c feat: Enhances casting player with trickplay
Implements trickplay functionality with preview images to improve the casting player's seeking experience.

Adds a progress slider with trickplay preview, allowing users to scrub through media with visual feedback. Integrates device volume control and mute functionality to the Chromecast device sheet. Also fixes minor bugs and improves UI.
2026-05-21 00:47:31 +02:00
Uruk
9dcbcdc41d fix: Refactors Chromecast casting player
Refactors the Chromecast casting player for better compatibility, UI improvements, and stability.

- Adds auto-selection of stereo audio tracks for improved Chromecast compatibility
- Refactors episode list to filter out virtual episodes and allow season selection
- Improves UI layout and styling
- Removes connection quality indicator
- Fixes progress reporting to Jellyfin
- Updates volume control to use CastSession for device volume
2026-05-21 00:47:31 +02:00
Uruk
99775b353f feat: Enhances casting player with API data
Enriches the casting player screen by fetching item details from the Jellyfin API for a more reliable and complete user experience.

The casting player now prioritizes item data fetched directly from the API, providing richer metadata and ensuring accurate information display.

- Fetches full item data based on content ID.
- Uses fetched data as the primary source of item information, falling back to customData or minimal info if unavailable.
- Improves UI by showing connection quality and bitrate.
- Enhances episode list display and scrolling.
- Adds a stop casting button.
- Minor UI adjustments for better readability and aesthetics.

This change enhances the accuracy and reliability of displayed information, improving the overall user experience of the casting player.
2026-05-21 00:47:31 +02:00
Uruk
7589ccd284 feat: Enhance Chromecast functionality and UI improvements
- Implemented a retry mechanism for Chromecast device discovery with a maximum of 3 attempts.
- Added logging for discovered devices to aid in debugging.
- Updated Chromecast button interactions to streamline navigation to the casting player.
- Changed the color scheme for Chromecast components to a consistent purple theme.
- Modified the ChromecastDeviceSheet to sync volume slider with prop changes.
- Improved the ChromecastSettingsMenu to conditionally render audio and subtitle tracks based on availability.
- Updated translations for the casting player to include new strings for better user experience.
2026-05-21 00:47:31 +02:00
Uruk
d4f730fc54 fix: use full route path for casting-player navigation 2026-05-21 00:47:31 +02:00
Uruk
e002381706 debug: add logging to Chromecast button tap handler 2026-05-21 00:47:31 +02:00
Uruk
838a248d28 fix: handle casting-player navigation when no back stack exists
Use useEffect to check connection state and redirect properly. If no back
stack exists, navigate to home tab instead of calling router.back().
2026-05-21 00:47:31 +02:00
Uruk
a5c72011a8 fix: route Chromecast button to custom casting-player instead of native UI 2026-05-21 00:47:31 +02:00
Uruk
51bd8a92da refactor(casting): remove AirPlay references, keep extensible architecture
- Remove AirPlay from CastProtocol type union (Chromecast only for now)
- Replace AirPlay TODOs with generic 'Future: Add X for other protocols' comments
- Remove PROTOCOL_COLORS export, use hardcoded Chromecast color (#F9AB00)
- Update all component headers to be protocol-agnostic
- Keep switch statements extensible for future protocol additions
- Maintain clean architecture for easy integration of new casting protocols

Architecture remains flexible for future protocols (AirPlay, DLNA, etc.)
2026-05-21 00:47:31 +02:00