Fix Android ViewShot dropping frames and date overlays by temporarily lifting pointerEvents=none during capture
This commit is contained in:
@@ -3,6 +3,7 @@ import { StyleSheet, Image, View } from 'react-native';
|
||||
|
||||
interface FrameOverlayProps {
|
||||
frameAsset: any; // require() asset
|
||||
isCapturing?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10,11 +11,11 @@ interface FrameOverlayProps {
|
||||
* The frame PNG must have a transparent center (alpha=0) so the photo shows through.
|
||||
* Positioned absolutely to cover the entire photo canvas.
|
||||
*/
|
||||
export default function FrameOverlay({ frameAsset }: FrameOverlayProps) {
|
||||
export default function FrameOverlay({ frameAsset, isCapturing = false }: FrameOverlayProps) {
|
||||
if (!frameAsset) return null;
|
||||
|
||||
return (
|
||||
<View style={styles.container} pointerEvents="none" collapsable={false}>
|
||||
<View style={styles.container} pointerEvents={isCapturing ? "auto" : "none"} collapsable={false}>
|
||||
<Image
|
||||
source={frameAsset}
|
||||
style={styles.frameImage}
|
||||
|
||||
@@ -64,6 +64,7 @@ export default function PreviewScreen({
|
||||
}: PreviewScreenProps) {
|
||||
const [layout, setLayout] = useState<CollageLayout>('single');
|
||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||
const [isCapturing, setIsCapturing] = useState<boolean>(false);
|
||||
const [statusMessage, setStatusMessage] = useState<string>('');
|
||||
|
||||
|
||||
@@ -204,14 +205,21 @@ export default function PreviewScreen({
|
||||
try {
|
||||
logger.log(`captureComposite started. Has ViewShot ref: ${!!viewShotRef.current}`);
|
||||
if (viewShotRef.current) {
|
||||
setIsCapturing(true);
|
||||
// Wait for React to re-render and remove pointerEvents="none" which blocks ViewShot on Android
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
|
||||
logger.log('Executing viewShotRef.current.capture()...');
|
||||
const uri = await viewShotRef.current.capture();
|
||||
|
||||
setIsCapturing(false);
|
||||
logger.log(`ViewShot successfully generated collage URI: ${uri}`);
|
||||
return uri;
|
||||
}
|
||||
logger.log('[WARNING] viewShotRef.current was null, falling back to raw photo.');
|
||||
return fallbackPhoto;
|
||||
} catch (e: any) {
|
||||
setIsCapturing(false);
|
||||
logger.error('Failed to capture composite (ViewShot crashed)', e?.message || e);
|
||||
return fallbackPhoto;
|
||||
}
|
||||
@@ -453,11 +461,11 @@ export default function PreviewScreen({
|
||||
{renderCollageView()}
|
||||
|
||||
{/* Frame Overlay */}
|
||||
{activeFrame && <FrameOverlay frameAsset={activeFrame.asset} />}
|
||||
{activeFrame && <FrameOverlay frameAsset={activeFrame.asset} isCapturing={isCapturing} />}
|
||||
|
||||
{/* Date/Time Overlay */}
|
||||
{dateOverlay !== 'off' && (
|
||||
<View style={[styles.dateOverlay, getDatePositionStyle()]} pointerEvents="none">
|
||||
<View style={[styles.dateOverlay, getDatePositionStyle()]} pointerEvents={isCapturing ? "auto" : "none"}>
|
||||
<Text style={styles.dateOverlayText}>
|
||||
{formatDate(dateOverlay)}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user