diff --git a/bun.lockb b/bun.lockb index 2c4c76c0..ebdbe965 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/video-player/controls/AudioSlider.tsx b/components/video-player/controls/AudioSlider.tsx new file mode 100644 index 00000000..0fe613d3 --- /dev/null +++ b/components/video-player/controls/AudioSlider.tsx @@ -0,0 +1,94 @@ +import React, { useEffect } from "react"; +import { View, StyleSheet } from "react-native"; +import { useSharedValue } from "react-native-reanimated"; +import { Slider } from "react-native-awesome-slider"; +import { VolumeManager } from "react-native-volume-manager"; +import { Ionicons } from "@expo/vector-icons"; + +const AudioSlider = () => { + const volume = useSharedValue(50); // Explicitly type as number + const min = useSharedValue(0); // Explicitly type as number + const max = useSharedValue(100); // Explicitly type as number + + useEffect(() => { + const fetchInitialVolume = async () => { + try { + const { volume: initialVolume } = await VolumeManager.getVolume(); + console.log("initialVolume", initialVolume); + 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 }); + }; + }, []); + + const handleValueChange = async (value: number) => { + volume.value = value; + console.log("volume", value); + await VolumeManager.setVolume(value / 100); + + // Re-call showNativeVolumeUI to ensure the setting is applied on iOS + VolumeManager.showNativeVolumeUI({ enabled: false }); + }; + + useEffect(() => { + const volumeListener = VolumeManager.addVolumeListener((result) => { + console.log("Volume changed:", result.volume); + volume.value = result.volume * 100; + }); + + return () => { + volumeListener.remove(); + }; + }, []); + + return ( + + + + + ); +}; + +const styles = StyleSheet.create({ + sliderContainer: { + width: 150, + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + }, +}); + +export default AudioSlider; diff --git a/components/video-player/controls/Controls.tsx b/components/video-player/controls/Controls.tsx index 50c88ae0..b875a859 100644 --- a/components/video-player/controls/Controls.tsx +++ b/components/video-player/controls/Controls.tsx @@ -58,6 +58,7 @@ import { BlurView } from "expo-blur"; import { getItemById } from "@/utils/jellyfin/user-library/getItemById"; import { useAtom } from "jotai"; import { apiAtom } from "@/providers/JellyfinProvider"; +import AudioSlider from "./AudioSlider"; interface Props { item: BaseItemDto; @@ -554,6 +555,7 @@ export const Controls: React.FC = ({ position: "absolute", alignItems: "center", transform: [{ rotate: "270deg" }], // Rotate the slider to make it vertical + left: 0, bottom: 30, }} > @@ -627,6 +629,18 @@ export const Controls: React.FC = ({ + + + +