UNPKG

onfido-sdk-ui

Version:

JavaScript SDK view layer for Onfido identity verification

120 lines (100 loc) 2.84 kB
// @flow import * as React from 'react' import { h, Component } from 'preact' import Visibility from 'visibilityjs' import { screenshot } from '~utils/camera' import { blobToLossyBase64 } from '~utils/blob' import { randomId } from '~utils/string' import { DocumentOverlay } from '../Overlay' import Camera from '../Camera' import CameraError from '../CameraError' import { postToBackend } from '~utils/sdkBackend'; const maxAttempts = 3 const serverError = { name: 'SERVER_ERROR', type: 'error' } type State = { hasError: boolean, } type Props = { token: string, onValidCapture: Function, onError: Function, renderFallback: Function, trackScreen: Function, } export default class DocumentAutoCapture extends Component<Props, State> { webcam = null interval: ?Visibility captureIds: string[] = [] state: State = { hasError: false, } componentDidMount () { this.start() } componentWillUnmount () { this.stop() } screenshot = () => { if (this.captureIds.length < maxAttempts) { screenshot(this.webcam, blob => this.handleScreenshotBlob(blob)) } else { console.warn('Screenshotting is slow, waiting for responses before uploading more') } } start() { this.stop() this.interval = Visibility.every(1000, this.screenshot) } stop() { Visibility.stop(this.interval) } handleScreenshotBlob = (blob: Blob) => blobToLossyBase64(blob, base64 => this.handleScreenshot(blob, base64), error => console.error('Error converting screenshot to base64', error), { maxWidth: 200 }) handleScreenshot = (blob: Blob, base64: string) => { if (base64) { const id = randomId() this.captureIds.push(id) this.validate(base64, id, valid => valid ? this.props.onValidCapture({ blob, base64, id }) : null ) } } validate = (base64: string, id: string, callback: Function) => { const { token } = this.props const data = JSON.stringify({ image: base64, id }) postToBackend(data, token, ({ valid }) => { this.setProcessed(id) callback(valid) }, this.handleValidationError) } setProcessed(id: string) { this.captureIds = this.captureIds.filter(captureId => captureId === id) } handleValidationError = () => { this.setState({ hasError: true }) this.props.onError() } render() { const { hasError } = this.state const { trackScreen, renderFallback } = this.props return ( <div> <Camera {...this.props} webcamRef={ c => this.webcam = c } renderError={ hasError ? <CameraError error={serverError} {...{trackScreen, renderFallback}} /> : undefined } > <DocumentOverlay /> </Camera> </div> ) } }