diff --git a/components/StyledButton.tsx b/components/StyledButton.tsx index 55192e5..ec71912 100644 --- a/components/StyledButton.tsx +++ b/components/StyledButton.tsx @@ -34,7 +34,7 @@ export const StyledButton: React.FC = ({ const colorScheme = useColorScheme() ?? "dark"; const colors = Colors[colorScheme]; const [isFocused, setIsFocused] = React.useState(false); - const animationStyle = useButtonAnimation(isSelected, isFocused); + const animationStyle = useButtonAnimation(isFocused); const variantStyles = { default: StyleSheet.create({ diff --git a/hooks/useButtonAnimation.ts b/hooks/useButtonAnimation.ts index 229516b..6649647 100644 --- a/hooks/useButtonAnimation.ts +++ b/hooks/useButtonAnimation.ts @@ -1,16 +1,16 @@ import { useRef, useEffect } from 'react'; import { Animated } from 'react-native'; -export const useButtonAnimation = (isSelected: boolean, isFocused: boolean) => { +export const useButtonAnimation = (isFocused: boolean) => { const scaleValue = useRef(new Animated.Value(1)).current; useEffect(() => { Animated.spring(scaleValue, { - toValue: isSelected || isFocused ? 1.1 : 1, + toValue: isFocused ? 1.1 : 1, friction: 5, useNativeDriver: true, }).start(); - }, [isSelected, isFocused, scaleValue]); + }, [ isFocused, scaleValue]); return { transform: [{ scale: scaleValue }], diff --git a/hooks/useTVRemoteHandler.ts b/hooks/useTVRemoteHandler.ts index 1af15ce..d3c942f 100644 --- a/hooks/useTVRemoteHandler.ts +++ b/hooks/useTVRemoteHandler.ts @@ -2,6 +2,8 @@ import { useEffect, useRef, useCallback } from "react"; import { useTVEventHandler, HWEvent } from "react-native"; import usePlayerStore from "@/stores/playerStore"; +const SEEK_STEP = 20 * 1000; // 快进/快退的时间步长(毫秒) + // 定时器延迟时间(毫秒) const CONTROLS_TIMEOUT = 5000; @@ -13,6 +15,7 @@ export const useTVRemoteHandler = () => { const { showControls, setShowControls, showEpisodeModal, togglePlayPause, seek } = usePlayerStore(); const controlsTimer = useRef(null); + const fastForwardIntervalRef = useRef(null); // 重置或启动隐藏控件的定时器 const resetTimer = useCallback(() => { @@ -45,38 +48,71 @@ export const useTVRemoteHandler = () => { }; }, [showControls, resetTimer]); + // 组件卸载时清除快进定时器 + useEffect(() => { + return () => { + if (fastForwardIntervalRef.current) { + clearInterval(fastForwardIntervalRef.current); + } + }; + }, []); + // 处理遥控器事件 const handleTVEvent = useCallback( (event: HWEvent) => { - // 如果剧集选择模态框显示,则不处理任何事件 if (showEpisodeModal) { return; } + if (event.eventType === "longRight" || event.eventType === "longLeft") { + if (event.eventKeyAction === 1) { + if (fastForwardIntervalRef.current) { + console.log("Long right key released, stopping fast forward."); + clearInterval(fastForwardIntervalRef.current); + fastForwardIntervalRef.current = null; + } + } + } + resetTimer(); - if (!showControls) { - switch (event.eventType) { - case "select": - togglePlayPause(); - setShowControls(true); - break; - case "left": - seek(-15000); // 快退15秒 - break; - case "right": - seek(15000); // 快进15秒 - break; - case "longLeft": - seek(-60000); // 快退60秒 - break; - case "longRight": - seek(60000); // 快进60秒 - break; - case "down": - setShowControls(true); - break; - } + if (showControls) { + // 如果控制条已显示,则不处理后台的快进/快退等操作 + // 避免与控制条上的按钮焦点冲突 + return; + } + + console.log("TV Event:", event); + + switch (event.eventType) { + case "select": + togglePlayPause(); + setShowControls(true); + break; + case "left": + seek(-SEEK_STEP); // 快退15秒 + break; + case "longLeft": + if (!fastForwardIntervalRef.current && event.eventKeyAction === 0) { + fastForwardIntervalRef.current = setInterval(() => { + seek(-SEEK_STEP); + }, 200); + } + break; + case "right": + seek(SEEK_STEP); + break; + case "longRight": + // 长按开始: 启动连续快进 + if (!fastForwardIntervalRef.current && event.eventKeyAction === 0) { + fastForwardIntervalRef.current = setInterval(() => { + seek(SEEK_STEP); + }, 200); + } + break; + case "down": + setShowControls(true); + break; } }, [showControls, showEpisodeModal, setShowControls, resetTimer, togglePlayPause, seek] diff --git a/package.json b/package.json index 9fa962d..866676e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "OrionTV", "private": true, "main": "expo-router/entry", - "version": "1.0.6", + "version": "1.1.0", "scripts": { "start": "EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start", "start-tv": "EXPO_TV=1 EXPO_USE_METRO_WORKSPACE_ROOT=1 expo start",