1- import { useState , useCallback , useRef } from 'react' ;
2- import { captureRef } from 'react-native-view-shot' ;
1+ import { useState , useCallback , useRef , useEffect } from 'react' ;
2+ import {
3+ captureRef ,
4+ releaseCapture ,
5+ type CaptureOptions ,
6+ type ViewShotRef ,
7+ } from 'react-native-view-shot' ;
38
4- export interface CaptureOptions {
5- format ?: 'png' | 'jpg' | 'webm' ;
6- quality ?: number ;
7- result ?: 'tmpfile' | 'base64' | 'zip-base64' | 'data-uri' ;
8- handleGLSurfaceViewOnAndroid ?: boolean ;
9- }
9+ export type { CaptureOptions } from 'react-native-view-shot' ;
1010
1111export const useViewShotCapture = ( successMessage ?: string ) => {
12- const [ capturedUri , setCapturedUri ] = useState < string | null > ( null ) ;
12+ const [ capture , setCapture ] = useState < {
13+ uri : string ;
14+ temporary : boolean ;
15+ } | null > ( null ) ;
1316 const [ isCapturing , setIsCapturing ] = useState ( false ) ;
14- const viewShotRef = useRef < any > ( null ) ;
17+ const viewShotRef = useRef < ViewShotRef | null > ( null ) ;
18+ const requestId = useRef ( 0 ) ;
1519
16- const onCapture = useCallback (
17- ( uri : string ) => {
18- setCapturedUri ( uri ) ;
19- setIsCapturing ( false ) ;
20- console . log ( successMessage || 'Captured!' , `Content captured: ${ uri } ` ) ;
20+ useEffect (
21+ ( ) => ( ) => {
22+ requestId . current ++ ;
2123 } ,
22- [ successMessage ] ,
24+ [ ] ,
2325 ) ;
2426
25- const onCaptureFailure = useCallback ( ( error : Error ) => {
26- setIsCapturing ( false ) ;
27- console . error ( 'Capture Failed' , `Error: ${ error . message } ` ) ;
28- } , [ ] ) ;
27+ useEffect ( ( ) => {
28+ if ( capture ?. temporary ) {
29+ return ( ) => releaseCapture ( capture . uri ) ;
30+ }
31+ } , [ capture ] ) ;
2932
3033 const startCapture = useCallback (
3134 async ( options : CaptureOptions = { } ) => {
@@ -34,31 +37,44 @@ export const useViewShotCapture = (successMessage?: string) => {
3437 return ;
3538 }
3639
40+ const id = ++ requestId . current ;
41+ const temporary = ! options . result || options . result === 'tmpfile' ;
3742 setIsCapturing ( true ) ;
38- setCapturedUri ( null ) ;
43+ setCapture ( null ) ;
3944
4045 try {
41- const captureOptions = {
42- format : 'png' as const ,
46+ const uri = await captureRef ( viewShotRef , {
47+ format : 'png' ,
4348 quality : 0.8 ,
4449 ...options ,
45- } ;
46- const uri = await captureRef ( viewShotRef , captureOptions ) ;
47- onCapture ( uri ) ;
50+ } ) ;
51+ if ( id !== requestId . current ) {
52+ if ( temporary ) releaseCapture ( uri ) ;
53+ return ;
54+ }
55+ setCapture ( { uri, temporary } ) ;
56+ setIsCapturing ( false ) ;
57+ console . log ( successMessage || 'Captured!' ) ;
4858 } catch ( error ) {
49- onCaptureFailure ( error as Error ) ;
59+ if ( id !== requestId . current ) return ;
60+ setIsCapturing ( false ) ;
61+ console . error (
62+ 'Capture Failed' ,
63+ error instanceof Error ? error . message : String ( error ) ,
64+ ) ;
5065 }
5166 } ,
52- [ onCapture , onCaptureFailure ] ,
67+ [ successMessage ] ,
5368 ) ;
5469
5570 const resetCapture = useCallback ( ( ) => {
56- setCapturedUri ( null ) ;
71+ requestId . current ++ ;
72+ setCapture ( null ) ;
5773 setIsCapturing ( false ) ;
5874 } , [ ] ) ;
5975
6076 return {
61- capturedUri,
77+ capturedUri : capture ?. uri ?? null ,
6278 isCapturing,
6379 viewShotRef,
6480 startCapture,
0 commit comments