mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-02-04 03:36:29 +08:00
Refactor button animation logic to focus only on isFocused state and update version to 1.1.0
This commit is contained in:
@@ -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({
|
||||
|
||||
@@ -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 }],
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user