feat: drop rn-qr-generator depenedency
This commit is contained in:
parent
f82de26f59
commit
15319ed2e6
@ -2,7 +2,7 @@ import { Platform } from 'react-native';
|
||||
import { pick, types, keepLocalCopy, errorCodes } from '@react-native-documents/picker';
|
||||
import RNFS from 'react-native-fs';
|
||||
import { launchImageLibrary, ImagePickerResponse } from 'react-native-image-picker';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
import { detectQRCodeInImage } from 'react-native-camera-kit-no-google';
|
||||
import Share from 'react-native-share';
|
||||
|
||||
import presentAlert from '../components/Alert';
|
||||
@ -113,6 +113,7 @@ export const showImagePickerAndReadImage = async (): Promise<string | undefined>
|
||||
maxHeight: 800,
|
||||
maxWidth: 600,
|
||||
selectionLimit: 1,
|
||||
includeBase64: true,
|
||||
});
|
||||
|
||||
if (response.didCancel) {
|
||||
@ -120,19 +121,12 @@ export const showImagePickerAndReadImage = async (): Promise<string | undefined>
|
||||
} else if (response.errorCode) {
|
||||
throw new Error(response.errorMessage);
|
||||
} else if (response.assets) {
|
||||
try {
|
||||
const uri = response.assets[0].uri;
|
||||
if (uri) {
|
||||
const result = await RNQRGenerator.detect({ uri: decodeURI(uri.toString()) });
|
||||
if (result?.values.length > 0) {
|
||||
return result?.values[0];
|
||||
}
|
||||
}
|
||||
throw new Error(loc.send.qr_error_no_qrcode);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
const base64 = response.assets[0].base64;
|
||||
if (base64) {
|
||||
const result = await detectQRCodeInImage(base64);
|
||||
if (result) return result;
|
||||
}
|
||||
throw new Error(loc.send.qr_error_no_qrcode);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -186,33 +180,23 @@ export const showFilePickerAndReadFile = async function (): Promise<{ data: stri
|
||||
}
|
||||
};
|
||||
|
||||
const handleImageFile = async (fileCopyUri: string): Promise<{ data: string | false; uri: string | false }> => {
|
||||
const readFileAsBase64 = async (uri: string): Promise<string> => {
|
||||
try {
|
||||
const exists = await RNFS.exists(fileCopyUri);
|
||||
if (!exists) {
|
||||
presentAlert({ message: 'File does not exist' });
|
||||
return { data: false, uri: false };
|
||||
}
|
||||
// First attempt: use original URI
|
||||
let result = await RNQRGenerator.detect({ uri: decodeURI(fileCopyUri) });
|
||||
if (result?.values && result.values.length > 0) {
|
||||
return { data: result.values[0], uri: fileCopyUri };
|
||||
}
|
||||
// Second attempt: remove file:// prefix and try again
|
||||
const altUri = fileCopyUri.replace(/^file:\/\//, '');
|
||||
result = await RNQRGenerator.detect({ uri: decodeURI(altUri) });
|
||||
if (result?.values && result.values.length > 0) {
|
||||
return { data: result.values[0], uri: fileCopyUri };
|
||||
}
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
return { data: false, uri: false };
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
return { data: false, uri: false };
|
||||
return await RNFS.readFile(uri, 'base64');
|
||||
} catch {
|
||||
return await RNFS.readFile(uri.replace(/^file:\/\//, ''), 'base64');
|
||||
}
|
||||
};
|
||||
|
||||
const handleImageFile = async (fileCopyUri: string): Promise<{ data: string | false; uri: string | false }> => {
|
||||
const base64 = await readFileAsBase64(fileCopyUri);
|
||||
const result = await detectQRCodeInImage(base64);
|
||||
if (result) {
|
||||
return { data: result, uri: fileCopyUri };
|
||||
}
|
||||
throw new Error(loc.send.qr_error_no_qrcode);
|
||||
};
|
||||
|
||||
export const readFileOutsideSandbox = (filePath: string) => {
|
||||
if (Platform.OS === 'ios') {
|
||||
return readFile(filePath);
|
||||
|
||||
@ -6,7 +6,7 @@ import loc from '../loc';
|
||||
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
|
||||
import presentAlert from './Alert';
|
||||
import { useTheme } from './themes';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
import { detectQRCodeInImage } from 'react-native-camera-kit-no-google';
|
||||
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
|
||||
import { useSettings } from '../hooks/context/useSettings';
|
||||
import { scanQrHelper } from '../helpers/scan-qr.ts';
|
||||
@ -79,12 +79,9 @@ export const AddressInputScanButton = ({
|
||||
if (getImage) {
|
||||
try {
|
||||
const base64Data = getImage.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');
|
||||
const values = await RNQRGenerator.detect({
|
||||
base64: base64Data,
|
||||
});
|
||||
|
||||
if (values && values.values.length > 0) {
|
||||
onChangeText(values.values[0]);
|
||||
const result = await detectQRCodeInImage(base64Data);
|
||||
if (result) {
|
||||
onChangeText(result);
|
||||
} else {
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
}
|
||||
|
||||
@ -19,7 +19,8 @@ import { Chain } from '../models/bitcoinUnits';
|
||||
import { navigationRef } from '../NavigationService';
|
||||
import ActionSheet from '../screen/ActionSheet';
|
||||
import { useStorage } from './context/useStorage';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
import { detectQRCodeInImage } from 'react-native-camera-kit-no-google';
|
||||
import RNFS from 'react-native-fs';
|
||||
import presentAlert from '../components/Alert';
|
||||
import useWidgetCommunication from './useWidgetCommunication';
|
||||
import useWatchConnectivity from './useWatchConnectivity';
|
||||
@ -202,35 +203,27 @@ const useCompanionListeners = (skipIfNotInitialized = true) => {
|
||||
}
|
||||
const fileName = decodedUrl.split('/').pop()?.toLowerCase() || '';
|
||||
if (/\.(jpe?g|png)$/i.test(fileName)) {
|
||||
let qrResult;
|
||||
let base64: string;
|
||||
try {
|
||||
qrResult = await RNQRGenerator.detect({ uri: decodedUrl });
|
||||
} catch (e) {
|
||||
console.error('QR detection first attempt failed:', e);
|
||||
base64 = await RNFS.readFile(decodedUrl, 'base64');
|
||||
} catch {
|
||||
base64 = await RNFS.readFile(decodedUrl.replace(/^file:\/\//, ''), 'base64');
|
||||
}
|
||||
if (!qrResult || !qrResult.values || qrResult.values.length === 0) {
|
||||
const altUrl = decodedUrl.replace(/^file:\/\//, '');
|
||||
try {
|
||||
qrResult = await RNQRGenerator.detect({ uri: altUrl });
|
||||
} catch (e) {
|
||||
console.error('QR detection second attempt failed:', e);
|
||||
}
|
||||
}
|
||||
if (qrResult?.values?.length) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
DeeplinkSchemaMatch.navigationRouteFor(
|
||||
{ url: qrResult.values[0] },
|
||||
(value: [string, any]) => navigationRef.navigate(...value),
|
||||
{
|
||||
wallets,
|
||||
addWallet,
|
||||
saveToDisk,
|
||||
setSharedCosigner,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
const qrValue = await detectQRCodeInImage(base64);
|
||||
if (!qrValue) {
|
||||
throw new Error(loc.send.qr_error_no_qrcode);
|
||||
}
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
DeeplinkSchemaMatch.navigationRouteFor(
|
||||
{ url: qrValue },
|
||||
(value: [string, any]) => navigationRef.navigate(...value),
|
||||
{
|
||||
wallets,
|
||||
addWallet,
|
||||
saveToDisk,
|
||||
setSharedCosigner,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
DeeplinkSchemaMatch.navigationRouteFor(event, (value: [string, any]) => navigationRef.navigate(...value), {
|
||||
wallets,
|
||||
|
||||
@ -2156,29 +2156,6 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- ReactNativeDependencies
|
||||
- Yoga
|
||||
- RNQrGenerator (2.0.0):
|
||||
- hermes-engine
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-Core-prebuilt
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-jsi
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-renderercss
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- ReactNativeDependencies
|
||||
- Yoga
|
||||
- ZXingObjC
|
||||
- RNQuickAction (0.3.13):
|
||||
- React
|
||||
- RNReactNativeHapticFeedback (2.3.4):
|
||||
@ -2465,9 +2442,6 @@ PODS:
|
||||
- ReactNativeDependencies
|
||||
- Yoga
|
||||
- Yoga (0.0.0)
|
||||
- ZXingObjC (3.6.9):
|
||||
- ZXingObjC/All (= 3.6.9)
|
||||
- ZXingObjC/All (3.6.9)
|
||||
|
||||
DEPENDENCIES:
|
||||
- "BugsnagReactNative (from `../node_modules/@bugsnag/react-native`)"
|
||||
@ -2576,7 +2550,6 @@ DEPENDENCIES:
|
||||
- RNKeychain (from `../node_modules/react-native-keychain`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNPermissions (from `../node_modules/react-native-permissions`)
|
||||
- RNQrGenerator (from `../node_modules/rn-qr-generator`)
|
||||
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
|
||||
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
@ -2591,7 +2564,6 @@ SPEC REPOS:
|
||||
trunk:
|
||||
- CocoaAsyncSocket
|
||||
- lottie-ios
|
||||
- ZXingObjC
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
BugsnagReactNative:
|
||||
@ -2805,8 +2777,6 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNPermissions:
|
||||
:path: "../node_modules/react-native-permissions"
|
||||
RNQrGenerator:
|
||||
:path: "../node_modules/rn-qr-generator"
|
||||
RNQuickAction:
|
||||
:path: "../node_modules/react-native-quick-actions"
|
||||
RNReactNativeHapticFeedback:
|
||||
@ -2831,7 +2801,7 @@ SPEC CHECKSUMS:
|
||||
BVLinearGradient: cb006ba232a1f3e4f341bb62c42d1098c284da70
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
FBLazyVector: e97c19a5a442429d1988f182a1940fb08df514da
|
||||
hermes-engine: 26a52ac276936854ac2797880e2c181aa1fb0025
|
||||
hermes-engine: 5b6b255f9e4ba0f6f699433393c9ca57c402fc96
|
||||
lottie-ios: 8f959969761e9c45d70353667d00af0e5b9cadb3
|
||||
lottie-react-native: 6a080b2f109ef611c75c503a33ebb8ea75db0c91
|
||||
RCTDeprecation: af44b104091a34482596cd9bd7e8d90c4e9b4bd7
|
||||
@ -2842,7 +2812,7 @@ SPEC CHECKSUMS:
|
||||
React: 1ba7d364ade7d883a1ec055bfc3606f35fdee17b
|
||||
React-callinvoker: bc2a26f8d84fb01f003fc6de6c9337b64715f95b
|
||||
React-Core: 7840d3a80b43a95c5e80ef75146bd70925ebab0f
|
||||
React-Core-prebuilt: 96b4b7f11b336f3b9d498eca3460c82ee260b31e
|
||||
React-Core-prebuilt: fe445abdc8b577160a3ecf632edd6545f00f10cf
|
||||
React-CoreModules: 2eb010400b63b89e53a324ffb3c112e4c7c3ce42
|
||||
React-cxxreact: a558e92199d26f145afa9e62c4233cf8e7950efe
|
||||
React-debug: 755200a6e7f5e6e0a40ff8d215493d43cce285fc
|
||||
@ -2922,7 +2892,7 @@ SPEC CHECKSUMS:
|
||||
ReactCodegen: c8cd59a80d11b8c2f8e70fab3cdc62673ae56f1b
|
||||
ReactCommon: 07572bf9e687c8a52fbe4a3641e9e3a1a477c78e
|
||||
ReactNativeCameraKit: 2f24ad111e0f525a6529dd0eff5bf5d4454a24ba
|
||||
ReactNativeDependencies: d91ea5381a1df88b4bc29bfb8a525ececa743c3d
|
||||
ReactNativeDependencies: 9f044a84d7bddd9822da88447b4a37e7cc085862
|
||||
RealmJS: 1c37c6bdfe060f4caa0f9175aa0eedb962622ee1
|
||||
RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4
|
||||
RNCClipboard: 88d7eeb555d1183915f0885bdbc5c97eb6f7f3ba
|
||||
@ -2934,7 +2904,6 @@ SPEC CHECKSUMS:
|
||||
RNKeychain: 667b7bd224f14055ae4cb52b41a82ad0ad70574f
|
||||
RNLocalize: 1e6eb4290e89502c3d2193d82dfb7de14a9e672b
|
||||
RNPermissions: 71ff057a9f7607de93c7b4e27db8a76cf03d2367
|
||||
RNQrGenerator: dd31405ad364fc0950cda4e4e9c08293d26c7058
|
||||
RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d
|
||||
RNReactNativeHapticFeedback: d6666654afe70a15d04ecb6257809a4081fab84c
|
||||
RNReanimated: 66fa99647173f254f731e6aa59a0a2cc8c838ac1
|
||||
@ -2944,7 +2913,6 @@ SPEC CHECKSUMS:
|
||||
RNWatch: 28fe1f5e0c6410d45fd20925f4796fce05522e3f
|
||||
RNWorklets: 30f9a363d681c776a5f9d74f6d21a6d1bb7bfe80
|
||||
Yoga: c0b3f2c7e8d3e327e450223a2414ca3fa296b9a2
|
||||
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
|
||||
|
||||
PODFILE CHECKSUM: 7e23f7f009125b117989e69fd28c8a04aa4eacc8
|
||||
|
||||
|
||||
19
package-lock.json
generated
19
package-lock.json
generated
@ -73,7 +73,7 @@
|
||||
"react-native": "0.84.1",
|
||||
"react-native-biometrics": "3.0.1",
|
||||
"react-native-blue-crypto": "github:BlueWallet/react-native-blue-crypto#3cb5442",
|
||||
"react-native-camera-kit-no-google": "github:BlueWallet/react-native-camera-kit-no-google#e6dd85b4ea2a7b17da65ab8bfc762960d177b882",
|
||||
"react-native-camera-kit-no-google": "github:BlueWallet/react-native-camera-kit-no-google#0ed049a62da29cf304019363ec9d9ef3a73652e6",
|
||||
"react-native-capture-protection": "github:BlueWallet/react-native-capture-protection#bb78a40",
|
||||
"react-native-context-menu-view": "github:BlueWallet/react-native-context-menu-view#144110b02afdb11b431741aef5da95e91b942a9b",
|
||||
"react-native-default-preference": "github:BlueWallet/react-native-default-preference#6338a1f1235e4130b8cfc2dd3b53015eeff2870c",
|
||||
@ -107,7 +107,6 @@
|
||||
"react-test-renderer": "19.2.3",
|
||||
"readable-stream": "3.6.2",
|
||||
"realm": "20.2.0",
|
||||
"rn-qr-generator": "github:BlueWallet/rn-qr-generator#d53be844c985759197da91b325f7a89d5ef02f90",
|
||||
"silent-payments": "github:BlueWallet/SilentPayments#59a037",
|
||||
"slip39": "github:BlueWallet/slip39-js#d316ee6",
|
||||
"stream-browserify": "3.0.0",
|
||||
@ -15886,9 +15885,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-camera-kit-no-google": {
|
||||
"version": "17.0.3",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-camera-kit-no-google.git#e6dd85b4ea2a7b17da65ab8bfc762960d177b882",
|
||||
"integrity": "sha512-T+DtI1hLUZ1LQ+cVCD3LQR0J6t1bJGXo2gKF+JFt14R6nXjcbd+SZDjGjQGuRfP2TchRny/cf1GNQpgIc9QcaQ==",
|
||||
"version": "17.0.4",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-camera-kit-no-google.git#0ed049a62da29cf304019363ec9d9ef3a73652e6",
|
||||
"integrity": "sha512-w/8o4w5QGxTqrlUVjm/HunWCUi2BIh10xnUX/WB76YOhK1duJCF97lrGGQMGgkokFvjGQrjUTBDkYu6s4r0kSw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@ -16804,16 +16803,6 @@
|
||||
"inherits": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/rn-qr-generator": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/rn-qr-generator.git#d53be844c985759197da91b325f7a89d5ef02f90",
|
||||
"integrity": "sha512-yLDNmNsvZxblXyd5kOBF81cXf7bGNANhGYyRdzvycFV4l8UNAE3fObQFfvaj3mSym9gBGh6uxRFB9h7Xji31rg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": ">=0.71.0"
|
||||
}
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"funding": [
|
||||
|
||||
@ -155,7 +155,7 @@
|
||||
"react-native": "0.84.1",
|
||||
"react-native-biometrics": "3.0.1",
|
||||
"react-native-blue-crypto": "github:BlueWallet/react-native-blue-crypto#3cb5442",
|
||||
"react-native-camera-kit-no-google": "github:BlueWallet/react-native-camera-kit-no-google#e6dd85b4ea2a7b17da65ab8bfc762960d177b882",
|
||||
"react-native-camera-kit-no-google": "github:BlueWallet/react-native-camera-kit-no-google#0ed049a62da29cf304019363ec9d9ef3a73652e6",
|
||||
"react-native-capture-protection": "github:BlueWallet/react-native-capture-protection#bb78a40",
|
||||
"react-native-context-menu-view": "github:BlueWallet/react-native-context-menu-view#144110b02afdb11b431741aef5da95e91b942a9b",
|
||||
"react-native-default-preference": "github:BlueWallet/react-native-default-preference#6338a1f1235e4130b8cfc2dd3b53015eeff2870c",
|
||||
@ -189,7 +189,6 @@
|
||||
"react-test-renderer": "19.2.3",
|
||||
"readable-stream": "3.6.2",
|
||||
"realm": "20.2.0",
|
||||
"rn-qr-generator": "github:BlueWallet/rn-qr-generator#d53be844c985759197da91b325f7a89d5ef02f90",
|
||||
"silent-payments": "github:BlueWallet/SilentPayments#59a037",
|
||||
"slip39": "github:BlueWallet/slip39-js#d316ee6",
|
||||
"stream-browserify": "3.0.0",
|
||||
|
||||
@ -230,12 +230,12 @@ jest.mock('realm', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('rn-qr-generator', () => ({
|
||||
detect: jest.fn(uri => {
|
||||
if (uri === 'invalid-image') {
|
||||
return Promise.reject(new Error('Failed to decode QR code'));
|
||||
jest.mock('react-native-camera-kit-no-google', () => ({
|
||||
detectQRCodeInImage: jest.fn(base64 => {
|
||||
if (base64 === 'invalid-image') {
|
||||
return Promise.reject(new Error('Invalid image data'));
|
||||
}
|
||||
return Promise.resolve({ values: ['mocked-qr-code'] });
|
||||
return Promise.resolve('mocked-qr-code');
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user