@dynamic-labs/sdk-react-core 3.0.0-alpha.58 → 3.0.0-alpha.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +11 -12
- package/src/index.cjs +2 -1
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/lib/context/DynamicContext/hooks/useSelectedWalletConnector/useSelectedWalletConnector.d.ts +1 -1
- package/src/lib/context/UserWalletsContext/UserWalletsContext.d.ts +1 -1
- package/src/lib/context/ViewContext/types/index.d.ts +1 -1
- package/src/lib/locale/en/translation.cjs +42 -0
- package/src/lib/locale/en/translation.d.ts +42 -0
- package/src/lib/locale/en/translation.js +42 -0
- package/src/lib/styles/index.shadow.cjs +1 -1
- package/src/lib/styles/index.shadow.js +1 -1
- package/src/lib/utils/hooks/useAuthLayoutChecks/useAuthLayoutChecks.cjs +1 -0
- package/src/lib/utils/hooks/useAuthLayoutChecks/useAuthLayoutChecks.js +1 -0
- package/src/lib/utils/hooks/useConnectedAccountWallet/useConnectedAccountWallet.d.ts +1 -1
- package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.d.ts +2 -2
- package/src/lib/views/GlobalWalletInfoView/GlobalWalletInfoView.cjs +34 -0
- package/src/lib/views/GlobalWalletInfoView/GlobalWalletInfoView.d.ts +3 -0
- package/src/lib/views/GlobalWalletInfoView/GlobalWalletInfoView.js +29 -0
- package/src/lib/views/viewToComponentMap.cjs +2 -0
- package/src/lib/views/viewToComponentMap.d.ts +1 -0
- package/src/lib/views/viewToComponentMap.js +2 -0
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/GlobalWalletTypes.d.ts +31 -0
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/GlobalWalletView.cjs +84 -95
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/GlobalWalletView.js +86 -97
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/scanner/GlobalWalletScanner.cjs +54 -0
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/scanner/GlobalWalletScanner.d.ts +7 -0
- package/src/lib/widgets/DynamicWidget/views/GlobalWalletView/scanner/GlobalWalletScanner.js +49 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../../../_virtual/_tslib.js';
|
|
3
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import { isMobile } from '@dynamic-labs/utils';
|
|
6
7
|
import '@dynamic-labs/sdk-api-core';
|
|
7
8
|
import '../../../../shared/logger.js';
|
|
8
9
|
import '@dynamic-labs/iconic';
|
|
@@ -11,13 +12,13 @@ import { useViewContext } from '../../../../context/ViewContext/ViewContext.js';
|
|
|
11
12
|
import { ReactComponent as SvgArrowLeft } from '../../../../shared/assets/arrow-left.js';
|
|
12
13
|
import { ReactComponent as SvgCopy } from '../../../../shared/assets/copy.js';
|
|
13
14
|
import { ReactComponent as SvgBlueWalletconnect } from '../../../../shared/assets/blue-walletconnect.js';
|
|
15
|
+
import { ReactComponent as SvgQuestionMark } from '../../../../shared/assets/question-mark.js';
|
|
14
16
|
import '@dynamic-labs/wallet-book';
|
|
15
17
|
import '../../../../utils/constants/colors.js';
|
|
16
18
|
import '../../../../utils/constants/values.js';
|
|
17
19
|
import '../../../../shared/utils/classes/storage/localStorage.js';
|
|
18
20
|
import '../../../../shared/utils/classes/storage/sessionStorage.js';
|
|
19
21
|
import '../../../../store/state/loadingAndLifecycle.js';
|
|
20
|
-
import '@dynamic-labs/utils';
|
|
21
22
|
import '../../../../shared/consts/index.js';
|
|
22
23
|
import { IconButton } from '../../../../components/IconButton/IconButton.js';
|
|
23
24
|
import { useWidgetContext } from '../../context/DynamicWidgetContext.js';
|
|
@@ -64,6 +65,7 @@ import '../../../../context/SocialRedirectContext/SocialRedirectContext.js';
|
|
|
64
65
|
import '../../../../context/WalletGroupContext/WalletGroupContext.js';
|
|
65
66
|
import '../../components/DynamicWidgetHeader/DynamicWidgetHeader.js';
|
|
66
67
|
import 'react-focus-lock';
|
|
68
|
+
import { Divider } from '../../../../components/Divider/Divider.js';
|
|
67
69
|
import '../../../../components/MenuList/Dropdown/Dropdown.js';
|
|
68
70
|
import 'formik';
|
|
69
71
|
import '../../../../store/state/sendBalances/sendBalances.js';
|
|
@@ -71,6 +73,7 @@ import '../../../../views/TransactionConfirmationView/helpers/transactionErrorMe
|
|
|
71
73
|
import { Input } from '../../../../components/Input/Input.js';
|
|
72
74
|
import '../../../../context/PasskeyContext/PasskeyContext.js';
|
|
73
75
|
import '../ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.js';
|
|
76
|
+
import { GlobalWalletScanner } from './scanner/GlobalWalletScanner.js';
|
|
74
77
|
import '../../../../../polyfills.js';
|
|
75
78
|
import '../../../../context/DynamicContext/DynamicContext.js';
|
|
76
79
|
import '../../../../context/ErrorBoundary/ErrorBoundaryBase.js';
|
|
@@ -97,6 +100,7 @@ import '../../../../components/InlineWidget/InlineWidget.js';
|
|
|
97
100
|
import 'qrcode';
|
|
98
101
|
|
|
99
102
|
const GlobalWalletView = () => {
|
|
103
|
+
var _a;
|
|
100
104
|
const { t } = useTranslation();
|
|
101
105
|
const { setDynamicWidgetView, goToInitialDynamicWidgetView } = useWidgetContext();
|
|
102
106
|
const { setView } = useViewContext();
|
|
@@ -104,47 +108,60 @@ const GlobalWalletView = () => {
|
|
|
104
108
|
const { primaryWallet } = useDynamicContext();
|
|
105
109
|
const [walletConnectUri, setWalletConnectUri] = useState('');
|
|
106
110
|
const [bannerMessage, setBannerMessage] = useState(null);
|
|
107
|
-
const [
|
|
108
|
-
const
|
|
109
|
-
|
|
111
|
+
const [isScanned, setIsScanned] = useState(false);
|
|
112
|
+
const { globalWallet } =
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
+
(_a = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector) !== null && _a !== void 0 ? _a : {};
|
|
110
115
|
if (!globalWallet)
|
|
111
116
|
throw new Error('Global Wallet not found');
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}, [bannerMessage]);
|
|
125
|
-
const onClickBack = () => {
|
|
126
|
-
goToInitialDynamicWidgetView();
|
|
127
|
-
};
|
|
128
|
-
const onConnectClick = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
+
const showBanner = useCallback((message, type) => {
|
|
118
|
+
setBannerMessage({ message, type });
|
|
119
|
+
const timeout = type === 'success' ? 2000 : 3000;
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
setBannerMessage(null);
|
|
122
|
+
if (type === 'success')
|
|
123
|
+
goToInitialDynamicWidgetView();
|
|
124
|
+
}, timeout);
|
|
125
|
+
}, [goToInitialDynamicWidgetView]);
|
|
126
|
+
const handlePairing = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
127
|
if (!walletConnectUri.startsWith('wc:')) {
|
|
130
|
-
|
|
131
|
-
message: t('global_wallet.banner.bad_input'),
|
|
132
|
-
type: 'error',
|
|
133
|
-
});
|
|
128
|
+
showBanner(t('global_wallet.banner.bad_input'), 'error');
|
|
134
129
|
return;
|
|
135
130
|
}
|
|
136
131
|
try {
|
|
137
132
|
yield globalWallet.pairWithWC(walletConnectUri);
|
|
138
|
-
// wait 0.5 second to receive the pairing request event
|
|
139
133
|
yield new Promise((resolve) => setTimeout(resolve, 500));
|
|
140
134
|
const pendingPairing = globalWallet.getPendingPairing();
|
|
141
135
|
if (!pendingPairing)
|
|
142
136
|
throw new Error('No pending pairing');
|
|
143
|
-
const { name, url, icons } = pendingPairing.params
|
|
144
|
-
.proposer.metadata;
|
|
137
|
+
const { name, url, icons } = pendingPairing.params.proposer.metadata;
|
|
145
138
|
setView('global-wallet-confirm', {
|
|
146
|
-
onCancel:
|
|
147
|
-
|
|
139
|
+
onCancel: () => {
|
|
140
|
+
setDynamicWidgetView('global-wallet');
|
|
141
|
+
setShowAuthFlow(false, {
|
|
142
|
+
ignoreIfIsEmbeddedWidget: false,
|
|
143
|
+
performMultiWalletChecks: false,
|
|
144
|
+
});
|
|
145
|
+
setWalletConnectUri('');
|
|
146
|
+
},
|
|
147
|
+
onConfirm: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
try {
|
|
149
|
+
yield globalWallet.confirmPairing(true);
|
|
150
|
+
setDynamicWidgetView('global-wallet');
|
|
151
|
+
setShowAuthFlow(false, {
|
|
152
|
+
ignoreIfIsEmbeddedWidget: false,
|
|
153
|
+
performMultiWalletChecks: false,
|
|
154
|
+
});
|
|
155
|
+
showBanner(t('global_wallet.banner.success', {
|
|
156
|
+
name: name !== null && name !== void 0 ? name : t('global_wallet.the_dapp'),
|
|
157
|
+
}), 'success');
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
showBanner(t('global_wallet.banner.warning', {
|
|
161
|
+
name: name !== null && name !== void 0 ? name : t('global_wallet.the_dapp'),
|
|
162
|
+
}), 'error');
|
|
163
|
+
}
|
|
164
|
+
}),
|
|
148
165
|
pairingInfo: { icons, name, url },
|
|
149
166
|
});
|
|
150
167
|
setShowAuthFlow(true, {
|
|
@@ -153,78 +170,50 @@ const GlobalWalletView = () => {
|
|
|
153
170
|
});
|
|
154
171
|
}
|
|
155
172
|
catch (error) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
name: 'this app',
|
|
160
|
-
}),
|
|
161
|
-
type: 'error',
|
|
162
|
-
});
|
|
173
|
+
const errorMessage = String(error);
|
|
174
|
+
if (errorMessage.includes('expired')) {
|
|
175
|
+
showBanner(t('global_wallet.banner.expired'), 'error');
|
|
163
176
|
}
|
|
164
|
-
else if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}),
|
|
169
|
-
type: 'success',
|
|
170
|
-
});
|
|
177
|
+
else if (errorMessage.includes('exists')) {
|
|
178
|
+
showBanner(t('global_wallet.banner.already_connected', {
|
|
179
|
+
name: t('global_wallet.this_app'),
|
|
180
|
+
}), 'success');
|
|
171
181
|
}
|
|
172
182
|
else {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
});
|
|
183
|
+
showBanner(t('global_wallet.banner.warning', {
|
|
184
|
+
name: t('global_wallet.the_dapp'),
|
|
185
|
+
}), 'error');
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
yield globalWallet.confirmPairing(true);
|
|
186
|
-
setDynamicWidgetView('global-wallet');
|
|
187
|
-
setShowAuthFlow(false, {
|
|
188
|
-
ignoreIfIsEmbeddedWidget: false,
|
|
189
|
-
performMultiWalletChecks: false,
|
|
190
|
-
});
|
|
191
|
-
setBannerMessage({
|
|
192
|
-
message: t('global_wallet.banner.success', {
|
|
193
|
-
name: name !== null && name !== void 0 ? name : 'the dApp',
|
|
194
|
-
}),
|
|
195
|
-
type: 'success',
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
setBannerMessage({
|
|
200
|
-
message: t('global_wallet.banner.warning', {
|
|
201
|
-
name: name !== null && name !== void 0 ? name : 'the dApp',
|
|
202
|
-
}),
|
|
203
|
-
type: 'error',
|
|
204
|
-
});
|
|
188
|
+
}), // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
189
|
+
[walletConnectUri]);
|
|
190
|
+
const handleScan = useCallback((result) => {
|
|
191
|
+
if (result) {
|
|
192
|
+
setIsScanned(true);
|
|
193
|
+
setWalletConnectUri(result);
|
|
205
194
|
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
ignoreIfIsEmbeddedWidget: false,
|
|
211
|
-
performMultiWalletChecks: false,
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
const handleSubmit = (e) => {
|
|
215
|
-
e.preventDefault();
|
|
216
|
-
onConnectClick();
|
|
217
|
-
};
|
|
218
|
-
const handleKeyDown = (e) => {
|
|
219
|
-
if (e.key === 'Enter') {
|
|
220
|
-
handleSubmit(e);
|
|
195
|
+
}, []);
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
if (walletConnectUri.startsWith('wc:')) {
|
|
198
|
+
handlePairing();
|
|
221
199
|
}
|
|
222
|
-
};
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
200
|
+
}, [walletConnectUri, handlePairing]);
|
|
201
|
+
const renderHeader = () => (jsxs("div", { className: 'header', children: [jsx(IconButton, { type: 'button', onClick: goToInitialDynamicWidgetView, "data-testid": 'back-button', children: jsx(SvgArrowLeft, {}) }), jsx(Typography, { variant: 'title', weight: 'medium', color: 'primary', as: 'h1', copykey: 'global_wallet.connect_to_apps', children: t('global_wallet.connect_to_apps') }), isMobile() && (jsx(IconButton, { type: 'button', onClick: () => {
|
|
202
|
+
setView('global-wallet-info');
|
|
203
|
+
setShowAuthFlow(true, {
|
|
204
|
+
ignoreIfIsEmbeddedWidget: false,
|
|
205
|
+
performMultiWalletChecks: false,
|
|
206
|
+
});
|
|
207
|
+
}, "data-testid": 'info-button', children: jsx(SvgQuestionMark, {}) }))] }));
|
|
208
|
+
const renderScanner = () => isMobile() && (jsxs(Fragment, { children: [jsxs("div", { className: 'scanner-wrapper', children: [jsx(GlobalWalletScanner, { onScan: handleScan, jsQR: globalWallet.qrScanner }), jsxs("div", { className: 'scanner-overlay', children: [jsxs("div", { className: 'scanner-frame', children: [jsx("div", { className: 'corner top-left' }), jsx("div", { className: 'corner top-right' }), jsx("div", { className: 'corner bottom-left' }), jsx("div", { className: 'corner bottom-right' })] }), jsxs("div", { className: 'scanner-overlay-content', children: [jsx(SvgBlueWalletconnect, { className: 'scanner-icon' }), jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'white', copykey: 'global_wallet.scan_qr_code', children: t('global_wallet.scan_qr_code') })] })] })] }), jsx(Divider, { text: t('global_wallet.or') })] }));
|
|
209
|
+
const renderInput = () => (jsxs("div", { className: 'wallet-connect-card', children: [jsx("div", { className: 'input-group', children: jsx(Input, { copykey: 'global_wallet.walletconnect_uri', id: 'walletconnect-uri', label: t('global_wallet.walletconnect_uri'), placeholder: 'wc:...', value: isScanned ? '' : walletConnectUri, onChange: (e) => {
|
|
210
|
+
setWalletConnectUri(e.target.value);
|
|
211
|
+
setIsScanned(false);
|
|
212
|
+
}, variant: 'dense', onKeyDown: (e) => e.key === 'Enter' && handlePairing(), suffix:
|
|
213
|
+
// eslint-disable-next-line react/jsx-wrap-multilines
|
|
214
|
+
jsx("div", { className: 'input-suffix', onClick: handlePairing, role: 'button', tabIndex: 0, children: jsx(InlineSubmitButton, { disabled: false, highlighted: Boolean(walletConnectUri) && !isScanned, isFocused: false, isHovered: false, emailSubmitButtonInsideInput: true }) }) }) }), bannerMessage && (jsx("div", { className: `banner ${bannerMessage.type}`, children: jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'primary', children: bannerMessage.message }) }))] }));
|
|
215
|
+
const renderInfoCard = () => !isMobile() && (jsx("div", { className: 'info-card', children: jsxs("div", { className: 'wrapper', children: [jsx(Typography, { variant: 'body_small', weight: 'bold', color: 'primary', as: 'h2', children: t('global_wallet.help.title') }), jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'secondary', children: t('global_wallet.help.step.1') }), jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'secondary', children: t('global_wallet.help.step.2') }), jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'secondary', children: jsxs("span", { className: 'inline-logo-text', children: ["3. Open WalletConnect", jsx(SvgBlueWalletconnect, { className: 'inline-logo' }), " from the list"] }) }), jsx(Typography, { variant: 'body_small', weight: 'regular', color: 'secondary', children: jsxs("span", { className: 'inline-logo-text', children: ["4. Locate and click ", jsx(SvgCopy, { className: 'inline-logo' }), " to copy the URI code"] }) })] }) }));
|
|
216
|
+
return (jsxs("div", { className: 'connect-dapps-view', children: [renderHeader(), renderScanner(), renderInput(), renderInfoCard()] }));
|
|
228
217
|
};
|
|
229
218
|
|
|
230
219
|
export { GlobalWalletView, GlobalWalletView as default };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
|
|
9
|
+
const GlobalWalletScanner = ({ onScan, jsQR, }) => {
|
|
10
|
+
const videoRef = React.useRef(null);
|
|
11
|
+
const canvasRef = React.useRef(null);
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
const video = videoRef.current;
|
|
14
|
+
const canvas = canvasRef.current;
|
|
15
|
+
if (!video || !canvas)
|
|
16
|
+
return;
|
|
17
|
+
const ctx = canvas.getContext('2d');
|
|
18
|
+
if (!ctx)
|
|
19
|
+
return;
|
|
20
|
+
const constraints = {
|
|
21
|
+
video: { facingMode: 'environment' },
|
|
22
|
+
};
|
|
23
|
+
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
|
|
24
|
+
video.srcObject = stream;
|
|
25
|
+
video.setAttribute('playsinline', 'true'); // required to tell iOS safari we don't want fullscreen
|
|
26
|
+
video.play();
|
|
27
|
+
requestAnimationFrame(tick);
|
|
28
|
+
});
|
|
29
|
+
const tick = () => {
|
|
30
|
+
if (video.readyState === video.HAVE_ENOUGH_DATA) {
|
|
31
|
+
canvas.height = video.videoHeight;
|
|
32
|
+
canvas.width = video.videoWidth;
|
|
33
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
34
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
35
|
+
const code = jsQR(imageData.data, imageData.width, imageData.height, {
|
|
36
|
+
inversionAttempts: 'dontInvert',
|
|
37
|
+
});
|
|
38
|
+
if (code) {
|
|
39
|
+
onScan(code.data);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
requestAnimationFrame(tick);
|
|
43
|
+
};
|
|
44
|
+
return () => {
|
|
45
|
+
const stream = video.srcObject;
|
|
46
|
+
const tracks = stream === null || stream === void 0 ? void 0 : stream.getTracks();
|
|
47
|
+
tracks === null || tracks === void 0 ? void 0 : tracks.forEach((track) => track.stop());
|
|
48
|
+
};
|
|
49
|
+
}, [onScan]);
|
|
50
|
+
return (jsxRuntime.jsx("div", { children: jsxRuntime.jsxs("div", { className: 'videoWrapper', children: [jsxRuntime.jsx("video", { ref: videoRef, className: 'qrVideo' }), jsxRuntime.jsx("canvas", { ref: canvasRef, style: { display: 'none' } })] }) }));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
exports.GlobalWalletScanner = GlobalWalletScanner;
|
|
54
|
+
exports["default"] = GlobalWalletScanner;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface GlobalWalletScannerProps {
|
|
3
|
+
jsQR: (data: Uint8ClampedArray, width: number, height: number, providedOptions?: any) => any;
|
|
4
|
+
onScan: (result: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const GlobalWalletScanner: React.FC<GlobalWalletScannerProps>;
|
|
7
|
+
export default GlobalWalletScanner;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
const GlobalWalletScanner = ({ onScan, jsQR, }) => {
|
|
6
|
+
const videoRef = useRef(null);
|
|
7
|
+
const canvasRef = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const video = videoRef.current;
|
|
10
|
+
const canvas = canvasRef.current;
|
|
11
|
+
if (!video || !canvas)
|
|
12
|
+
return;
|
|
13
|
+
const ctx = canvas.getContext('2d');
|
|
14
|
+
if (!ctx)
|
|
15
|
+
return;
|
|
16
|
+
const constraints = {
|
|
17
|
+
video: { facingMode: 'environment' },
|
|
18
|
+
};
|
|
19
|
+
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
|
|
20
|
+
video.srcObject = stream;
|
|
21
|
+
video.setAttribute('playsinline', 'true'); // required to tell iOS safari we don't want fullscreen
|
|
22
|
+
video.play();
|
|
23
|
+
requestAnimationFrame(tick);
|
|
24
|
+
});
|
|
25
|
+
const tick = () => {
|
|
26
|
+
if (video.readyState === video.HAVE_ENOUGH_DATA) {
|
|
27
|
+
canvas.height = video.videoHeight;
|
|
28
|
+
canvas.width = video.videoWidth;
|
|
29
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
30
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
31
|
+
const code = jsQR(imageData.data, imageData.width, imageData.height, {
|
|
32
|
+
inversionAttempts: 'dontInvert',
|
|
33
|
+
});
|
|
34
|
+
if (code) {
|
|
35
|
+
onScan(code.data);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
requestAnimationFrame(tick);
|
|
39
|
+
};
|
|
40
|
+
return () => {
|
|
41
|
+
const stream = video.srcObject;
|
|
42
|
+
const tracks = stream === null || stream === void 0 ? void 0 : stream.getTracks();
|
|
43
|
+
tracks === null || tracks === void 0 ? void 0 : tracks.forEach((track) => track.stop());
|
|
44
|
+
};
|
|
45
|
+
}, [onScan]);
|
|
46
|
+
return (jsx("div", { children: jsxs("div", { className: 'videoWrapper', children: [jsx("video", { ref: videoRef, className: 'qrVideo' }), jsx("canvas", { ref: canvasRef, style: { display: 'none' } })] }) }));
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { GlobalWalletScanner, GlobalWalletScanner as default };
|