Skip to content

Commit

Permalink
migrate to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
eucool committed Mar 24, 2024
1 parent 9addf33 commit dcab8c7
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ type MoneyRequestNavigatorParamList = {
iouType: string;
reportID: string;
};
[SCREENS.MONEY_REQUEST.SCAN_TAB]: {
[SCREENS.MONEY_REQUEST.STEP_SCAN]: {
action: ValueOf<typeof CONST.IOU.ACTION>;
iouType: ValueOf<typeof CONST.IOU.TYPE>;
transactionID: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useFocusEffect} from '@react-navigation/core';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import React, {useCallback, useRef, useState} from 'react';
import {ActivityIndicator, Alert, AppState, InteractionManager, View} from 'react-native';
import {Gesture, GestureDetector} from 'react-native-gesture-handler';
import {RESULTS} from 'react-native-permissions';
Expand Down Expand Up @@ -91,7 +91,7 @@ function IOURequestStepScan({

const tapGesture = Gesture.Tap()
.enabled(device?.supportsFocus ?? false)
.onStart((ev) => {
.onStart((ev: {x: number; y: number}) => {
const point = {x: ev.x, y: ev.y};

focusIndicatorOpacity.value = withSequence(withTiming(0.8, {duration: 250}), withDelay(1000, withTiming(0, {duration: 250})));
Expand Down
58 changes: 38 additions & 20 deletions src/pages/iou/request/step/IOURequestStepScan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ function IOURequestStepScan({
const [isFlashLightOn, toggleFlashlight] = useReducer((state) => !state, false);
const [isTorchAvailable, setIsTorchAvailable] = useState(false);
const cameraRef = useRef<Webcam>(null);
const trackRef = useRef(null);
const trackRef = useRef<MediaStreamTrack | null>(null);

const getScreenshotTimeoutRef = useRef(null);
const getScreenshotTimeoutRef = useRef<NodeJS.Timeout | null>(null);

const [videoConstraints, setVideoConstraints] = useState(null);
const [videoConstraints, setVideoConstraints] = useState<MediaTrackConstraints>();
const tabIndex = 1;
const isTabActive = useTabNavigatorFocus({tabIndex});

Expand All @@ -70,22 +70,30 @@ function IOURequestStepScan({
* The last deviceId is of regular len camera.
*/
useEffect(() => {
if (!_.isEmpty(videoConstraints) || !isTabActive || !Browser.isMobile()) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (videoConstraints || !isTabActive || !Browser.isMobile()) {
return;
}

const defaultConstraints = {facingMode: {exact: 'environment'}};
navigator.mediaDevices
// @ts-expect-error there is a type mismatch in typescipt types for MediaStreamTrack microsoft/TypeScript#39010
.getUserMedia({video: {facingMode: {exact: 'environment'}, zoom: {ideal: 1}}})
.then((stream) => {
_.forEach(stream.getTracks(), (track) => track.stop());
// Stop all tracks
stream.getTracks().forEach((track) => track.stop());

// Only Safari 17+ supports zoom constraint
if (Browser.isMobileSafari() && stream.getTracks().length > 0) {
const deviceId = _.chain(stream.getTracks())
.map((track) => track.getSettings())
.find((setting) => setting.zoom === 1)
.get('deviceId')
.value();
let deviceId;
for (const track of stream.getTracks()) {
const setting = track.getSettings();
// @ts-expect-error there is a type mismatch in typescipt types for MediaStreamTrack microsoft/TypeScript#39010
if (setting.zoom === 1) {
deviceId = setting.deviceId;
break;
}
}
if (deviceId) {
setVideoConstraints({deviceId});
return;
Expand All @@ -96,12 +104,14 @@ function IOURequestStepScan({
return;
}
navigator.mediaDevices.enumerateDevices().then((devices) => {
const lastBackDeviceId = _.chain(devices)
.filter((item) => item.kind === 'videoinput')
.last()
.get('deviceId', '')
.value();

let lastBackDeviceId = '';
for (let i = devices.length - 1; i >= 0; i--) {
const device = devices[i];
if (device.kind === 'videoinput') {
lastBackDeviceId = device.deviceId;
break;
}
}
if (!lastBackDeviceId) {
setVideoConstraints(defaultConstraints);
return;
Expand Down Expand Up @@ -198,15 +208,16 @@ function IOURequestStepScan({
navigateToConfirmationStep();
};

const setupCameraPermissionsAndCapabilities = (stream) => {
const setupCameraPermissionsAndCapabilities = (stream: MediaStream) => {
setCameraPermissionState('granted');

const [track] = stream.getVideoTracks();
const capabilities = track.getCapabilities();
if (capabilities.torch) {

if ('torch' in capabilities && capabilities.torch) {
trackRef.current = track;
}
setIsTorchAvailable(!!capabilities.torch);
setIsTorchAvailable('torch' in capabilities && !!capabilities.torch);
};

const getScreenshot = useCallback(() => {
Expand Down Expand Up @@ -234,6 +245,7 @@ function IOURequestStepScan({
return;
}
trackRef.current.applyConstraints({
// @ts-expect-error there is a type mismatch in typescipt types for MediaStreamTrack microsoft/TypeScript#39010
advanced: [{torch: false}],
});
}, []);
Expand All @@ -242,6 +254,7 @@ function IOURequestStepScan({
if (trackRef.current && isFlashLightOn) {
trackRef.current
.applyConstraints({
// @ts-expect-error there is a type mismatch in typescipt types for MediaStreamTrack microsoft/TypeScript#39010
advanced: [{torch: true}],
})
.then(() => {
Expand Down Expand Up @@ -294,7 +307,7 @@ function IOURequestStepScan({
<Text style={[styles.subTextReceiptUpload]}>{translate('receipt.cameraAccess')}</Text>
</View>
)}
{!_.isEmpty(videoConstraints) && (
{videoConstraints && (
<NavigationAwareCamera
onUserMedia={setupCameraPermissionsAndCapabilities}
onUserMediaError={() => setCameraPermissionState('denied')}
Expand All @@ -304,6 +317,11 @@ function IOURequestStepScan({
videoConstraints={videoConstraints}
forceScreenshotSourceSize
cameraTabIndex={tabIndex}
audio={false}
disablePictureInPicture={false}
imageSmoothing={false}
mirrored={false}
screenshotQuality={0}
/>
)}
</View>
Expand Down
4 changes: 3 additions & 1 deletion src/pages/iou/request/step/withWritableReportOrNotFound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import type {Report} from '@src/types/onyx';
import type {Report, Transaction} from '@src/types/onyx';

type WithWritableReportOrNotFoundOnyxProps = {
/** The report corresponding to the reportID in the route params */
report: OnyxEntry<Report>;
/** The transaction that the user is trying to create */
transaction?: OnyxEntry<Transaction>;
};

type Route = RouteProp<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_WAYPOINT>;
Expand Down

0 comments on commit dcab8c7

Please sign in to comment.