import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react'; import { NativeSyntheticEvent, StyleSheet, View } from 'react-native'; import { DeepPartial, autorelease, createSBError } from '../../types'; import NativeCroppingView, { Commands, CroppingViewEvent, } from '../spec/ScanbotCroppingViewNativeComponent'; import { CroppingViewResult, CroppingViewRotation, FileSrc, ImageSrc, ScanbotCroppingViewHandle, ScanbotCroppingViewProperties, } from './ScanbotCroppingViewProperties'; function isFileSrc(src: ImageSrc): src is FileSrc { return (src as FileSrc).imageFileUri !== undefined; } export const ScanbotCroppingView = forwardRef< ScanbotCroppingViewHandle, ScanbotCroppingViewProperties >(({ onCroppedAreaResult, onError, ...props }, forwardedRef) => { const viewRef = useRef(null); useImperativeHandle(forwardedRef, () => { return { detectPolygon() { if (viewRef.current) { Commands.detectPolygon(viewRef.current); } }, resetPolygon() { if (viewRef.current) { Commands.resetPolygon(viewRef.current); } }, rotate(rotation: CroppingViewRotation) { if (viewRef.current) { Commands.rotate(viewRef.current, rotation === 'CLOCKWISE'); } }, extractCroppedArea() { if (viewRef.current) { Commands.extractCroppedArea(viewRef.current); } }, }; }); const _nativeViewSrc = useMemo(() => { if (isFileSrc(props.src)) { return { imageFileUri: props.src.imageFileUri, imageRef: undefined, }; } else { return { imageFileUri: undefined, imageRef: props.src.imageRefUUID, }; } }, [props.src]); const _onCroppedAreaResult = useCallback( (event: NativeSyntheticEvent) => { if (event.nativeEvent.result !== null) { autorelease(async () => { await onCroppedAreaResult( new CroppingViewResult( JSON.parse(event.nativeEvent.result) as DeepPartial ) ); }); } }, [onCroppedAreaResult] ); const _onError = useCallback( (event: NativeSyntheticEvent) => { if (onError) { onError(createSBError(event.nativeEvent)); } }, [onError] ); return ( ); }); const styles = StyleSheet.create({ container: { flex: 1, }, });