onfido-sdk-ui
Version:
JavaScript SDK view layer for Onfido identity verification
111 lines (97 loc) • 3.26 kB
JavaScript
// @flow
import * as React from 'react'
import { h, Component } from 'preact'
import { screenshot } from '../utils/camera.js'
import { fileType } from '../utils/file.js'
import { FaceOverlay } from '../Overlay'
import { ToggleFullScreen } from '../FullScreen'
import Timeout from '../Timeout'
import Camera from '../Camera'
import CameraError from '../CameraError'
import style from './style.css'
type State = {
hasBecomeInactive: boolean,
snapshotBuffer: Array<{
blob: Blob
}>,
}
type Props = {
onCapture: Function,
renderFallback: Function,
trackScreen: Function,
inactiveError: Object,
useMultipleSelfieCapture: boolean,
snapshotInterval: number,
}
export default class Selfie extends Component<Props, State> {
webcam = null
snapshotIntervalRef: ?IntervalID = null
state: State = {
hasBecomeInactive: false,
snapshotBuffer: [],
}
handleTimeout = () => this.setState({ hasBecomeInactive: true })
handleSelfie = (blob: Blob, _: string, sdkMetadata: Object) => {
const selfie = { blob, sdkMetadata, filename: `applicant_selfie.${fileType(blob)}`}
/* Attempt to get the 'ready' snapshot. But, if that fails, try to get the fresh snapshot - it's better
to have a snapshot, even if it's not an ideal one */
const snapshot = this.state.snapshotBuffer[0] || this.state.snapshotBuffer[1]
const captureData = this.props.useMultipleSelfieCapture ?
{ snapshot, ...selfie } : selfie
this.props.onCapture(captureData)
}
handleSnapshot = (blob: Blob, _: string, sdkMetadata: Object) => {
// Always try to get the older snapshot to ensure
// it's different enough from the user initiated selfie
this.setState(({ snapshotBuffer: [, newestSnapshot] }) => ({
snapshotBuffer: [newestSnapshot, { blob, sdkMetadata, filename: `applicant_snapshot.${fileType(blob)}` }]
}))
}
takeSnapshot = () =>
this.webcam && screenshot(this.webcam, this.handleSnapshot)
takeSelfie = () => screenshot(this.webcam, this.handleSelfie)
setupSnapshots = () => {
if (this.props.useMultipleSelfieCapture) {
setTimeout(this.takeSnapshot, this.props.snapshotInterval / 4)
this.snapshotIntervalRef = setInterval(
this.takeSnapshot,
this.props.snapshotInterval
);
}
}
componentWillUnmount() {
if (this.snapshotIntervalRef) {
clearInterval(this.snapshotIntervalRef)
}
}
render() {
const { trackScreen, renderFallback, inactiveError} = this.props
const { hasBecomeInactive } = this.state
return (
<div>
<Camera
{...this.props}
webcamRef={ c => this.webcam = c }
onUserMedia={ this.setupSnapshots }
renderError={ hasBecomeInactive ?
<CameraError
{...{trackScreen, renderFallback}}
error={inactiveError}
isDismissible
/> : null
}
>
<Timeout seconds={ 10 } onTimeout={ this.handleTimeout } />
<ToggleFullScreen />
<FaceOverlay />
<div className={style.actions}>
<button
className={style.btn}
onClick={this.takeSelfie}
/>
</div>
</Camera>
</div>
)
}
}