Fix final 4 resilience edge cases

This commit is contained in:
2026-06-01 10:54:35 +02:00
parent 40704fa49b
commit 1c223e3cf6
4 changed files with 26 additions and 17 deletions
+2 -1
View File
@@ -81,7 +81,8 @@ export default function App() {
const handleBurstComplete = (uris: string[]) => { const handleBurstComplete = (uris: string[]) => {
setPhotoUris((prev) => { setPhotoUris((prev) => {
const next = [...prev, ...uris]; 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]); setCaptureHistory((prev) => [...prev, uris.length]);
setCurrentScreen('preview'); setCurrentScreen('preview');
+2
View File
@@ -152,6 +152,7 @@ const styles = StyleSheet.create({
position: 'absolute', position: 'absolute',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
zIndex: 100,
}, },
emojiText: { emojiText: {
fontSize: 48, fontSize: 48,
@@ -184,6 +185,7 @@ const styles = StyleSheet.create({
backgroundColor: THEME.colors.error, backgroundColor: THEME.colors.error,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
zIndex: 200,
}, },
deleteBtnText: { deleteBtnText: {
color: '#fff', color: '#fff',
+12 -11
View File
@@ -23,7 +23,7 @@ import Animated, {
FadeIn, FadeIn,
FadeOut, FadeOut,
withSequence, withSequence,
Easing, withDelay,
runOnJS, runOnJS,
} from 'react-native-reanimated'; } from 'react-native-reanimated';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
@@ -210,16 +210,8 @@ export default function CameraScreen({
if (burstTimerRef.current) clearTimeout(burstTimerRef.current); if (burstTimerRef.current) clearTimeout(burstTimerRef.current);
if (countdownTimerRef.current) clearTimeout(countdownTimerRef.current); if (countdownTimerRef.current) clearTimeout(countdownTimerRef.current);
if (completionTimerRef.current) clearTimeout(completionTimerRef.current); if (completionTimerRef.current) clearTimeout(completionTimerRef.current);
const urisToDelete = [...burstUris];
// 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);
}
}
setCountdown(countdownDuration); setCountdown(countdownDuration);
setIsCapturing(false); setIsCapturing(false);
setIsBurstWaiting(false); setIsBurstWaiting(false);
@@ -228,6 +220,15 @@ export default function CameraScreen({
setBurstUris([]); setBurstUris([]);
setShowBurstIndicator(''); setShowBurstIndicator('');
onCancel(); 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) // 3. Start the countdown on screen load (only when NOT idle)
+10 -5
View File
@@ -289,8 +289,8 @@ export default function PreviewScreen({
} }
}; };
// Auto-save and exit const handleExitRef = useRef<() => void>();
const handleExit = useCallback(async () => { handleExitRef.current = async () => {
if (idleTimerRef.current) clearTimeout(idleTimerRef.current); if (idleTimerRef.current) clearTimeout(idleTimerRef.current);
if (!mountedRef.current) return; if (!mountedRef.current) return;
if (isProcessing) return; if (isProcessing) return;
@@ -319,15 +319,20 @@ export default function PreviewScreen({
setIsProcessing(false); setIsProcessing(false);
state.onReset(); state.onReset();
} }
}, []); // Stable reference };
// Auto-save and exit
const handleExit = useCallback(async () => {
if (handleExitRef.current) handleExitRef.current();
}, []);
// Idle timer logic // Idle timer logic
const resetIdleTimer = useCallback(() => { const resetIdleTimer = useCallback(() => {
if (idleTimerRef.current) clearTimeout(idleTimerRef.current); if (idleTimerRef.current) clearTimeout(idleTimerRef.current);
idleTimerRef.current = setTimeout(() => { idleTimerRef.current = setTimeout(() => {
handleExit(); if (handleExitRef.current) handleExitRef.current();
}, 60000); }, 60000);
}, [handleExit]); }, []);
useEffect(() => { useEffect(() => {
resetIdleTimer(); resetIdleTimer();