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
This commit is contained in:
Uruk
2026-02-09 22:31:07 +01:00
committed by Gauvain
parent a841619d78
commit fcd7e46599
7 changed files with 55 additions and 34 deletions

View File

@@ -120,8 +120,13 @@ export const useCasting = (item: BaseItemDto | null) => {
const playStateApi = getPlaystateApi(api);
// Report playback start when media begins (only once per item)
// Don't require progress > 0 — playback can legitimately start at position 0
const currentState = stateRef.current;
if (hasReportedStartRef.current !== item.Id && currentState.progress > 0) {
const isPlaybackActive =
currentState.isPlaying ||
mediaStatus?.playerState === "playing" ||
currentState.progress > 0;
if (hasReportedStartRef.current !== item.Id && isPlaybackActive) {
// Set synchronously before async call to prevent race condition duplicates
hasReportedStartRef.current = item.Id || null;
@@ -366,8 +371,11 @@ export const useCasting = (item: BaseItemDto | null) => {
duration: state.duration,
volume: state.volume,
// Availability
isChromecastAvailable: true, // Always available via react-native-google-cast
// Availability - derived from actual cast state
isChromecastAvailable:
castState === CastState.CONNECTED ||
castState === CastState.CONNECTING ||
castState === CastState.NOT_CONNECTED,
// Raw clients (for advanced operations)
remoteMediaClient: client,