diff --git a/apps/expo/index.js b/apps/expo/index.js
index ab16fb5..a561933 100644
--- a/apps/expo/index.js
+++ b/apps/expo/index.js
@@ -1,2 +1,3 @@
import "expo-router/entry";
+import "react-native-gesture-handler";
import "@react-native-anywhere/polyfill-base64";
diff --git a/apps/expo/src/app/_layout.tsx b/apps/expo/src/app/_layout.tsx
index e186aaa..8d95069 100644
--- a/apps/expo/src/app/_layout.tsx
+++ b/apps/expo/src/app/_layout.tsx
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { useEffect } from "react";
import { useColorScheme } from "react-native";
+import { GestureHandlerRootView } from "react-native-gesture-handler";
import { useFonts } from "expo-font";
import { SplashScreen, Stack } from "expo-router";
import FontAwesome from "@expo/vector-icons/FontAwesome";
@@ -57,7 +58,11 @@ export default function RootLayout() {
return null;
}
- return ;
+ return (
+
+
+
+ );
}
function RootLayoutNav() {
diff --git a/apps/expo/src/app/videoPlayer/index.tsx b/apps/expo/src/app/videoPlayer/index.tsx
index b9309e6..23e607a 100644
--- a/apps/expo/src/app/videoPlayer/index.tsx
+++ b/apps/expo/src/app/videoPlayer/index.tsx
@@ -1,6 +1,8 @@
import type { AVPlaybackSource } from "expo-av";
import React, { useEffect, useState } from "react";
import { ActivityIndicator, Platform, StyleSheet, View } from "react-native";
+import { Gesture, GestureDetector } from "react-native-gesture-handler";
+import { runOnJS, useSharedValue } from "react-native-reanimated";
import { ResizeMode, Video } from "expo-av";
import * as NavigationBar from "expo-navigation-bar";
import { useLocalSearchParams, useRouter } from "expo-router";
@@ -37,7 +39,9 @@ const VideoPlayer: React.FC = ({ data }) => {
const [videoSrc, setVideoSrc] = useState();
const [isLoading, setIsLoading] = useState(true);
const [headerData, setHeaderData] = useState();
+ const [resizeMode, setResizeMode] = useState(ResizeMode.CONTAIN);
const router = useRouter();
+ const scale = useSharedValue(1);
const setVideoRef = usePlayerStore((state) => state.setVideoRef);
const setStatus = usePlayerStore((state) => state.setStatus);
const setIsIdle = usePlayerStore((state) => state.setIsIdle);
@@ -48,6 +52,19 @@ const VideoPlayer: React.FC = ({ data }) => {
(state) => state.dismissFullscreenPlayer,
);
+ const updateResizeMode = (newMode: ResizeMode) => {
+ setResizeMode(newMode);
+ };
+
+ const pinchGesture = Gesture.Pinch().onUpdate((e) => {
+ scale.value = e.scale;
+ if (scale.value > 1 && resizeMode !== ResizeMode.COVER) {
+ runOnJS(updateResizeMode)(ResizeMode.COVER);
+ } else if (scale.value <= 1 && resizeMode !== ResizeMode.CONTAIN) {
+ runOnJS(updateResizeMode)(ResizeMode.CONTAIN);
+ }
+ });
+
useEffect(() => {
const initializePlayer = async () => {
StatusBar.setStatusBarHidden(true);
@@ -122,22 +139,24 @@ const VideoPlayer: React.FC = ({ data }) => {
};
return (
-
-
+
+
+
+
);
};