diff --git a/App.tsx b/App.tsx index d6614fe4..c72c7ead 100644 --- a/App.tsx +++ b/App.tsx @@ -81,7 +81,8 @@ export default function App() { const handleBurstComplete = (uris: string[]) => { setPhotoUris((prev) => { const next = [...prev, ...uris]; - return next.length > 4 ? next.slice(-4) : next; + const maxKeep = Math.max(4, uris.length); + return next.length > maxKeep ? next.slice(-maxKeep) : next; }); setCaptureHistory((prev) => [...prev, uris.length]); setCurrentScreen('preview'); diff --git a/src/components/DraggableSticker.tsx b/src/components/DraggableSticker.tsx index 7ad8f7f2..f5c7425d 100644 --- a/src/components/DraggableSticker.tsx +++ b/src/components/DraggableSticker.tsx @@ -152,6 +152,7 @@ const styles = StyleSheet.create({ position: 'absolute', alignItems: 'center', justifyContent: 'center', + zIndex: 100, }, emojiText: { fontSize: 48, @@ -184,6 +185,7 @@ const styles = StyleSheet.create({ backgroundColor: THEME.colors.error, alignItems: 'center', justifyContent: 'center', + zIndex: 200, }, deleteBtnText: { color: '#fff', diff --git a/src/screens/CameraScreen.tsx b/src/screens/CameraScreen.tsx index 37b575ce..f44b61ae 100644 --- a/src/screens/CameraScreen.tsx +++ b/src/screens/CameraScreen.tsx @@ -23,7 +23,7 @@ import Animated, { FadeIn, FadeOut, withSequence, - Easing, + withDelay, runOnJS, } from 'react-native-reanimated'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; @@ -210,16 +210,8 @@ export default function CameraScreen({ if (burstTimerRef.current) clearTimeout(burstTimerRef.current); if (countdownTimerRef.current) clearTimeout(countdownTimerRef.current); if (completionTimerRef.current) clearTimeout(completionTimerRef.current); - - // Clean up any temp files from a partially completed burst - for (const uri of burstUris) { - try { - await FileSystem.deleteAsync(uri, { idempotent: true }); - } catch (e) { - console.warn('Failed to delete temp file on cancel:', e); - } - } - + const urisToDelete = [...burstUris]; + setCountdown(countdownDuration); setIsCapturing(false); setIsBurstWaiting(false); @@ -228,6 +220,15 @@ export default function CameraScreen({ setBurstUris([]); setShowBurstIndicator(''); onCancel(); + + // Clean up any temp files from a partially completed burst in the background + Promise.all( + urisToDelete.map(uri => + FileSystem.deleteAsync(uri, { idempotent: true }).catch(e => { + console.warn('Failed to delete temp file on cancel:', e); + }) + ) + ); }; // 3. Start the countdown on screen load (only when NOT idle) diff --git a/src/screens/PreviewScreen.tsx b/src/screens/PreviewScreen.tsx index 28def0db..3c763642 100644 --- a/src/screens/PreviewScreen.tsx +++ b/src/screens/PreviewScreen.tsx @@ -289,8 +289,8 @@ export default function PreviewScreen({ } }; - // Auto-save and exit - const handleExit = useCallback(async () => { + const handleExitRef = useRef<() => void>(); + handleExitRef.current = async () => { if (idleTimerRef.current) clearTimeout(idleTimerRef.current); if (!mountedRef.current) return; if (isProcessing) return; @@ -319,15 +319,20 @@ export default function PreviewScreen({ setIsProcessing(false); state.onReset(); } - }, []); // Stable reference + }; + + // Auto-save and exit + const handleExit = useCallback(async () => { + if (handleExitRef.current) handleExitRef.current(); + }, []); // Idle timer logic const resetIdleTimer = useCallback(() => { if (idleTimerRef.current) clearTimeout(idleTimerRef.current); idleTimerRef.current = setTimeout(() => { - handleExit(); + if (handleExitRef.current) handleExitRef.current(); }, 60000); - }, [handleExit]); + }, []); useEffect(() => { resetIdleTimer();