mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-04-25 01:54:42 +01:00
fix(tv): improve skip/countdown focus and back button handling
This commit is contained in:
@@ -31,8 +31,6 @@ export interface TVNextEpisodeCountdownProps {
|
||||
onFinish: () => void;
|
||||
/** Called when user presses the card to skip to next episode */
|
||||
onPlayNext?: () => void;
|
||||
/** Whether this card should capture focus when visible */
|
||||
hasFocus?: boolean;
|
||||
/** Whether controls are visible - affects card position */
|
||||
controlsVisible?: boolean;
|
||||
}
|
||||
@@ -48,7 +46,6 @@ export const TVNextEpisodeCountdown: FC<TVNextEpisodeCountdownProps> = ({
|
||||
isPlaying,
|
||||
onFinish,
|
||||
onPlayNext,
|
||||
hasFocus = false,
|
||||
controlsVisible = false,
|
||||
}) => {
|
||||
const typography = useScaledTVTypography();
|
||||
@@ -141,7 +138,7 @@ export const TVNextEpisodeCountdown: FC<TVNextEpisodeCountdownProps> = ({
|
||||
onPress={onPlayNext}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
hasTVPreferredFocus={hasFocus}
|
||||
hasTVPreferredFocus={true}
|
||||
focusable={true}
|
||||
>
|
||||
<RNAnimated.View style={[animatedStyle, focused && styles.focusedCard]}>
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { type FC, useEffect, useRef } from "react";
|
||||
import type { FC } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Pressable,
|
||||
Animated as RNAnimated,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { Pressable, Animated as RNAnimated, StyleSheet } from "react-native";
|
||||
import Animated, {
|
||||
Easing,
|
||||
useAnimatedStyle,
|
||||
@@ -20,8 +16,6 @@ export interface TVSkipSegmentCardProps {
|
||||
show: boolean;
|
||||
onPress: () => void;
|
||||
type: "intro" | "credits";
|
||||
/** Whether this card should capture focus when visible */
|
||||
hasFocus?: boolean;
|
||||
/** Whether controls are visible - affects card position */
|
||||
controlsVisible?: boolean;
|
||||
}
|
||||
@@ -34,30 +28,15 @@ export const TVSkipSegmentCard: FC<TVSkipSegmentCardProps> = ({
|
||||
show,
|
||||
onPress,
|
||||
type,
|
||||
hasFocus = false,
|
||||
controlsVisible = false,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const pressableRef = useRef<View>(null);
|
||||
const { focused, handleFocus, handleBlur, animatedStyle } =
|
||||
useTVFocusAnimation({
|
||||
scaleAmount: 1.1,
|
||||
duration: 120,
|
||||
});
|
||||
|
||||
// Programmatically request focus when card appears with hasFocus=true
|
||||
useEffect(() => {
|
||||
if (!show || !hasFocus || !pressableRef.current) return;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
// Use setNativeProps to trigger focus update on tvOS
|
||||
(pressableRef.current as any)?.setNativeProps?.({
|
||||
hasTVPreferredFocus: true,
|
||||
});
|
||||
}, 50);
|
||||
return () => clearTimeout(timer);
|
||||
}, [show, hasFocus]);
|
||||
|
||||
// Animated position based on controls visibility
|
||||
const bottomPosition = useSharedValue(
|
||||
controlsVisible ? BOTTOM_WITH_CONTROLS : BOTTOM_WITHOUT_CONTROLS,
|
||||
@@ -88,11 +67,10 @@ export const TVSkipSegmentCard: FC<TVSkipSegmentCardProps> = ({
|
||||
pointerEvents='box-none'
|
||||
>
|
||||
<Pressable
|
||||
ref={pressableRef}
|
||||
onPress={onPress}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
hasTVPreferredFocus={hasFocus}
|
||||
hasTVPreferredFocus={true}
|
||||
>
|
||||
<RNAnimated.View
|
||||
style={[
|
||||
|
||||
Reference in New Issue
Block a user