add play and seek buttons

This commit is contained in:
Jorrin
2024-02-12 18:47:20 +01:00
parent 9dbe9e663f
commit 5bc848ed5f
6 changed files with 105 additions and 12 deletions

View File

@@ -13,6 +13,7 @@ import { fetchMediaDetails } from "@movie-web/tmdb";
import type { ItemData } from "~/components/item/item";
import { Header } from "~/components/player/Header";
import { MiddleControls } from "~/components/player/MiddleButtons";
import { usePlayerStore } from "~/stores/player/store";
export default function VideoPlayerWrapper() {
@@ -145,6 +146,7 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
/>
{isLoading && <ActivityIndicator size="large" color="#0000ff" />}
{!isLoading && data && <Header title={data.title} />}
{!isLoading && <MiddleControls />}
</View>
);
};

View File

@@ -1,13 +1,24 @@
import { View } from "react-native";
import React from "react";
import { TouchableOpacity } from "react-native";
import { usePlayerStore } from "~/stores/player/store";
interface ControlsProps {
interface ControlsProps extends React.ComponentProps<typeof TouchableOpacity> {
children: React.ReactNode;
}
export const Controls = ({ children }: ControlsProps) => {
export const Controls = ({ children, className }: ControlsProps) => {
const idle = usePlayerStore((state) => state.interface.isIdle);
const setIsIdle = usePlayerStore((state) => state.setIsIdle);
return <View className="flex-1 items-center">{!idle && children}</View>;
return (
<TouchableOpacity
onPress={() => {
setIsIdle(false);
}}
className={className}
>
{!idle && children}
</TouchableOpacity>
);
};

View File

@@ -11,14 +11,12 @@ interface HeaderProps {
export const Header = ({ title }: HeaderProps) => {
return (
<Controls>
<View className="absolute top-0 flex w-full flex-row items-center justify-between px-6 pt-6">
<BackButton className="w-36" />
<Text className="font-bold">{title}</Text>
<View className="flex w-36 flex-row items-center justify-center gap-2 space-x-2 rounded-full bg-secondary-300 px-4 py-2 opacity-80">
<Image source={Icon} className="h-6 w-6" />
<Text className="font-bold">movie-web</Text>
</View>
<Controls className="absolute top-0 flex w-full flex-row items-center justify-between px-6 pt-6">
<BackButton className="w-36" />
<Text className="font-bold">{title}</Text>
<View className="flex w-36 flex-row items-center justify-center gap-2 space-x-2 rounded-full bg-secondary-300 px-4 py-2 opacity-80">
<Image source={Icon} className="h-6 w-6" />
<Text className="font-bold">movie-web</Text>
</View>
</Controls>
);

View File

@@ -0,0 +1,21 @@
import { View } from "react-native";
import { Controls } from "./Controls";
import { PlayButton } from "./PlayButton";
import { SeekButton } from "./SeekButton";
export const MiddleControls = () => {
return (
<View className="absolute flex h-full w-full flex-1 flex-row items-center justify-center gap-24">
<Controls>
<SeekButton type="backward" />
</Controls>
<Controls>
<PlayButton />
</Controls>
<Controls>
<SeekButton type="forward" />
</Controls>
</View>
);
};

View File

@@ -0,0 +1,29 @@
import { FontAwesome } from "@expo/vector-icons";
import { usePlayerStore } from "~/stores/player/store";
export const PlayButton = () => {
const videoRef = usePlayerStore((state) => state.videoRef);
const status = usePlayerStore((state) => state.status);
return (
<FontAwesome
name={status?.isLoaded && status.isPlaying ? "pause" : "play"}
size={36}
color="white"
onPress={() => {
if (status?.isLoaded) {
if (status.isPlaying) {
videoRef?.pauseAsync().catch(() => {
console.log("Error pausing video");
});
} else {
videoRef?.playAsync().catch(() => {
console.log("Error playing video");
});
}
}
}}
/>
);
};

View File

@@ -0,0 +1,32 @@
import { MaterialIcons } from "@expo/vector-icons";
import { usePlayerStore } from "~/stores/player/store";
interface SeekProps {
type: "forward" | "backward";
}
export const SeekButton = ({ type }: SeekProps) => {
const videoRef = usePlayerStore((state) => state.videoRef);
const status = usePlayerStore((state) => state.status);
return (
<MaterialIcons
name={type === "forward" ? "forward-10" : "replay-10"}
size={36}
color="white"
onPress={() => {
if (status?.isLoaded) {
const position =
type === "forward"
? status.positionMillis + 10000
: status.positionMillis - 10000;
videoRef?.setPositionAsync(position).catch(() => {
console.log("Error seeking backwards");
});
}
}}
/>
);
};