Refactor button animation logic to focus only on isFocused state and update version to 1.1.0

This commit is contained in:
zimplexing
2025-07-08 20:33:06 +08:00
parent 74ad0872cb
commit b238ffe3ba
4 changed files with 64 additions and 28 deletions

View File

@@ -34,7 +34,7 @@ export const StyledButton: React.FC<StyledButtonProps> = ({
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({

View File

@@ -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 }],

View File

@@ -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<NodeJS.Timeout | null>(null);
const fastForwardIntervalRef = useRef<NodeJS.Timeout | null>(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]

View File

@@ -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",