mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-21 22:42:21 +01:00
REF: Use a better QR image decoder
This commit is contained in:
parent
cebdea6d25
commit
e0f906f594
10 changed files with 187 additions and 56 deletions
|
@ -1,4 +1,3 @@
|
|||
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
|
||||
import { Alert, Linking, Platform } from 'react-native';
|
||||
import DocumentPicker from 'react-native-document-picker';
|
||||
import RNFS from 'react-native-fs';
|
||||
|
@ -9,6 +8,7 @@ import presentAlert from '../components/Alert';
|
|||
import loc from '../loc';
|
||||
import { isDesktop } from './environment';
|
||||
import { readFile } from './react-native-bw-file-access';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
|
||||
const _sanitizeFileName = (fileName: string) => {
|
||||
// Remove any path delimiters and non-alphanumeric characters except for -, _, and .
|
||||
|
@ -128,14 +128,18 @@ export const showImagePickerAndReadImage = (): Promise<string | undefined> => {
|
|||
if (!response.didCancel) {
|
||||
const asset = response.assets?.[0] ?? {};
|
||||
if (asset.uri) {
|
||||
const uri = asset.uri.toString().replace('file://', '');
|
||||
LocalQRCode.decode(uri, (error: any, result: string) => {
|
||||
if (!error) {
|
||||
resolve(result);
|
||||
} else {
|
||||
RNQRGenerator.detect({
|
||||
uri: decodeURI(asset.uri.toString()),
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
resolve(result.values[0]);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
reject(new Error(loc.send.qr_error_no_qrcode));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -183,13 +187,19 @@ export const showFilePickerAndReadFile = async function (): Promise<{ data: stri
|
|||
return;
|
||||
}
|
||||
const uri2 = res.fileCopyUri.replace('file://', '');
|
||||
LocalQRCode.decode(decodeURI(uri2), (error: any, result: string) => {
|
||||
if (!error) {
|
||||
resolve({ data: result, uri: fileCopyUri });
|
||||
} else {
|
||||
|
||||
RNQRGenerator.detect({
|
||||
uri: decodeURI(uri2),
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
resolve({ data: result.values[0], uri: fileCopyUri });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
resolve({ data: false, uri: false });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@ import { scanQrHelper } from '../helpers/scan-qr';
|
|||
import loc from '../loc';
|
||||
import presentAlert from './Alert';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
import { useTheme } from './themes';
|
||||
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
|
||||
|
||||
interface AddressInputProps {
|
||||
isLoading?: boolean;
|
||||
|
@ -73,7 +78,7 @@ const AddressInput = ({
|
|||
}, [launchedBy, onBarScanned, scanButtonTapped]);
|
||||
|
||||
const onMenuItemPressed = useCallback(
|
||||
(action: string) => {
|
||||
async (action: string) => {
|
||||
if (onBarScanned === undefined) throw new Error('onBarScanned is required');
|
||||
switch (action) {
|
||||
case actionKeys.ScanQR:
|
||||
|
@ -87,12 +92,42 @@ const AddressInput = ({
|
|||
}
|
||||
|
||||
break;
|
||||
case actionKeys.CopyFromClipboard:
|
||||
Clipboard.getString()
|
||||
.then(onChangeText)
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
case CommonToolTipActions.CopyFromClipboard.id:
|
||||
try {
|
||||
let getImage: string | null = null;
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
getImage = await Clipboard.getImage();
|
||||
} else {
|
||||
const hasImage = await Clipboard.hasImage();
|
||||
if (hasImage) {
|
||||
getImage = await Clipboard.getImageJPG();
|
||||
}
|
||||
}
|
||||
|
||||
if (getImage) {
|
||||
try {
|
||||
const base64Data = getImage.replace(/^data:image\/jpeg;base64,/, '');
|
||||
|
||||
const values = await RNQRGenerator.detect({
|
||||
base64: base64Data,
|
||||
});
|
||||
|
||||
if (values && values.values.length > 0) {
|
||||
onChangeText(values.values[0]);
|
||||
} else {
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
}
|
||||
} catch (error) {
|
||||
presentAlert({ message: (error as Error).message });
|
||||
}
|
||||
} else {
|
||||
const clipboardText = await Clipboard.getString();
|
||||
onChangeText(clipboardText);
|
||||
}
|
||||
} catch (error) {
|
||||
presentAlert({ message: (error as Error).message });
|
||||
}
|
||||
break;
|
||||
case actionKeys.ChoosePhoto:
|
||||
showImagePickerAndReadImage()
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Chain } from '../models/bitcoinUnits';
|
|||
import { navigationRef } from '../NavigationService';
|
||||
import ActionSheet from '../screen/ActionSheet';
|
||||
import { useStorage } from '../hooks/context/useStorage';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
|
||||
const MenuElements = lazy(() => import('../components/MenuElements'));
|
||||
const DeviceQuickActions = lazy(() => import('../components/DeviceQuickActions'));
|
||||
|
@ -104,15 +105,56 @@ const CompanionDelegates = () => {
|
|||
}, [fetchAndSaveWalletTransactions, refreshAllWalletTransactions, wallets]);
|
||||
|
||||
const handleOpenURL = useCallback(
|
||||
(event: { url: string }) => {
|
||||
DeeplinkSchemaMatch.navigationRouteFor(event, value => navigationRef.navigate(...value), {
|
||||
wallets,
|
||||
addWallet,
|
||||
saveToDisk,
|
||||
setSharedCosigner,
|
||||
});
|
||||
async (event: { url: string }): Promise<void> => {
|
||||
const { url } = event;
|
||||
|
||||
if (url && (url.endsWith('.jpg') || url.endsWith('.png') || url.endsWith('.jpeg'))) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const imageData = await response.blob();
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = async () => {
|
||||
const base64Image = reader.result as string;
|
||||
const base64Data = base64Image.replace(/^data:image\/jpeg;base64,/, ''); //
|
||||
try {
|
||||
const values = await RNQRGenerator.detect({
|
||||
base64: base64Data,
|
||||
});
|
||||
|
||||
if (values && values.values.length > 0) {
|
||||
DeeplinkSchemaMatch.navigationRouteFor(
|
||||
{ url: values.values[0] },
|
||||
(value: [string, any]) => navigationRef.navigate(...value),
|
||||
{
|
||||
wallets,
|
||||
addWallet,
|
||||
saveToDisk,
|
||||
setSharedCosigner,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.log('No QR code detected in the image.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error detecting QR code:', error);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(imageData);
|
||||
} catch (error) {
|
||||
console.error('Error fetching image:', error);
|
||||
}
|
||||
} else {
|
||||
// Handle other deeplinks if it's not an image
|
||||
DeeplinkSchemaMatch.navigationRouteFor(event, value => navigationRef.navigate(...value), {
|
||||
wallets,
|
||||
addWallet,
|
||||
saveToDisk,
|
||||
setSharedCosigner,
|
||||
});
|
||||
}
|
||||
},
|
||||
[addWallet, saveToDisk, setSharedCosigner, wallets],
|
||||
[wallets, addWallet, saveToDisk, setSharedCosigner],
|
||||
);
|
||||
|
||||
const showClipboardAlert = useCallback(
|
||||
|
|
|
@ -31,6 +31,22 @@
|
|||
<string>io.bluewallet.psbt</string>
|
||||
</array>
|
||||
</dict>
|
||||
<!-- Image file types -->
|
||||
<dict>
|
||||
<key>CFBundleTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.jpeg</string>
|
||||
<string>public.image</string>
|
||||
</array>
|
||||
</dict>
|
||||
<!-- TXN file type -->
|
||||
<dict>
|
||||
<key>CFBundleTypeIconFiles</key>
|
||||
|
@ -158,7 +174,7 @@
|
|||
</dict>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.</string>
|
||||
<string>In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.</string>
|
||||
<key>NSFaceIDUsageDescription</key>
|
||||
<string>In order to use FaceID please confirm your permission.</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
|
@ -209,7 +225,7 @@
|
|||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
|
||||
|
||||
<!-- Define exported types (UTIs) for file types -->
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
|
@ -306,6 +322,8 @@
|
|||
<string>application/json</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
|
@ -320,4 +338,4 @@
|
|||
<key>FIREBASE_MESSAGING_AUTO_INIT_ENABLED</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
|
@ -1317,8 +1317,6 @@ PODS:
|
|||
- React-Core
|
||||
- react-native-menu (1.1.3):
|
||||
- React
|
||||
- react-native-qrcode-local-image (1.0.4):
|
||||
- React
|
||||
- react-native-randombytes (3.6.1):
|
||||
- React-Core
|
||||
- react-native-safe-area-context (4.11.1):
|
||||
|
@ -1635,6 +1633,9 @@ PODS:
|
|||
- React-Core
|
||||
- RNPermissions (4.1.5):
|
||||
- React-Core
|
||||
- RNQrGenerator (1.4.2):
|
||||
- React
|
||||
- ZXingObjC
|
||||
- RNQuickAction (0.3.13):
|
||||
- React
|
||||
- RNRate (1.2.12):
|
||||
|
@ -1819,6 +1820,9 @@ PODS:
|
|||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- Yoga (0.0.0)
|
||||
- ZXingObjC (3.6.9):
|
||||
- ZXingObjC/All (= 3.6.9)
|
||||
- ZXingObjC/All (3.6.9)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
|
@ -1868,7 +1872,6 @@ DEPENDENCIES:
|
|||
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
|
||||
- react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`)
|
||||
- "react-native-menu (from `../node_modules/@react-native-menu/menu`)"
|
||||
- "react-native-qrcode-local-image (from `../node_modules/@remobile/react-native-qrcode-local-image`)"
|
||||
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- react-native-screen-capture (from `../node_modules/react-native-screen-capture`)
|
||||
|
@ -1913,6 +1916,7 @@ 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`)
|
||||
- RNRate (from `../node_modules/react-native-rate`)
|
||||
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
|
||||
|
@ -1930,6 +1934,7 @@ SPEC REPOS:
|
|||
- CocoaAsyncSocket
|
||||
- lottie-ios
|
||||
- SocketRocket
|
||||
- ZXingObjC
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
|
@ -2023,8 +2028,6 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native-ios-context-menu"
|
||||
react-native-menu:
|
||||
:path: "../node_modules/@react-native-menu/menu"
|
||||
react-native-qrcode-local-image:
|
||||
:path: "../node_modules/@remobile/react-native-qrcode-local-image"
|
||||
react-native-randombytes:
|
||||
:path: "../node_modules/react-native-randombytes"
|
||||
react-native-safe-area-context:
|
||||
|
@ -2113,6 +2116,8 @@ 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"
|
||||
RNRate:
|
||||
|
@ -2184,7 +2189,6 @@ SPEC CHECKSUMS:
|
|||
react-native-image-picker: 2fbbafdae7a7c6db9d25df2f2b1db4442d2ca2ad
|
||||
react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5
|
||||
react-native-menu: c30eb7a85d7b04d51945f61ea8a8986ed366ac5c
|
||||
react-native-qrcode-local-image: 35ccb306e4265bc5545f813e54cc830b5d75bcfc
|
||||
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
|
||||
react-native-safe-area-context: 5141f11858b033636f1788b14f32eaba92cee810
|
||||
react-native-screen-capture: 75db9b051c41fea47fa68665506e9257d4b1dadc
|
||||
|
@ -2229,6 +2233,7 @@ SPEC CHECKSUMS:
|
|||
RNKeychain: bfe3d12bf4620fe488771c414530bf16e88f3678
|
||||
RNLocalize: 4f22418187ecd5ca693231093ff1d912d1b3c9bc
|
||||
RNPermissions: 9fa74223844f437bc309e112994859dc47194829
|
||||
RNQrGenerator: 5c12ab86443a07e923735800679da7b6fcaaeb31
|
||||
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
|
||||
RNRate: ef3bcff84f39bb1d1e41c5593d3eea4aab2bd73a
|
||||
RNReactNativeHapticFeedback: 0d591ea1e150f36cb96d868d4e8d77272243d78a
|
||||
|
@ -2241,6 +2246,7 @@ SPEC CHECKSUMS:
|
|||
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
|
||||
TrueSheet: 49bf7af5d5a29f018f02879c26a1afe595c85829
|
||||
Yoga: 055f92ad73f8c8600a93f0e25ac0b2344c3b07e6
|
||||
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
|
||||
|
||||
PODFILE CHECKSUM: 95cd28e70ae47c36e1e0b30f60bba0bd6ffa77d8
|
||||
|
||||
|
|
17
package-lock.json
generated
17
package-lock.json
generated
|
@ -26,7 +26,6 @@
|
|||
"@react-navigation/drawer": "6.7.2",
|
||||
"@react-navigation/native": "6.1.18",
|
||||
"@react-navigation/native-stack": "6.11.0",
|
||||
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
|
||||
"@rneui/base": "4.0.0-rc.8",
|
||||
"@rneui/themed": "4.0.0-rc.8",
|
||||
"@spsina/bip47": "github:BlueWallet/bip47#df82345",
|
||||
|
@ -99,6 +98,7 @@
|
|||
"readable-stream": "3.6.2",
|
||||
"realm": "12.13.1",
|
||||
"rn-nodeify": "10.3.0",
|
||||
"rn-qr-generator": "https://github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
|
||||
"scryptsy": "2.1.0",
|
||||
"silent-payments": "github:BlueWallet/SilentPayments#7ac4d17",
|
||||
"slip39": "https://github.com/BlueWallet/slip39-js#d316ee6",
|
||||
|
@ -6233,12 +6233,6 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@remobile/react-native-qrcode-local-image": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-qrcode-local-image.git#31b0113110fbafcf5a5f3ca4183a563550f5c352",
|
||||
"integrity": "sha512-ooA3KFI5wUUx4++U5llEIUs2ADGop7oAOeHsZgisu/4A8Hsw27wJj26d74OonVGYgeZkWXwx6KQDe1dxRa/2WQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rneui/base": {
|
||||
"version": "4.0.0-rc.8",
|
||||
"resolved": "https://registry.npmjs.org/@rneui/base/-/base-4.0.0-rc.8.tgz",
|
||||
|
@ -21654,6 +21648,15 @@
|
|||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/rn-qr-generator": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "git+ssh://git@github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
|
||||
"integrity": "sha512-dTGlzCUuPfaSsBeeVCGDEvzFhw3rWSz+4Fxc98ImJO+Ld/7J7gg4u1LFWhmsfrqsL34Ylm8Lr9cffVzxx3WzwA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.55"
|
||||
}
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
"@react-navigation/drawer": "6.7.2",
|
||||
"@react-navigation/native": "6.1.18",
|
||||
"@react-navigation/native-stack": "6.11.0",
|
||||
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
|
||||
"@rneui/base": "4.0.0-rc.8",
|
||||
"@rneui/themed": "4.0.0-rc.8",
|
||||
"@spsina/bip47": "github:BlueWallet/bip47#df82345",
|
||||
|
@ -163,6 +162,7 @@
|
|||
"readable-stream": "3.6.2",
|
||||
"realm": "12.13.1",
|
||||
"rn-nodeify": "10.3.0",
|
||||
"rn-qr-generator": "https://github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
|
||||
"scryptsy": "2.1.0",
|
||||
"silent-payments": "github:BlueWallet/SilentPayments#7ac4d17",
|
||||
"slip39": "https://github.com/BlueWallet/slip39-js#d316ee6",
|
||||
|
|
|
@ -340,7 +340,11 @@ const Confirm: React.FC = () => {
|
|||
{state.isLoading ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<Button disabled={isElectrumDisabled || state.isButtonDisabled} onPress={handleSendTransaction} title={loc.send.confirm_sendNow} />
|
||||
<Button
|
||||
disabled={isElectrumDisabled || state.isButtonDisabled}
|
||||
onPress={handleSendTransaction}
|
||||
title={loc.send.confirm_sendNow}
|
||||
/>
|
||||
)}
|
||||
</BlueCard>
|
||||
</View>
|
||||
|
@ -444,4 +448,4 @@ const styles = StyleSheet.create({
|
|||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { useFocusEffect, useIsFocused, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
import createHash from 'create-hash';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
@ -19,6 +18,7 @@ import { useTheme } from '../../components/themes';
|
|||
import { isCameraAuthorizationStatusGranted } from '../../helpers/scan-qr';
|
||||
import loc from '../../loc';
|
||||
import { useSettings } from '../../hooks/context/useSettings';
|
||||
import RNQRGenerator from 'rn-qr-generator';
|
||||
|
||||
let decoder = false;
|
||||
|
||||
|
@ -312,15 +312,21 @@ const ScanQRCode = () => {
|
|||
} else {
|
||||
const asset = response.assets[0];
|
||||
if (asset.uri) {
|
||||
const uri = asset.uri.toString().replace('file://', '');
|
||||
LocalQRCode.decode(uri, (error, result) => {
|
||||
if (!error) {
|
||||
onBarCodeRead({ data: result });
|
||||
} else {
|
||||
RNQRGenerator.detect({
|
||||
uri: decodeURI(asset.uri.toString()),
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
onBarCodeRead({ data: result.values[0] });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
presentAlert({ message: loc.send.qr_error_no_qrcode });
|
||||
})
|
||||
.finally(() => {
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ const keys = {
|
|||
RemoveAllRecipients: 'RemoveAllRecipients',
|
||||
AddRecipient: 'AddRecipient',
|
||||
RemoveRecipient: 'RemoveRecipient',
|
||||
CopyFromClipboard: 'copyFromClipboard',
|
||||
};
|
||||
|
||||
const icons = {
|
||||
|
@ -73,6 +74,7 @@ const icons = {
|
|||
RemoveAllRecipients: { iconValue: 'person.2.slash' },
|
||||
AddRecipient: { iconValue: 'person.badge.plus' },
|
||||
RemoveRecipient: { iconValue: 'person.badge.minus' },
|
||||
CopyFromClipboard: { iconValue: 'doc.on.clipboard' },
|
||||
};
|
||||
|
||||
export const CommonToolTipActions = {
|
||||
|
@ -185,4 +187,9 @@ export const CommonToolTipActions = {
|
|||
icon: icons.PaymentsCode,
|
||||
menuState: false,
|
||||
},
|
||||
CopyFromClipboard: {
|
||||
id: keys.CopyFromClipboard,
|
||||
text: loc.transactions.details_copy_amount,
|
||||
icon: icons.CopyFromClipboard,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue