Fix final 4 resilience edge cases
This commit is contained in:
@@ -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');
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user