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
parent 3badf08363
commit c6422c1b03
7 changed files with 55 additions and 34 deletions

View File

@@ -45,9 +45,9 @@ export const CastingMiniPlayer: React.FC = () => {
return mediaStatus?.mediaInfo?.customData as BaseItemDto | undefined;
}, [mediaStatus?.mediaInfo?.customData]);
// Trickplay support - pass currentItem as BaseItemDto or empty object
// Trickplay support - pass currentItem as BaseItemDto or null
const { trickPlayUrl, calculateTrickplayUrl, trickplayInfo } = useTrickplay(
currentItem || ({} as BaseItemDto),
currentItem || null,
);
const [trickplayTime, setTrickplayTime] = useState({
hours: 0,
@@ -121,7 +121,7 @@ export const CastingMiniPlayer: React.FC = () => {
}
}, [progress, sliderProgress]);
// For episodes, use season poster; for other content, use item poster
// For episodes, use series poster; for other content, use item poster
const posterUrl = useMemo(() => {
if (!api?.basePath || !currentItem) return null;
@@ -131,8 +131,8 @@ export const CastingMiniPlayer: React.FC = () => {
currentItem.ParentIndexNumber !== undefined &&
currentItem.SeasonId
) {
// Build season poster URL using SeriesId and image tag for cache validation
const imageTag = currentItem.ImageTags?.Primary || "";
// Build series poster URL using SeriesId and series-level image tag
const imageTag = currentItem.SeriesPrimaryImageTag || "";
const tagParam = imageTag ? `&tag=${imageTag}` : "";
return `${api.basePath}/Items/${currentItem.SeriesId}/Images/Primary?fillHeight=120&fillWidth=80&quality=96${tagParam}`;
}