From cdc0b70b87b19b5f9e637eb0d11b8064d32fa40f Mon Sep 17 00:00:00 2001 From: PriestFaria Date: Tue, 8 Jul 2025 20:27:12 +0300 Subject: [PATCH 1/3] camera boilerplate --- client/package.json | 1 + client/src/components/overlays/camera.tsx | 161 ++++++++++++++++++ .../screens/main/game/game.screen.tsx | 12 ++ .../components/screens/main/home.screen.tsx | 21 ++- client/src/components/ui/icons/icons.tsx | 32 +++- client/yarn.lock | 7 + 6 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 client/src/components/overlays/camera.tsx diff --git a/client/package.json b/client/package.json index 83df71b..6863b31 100644 --- a/client/package.json +++ b/client/package.json @@ -24,6 +24,7 @@ "class-variance-authority": "^0.7.1", "expo": "53.0.12", "expo-blur": "~14.1.5", + "expo-camera": "~16.1.10", "expo-constants": "~17.1.6", "expo-dev-client": "~5.2.1", "expo-gradle-ext-vars": "^0.1.3", diff --git a/client/src/components/overlays/camera.tsx b/client/src/components/overlays/camera.tsx new file mode 100644 index 0000000..f791f6c --- /dev/null +++ b/client/src/components/overlays/camera.tsx @@ -0,0 +1,161 @@ +import { IconContainer } from "@/components/ui/icons/icon-container"; +import { Icons } from "@/components/ui/icons/icons"; +import { useSocket } from "@/shared/hooks/useSocket"; +import { BlurView } from "expo-blur"; +import React, { useRef, useEffect, useState } from "react"; +import { + Pressable, + ScrollView, + View, + ScrollView as ScrollViewType, + Platform, + KeyboardAvoidingView, + StyleSheet, + Text, +} from "react-native"; +import Animated, { + useAnimatedStyle, + useSharedValue, + withTiming, +} from "react-native-reanimated"; +import { twMerge } from "tailwind-merge"; +import { CameraView, CameraType, useCameraPermissions } from "expo-camera"; +import { Button } from "../ui/button"; +import { logger } from "@/shared/instances/logger.instance"; + +interface CameraOverlayProps { + visible?: boolean; + onClose: () => void; +} + +export const CameraOverlay = ({ visible, onClose }: CameraOverlayProps) => { + const [permission, requestPermission] = useCameraPermissions(); + const [facing, setFacing] = useState("back"); + + const { emit } = useSocket(); + + const scrollViewRef = useRef(null); + + const opacity = useSharedValue(0); + + const ref = useRef(null); + + const toggleFacing = () => { + setFacing((prev) => (prev === "back" ? "front" : "back")); + }; + + useEffect(() => { + if (visible) { + opacity.value = withTiming(1, { duration: 300 }); + } else { + opacity.value = withTiming(0, { duration: 300 }); + } + }, [visible]); + + const animatedStyle = useAnimatedStyle(() => ({ + opacity: opacity.value, + })); + + if (!permission) { + return ; + } + return ( + + + + + + + {!permission.granted && ( +