diff --git a/app/(auth)/(tabs)/(home)/index.tsx b/app/(auth)/(tabs)/(home)/index.tsx index f46bf058..b7e9b627 100644 --- a/app/(auth)/(tabs)/(home)/index.tsx +++ b/app/(auth)/(tabs)/(home)/index.tsx @@ -273,47 +273,47 @@ export default function index() { mediaListCollections, ]); - if (isConnected === false) { - return ( - - No Internet - - No worries, you can still watch{"\n"}downloaded content. - - - - - - - ); - } + // if (isConnected === false) { + // return ( + // + // No Internet + // + // No worries, you can still watch{"\n"}downloaded content. + // + // + // + // + // + // + // ); + // } const insets = useSafeAreaInsets(); diff --git a/bun.lockb b/bun.lockb index 917dee0e..babebe84 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/CurrentlyPlayingBar.tsx b/components/CurrentlyPlayingBar.tsx index 92a938a7..8bdd1e41 100644 --- a/components/CurrentlyPlayingBar.tsx +++ b/components/CurrentlyPlayingBar.tsx @@ -7,16 +7,19 @@ import { Ionicons } from "@expo/vector-icons"; import { BlurView } from "expo-blur"; import { useRouter, useSegments } from "expo-router"; import { useAtom } from "jotai"; -import { useEffect, useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; import { Alert, Platform, TouchableOpacity, View } from "react-native"; import Animated, { useAnimatedStyle, useSharedValue, + withDecay, withTiming, } from "react-native-reanimated"; import Video from "react-native-video"; import { Text } from "./common/Text"; import { Loader } from "./Loader"; +import { Dimensions } from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; export const CurrentlyPlayingBar: React.FC = () => { const segments = useSegments(); @@ -32,79 +35,55 @@ export const CurrentlyPlayingBar: React.FC = () => { presentFullscreenPlayer, onProgress, } = usePlayback(); + const router = useRouter(); + const insets = useSafeAreaInsets(); const [api] = useAtom(apiAtom); - const aBottom = useSharedValue(0); - const aPadding = useSharedValue(0); - const aHeight = useSharedValue(100); - const router = useRouter(); - const animatedOuterStyle = useAnimatedStyle(() => { + const [size, setSize] = useState<"full" | "small">("small"); + + const screenHeight = Dimensions.get("window").height; + const screenWiidth = Dimensions.get("window").width; + + const backgroundValues = useSharedValue({ + bottom: 70, + height: 80, + padding: 0, + width: screenWiidth - 100, + left: 50, + }); + + const videoValues = useSharedValue({ + bottom: 90, + height: 70, + width: 125, + left: 16, + }); + + const buttonsValues = useSharedValue({ + bottom: 90, + opacity: 1, + right: 16, + }); + + const animatedButtonStyle = useAnimatedStyle(() => { return { - bottom: withTiming(aBottom.value, { duration: 500 }), - height: withTiming(aHeight.value, { duration: 500 }), - padding: withTiming(aPadding.value, { duration: 500 }), + bottom: withTiming(buttonsValues.value.bottom, { duration: 500 }), + opacity: withTiming(buttonsValues.value.opacity, { duration: 500 }), + right: withTiming(buttonsValues.value.right, { duration: 500 }), }; }); - const aPaddingBottom = useSharedValue(30); - const aPaddingInner = useSharedValue(12); - const aBorderRadiusBottom = useSharedValue(12); - const animatedInnerStyle = useAnimatedStyle(() => { + const animatedBackgroundStyle = useAnimatedStyle(() => { return { - padding: withTiming(aPaddingInner.value, { duration: 500 }), - paddingBottom: withTiming(aPaddingBottom.value, { duration: 500 }), - borderBottomLeftRadius: withTiming(aBorderRadiusBottom.value, { - duration: 500, - }), - borderBottomRightRadius: withTiming(aBorderRadiusBottom.value, { - duration: 500, - }), + bottom: withTiming(backgroundValues.value.bottom, { duration: 500 }), + width: withTiming(backgroundValues.value.width, { duration: 500 }), + height: withTiming(backgroundValues.value.height, { duration: 500 }), + padding: withTiming(backgroundValues.value.padding, { duration: 500 }), + left: withTiming(backgroundValues.value.left, { duration: 500 }), }; }); - const from = useMemo(() => segments[2], [segments]); - - useEffect(() => { - if (segments.find((s) => s.includes("tabs"))) { - // Tab screen - i.e. home - aBottom.value = Platform.OS === "ios" ? 78 : 50; - aHeight.value = 80; - aPadding.value = 8; - aPaddingBottom.value = 8; - aPaddingInner.value = 8; - } else { - // Inside a normal screen - aBottom.value = Platform.OS === "ios" ? 0 : 0; - aHeight.value = Platform.OS === "ios" ? 110 : 80; - aPadding.value = Platform.OS === "ios" ? 0 : 8; - aPaddingInner.value = Platform.OS === "ios" ? 12 : 8; - aPaddingBottom.value = Platform.OS === "ios" ? 40 : 12; - } - }, [segments]); - - const startPosition = useMemo( - () => - currentlyPlaying?.item?.UserData?.PlaybackPositionTicks - ? Math.round( - currentlyPlaying?.item.UserData.PlaybackPositionTicks / 10000 - ) - : 0, - [currentlyPlaying?.item] - ); - - const poster = useMemo(() => { - if (currentlyPlaying?.item.Type === "Audio") - return `${api?.basePath}/Items/${currentlyPlaying.item.AlbumId}/Images/Primary?tag=${currentlyPlaying.item.AlbumPrimaryImageTag}&quality=90&maxHeight=200&maxWidth=200`; - else - return getBackdropUrl({ - api, - item: currentlyPlaying?.item, - quality: 70, - width: 200, - }); - }, [currentlyPlaying?.item.Id, api]); - const videoSource = useMemo(() => { if (!api || !currentlyPlaying || !poster) return null; return { @@ -128,179 +107,184 @@ export const CurrentlyPlayingBar: React.FC = () => { }; }, [currentlyPlaying, startPosition, api, poster]); + const animatedVideoStyle = useAnimatedStyle(() => { + return { + height: withTiming(videoValues.value.height, { duration: 500 }), + width: withTiming(videoValues.value.width, { duration: 500 }), + bottom: withTiming(videoValues.value.bottom, { duration: 500 }), + left: withTiming(videoValues.value.left, { duration: 500 }), + }; + }); + + const animatedValues = useSharedValue({ + paddingBottom: 0, + paddingInner: 0, + borderRadiusBottom: 0, + }); + + useEffect(() => { + if (size === "full") { + backgroundValues.value = { + bottom: 0, + height: screenHeight, + padding: 0, + width: screenWiidth, + left: 0, + }; + buttonsValues.value = { + bottom: screenHeight - insets.top - 38, + opacity: 1, + right: 16, + }; + videoValues.value = { + bottom: 0, + height: screenHeight, + width: screenWiidth, + left: 0, + }; + } else { + backgroundValues.value = { + bottom: 70, + height: 80, + padding: 0, + width: screenWiidth - 16, + left: 8, + }; + buttonsValues.value = { + bottom: 90, + opacity: 1, + right: 16, + }; + videoValues.value = { + bottom: 78, + height: 64, + width: 113, + left: 16, + }; + } + }, [size, screenHeight, insets]); + if (!api || !currentlyPlaying) return null; return ( - - + + + - { + if (size === "small") setSize("full"); + else setSize("small"); + }} + className="aspect-square rounded flex flex-col items-center justify-center p-2" > - - { - videoRef.current?.presentFullscreenPlayer(); + + + { + stopPlayback(); + }} + className="aspect-square rounded flex flex-col items-center justify-center p-2" + > + + + + + + + {videoSource && ( + - - { - if (isPlaying) pauseVideo(); - else playVideo(); }} - className="aspect-square rounded flex flex-col items-center justify-center p-2" - > - {isPlaying ? ( - - ) : ( - - )} - - { - stopPlayback(); + onVolumeChange={(e) => { + setVolume(e.volume); }} - className="aspect-square rounded flex flex-col items-center justify-center p-2" - > - - - - - - + progressUpdateInterval={4000} + onError={(e) => { + console.log(e); + writeToLog( + "ERROR", + "Video playback error: " + JSON.stringify(e) + ); + Alert.alert("Error", "Cannot play this video file."); + setIsPlaying(false); + // setCurrentlyPlaying(null); + }} + renderLoader={ + currentlyPlaying.item?.Type !== "Audio" && ( + + + + ) + } + /> + )} + + + + {/* + + + + + */} + ); }; diff --git a/package.json b/package.json index a5c3a03f..395b572f 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.5", + "react-native-awesome-slider": "^2.5.3", "react-native-circular-progress": "^1.4.0", "react-native-compressor": "^1.8.25", "react-native-gesture-handler": "~2.16.1",