mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:43:25 +00:00
setup progress bar without functionalities
This commit is contained in:
@@ -3,6 +3,7 @@ import { View } from "react-native";
|
|||||||
import { usePlayerStore } from "~/stores/player/store";
|
import { usePlayerStore } from "~/stores/player/store";
|
||||||
import { Text } from "../ui/Text";
|
import { Text } from "../ui/Text";
|
||||||
import { Controls } from "./Controls";
|
import { Controls } from "./Controls";
|
||||||
|
import { ProgressBar } from "./ProgressBar";
|
||||||
import { mapMillisecondsToTime } from "./utils";
|
import { mapMillisecondsToTime } from "./utils";
|
||||||
|
|
||||||
export const BottomControls = () => {
|
export const BottomControls = () => {
|
||||||
@@ -13,10 +14,11 @@ export const BottomControls = () => {
|
|||||||
return (
|
return (
|
||||||
<Controls>
|
<Controls>
|
||||||
<View className="flex h-16 w-full flex-row items-center justify-center">
|
<View className="flex h-16 w-full flex-row items-center justify-center">
|
||||||
<View className="flex flex-row items-center justify-center gap-2 px-4 py-2">
|
<View className="flex flex-row items-center justify-center gap-5 px-4 py-2">
|
||||||
<Text className="font-bold">
|
<Text className="font-bold">
|
||||||
{mapMillisecondsToTime(status.positionMillis ?? 0)}
|
{mapMillisecondsToTime(status.positionMillis ?? 0)}
|
||||||
</Text>
|
</Text>
|
||||||
|
<ProgressBar />
|
||||||
<Text className="font-bold">
|
<Text className="font-bold">
|
||||||
{mapMillisecondsToTime(status.durationMillis ?? 0)}
|
{mapMillisecondsToTime(status.durationMillis ?? 0)}
|
||||||
</Text>
|
</Text>
|
||||||
|
80
apps/expo/src/components/player/ProgressBar.tsx
Normal file
80
apps/expo/src/components/player/ProgressBar.tsx
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import { useCallback, useRef } from "react";
|
||||||
|
import { Dimensions, PanResponder, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
|
import { usePlayerStore } from "~/stores/player/store";
|
||||||
|
|
||||||
|
export const ProgressBar = () => {
|
||||||
|
const status = usePlayerStore((state) => state.status);
|
||||||
|
const videoRef = usePlayerStore((state) => state.videoRef);
|
||||||
|
|
||||||
|
const screenWidth = Dimensions.get("window").width;
|
||||||
|
const progressBarWidth = screenWidth - 40; // Adjust the padding as needed
|
||||||
|
|
||||||
|
const updateProgress = useCallback(
|
||||||
|
(newProgress: number) => {
|
||||||
|
videoRef?.setStatusAsync({ positionMillis: newProgress }).catch(() => {
|
||||||
|
console.log("Error updating progress");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[videoRef],
|
||||||
|
);
|
||||||
|
|
||||||
|
const panResponder = useRef(
|
||||||
|
PanResponder.create({
|
||||||
|
onStartShouldSetPanResponder: () => true,
|
||||||
|
onMoveShouldSetPanResponder: () => true,
|
||||||
|
onPanResponderMove: (e, gestureState) => {
|
||||||
|
console.log(gestureState.moveX, gestureState.x0, gestureState.dx);
|
||||||
|
},
|
||||||
|
onPanResponderRelease: (e, gestureState) => {
|
||||||
|
console.log("onPanResponderRelease");
|
||||||
|
const { moveX, x0 } = gestureState;
|
||||||
|
const newProgress = (moveX - x0) / progressBarWidth;
|
||||||
|
updateProgress(newProgress);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).current;
|
||||||
|
|
||||||
|
if (status?.isLoaded) {
|
||||||
|
const progressRatio =
|
||||||
|
status.durationMillis && status.durationMillis !== 0
|
||||||
|
? status.positionMillis / status.durationMillis
|
||||||
|
: 0;
|
||||||
|
return (
|
||||||
|
<View className="flex h-8 flex-1 items-center justify-center">
|
||||||
|
{/* Progress Dot */}
|
||||||
|
<View className="absolute inset-x-0 top-0">
|
||||||
|
<View
|
||||||
|
className="z-10 h-4 w-4 rounded-full bg-primary-100"
|
||||||
|
style={{
|
||||||
|
left: `${progressRatio * 100}%`,
|
||||||
|
transform: [
|
||||||
|
{ translateY: 7 },
|
||||||
|
{
|
||||||
|
translateX: -4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Full bar */}
|
||||||
|
<TouchableOpacity
|
||||||
|
className="relative h-1 w-full rounded-full bg-secondary-300 bg-opacity-25 transition-[height] duration-100"
|
||||||
|
{...panResponder.panHandlers}
|
||||||
|
>
|
||||||
|
{/* TODO: Preloaded */}
|
||||||
|
<View className="absolute left-0 top-0 h-full rounded-full bg-secondary-300" />
|
||||||
|
|
||||||
|
{/* Progress */}
|
||||||
|
<View
|
||||||
|
className="dir-neutral:left-0 absolute top-0 flex h-full items-center justify-end rounded-full bg-primary-100"
|
||||||
|
style={{
|
||||||
|
width: `${progressRatio * 100}%`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user