From 1d2852912f3babb03378465af2942f9f41826ad0 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Tue, 12 Nov 2024 13:03:44 +0100 Subject: [PATCH 1/8] upgrade react-native-vision-camera --- ios/Podfile.lock | 27 ++++++--------------------- package-lock.json | 14 ++++++++++++-- package.json | 2 +- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6494782a6ec0..b9872d857574 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2695,27 +2695,12 @@ PODS: - SDWebImage/Core (~> 5.17) - SocketRocket (0.7.0) - Turf (2.8.0) - - VisionCamera (4.0.0-beta.13): - - DoubleConversion - - glog - - hermes-engine - - RCT-Folly (= 2024.01.01.00) - - RCTRequired - - RCTTypeSafety + - VisionCamera (4.6.1): + - VisionCamera/Core (= 4.6.1) + - VisionCamera/React (= 4.6.1) + - VisionCamera/Core (4.6.1) + - VisionCamera/React (4.6.1): - React-Core - - React-debug - - React-Fabric - - React-featureflags - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCodegen - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - Yoga (0.0.0) DEPENDENCIES: @@ -3280,7 +3265,7 @@ SPEC CHECKSUMS: SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e - VisionCamera: c6c8aa4b028501fc87644550fbc35a537d4da3fb + VisionCamera: c95a8ad535f527562be1fb05fb2fd324578e769c Yoga: a1d7895431387402a674fd0d1c04ec85e87909b8 PODFILE CHECKSUM: 15e2f095b9c80d658459723edf84005a6867debf diff --git a/package-lock.json b/package-lock.json index f2dbe85646d1..ce4559478107 100644 --- a/package-lock.json +++ b/package-lock.json @@ -115,7 +115,7 @@ "react-native-tab-view": "^3.5.2", "react-native-url-polyfill": "^2.0.0", "react-native-view-shot": "3.8.0", - "react-native-vision-camera": "4.0.0-beta.13", + "react-native-vision-camera": "^4.6.1", "react-native-web": "0.19.13", "react-native-webview": "13.8.6", "react-plaid-link": "3.3.2", @@ -35812,14 +35812,24 @@ } }, "node_modules/react-native-vision-camera": { - "version": "4.0.0-beta.13", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/react-native-vision-camera/-/react-native-vision-camera-4.6.1.tgz", + "integrity": "sha512-USp7g+Q/H7nzIS2XBJTWVdzZArxgZu+IFafgswVzxdmr0iSpLjLUtoUp+SUWxZ+nLhJriYYvqg8hfZrJtnpnlw==", "license": "MIT", "peerDependencies": { + "@shopify/react-native-skia": "*", "react": "*", "react-native": "*", + "react-native-reanimated": "*", "react-native-worklets-core": "*" }, "peerDependenciesMeta": { + "@shopify/react-native-skia": { + "optional": true + }, + "react-native-reanimated": { + "optional": true + }, "react-native-worklets-core": { "optional": true } diff --git a/package.json b/package.json index 2089a372a4d4..4d637e0cf432 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,7 @@ "react-native-tab-view": "^3.5.2", "react-native-url-polyfill": "^2.0.0", "react-native-view-shot": "3.8.0", - "react-native-vision-camera": "4.0.0-beta.13", + "react-native-vision-camera": "^4.6.1", "react-native-web": "0.19.13", "react-native-webview": "13.8.6", "react-plaid-link": "3.3.2", From 33511a145e297d67eb680a7114b3683517574b99 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Tue, 12 Nov 2024 16:56:59 +0100 Subject: [PATCH 2/8] draft folder receipt creation --- .../step/IOURequestStepScan/index.native.tsx | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index f7e575b898fd..ea99d2cf0151 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -2,6 +2,7 @@ import {useFocusEffect} from '@react-navigation/core'; import {Str} from 'expensify-common'; import React, {useCallback, useMemo, useRef, useState} from 'react'; import {ActivityIndicator, Alert, AppState, InteractionManager, View} from 'react-native'; +import ReactNativeBlobUtil from 'react-native-blob-util'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; import {useOnyx} from 'react-native-onyx'; import {RESULTS} from 'react-native-permissions'; @@ -494,12 +495,44 @@ function IOURequestStepScan({ setDidCapturePhoto(true); + console.debug('[dev] Taking photo'); + console.debug('[dev] ReactNativeBlobUtil.fs.dirs.DocumentDir', ReactNativeBlobUtil.fs.dirs.DocumentDir); + + const path = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/Receipts-Pending-Upload`; + + console.debug('ReactNativeBlobUtil.fs.isDir(path)', ReactNativeBlobUtil.fs.isDir(path)); + + ReactNativeBlobUtil.fs + .isDir(path) + .then((isDir) => { + console.debug('[dev] ReactNativeBlobUtil.fs.isDir:', isDir); + if (isDir) { + return; + } + + ReactNativeBlobUtil.fs + .mkdir(path) + .then(() => { + console.debug('[dev] Directory created successfully'); + }) + .catch((error) => { + console.error('[dev] Error creating directory:', error); + }); + }) + .catch((error) => { + console.error('[dev] Error checking if directory exists:', error); + }); + camera?.current ?.takePhoto({ flash: flash && hasFlash ? 'on' : 'off', enableShutterSound: !isPlatformMuted, + path, }) .then((photo: PhotoFile) => { + console.debug('[dev] photo', photo); + return; + // Store the receipt on the transaction object in Onyx const source = getPhotoSource(photo.path); IOU.setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); @@ -529,14 +562,14 @@ function IOURequestStepScan({ () => { setDidCapturePhoto(false); showCameraAlert(); - Log.warn('Error reading photo'); + Log.warn('[dev] Error reading photo'); }, ); }) .catch((error: string) => { setDidCapturePhoto(false); showCameraAlert(); - Log.warn('Error taking photo', error); + Log.warn('[dev] Error taking photo', error); }); }, [ cameraPermissionStatus, From 7647b6d386a90740e6a6a7c00560ccee0c985cd7 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 13 Nov 2024 11:23:37 +0100 Subject: [PATCH 3/8] use outputOrientation --- src/pages/iou/request/step/IOURequestStepScan/index.native.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index ea99d2cf0151..9f342ed7b0ea 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -662,7 +662,7 @@ function IOURequestStepScan({ zoom={device.neutralZoom} photo cameraTabIndex={1} - orientation="portrait" + outputOrientation="preview" /> From fd6168b77867db70694cf71901f57e60d12a581e Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 13 Nov 2024 13:01:10 +0100 Subject: [PATCH 4/8] integrate getReceiptsUploadFolderPath --- src/CONST.ts | 1 + src/libs/getReceiptsUploadFolderPath/index.android.ts | 7 +++++++ src/libs/getReceiptsUploadFolderPath/index.ios.ts | 7 +++++++ src/libs/getReceiptsUploadFolderPath/index.ts | 5 +++++ src/libs/getReceiptsUploadFolderPath/types.ts | 3 +++ 5 files changed, 23 insertions(+) create mode 100644 src/libs/getReceiptsUploadFolderPath/index.android.ts create mode 100644 src/libs/getReceiptsUploadFolderPath/index.ios.ts create mode 100644 src/libs/getReceiptsUploadFolderPath/index.ts create mode 100644 src/libs/getReceiptsUploadFolderPath/types.ts diff --git a/src/CONST.ts b/src/CONST.ts index e95e3d4a5603..657135a238f6 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5845,6 +5845,7 @@ const CONST = { DOWNLOADS_PATH: '/Downloads', DOWNLOADS_TIMEOUT: 5000, NEW_EXPENSIFY_PATH: '/New Expensify', + RECEIPTS_UPLOAD_PATH: '/Receipts-Pending-Upload', ENVIRONMENT_SUFFIX: { DEV: ' Dev', diff --git a/src/libs/getReceiptsUploadFolderPath/index.android.ts b/src/libs/getReceiptsUploadFolderPath/index.android.ts new file mode 100644 index 000000000000..5179afd64134 --- /dev/null +++ b/src/libs/getReceiptsUploadFolderPath/index.android.ts @@ -0,0 +1,7 @@ +import ReactNativeBlobUtil from 'react-native-blob-util'; +import CONST from '@src/CONST'; +import type GetReceiptsUploadFolderPath from './types'; + +const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${ReactNativeBlobUtil.fs.dirs.DownloadDir}${CONST.RECEIPTS_UPLOAD_PATH}`; + +export default getReceiptsUploadFolderPath; diff --git a/src/libs/getReceiptsUploadFolderPath/index.ios.ts b/src/libs/getReceiptsUploadFolderPath/index.ios.ts new file mode 100644 index 000000000000..c787909055a6 --- /dev/null +++ b/src/libs/getReceiptsUploadFolderPath/index.ios.ts @@ -0,0 +1,7 @@ +import ReactNativeBlobUtil from 'react-native-blob-util'; +import CONST from '@src/CONST'; +import type GetReceiptsUploadFolderPath from './types'; + +const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${ReactNativeBlobUtil.fs.dirs.DocumentDir}${CONST.RECEIPTS_UPLOAD_PATH}`; + +export default getReceiptsUploadFolderPath; diff --git a/src/libs/getReceiptsUploadFolderPath/index.ts b/src/libs/getReceiptsUploadFolderPath/index.ts new file mode 100644 index 000000000000..fcec3b2d6711 --- /dev/null +++ b/src/libs/getReceiptsUploadFolderPath/index.ts @@ -0,0 +1,5 @@ +import type GetReceiptsUploadFolderPath from './types'; + +const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => ''; + +export default getReceiptsUploadFolderPath; diff --git a/src/libs/getReceiptsUploadFolderPath/types.ts b/src/libs/getReceiptsUploadFolderPath/types.ts new file mode 100644 index 000000000000..44c21e513f4d --- /dev/null +++ b/src/libs/getReceiptsUploadFolderPath/types.ts @@ -0,0 +1,3 @@ +type GetReceiptsUploadFolderPath = () => string; + +export default GetReceiptsUploadFolderPath; From be154dbf5ce671dfe0df92536a760fddd4488cc6 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 13 Nov 2024 16:07:36 +0100 Subject: [PATCH 5/8] get new flow workable --- .../step/IOURequestStepScan/index.native.tsx | 97 ++++++++++--------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 9f342ed7b0ea..5bf50419bcbc 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -32,6 +32,7 @@ import * as FileUtils from '@libs/fileDownload/FileUtils'; import getPhotoSource from '@libs/fileDownload/getPhotoSource'; import getCurrentPosition from '@libs/getCurrentPosition'; import getPlatform from '@libs/getPlatform'; +import getReceiptsUploadFolderPath from '@libs/getReceiptsUploadFolderPath'; import * as IOUUtils from '@libs/IOUUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -496,16 +497,16 @@ function IOURequestStepScan({ setDidCapturePhoto(true); console.debug('[dev] Taking photo'); - console.debug('[dev] ReactNativeBlobUtil.fs.dirs.DocumentDir', ReactNativeBlobUtil.fs.dirs.DocumentDir); - const path = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/Receipts-Pending-Upload`; + const path = getReceiptsUploadFolderPath(); - console.debug('ReactNativeBlobUtil.fs.isDir(path)', ReactNativeBlobUtil.fs.isDir(path)); + console.debug('[dev] path', path); ReactNativeBlobUtil.fs .isDir(path) .then((isDir) => { - console.debug('[dev] ReactNativeBlobUtil.fs.isDir:', isDir); + console.debug('[dev] Checking if directory exists', isDir); + if (isDir) { return; } @@ -521,55 +522,55 @@ function IOURequestStepScan({ }) .catch((error) => { console.error('[dev] Error checking if directory exists:', error); - }); - - camera?.current - ?.takePhoto({ - flash: flash && hasFlash ? 'on' : 'off', - enableShutterSound: !isPlatformMuted, - path, }) - .then((photo: PhotoFile) => { - console.debug('[dev] photo', photo); - return; - - // Store the receipt on the transaction object in Onyx - const source = getPhotoSource(photo.path); - IOU.setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); - - FileUtils.readFileAsync( - source, - photo.path, - (file) => { - if (isEditing) { - updateScanAndNavigate(file, source); - return; - } - if (shouldSkipConfirmation) { - setFileResize(file); - setFileSource(source); - const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; - if (gpsRequired) { - const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); - if (shouldStartLocationPermissionFlow) { - setStartLocationPermissionFlow(true); + .then(() => { + camera?.current + ?.takePhoto({ + flash: flash && hasFlash ? 'on' : 'off', + enableShutterSound: !isPlatformMuted, + path, + }) + .then((photo: PhotoFile) => { + console.debug('[dev] photo', photo); + + // Store the receipt on the transaction object in Onyx + const source = getPhotoSource(photo.path); + IOU.setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); + + FileUtils.readFileAsync( + source, + photo.path, + (file) => { + if (isEditing) { + updateScanAndNavigate(file, source); return; } - } - } - navigateToConfirmationStep(file, source, false); - }, - () => { + if (shouldSkipConfirmation) { + setFileResize(file); + setFileSource(source); + const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && file; + if (gpsRequired) { + const shouldStartLocationPermissionFlow = IOUUtils.shouldStartLocationPermissionFlow(); + if (shouldStartLocationPermissionFlow) { + setStartLocationPermissionFlow(true); + return; + } + } + } + navigateToConfirmationStep(file, source, false); + }, + () => { + setDidCapturePhoto(false); + showCameraAlert(); + Log.warn('[dev] Error reading photo'); + }, + ); + }) + .catch((error: string) => { setDidCapturePhoto(false); showCameraAlert(); - Log.warn('[dev] Error reading photo'); - }, - ); - }) - .catch((error: string) => { - setDidCapturePhoto(false); - showCameraAlert(); - Log.warn('[dev] Error taking photo', error); + Log.warn('[dev] Error taking photo', error); + }); }); }, [ cameraPermissionStatus, From 27b9f40d0cd55c3d6245a18616303dd8bcbea8e9 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 28 Nov 2024 16:30:39 +0100 Subject: [PATCH 6/8] rename folder --- src/CONST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 3ff41b466c79..f33041921a7b 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5956,7 +5956,7 @@ const CONST = { DOWNLOADS_PATH: '/Downloads', DOWNLOADS_TIMEOUT: 5000, NEW_EXPENSIFY_PATH: '/New Expensify', - RECEIPTS_UPLOAD_PATH: '/Receipts-Pending-Upload', + RECEIPTS_UPLOAD_PATH: '/Receipts-Upload', ENVIRONMENT_SUFFIX: { DEV: ' Dev', From 2a605bac8e9c74bfbb1ac62d9fd427be304520da Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 28 Nov 2024 16:32:16 +0100 Subject: [PATCH 7/8] rename import --- src/libs/getReceiptsUploadFolderPath/index.android.ts | 4 ++-- src/libs/getReceiptsUploadFolderPath/index.ios.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/getReceiptsUploadFolderPath/index.android.ts b/src/libs/getReceiptsUploadFolderPath/index.android.ts index 5179afd64134..d88f83994524 100644 --- a/src/libs/getReceiptsUploadFolderPath/index.android.ts +++ b/src/libs/getReceiptsUploadFolderPath/index.android.ts @@ -1,7 +1,7 @@ -import ReactNativeBlobUtil from 'react-native-blob-util'; +import RNFetchBlob from 'react-native-blob-util'; import CONST from '@src/CONST'; import type GetReceiptsUploadFolderPath from './types'; -const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${ReactNativeBlobUtil.fs.dirs.DownloadDir}${CONST.RECEIPTS_UPLOAD_PATH}`; +const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${RNFetchBlob.fs.dirs.DownloadDir}${CONST.RECEIPTS_UPLOAD_PATH}`; export default getReceiptsUploadFolderPath; diff --git a/src/libs/getReceiptsUploadFolderPath/index.ios.ts b/src/libs/getReceiptsUploadFolderPath/index.ios.ts index c787909055a6..987d66bf17c0 100644 --- a/src/libs/getReceiptsUploadFolderPath/index.ios.ts +++ b/src/libs/getReceiptsUploadFolderPath/index.ios.ts @@ -1,7 +1,7 @@ -import ReactNativeBlobUtil from 'react-native-blob-util'; +import RNFetchBlob from 'react-native-blob-util'; import CONST from '@src/CONST'; import type GetReceiptsUploadFolderPath from './types'; -const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${ReactNativeBlobUtil.fs.dirs.DocumentDir}${CONST.RECEIPTS_UPLOAD_PATH}`; +const getReceiptsUploadFolderPath: GetReceiptsUploadFolderPath = () => `${RNFetchBlob.fs.dirs.DocumentDir}${CONST.RECEIPTS_UPLOAD_PATH}`; export default getReceiptsUploadFolderPath; From b1d45dc33229adce6fa3b1f1a62a1d1a827c9927 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Thu, 28 Nov 2024 17:17:35 +0100 Subject: [PATCH 8/8] clear logs --- .../step/IOURequestStepScan/index.native.tsx | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 9704829c70c6..4af9b008f827 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -499,32 +499,21 @@ function IOURequestStepScan({ setDidCapturePhoto(true); - console.debug('[dev] Taking photo'); - const path = getReceiptsUploadFolderPath(); - console.debug('[dev] path', path); - ReactNativeBlobUtil.fs .isDir(path) .then((isDir) => { - console.debug('[dev] Checking if directory exists', isDir); - if (isDir) { return; } - ReactNativeBlobUtil.fs - .mkdir(path) - .then(() => { - console.debug('[dev] Directory created successfully'); - }) - .catch((error) => { - console.error('[dev] Error creating directory:', error); - }); + ReactNativeBlobUtil.fs.mkdir(path).catch((error: string) => { + Log.warn('Error creating the directory', error); + }); }) - .catch((error) => { - console.error('[dev] Error checking if directory exists:', error); + .catch((error: string) => { + Log.warn('Error checking if the directory exists', error); }) .then(() => { camera?.current @@ -534,8 +523,6 @@ function IOURequestStepScan({ path, }) .then((photo: PhotoFile) => { - console.debug('[dev] photo', photo); - // Store the receipt on the transaction object in Onyx const source = getPhotoSource(photo.path); IOU.setMoneyRequestReceipt(transactionID, source, photo.path, !isEditing); @@ -565,14 +552,14 @@ function IOURequestStepScan({ () => { setDidCapturePhoto(false); showCameraAlert(); - Log.warn('[dev] Error reading photo'); + Log.warn('Error reading photo'); }, ); }) .catch((error: string) => { setDidCapturePhoto(false); showCameraAlert(); - Log.warn('[dev] Error taking photo', error); + Log.warn('Error taking photo', error); }); }); }, [