Keep screen awake in camera mode; nudge flip button toward shutter

This commit is contained in:
2026-09-09 18:40:58 +07:00
parent 55f4184e74
commit a0ca68f176
3 changed files with 17 additions and 3 deletions
+1
View File
@@ -8,6 +8,7 @@
"@shopify/react-native-skia": "2.6.2",
"babel-preset-expo": "~57.0.0",
"expo": "~57.0.7",
"expo-keep-awake": "~57.0.1",
"expo-asset": "~57.0.5",
"expo-dev-client": "~57.0.6",
"expo-file-system": "~57.0.1",
+4 -3
View File
@@ -32,7 +32,7 @@ export default function CameraControls({
className="flex-row items-center justify-between px-7 pt-2"
>
{/* Left cluster: Pick Image + gear (gear sits between library & shutter) */}
<View className="flex-row items-center space-x-3">
<View className="flex-row items-center gap-x-3">
<TouchableOpacity
onPress={onPickImage}
className="w-12 h-12 rounded-full bg-black/40 border border-zinc-700/70 flex items-center justify-center"
@@ -73,8 +73,9 @@ export default function CameraControls({
{/* Right cluster: flip camera (between shutter & preview) + preview.
Preview doubles as "back to camera" while in library mode; the flip
control is hidden then. */}
<View className="flex-row items-center space-x-3">
control is hidden then. Wider gap than the left cluster keeps the flip
button clear of the preview thumbnail (~2 glyph widths toward shutter). */}
<View className="flex-row items-center gap-x-8">
{!isLibraryMode && onFlipCamera && (
<TouchableOpacity
onPress={onFlipCamera}
+12
View File
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle, type ComponentProps } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, useWindowDimensions, AppState } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
import { useCameraDevice, type CameraPhotoOutput } from 'react-native-vision-camera';
import { SkiaCamera, type SkiaCameraRef } from 'react-native-vision-camera-skia';
import { createSynchronizable } from 'react-native-worklets';
@@ -313,6 +314,17 @@ const Viewfinder = forwardRef<ViewfinderHandle, ViewfinderProps>(function Viewfi
const sub = AppState.addEventListener('change', (s) => setAppActive(s === 'active'));
return () => sub.remove();
}, []);
// Keep the screen lit while the live camera is showing. Without this the
// display sleeps after the system timeout; when the user wakes it much later
// (deep idle/doze) the preview surface is gone but the JS AppState never saw
// a background event, so the session is never restarted and the viewfinder
// (and capture) stay black until the camera is re-mounted (flip/switch).
useEffect(() => {
if (mode === 'camera') {
activateKeepAwake('camera-viewfinder');
return () => deactivateKeepAwake('camera-viewfinder');
}
}, [mode]);
// Tap-to-focus / AE-AF-AWB lock point (view coords). null = auto continuous.
const [focusPoint, setFocusPoint] = useState<{ x: number; y: number } | null>(null);
const controller = cameraActive ? skiaCameraRef.current?.controller : undefined;