diff --git a/src/components/dashboard/FaceRecognition/FRError.js b/src/components/dashboard/FaceRecognition/FRError.js index a36d18b9c7..a142ec56d9 100644 --- a/src/components/dashboard/FaceRecognition/FRError.js +++ b/src/components/dashboard/FaceRecognition/FRError.js @@ -32,7 +32,7 @@ const FRError = props => { } const gotoFR = () => { - props.screenProps.navigateTo('FaceVerification') + props.screenProps.navigateTo('FaceVerification', { showHelper: false }) } log.debug(props.screenProps) diff --git a/src/components/dashboard/FaceRecognition/FRIntro.js b/src/components/dashboard/FaceRecognition/FRIntro.js index 07d5f898ff..5abe54cddc 100644 --- a/src/components/dashboard/FaceRecognition/FRIntro.js +++ b/src/components/dashboard/FaceRecognition/FRIntro.js @@ -7,6 +7,7 @@ import { CustomButton, Section, Wrapper } from '../../common' import Divider from '../../../assets/Dividers - Long Line - Stroke Width 2 - Round Cap - Light Blue.svg' import SmileyHug from '../../../assets/smileyhug.svg' import GDStore from '../../../lib/undux/GDStore' +import { fireEvent } from '../../../lib/analytics/analytics' import logger from '../../../lib/logger/pino-logger' @@ -24,6 +25,8 @@ const FRIntro = props => { } if (isValid) { props.screenProps.pop({ isValid: true }) + } else { + fireEvent('FR_Intro') } const gotoPrivacyArticle = () => props.screenProps.push('PP') const gotoFR = () => props.screenProps.navigateTo('FaceVerification') diff --git a/src/components/dashboard/FaceRecognition/FaceRecognition.js b/src/components/dashboard/FaceRecognition/FaceRecognition.js index 7fd963ef5e..c4d97e4b0b 100644 --- a/src/components/dashboard/FaceRecognition/FaceRecognition.js +++ b/src/components/dashboard/FaceRecognition/FaceRecognition.js @@ -5,6 +5,7 @@ import type { DashboardProps } from '../Dashboard' import logger from '../../../lib/logger/pino-logger' import { Wrapper } from '../../common' import userStorage from '../../../lib/gundb/UserStorage' +import { fireEvent } from '../../../lib/analytics/analytics' import FRapi from './FaceRecognitionAPI' import type FaceRecognitionResponse from './FaceRecognitionAPI' import GuidedFR from './GuidedFRProcessResults' @@ -27,6 +28,7 @@ type State = { zoomReady: boolean, captureResult: ZoomCaptureResult, isWhitelisted: boolean | void, + showHelper: boolean, } /** @@ -47,6 +49,7 @@ class FaceRecognition extends React.Component { zoomReady: false, captureResult: {}, isWhitelisted: undefined, + showHelper: get(this.props, 'screenProps.screenState.showHelper', true), } loadedZoom: any @@ -88,6 +91,7 @@ class FaceRecognition extends React.Component { onCaptureResult = (captureResult?: ZoomCaptureResult): void => { //TODO: rami check uninitilized, return log.debug('zoom capture completed', { captureResult }) + fireEvent('FR_Capture') if (captureResult === undefined) { log.error('empty capture result') this.showFRError('empty capture result') @@ -110,9 +114,9 @@ class FaceRecognition extends React.Component { log.error('FR API call failed:', { result }) this.showFRError(result.error) // TODO: rami } else if (get(result, 'enrollResult.enrollmentIdentifier', undefined)) { - this.setState({ ...this.state, isWhitelisted: true }) + this.setState({ ...this.state, isAPISuccess: true }) } else { - this.setState({ ...this.state, isWhitelisted: false }) + this.setState({ ...this.state, isAPISuccess: false }) } } catch (e) { log.error('FR API call failed:', e, e.message) @@ -121,22 +125,30 @@ class FaceRecognition extends React.Component { } showFRError = (error: string | Error) => { + fireEvent('FR_Error') this.setState({ showZoomCapture: false, showGuidedFR: false, sessionId: undefined }, () => { this.props.screenProps.navigateTo('FRError', { error }) }) } retry = () => { - this.setState({ showGuidedFR: false, sessionId: undefined, showZoomCapture: true }) + fireEvent('FR_Retry') + this.setState({ + showGuidedFR: false, + sessionId: undefined, + showZoomCapture: true, + isAPISuccess: undefined, + showHelper: false, + }) } done = () => { + fireEvent('FR_Success') this.props.screenProps.pop({ isValid: true }) } render() { - const { showZoomCapture, showGuidedFR, sessionId, isWhitelisted } = this.state - log.debug('Render:', { showZoomCapture }) + const { showZoomCapture, showGuidedFR, sessionId, isAPISuccess } = this.state return ( {showGuidedFR && ( @@ -146,7 +158,7 @@ class FaceRecognition extends React.Component { retry={this.retry} done={this.done} navigation={this.props.screenProps} - isWhitelisted={isWhitelisted} + isAPISuccess={isAPISuccess} /> )} @@ -157,6 +169,7 @@ class FaceRecognition extends React.Component { showZoomCapture={this.state.zoomReady && showZoomCapture} loadedZoom={this.loadedZoom} onError={this.showFRError} + showHelper={this.state.showHelper} /> )} diff --git a/src/components/dashboard/FaceRecognition/GuidedFRProcessResults.js b/src/components/dashboard/FaceRecognition/GuidedFRProcessResults.js index 319e0d14d9..98ef64730f 100644 --- a/src/components/dashboard/FaceRecognition/GuidedFRProcessResults.js +++ b/src/components/dashboard/FaceRecognition/GuidedFRProcessResults.js @@ -4,6 +4,8 @@ import { ActivityIndicator, Image, StyleSheet, View } from 'react-native' import { Text } from 'react-native-paper' import normalize from 'react-native-elements/src/helpers/normalizeText' import find from 'lodash/find' +import findKey from 'lodash/findKey' +import mapValues from 'lodash/mapValues' import { CustomButton, Section } from '../../common' import logger from '../../../lib/logger/pino-logger' import goodWallet from '../../../lib/wallet/GoodWallet' @@ -13,6 +15,7 @@ import Check from '../../../assets/Icons - Success - White.svg' import Cross from '../../../assets/Icons - Close X - White.svg' import LookingGood from '../../../assets/LookingGood.svg' import GDStore from '../../../lib/undux/GDStore' +import { fireEvent } from '../../../lib/analytics/analytics' const log = logger.child({ from: 'GuidedFRProcessResults' }) @@ -38,7 +41,7 @@ const FRStep = ({ title, isActive, status, isProcessFailed, paddingBottom }) => ) } -const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigation, isWhitelisted }: any) => { +const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigation, isAPISuccess }: any) => { const store = GDStore.useStore() const { fullName } = store.get('profile') @@ -48,12 +51,17 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati isEnrolled: undefined, isLive: undefined, isWhitelisted: undefined, + isProfileSaved: undefined, }) const updateProgress = data => { log.debug('updating progress', { data }) // let explanation = '' + let failedFR = findKey(data, (v, k) => v === false) + if (failedFR) { + fireEvent(`FR_Failed`, { failedFR }) + } setStatus({ ...processStatus, ...data }) // log.debug('analyzed data,', { processStatus }) @@ -80,7 +88,7 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati // let [showDialogWithData] = useDialog() let gun = userStorage.gun - log.debug({ sessionId, isWhitelisted }) + log.debug({ sessionId, isAPISuccess }) useEffect(() => { log.debug('subscriping to gun updates:', { sessionId }) @@ -112,6 +120,7 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati const gotoSupport = () => { navigation.push('Support') } + useEffect(() => { //done save profile and call done callback if (processStatus.isWhitelisted) { @@ -119,15 +128,19 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati } }, [processStatus.isWhitelisted]) - //API call finished, so it will pass isWhitelisted to us - //this is a backup incase the gundb messaging doesnt work - const gunOK = find(processStatus, (v, k) => v !== undefined) - if (gunOK === undefined && isWhitelisted) { - processStatus.isWhitelisted = true - saveProfileAndDone() - } else if (gunOK === undefined && isWhitelisted === false) { - processStatus.isWhitelisted = false - } + useEffect(() => { + if (isAPISuccess === undefined) { + return + } + + //API call finished, so it will pass isWhitelisted to us + //this is a backup incase the gundb messaging doesnt work + const gunOK = find(processStatus, (v, k) => v !== undefined) + if (gunOK === undefined) { + const newStatus = mapValues(processStatus, v => false) + setStatus({ ...newStatus, isWhitelisted: isAPISuccess, useAPIResult: true }) + } + }, [isAPISuccess]) const isProcessFailed = processStatus.isNotDuplicate === false || @@ -156,7 +169,9 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati ) : null let helpText - if (processStatus.isNotDuplicate === false) { + if (processStatus.useAPIResult && isAPISuccess === false) { + helpText = 'Something went wrong, please try again...' + } else if (processStatus.isNotDuplicate === false) { helpText = ( @@ -182,7 +197,7 @@ const GuidedFRProcessResults = ({ profileSaved, sessionId, retry, done, navigati helpText = 'We could not verify you are a living person. Funny hu? please make sure:\n\n\ A. Center your webcam\n\ -B. Ensure camera is at eye level\n\ +B. Camera is at eye level\n\ C. Light your face evenly' } else if (isProcessFailed) { helpText = 'Something went wrong, please try again...' @@ -223,6 +238,7 @@ C. Light your face evenly' { } useEffect(() => { + fireEvent(`FR_Unsupported_${reason}`) generateQRCode() }, []) diff --git a/src/components/dashboard/FaceRecognition/ZoomCapture.js b/src/components/dashboard/FaceRecognition/ZoomCapture.js index b6fa6f2702..e530428cc9 100644 --- a/src/components/dashboard/FaceRecognition/ZoomCapture.js +++ b/src/components/dashboard/FaceRecognition/ZoomCapture.js @@ -35,12 +35,16 @@ type ZoomCaptureProps = { loadedZoom: boolean, onCaptureResult: (captureResult?: ZoomCaptureResult) => void, onError: (error: string) => void, + showHelper: boolean, } const HelperWizard = props => { - const { done } = props + const { done, skip } = props const [step, setStep] = useState(0) const nextStep = () => setStep(step + 1) + if (skip) { + return null + } let text, imgs switch (step) { case 0: @@ -138,6 +142,9 @@ class ZoomCapture extends React.Component { let zoomSDK = this.props.loadedZoom this.zoom = new Zoom(zoomSDK, track) await this.zoom.ready + if (this.props.showHelper === false) { + this.captureUserMediaZoom() + } } catch (e) { log.error(`Failed on capture, error: ${e}`) this.props.onError(e) @@ -178,7 +185,7 @@ class ZoomCapture extends React.Component {
- +
{}