import { Ionicons } from "@expo/vector-icons"; import { t } from "i18next"; import React, { useEffect, useRef } from "react"; import { Animated, BackHandler, Easing, Platform, Pressable, View, } from "react-native"; import QRCode from "react-native-qrcode-svg"; import { Text } from "@/components/common/Text"; import { useScaledTVTypography } from "@/constants/TVTypography"; import { scaleSize } from "@/utils/scaleSize"; interface TVQRCodeDisplayProps { code: string; onBack?: () => void; } export const TVQRCodeDisplay: React.FC = ({ code, onBack, }) => { const typography = useScaledTVTypography(); const handledRef = useRef(false); const qrSize = scaleSize(280); const cardPadding = scaleSize(16); const sectionPadding = scaleSize(32); const outerPadding = scaleSize(60); const qrData = JSON.stringify({ action: "streamyfin-pair", code, }); // Handle Android TV back button useEffect(() => { if (!Platform.isTV || !onBack) return; const handleBackPress = () => { if (handledRef.current) return true; handledRef.current = true; setTimeout(() => { handledRef.current = false; }, 100); onBack(); return true; }; const subscription = BackHandler.addEventListener( "hardwareBackPress", handleBackPress, ); return () => subscription.remove(); }, [onBack]); return ( {/* Back Button */} {onBack && } {/* QR Code */} {t("pairing.waiting_for_phone")} {code} {t("pairing.scan_with_phone")} ); }; const TVBackButton: React.FC<{ onPress: () => void; }> = ({ onPress }) => { const [isFocused, setIsFocused] = React.useState(false); const scale = useRef(new Animated.Value(1)).current; const animateFocus = (focused: boolean) => { Animated.timing(scale, { toValue: focused ? 1.05 : 1, duration: 150, easing: Easing.out(Easing.quad), useNativeDriver: true, }).start(); }; return ( { setIsFocused(true); animateFocus(true); }} onBlur={() => { setIsFocused(false); animateFocus(false); }} style={{ alignSelf: "flex-start", marginBottom: 24 }} focusable > {t("common.back")} ); };