import { Ionicons } from "@expo/vector-icons"; import type React from "react"; import { useEffect, useRef } from "react"; import { Platform, StyleSheet, View } from "react-native"; import { Slider } from "react-native-awesome-slider"; import { useSharedValue } from "react-native-reanimated"; import type { VolumeResult } from "react-native-volume-manager"; const VolumeManager = Platform.isTV ? null : require("react-native-volume-manager"); interface AudioSliderProps { setVisibility: (show: boolean) => void; } const AudioSlider: React.FC = ({ setVisibility }) => { const isTv = Platform.isTV; const volume = useSharedValue(50); // Explicitly type as number const min = useSharedValue(0); // Explicitly type as number const max = useSharedValue(100); // Explicitly type as number const isUserInteracting = useRef(false); const timeoutRef = useRef | null>(null); // Use a ref to store the timeout ID useEffect(() => { if (isTv) return; const fetchInitialVolume = async () => { try { const { volume: initialVolume } = await VolumeManager.getVolume(); volume.value = initialVolume * 100; } catch (error) { console.error("Error fetching initial volume:", error); } }; fetchInitialVolume(); // Disable the native volume UI when the component mounts VolumeManager.showNativeVolumeUI({ enabled: false }); return () => { // Re-enable the native volume UI when the component unmounts VolumeManager.showNativeVolumeUI({ enabled: true }); }; }, [isTv, volume]); const handleValueChange = async (value: number) => { isUserInteracting.current = true; volume.value = value; try { await VolumeManager.setVolume(value / 100); } catch (error) { console.error("Error setting volume:", error); } // Re-call showNativeVolumeUI to ensure the setting is applied on iOS VolumeManager.showNativeVolumeUI({ enabled: false }); // Reset interaction flag after a delay setTimeout(() => { isUserInteracting.current = false; }, 100); }; useEffect(() => { if (isTv) return; const _volumeListener = VolumeManager.addVolumeListener( (result: VolumeResult) => { // Only update if user is not currently interacting with the slider if (!isUserInteracting.current) { volume.value = result.volume * 100; } setVisibility(true); // Clear any existing timeout if (timeoutRef.current) { clearTimeout(timeoutRef.current); } // Set a new timeout to hide the visibility after 2 seconds timeoutRef.current = setTimeout(() => { setVisibility(false); }, 1000); }, ); return () => { // volumeListener.remove(); if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, [isTv, volume, setVisibility]); if (isTv) return null; return ( ); }; const styles = StyleSheet.create({ sliderContainer: { width: 130, display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center", }, }); export default AudioSlider;