import { Ionicons } from "@expo/vector-icons"; import React, { useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Animated, Easing, Pressable, View } from "react-native"; import { Text } from "@/components/common/Text"; import { scaleSize } from "@/utils/scaleSize"; import type { SavedServerAccount } from "@/utils/secureCredentials"; interface TVAccountCardProps { account: SavedServerAccount; onPress: () => void; onLongPress?: () => void; hasTVPreferredFocus?: boolean; } export const TVAccountCard: React.FC = ({ account, onPress, onLongPress, hasTVPreferredFocus, }) => { const { t } = useTranslation(); const [isFocused, setIsFocused] = useState(false); const scale = useRef(new Animated.Value(1)).current; const glowOpacity = useRef(new Animated.Value(0)).current; const animateFocus = (focused: boolean) => { Animated.parallel([ Animated.timing(scale, { toValue: focused ? 1.03 : 1, duration: 150, easing: Easing.out(Easing.quad), useNativeDriver: true, }), Animated.timing(glowOpacity, { toValue: focused ? 0.6 : 0, duration: 150, easing: Easing.out(Easing.quad), useNativeDriver: true, }), ]).start(); }; const handleFocus = () => { setIsFocused(true); animateFocus(true); }; const handleBlur = () => { setIsFocused(false); animateFocus(false); }; const getSecurityIcon = (): keyof typeof Ionicons.glyphMap => { switch (account.securityType) { case "pin": return "keypad"; case "password": return "lock-closed"; default: return "key"; } }; const getSecurityText = (): string => { switch (account.securityType) { case "pin": return t("save_account.pin_code"); case "password": return t("save_account.password"); default: return t("save_account.no_protection"); } }; return ( {/* Avatar */} {/* Account Info */} {account.username} {getSecurityText()} {/* Security Icon */} ); };