@unif/react-native-hms-scan 0.6.2 → 2.0.0
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/README.md +3 -2
- package/android/src/main/AndroidManifest.xml +0 -9
- package/android/src/main/java/com/unif/reactnativehmsscan/HmsScanImage.kt +135 -0
- package/android/src/main/java/com/unif/reactnativehmsscan/HmsScanModule.kt +163 -147
- package/android/src/main/java/com/unif/reactnativehmsscan/HmsScanResultMapper.kt +17 -9
- package/android/src/main/java/com/unif/reactnativehmsscan/HmsScanView.kt +57 -19
- package/android/src/main/java/com/unif/reactnativehmsscan/HmsScanViewManager.kt +1 -1
- package/ios/HmsScanModule.mm +13 -37
- package/ios/HmsScanResultMapper.h +4 -3
- package/ios/HmsScanResultMapper.mm +31 -19
- package/ios/HmsScanView.h +1 -1
- package/ios/HmsScanView.mm +140 -25
- package/lib/module/HmsScanView/HmsScanView.js +66 -0
- package/lib/module/HmsScanView/HmsScanView.js.map +1 -0
- package/lib/module/HmsScanView/HmsScanView.web.js +26 -0
- package/lib/module/HmsScanView/HmsScanView.web.js.map +1 -0
- package/lib/module/HmsScanView/types.js +4 -0
- package/lib/module/HmsScanView/types.js.map +1 -0
- package/lib/module/HmsScanViewNativeComponent.ts +7 -5
- package/lib/module/NativeHmsScan.js +1 -1
- package/lib/module/NativeHmsScan.js.map +1 -1
- package/lib/module/ScanError.js +12 -0
- package/lib/module/ScanError.js.map +1 -0
- package/lib/module/Scanner/DeniedOverlay.js +1 -1
- package/lib/module/Scanner/DeniedOverlay.js.map +1 -1
- package/lib/module/Scanner/ResultFail.js +3 -2
- package/lib/module/Scanner/ResultFail.js.map +1 -1
- package/lib/module/Scanner/ResultFocus/ResultFocus.js +56 -0
- package/lib/module/Scanner/ResultFocus/ResultFocus.js.map +1 -0
- package/lib/module/Scanner/ResultFocus/styles.js +39 -0
- package/lib/module/Scanner/ResultFocus/styles.js.map +1 -0
- package/lib/module/Scanner/ResultFocus/types.js +4 -0
- package/lib/module/Scanner/ResultFocus/types.js.map +1 -0
- package/lib/module/Scanner/Scanner.js +11 -310
- package/lib/module/Scanner/Scanner.js.map +1 -1
- package/lib/module/Scanner/Scanner.web.js +29 -0
- package/lib/module/Scanner/Scanner.web.js.map +1 -0
- package/lib/module/Scanner/ScannerInner.js +310 -0
- package/lib/module/Scanner/ScannerInner.js.map +1 -0
- package/lib/module/Scanner/styles.js +11 -0
- package/lib/module/Scanner/styles.js.map +1 -0
- package/lib/module/Scanner/types.js +4 -0
- package/lib/module/Scanner/types.js.map +1 -0
- package/lib/module/constants.js +20 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/decodeImage.js +29 -24
- package/lib/module/decodeImage.js.map +1 -1
- package/lib/module/decodeImage.web.js +7 -0
- package/lib/module/decodeImage.web.js.map +1 -0
- package/lib/module/errors.js +24 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/format.js +53 -47
- package/lib/module/format.js.map +1 -1
- package/lib/module/index.js +5 -19
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +8 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/module/mock.js +2 -23
- package/lib/module/mock.js.map +1 -1
- package/lib/module/permissions.js +24 -20
- package/lib/module/permissions.js.map +1 -1
- package/lib/module/permissions.web.js +10 -0
- package/lib/module/permissions.web.js.map +1 -0
- package/lib/module/types.js +1 -45
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/src/HmsScanView/HmsScanView.d.ts +3 -0
- package/lib/typescript/src/HmsScanView/HmsScanView.d.ts.map +1 -0
- package/lib/typescript/src/HmsScanView/HmsScanView.web.d.ts +3 -0
- package/lib/typescript/src/HmsScanView/HmsScanView.web.d.ts.map +1 -0
- package/lib/typescript/src/HmsScanView/types.d.ts +12 -0
- package/lib/typescript/src/HmsScanView/types.d.ts.map +1 -0
- package/lib/typescript/src/HmsScanViewNativeComponent.d.ts +6 -4
- package/lib/typescript/src/HmsScanViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/NativeHmsScan.d.ts +3 -5
- package/lib/typescript/src/NativeHmsScan.d.ts.map +1 -1
- package/lib/typescript/src/ScanError.d.ts +7 -0
- package/lib/typescript/src/ScanError.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/DeniedOverlay.d.ts.map +1 -1
- package/lib/typescript/src/Scanner/ResultFail.d.ts +2 -1
- package/lib/typescript/src/Scanner/ResultFail.d.ts.map +1 -1
- package/lib/typescript/src/Scanner/ResultFocus/ResultFocus.d.ts +4 -0
- package/lib/typescript/src/Scanner/ResultFocus/ResultFocus.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/ResultFocus/styles.d.ts +36 -0
- package/lib/typescript/src/Scanner/ResultFocus/styles.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/ResultFocus/types.d.ts +8 -0
- package/lib/typescript/src/Scanner/ResultFocus/types.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/Scanner.d.ts +2 -45
- package/lib/typescript/src/Scanner/Scanner.d.ts.map +1 -1
- package/lib/typescript/src/Scanner/Scanner.web.d.ts +3 -0
- package/lib/typescript/src/Scanner/Scanner.web.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/ScannerInner.d.ts +3 -0
- package/lib/typescript/src/Scanner/ScannerInner.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/styles.d.ts +7 -0
- package/lib/typescript/src/Scanner/styles.d.ts.map +1 -0
- package/lib/typescript/src/Scanner/types.d.ts +20 -0
- package/lib/typescript/src/Scanner/types.d.ts.map +1 -0
- package/lib/typescript/src/constants.d.ts +8 -0
- package/lib/typescript/src/constants.d.ts.map +1 -0
- package/lib/typescript/src/decodeImage.d.ts +2 -12
- package/lib/typescript/src/decodeImage.d.ts.map +1 -1
- package/lib/typescript/src/decodeImage.web.d.ts +3 -0
- package/lib/typescript/src/decodeImage.web.d.ts.map +1 -0
- package/lib/typescript/src/errors.d.ts +6 -0
- package/lib/typescript/src/errors.d.ts.map +1 -0
- package/lib/typescript/src/format.d.ts +15 -12
- package/lib/typescript/src/format.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +6 -7
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +9 -0
- package/lib/typescript/src/index.web.d.ts.map +1 -0
- package/lib/typescript/src/mock.d.ts +9 -8
- package/lib/typescript/src/mock.d.ts.map +1 -1
- package/lib/typescript/src/permissions.d.ts +4 -8
- package/lib/typescript/src/permissions.d.ts.map +1 -1
- package/lib/typescript/src/permissions.web.d.ts +4 -0
- package/lib/typescript/src/permissions.web.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +31 -56
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +16 -9
- package/src/HmsScanView/HmsScanView.tsx +67 -0
- package/src/HmsScanView/HmsScanView.web.tsx +22 -0
- package/src/HmsScanView/types.ts +17 -0
- package/src/HmsScanViewNativeComponent.ts +7 -5
- package/src/NativeHmsScan.ts +3 -5
- package/src/ScanError.ts +13 -0
- package/src/Scanner/DeniedOverlay.tsx +4 -2
- package/src/Scanner/ResultFail.tsx +23 -5
- package/src/Scanner/ResultFocus/ResultFocus.tsx +43 -0
- package/src/Scanner/ResultFocus/styles.ts +25 -0
- package/src/Scanner/ResultFocus/types.ts +8 -0
- package/src/Scanner/Scanner.tsx +14 -432
- package/src/Scanner/Scanner.web.tsx +26 -0
- package/src/Scanner/ScannerInner.tsx +391 -0
- package/src/Scanner/styles.ts +6 -0
- package/src/Scanner/types.ts +36 -0
- package/src/constants.ts +55 -0
- package/src/decodeImage.ts +35 -29
- package/src/decodeImage.web.ts +8 -0
- package/src/errors.ts +26 -0
- package/src/format.ts +77 -76
- package/src/index.tsx +17 -32
- package/src/index.web.tsx +22 -0
- package/src/mock.ts +21 -29
- package/src/permissions.ts +33 -20
- package/src/permissions.web.ts +9 -0
- package/src/types.ts +38 -126
- package/lib/module/HmsScanView.js +0 -43
- package/lib/module/HmsScanView.js.map +0 -1
- package/lib/module/Scanner/ResultFocus.js +0 -171
- package/lib/module/Scanner/ResultFocus.js.map +0 -1
- package/lib/typescript/src/HmsScanView.d.ts +0 -33
- package/lib/typescript/src/HmsScanView.d.ts.map +0 -1
- package/lib/typescript/src/Scanner/ResultFocus.d.ts +0 -14
- package/lib/typescript/src/Scanner/ResultFocus.d.ts.map +0 -1
- package/src/HmsScanView.tsx +0 -87
- package/src/Scanner/ResultFocus.tsx +0 -122
package/ios/HmsScanView.mm
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
#import <ScanKitFrameWork/ScanKitFrameWork.h>
|
|
21
21
|
|
|
22
22
|
using namespace facebook::react;
|
|
23
|
+
static void *HmsScanTorchObservation = &HmsScanTorchObservation;
|
|
23
24
|
|
|
24
25
|
@interface HmsScanView () <CustomizedScanDelegate>
|
|
25
26
|
@end
|
|
@@ -34,6 +35,12 @@ using namespace facebook::react;
|
|
|
34
35
|
BOOL _appliedTorch;
|
|
35
36
|
BOOL _hasAppliedOnce;
|
|
36
37
|
BOOL _childAttached;
|
|
38
|
+
AVCaptureDevice *_torchDevice;
|
|
39
|
+
BOOL _observingTorch;
|
|
40
|
+
BOOL _awaitingTorchOff;
|
|
41
|
+
BOOL _hasTorchReport;
|
|
42
|
+
BOOL _lastTorchOn;
|
|
43
|
+
BOOL _lastTorchAvailable;
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
#pragma mark - Codegen wiring
|
|
@@ -54,7 +61,7 @@ using namespace facebook::react;
|
|
|
54
61
|
_hasAppliedOnce = NO;
|
|
55
62
|
_childAttached = NO;
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
// Fabric supplies the initial props before mounting. Construct only that configuration.
|
|
58
65
|
}
|
|
59
66
|
return self;
|
|
60
67
|
}
|
|
@@ -67,6 +74,11 @@ using namespace facebook::react;
|
|
|
67
74
|
// change requires rebuilding the controller.
|
|
68
75
|
[self teardownScanViewController];
|
|
69
76
|
|
|
77
|
+
_appliedFormatsCsv = csv ?: @"";
|
|
78
|
+
if ([HmsScanResultMapper unsupportedFormatInCsv:csv] != nil) {
|
|
79
|
+
[self emitScanErrorWithCode:@"E_UNSUPPORTED_FORMAT" message:@"iOS ScanKit 不支持请求的码制"];
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
70
82
|
unsigned int formatType = [HmsScanResultMapper scanFormatTypeFromCsv:csv];
|
|
71
83
|
HmsScanOptions *options = [[HmsScanOptions alloc] initWithScanFormatType:formatType Photo:NO];
|
|
72
84
|
|
|
@@ -135,8 +147,23 @@ using namespace facebook::react;
|
|
|
135
147
|
- (void)didMoveToWindow {
|
|
136
148
|
[super didMoveToWindow];
|
|
137
149
|
if (self.window != nil) {
|
|
150
|
+
_awaitingTorchOff = NO;
|
|
151
|
+
if ([HmsScanResultMapper unsupportedFormatInCsv:_appliedFormatsCsv] != nil) {
|
|
152
|
+
[self emitScanErrorWithCode:@"E_UNSUPPORTED_FORMAT" message:@"iOS ScanKit 不支持请求的码制"];
|
|
153
|
+
}
|
|
138
154
|
[self attachChildViewController];
|
|
155
|
+
if (_scanVC != nil) {
|
|
156
|
+
[self startObservingTorch];
|
|
157
|
+
[self applyTorch:_appliedTorch];
|
|
158
|
+
}
|
|
139
159
|
} else {
|
|
160
|
+
_awaitingTorchOff = YES;
|
|
161
|
+
[self applyTorch:NO];
|
|
162
|
+
// torchMode can change before torchActive. Keep observing until the device
|
|
163
|
+
// confirms shutdown, or until this view is recycled/deallocated.
|
|
164
|
+
if (!_torchDevice.isTorchActive) {
|
|
165
|
+
[self stopObservingTorch];
|
|
166
|
+
}
|
|
140
167
|
[self detachChildViewController];
|
|
141
168
|
}
|
|
142
169
|
}
|
|
@@ -155,9 +182,10 @@ using namespace facebook::react;
|
|
|
155
182
|
BOOL newTorch = newViewProps.torch;
|
|
156
183
|
|
|
157
184
|
BOOL first = !_hasAppliedOnce;
|
|
185
|
+
BOOL rebuilt = first || ![newCsv isEqualToString:_appliedFormatsCsv];
|
|
158
186
|
|
|
159
187
|
// formatsCsv change -> rebuild the controller (carry over continuous/paused).
|
|
160
|
-
if (
|
|
188
|
+
if (rebuilt) {
|
|
161
189
|
_appliedContinuous = newContinuous;
|
|
162
190
|
_appliedPaused = newPaused;
|
|
163
191
|
[self buildScanViewControllerWithCsv:newCsv];
|
|
@@ -179,9 +207,11 @@ using namespace facebook::react;
|
|
|
179
207
|
}
|
|
180
208
|
|
|
181
209
|
// torch change (best-effort, see applyTorch:).
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
210
|
+
BOOL torchChanged = newTorch != _appliedTorch;
|
|
211
|
+
_appliedTorch = newTorch;
|
|
212
|
+
if (self.window != nil && _scanVC != nil && (rebuilt || torchChanged)) {
|
|
213
|
+
[self startObservingTorch];
|
|
214
|
+
[self applyTorch:_appliedTorch];
|
|
185
215
|
}
|
|
186
216
|
|
|
187
217
|
_hasAppliedOnce = YES;
|
|
@@ -191,20 +221,23 @@ using namespace facebook::react;
|
|
|
191
221
|
|
|
192
222
|
#pragma mark - Torch (best-effort)
|
|
193
223
|
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
// guaranteed to stay in sync with HUAWEI's built-in torch button, and may be a
|
|
198
|
-
// no-op if HUAWEI holds an exclusive lock on the capture device's configuration.
|
|
224
|
+
// ScanKit has no public torch command. Observe the same AVCaptureDevice we
|
|
225
|
+
// configure, including changes made by the SDK or system. A configuration lock
|
|
226
|
+
// failure still reports the device's real state.
|
|
199
227
|
- (void)applyTorch:(BOOL)on {
|
|
200
228
|
BOOL available = NO;
|
|
201
|
-
BOOL
|
|
202
|
-
[self
|
|
229
|
+
BOOL commandFailed = NO;
|
|
230
|
+
BOOL torchOn = [self setTorchHardwareOn:on available:&available commandFailed:&commandFailed];
|
|
231
|
+
// A rejected command must acknowledge even an unchanged state so JS can retry.
|
|
232
|
+
// Accepted commands may update torchActive later; keep those observations deduplicated.
|
|
233
|
+
[self emitTorchStateAvailable:available on:torchOn force:commandFailed];
|
|
203
234
|
}
|
|
204
235
|
|
|
205
236
|
// 优先取「带手电的后置广角相机」(这通常就是华为扫码用的那颗);取不到再退回
|
|
206
237
|
// 默认 video 设备。比已弃用的 defaultDeviceWithMediaType 更可能命中正确设备。
|
|
207
238
|
- (AVCaptureDevice *)torchCaptureDevice {
|
|
239
|
+
if (_torchDevice != nil)
|
|
240
|
+
return _torchDevice;
|
|
208
241
|
AVCaptureDeviceDiscoverySession *session =
|
|
209
242
|
[AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[ AVCaptureDeviceTypeBuiltInWideAngleCamera ]
|
|
210
243
|
mediaType:AVMediaTypeVideo
|
|
@@ -217,32 +250,96 @@ using namespace facebook::react;
|
|
|
217
250
|
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
218
251
|
}
|
|
219
252
|
|
|
253
|
+
- (void)startObservingTorch {
|
|
254
|
+
if (_observingTorch)
|
|
255
|
+
return;
|
|
256
|
+
_torchDevice = [self torchCaptureDevice];
|
|
257
|
+
if (_torchDevice == nil)
|
|
258
|
+
return;
|
|
259
|
+
_observingTorch = YES;
|
|
260
|
+
[_torchDevice addObserver:self forKeyPath:@"torchActive" options:0 context:HmsScanTorchObservation];
|
|
261
|
+
[_torchDevice addObserver:self forKeyPath:@"torchAvailable" options:0 context:HmsScanTorchObservation];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
- (void)stopObservingTorch {
|
|
265
|
+
if (_observingTorch) {
|
|
266
|
+
[_torchDevice removeObserver:self forKeyPath:@"torchActive" context:HmsScanTorchObservation];
|
|
267
|
+
[_torchDevice removeObserver:self forKeyPath:@"torchAvailable" context:HmsScanTorchObservation];
|
|
268
|
+
}
|
|
269
|
+
_observingTorch = NO;
|
|
270
|
+
_awaitingTorchOff = NO;
|
|
271
|
+
_torchDevice = nil;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
275
|
+
ofObject:(id)object
|
|
276
|
+
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
|
|
277
|
+
context:(void *)context {
|
|
278
|
+
if (context != HmsScanTorchObservation) {
|
|
279
|
+
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
__weak HmsScanView *weakSelf = self;
|
|
283
|
+
void (^report)(void) = ^{
|
|
284
|
+
HmsScanView *view = weakSelf;
|
|
285
|
+
if (view == nil || !view->_observingTorch || view->_torchDevice != object)
|
|
286
|
+
return;
|
|
287
|
+
if (view.window == nil) {
|
|
288
|
+
if (view->_awaitingTorchOff) {
|
|
289
|
+
[view emitTorchStateAvailable:view->_torchDevice.hasTorch on:view->_torchDevice.isTorchActive force:NO];
|
|
290
|
+
if (!view->_torchDevice.isTorchActive)
|
|
291
|
+
[view stopObservingTorch];
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if ([keyPath isEqualToString:@"torchAvailable"] && view->_torchDevice.isTorchAvailable && view->_appliedTorch) {
|
|
296
|
+
[view applyTorch:YES];
|
|
297
|
+
} else {
|
|
298
|
+
[view emitTorchStateAvailable:view->_torchDevice.hasTorch on:view->_torchDevice.isTorchActive force:NO];
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
if ([NSThread isMainThread])
|
|
302
|
+
report();
|
|
303
|
+
else
|
|
304
|
+
dispatch_async(dispatch_get_main_queue(), report);
|
|
305
|
+
}
|
|
306
|
+
|
|
220
307
|
// Mutates the capture device's torch. Returns the resulting on-state and writes
|
|
221
|
-
// hardware availability into `available
|
|
222
|
-
// reused on teardown/recycle without
|
|
308
|
+
// hardware availability into `available` and rejection into `commandFailed`.
|
|
309
|
+
// Does NOT emit any event (so it can be reused on teardown/recycle without
|
|
310
|
+
// firing onTorchState on a stale emitter).
|
|
223
311
|
//
|
|
224
312
|
// best-effort:华为独占相机会话且无手电 API,这里直接操作设备硬件。可能因华为
|
|
225
313
|
// 持有配置锁(lockForConfiguration 失败)或用了别的设备而不生效。DEBUG 日志会
|
|
226
314
|
// 打印到底卡在哪一步,真机调试时看 Xcode console。
|
|
227
|
-
- (BOOL)setTorchHardwareOn:(BOOL)on available:(BOOL *)available {
|
|
315
|
+
- (BOOL)setTorchHardwareOn:(BOOL)on available:(BOOL *)available commandFailed:(BOOL *)commandFailed {
|
|
228
316
|
AVCaptureDevice *device = [self torchCaptureDevice];
|
|
229
317
|
BOOL hasTorch = (device != nil && device.hasTorch);
|
|
230
318
|
if (available != NULL) {
|
|
231
319
|
*available = hasTorch;
|
|
232
320
|
}
|
|
321
|
+
if (commandFailed != NULL) {
|
|
322
|
+
*commandFailed = NO;
|
|
323
|
+
}
|
|
233
324
|
if (!hasTorch) {
|
|
325
|
+
if (commandFailed != NULL) {
|
|
326
|
+
*commandFailed = on;
|
|
327
|
+
}
|
|
234
328
|
#if DEBUG
|
|
235
329
|
NSLog(@"[HmsScanView] torch: 无带手电的相机设备 (device=%@)", device);
|
|
236
330
|
#endif
|
|
237
331
|
return NO;
|
|
238
332
|
}
|
|
239
333
|
|
|
240
|
-
BOOL torchOn =
|
|
334
|
+
BOOL torchOn = device.isTorchActive;
|
|
241
335
|
NSError *error = nil;
|
|
242
336
|
if ([device lockForConfiguration:&error]) {
|
|
243
337
|
if (on && device.isTorchAvailable && [device isTorchModeSupported:AVCaptureTorchModeOn]) {
|
|
244
338
|
device.torchMode = AVCaptureTorchModeOn;
|
|
245
339
|
} else {
|
|
340
|
+
if (commandFailed != NULL) {
|
|
341
|
+
*commandFailed = on;
|
|
342
|
+
}
|
|
246
343
|
device.torchMode = AVCaptureTorchModeOff;
|
|
247
344
|
}
|
|
248
345
|
torchOn = device.isTorchActive; // 反映硬件真实状态,而非乐观假设
|
|
@@ -252,6 +349,9 @@ using namespace facebook::react;
|
|
|
252
349
|
device.isTorchAvailable);
|
|
253
350
|
#endif
|
|
254
351
|
} else {
|
|
352
|
+
if (commandFailed != NULL) {
|
|
353
|
+
*commandFailed = YES;
|
|
354
|
+
}
|
|
255
355
|
#if DEBUG
|
|
256
356
|
NSLog(@"[HmsScanView] torch lockForConfiguration 失败(华为可能占用了设备配置锁): %@", error);
|
|
257
357
|
#endif
|
|
@@ -264,14 +364,18 @@ using namespace facebook::react;
|
|
|
264
364
|
// Called by HUAWEI on every decode (repeatedly in continuous mode). `resultDic`
|
|
265
365
|
// is a single result dictionary; we wrap it into the contract's top-level array.
|
|
266
366
|
- (void)customizedScanDelegateForResult:(NSDictionary *)resultDic {
|
|
267
|
-
|
|
268
|
-
if (mapped == nil) {
|
|
269
|
-
// Decoded payload had no usable value; surface as a soft error event.
|
|
270
|
-
[self emitScanErrorWithCode:@"E_NO_RESULT" message:@"扫码结果为空或无法解析"];
|
|
367
|
+
if (_appliedPaused || self.window == nil)
|
|
271
368
|
return;
|
|
369
|
+
@try {
|
|
370
|
+
NSDictionary *mapped = [HmsScanResultMapper scanResultFromHuaweiDict:resultDic];
|
|
371
|
+
if (mapped == nil) {
|
|
372
|
+
[self emitScanErrorWithCode:@"E_INVALID_RESPONSE" message:@"扫码结果无法解析"];
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
[self emitScanResultJson:[HmsScanResultMapper jsonStringFromScanResults:@[ mapped ]]];
|
|
376
|
+
} @catch (NSException *exception) {
|
|
377
|
+
[self emitScanErrorWithCode:@"E_INVALID_RESPONSE" message:exception.reason ?: @"扫码结果无法解析"];
|
|
272
378
|
}
|
|
273
|
-
NSString *json = [HmsScanResultMapper jsonStringFromScanResults:@[ mapped ]];
|
|
274
|
-
[self emitScanResultJson:json];
|
|
275
379
|
}
|
|
276
380
|
|
|
277
381
|
#pragma mark - Event emitters
|
|
@@ -298,13 +402,21 @@ using namespace facebook::react;
|
|
|
298
402
|
});
|
|
299
403
|
}
|
|
300
404
|
|
|
301
|
-
- (void)
|
|
405
|
+
- (void)emitTorchStateAvailable:(BOOL)available on:(BOOL)on force:(BOOL)force {
|
|
302
406
|
if (!_eventEmitter) {
|
|
303
407
|
return;
|
|
304
408
|
}
|
|
409
|
+
if (!force && _hasTorchReport && available == _lastTorchAvailable && on == _lastTorchOn)
|
|
410
|
+
return;
|
|
411
|
+
_hasTorchReport = YES;
|
|
412
|
+
_lastTorchAvailable = available;
|
|
413
|
+
_lastTorchOn = on;
|
|
305
414
|
std::static_pointer_cast<const HmsScanViewEventEmitter>(_eventEmitter)
|
|
306
|
-
->
|
|
415
|
+
->onTorchState(HmsScanViewEventEmitter::OnTorchState{
|
|
307
416
|
.available = available ? true : false,
|
|
417
|
+
.hasAvailable = true,
|
|
418
|
+
.lowLight = false,
|
|
419
|
+
.hasLowLight = false,
|
|
308
420
|
.on = on ? true : false,
|
|
309
421
|
});
|
|
310
422
|
}
|
|
@@ -314,17 +426,20 @@ using namespace facebook::react;
|
|
|
314
426
|
- (void)prepareForRecycle {
|
|
315
427
|
// Reset imperative state so a recycled view re-applies props cleanly.
|
|
316
428
|
// Turn the torch off WITHOUT emitting (the emitter is being torn down).
|
|
317
|
-
[self
|
|
429
|
+
[self stopObservingTorch];
|
|
430
|
+
[self setTorchHardwareOn:NO available:NULL commandFailed:NULL];
|
|
318
431
|
[self teardownScanViewController];
|
|
319
432
|
_hasAppliedOnce = NO;
|
|
320
433
|
_appliedFormatsCsv = @"";
|
|
321
434
|
_appliedContinuous = YES;
|
|
322
435
|
_appliedPaused = NO;
|
|
323
436
|
_appliedTorch = NO;
|
|
437
|
+
_hasTorchReport = NO;
|
|
324
438
|
[super prepareForRecycle];
|
|
325
439
|
}
|
|
326
440
|
|
|
327
441
|
- (void)dealloc {
|
|
442
|
+
[self stopObservingTorch];
|
|
328
443
|
if (_scanVC != nil) {
|
|
329
444
|
_scanVC.customizedScanDelegate = nil;
|
|
330
445
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import NativeHmsScanView from '../HmsScanViewNativeComponent';
|
|
6
|
+
import { formatConfiguration, parseResultsJson } from "../format.js";
|
|
7
|
+
import { scanError } from "../errors.js";
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
export function HmsScanView({
|
|
10
|
+
formats,
|
|
11
|
+
continuous = true,
|
|
12
|
+
paused = false,
|
|
13
|
+
torch = false,
|
|
14
|
+
onScanResult,
|
|
15
|
+
onScanError,
|
|
16
|
+
onTorchState,
|
|
17
|
+
...viewProps
|
|
18
|
+
}) {
|
|
19
|
+
const config = formatConfiguration(formats);
|
|
20
|
+
const invalid = config.error;
|
|
21
|
+
const errorRef = useRef(onScanError);
|
|
22
|
+
errorRef.current = onScanError;
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (invalid) errorRef.current?.(invalid);
|
|
25
|
+
}, [invalid?.message]);
|
|
26
|
+
if (invalid) return /*#__PURE__*/_jsx(View, {
|
|
27
|
+
...viewProps
|
|
28
|
+
});
|
|
29
|
+
return /*#__PURE__*/_jsx(NativeHmsScanView, {
|
|
30
|
+
...viewProps,
|
|
31
|
+
formatsCsv: config.csv,
|
|
32
|
+
continuous: continuous,
|
|
33
|
+
paused: paused,
|
|
34
|
+
torch: torch,
|
|
35
|
+
onScanResult: event => {
|
|
36
|
+
let results;
|
|
37
|
+
try {
|
|
38
|
+
results = parseResultsJson(event.nativeEvent.resultsJson);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
onScanError?.(scanError(error, {
|
|
41
|
+
reason: 'invalid_response',
|
|
42
|
+
message: '扫码结果无法识别'
|
|
43
|
+
}));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
onScanResult?.(results);
|
|
47
|
+
},
|
|
48
|
+
onScanError: event => onScanError?.(scanError(event.nativeEvent, {
|
|
49
|
+
reason: 'unavailable',
|
|
50
|
+
message: '扫码相机不可用'
|
|
51
|
+
})),
|
|
52
|
+
onTorchState: event => {
|
|
53
|
+
const state = event.nativeEvent;
|
|
54
|
+
onTorchState?.({
|
|
55
|
+
on: state.on,
|
|
56
|
+
...(state.hasAvailable ? {
|
|
57
|
+
available: state.available
|
|
58
|
+
} : {}),
|
|
59
|
+
...(state.hasLowLight ? {
|
|
60
|
+
lowLight: state.lowLight
|
|
61
|
+
} : {})
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=HmsScanView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","View","NativeHmsScanView","formatConfiguration","parseResultsJson","scanError","jsx","_jsx","HmsScanView","formats","continuous","paused","torch","onScanResult","onScanError","onTorchState","viewProps","config","invalid","error","errorRef","current","message","formatsCsv","csv","event","results","nativeEvent","resultsJson","reason","state","on","hasAvailable","available","hasLowLight","lowLight"],"sourceRoot":"../../../src","sources":["HmsScanView/HmsScanView.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,OAAOC,iBAAiB,MAAM,+BAA+B;AAC7D,SAASC,mBAAmB,EAAEC,gBAAgB,QAAQ,cAAW;AACjE,SAASC,SAAS,QAAQ,cAAW;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAItC,OAAO,SAASC,WAAWA,CAAC;EAC1BC,OAAO;EACPC,UAAU,GAAG,IAAI;EACjBC,MAAM,GAAG,KAAK;EACdC,KAAK,GAAG,KAAK;EACbC,YAAY;EACZC,WAAW;EACXC,YAAY;EACZ,GAAGC;AACa,CAAC,EAAE;EACnB,MAAMC,MAAM,GAAGd,mBAAmB,CAACM,OAAO,CAAC;EAC3C,MAAMS,OAAO,GAAGD,MAAM,CAACE,KAAK;EAC5B,MAAMC,QAAQ,GAAGpB,MAAM,CAACc,WAAW,CAAC;EACpCM,QAAQ,CAACC,OAAO,GAAGP,WAAW;EAC9Bf,SAAS,CAAC,MAAM;IACd,IAAImB,OAAO,EAAEE,QAAQ,CAACC,OAAO,GAAGH,OAAO,CAAC;EAC1C,CAAC,EAAE,CAACA,OAAO,EAAEI,OAAO,CAAC,CAAC;EACtB,IAAIJ,OAAO,EAAE,oBAAOX,IAAA,CAACN,IAAI;IAAA,GAAKe;EAAS,CAAG,CAAC;EAC3C,oBACET,IAAA,CAACL,iBAAiB;IAAA,GACZc,SAAS;IACbO,UAAU,EAAEN,MAAM,CAACO,GAAI;IACvBd,UAAU,EAAEA,UAAW;IACvBC,MAAM,EAAEA,MAAO;IACfC,KAAK,EAAEA,KAAM;IACbC,YAAY,EAAGY,KAAK,IAAK;MACvB,IAAIC,OAA8B;MAClC,IAAI;QACFA,OAAO,GAAGtB,gBAAgB,CAACqB,KAAK,CAACE,WAAW,CAACC,WAAW,CAAC;MAC3D,CAAC,CAAC,OAAOT,KAAK,EAAE;QACdL,WAAW,GACTT,SAAS,CAACc,KAAK,EAAE;UACfU,MAAM,EAAE,kBAAkB;UAC1BP,OAAO,EAAE;QACX,CAAC,CACH,CAAC;QACD;MACF;MACAT,YAAY,GAAGa,OAAO,CAAC;IACzB,CAAE;IACFZ,WAAW,EAAGW,KAAK,IACjBX,WAAW,GACTT,SAAS,CAACoB,KAAK,CAACE,WAAW,EAAE;MAC3BE,MAAM,EAAE,aAAa;MACrBP,OAAO,EAAE;IACX,CAAC,CACH,CACD;IACDP,YAAY,EAAGU,KAAK,IAAK;MACvB,MAAMK,KAAK,GAAGL,KAAK,CAACE,WAAW;MAC/BZ,YAAY,GAAG;QACbgB,EAAE,EAAED,KAAK,CAACC,EAAE;QACZ,IAAID,KAAK,CAACE,YAAY,GAAG;UAAEC,SAAS,EAAEH,KAAK,CAACG;QAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,IAAIH,KAAK,CAACI,WAAW,GAAG;UAAEC,QAAQ,EAAEL,KAAK,CAACK;QAAS,CAAC,GAAG,CAAC,CAAC;MAC3D,CAAC,CAAC;IACJ;EAAE,CACH,CAAC;AAEN","ignoreList":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
import { unsupportedScanError } from "../errors.js";
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
export function HmsScanView({
|
|
8
|
+
onScanError,
|
|
9
|
+
formats: _formats,
|
|
10
|
+
paused: _paused,
|
|
11
|
+
torch: _torch,
|
|
12
|
+
continuous: _continuous,
|
|
13
|
+
onScanResult: _onScanResult,
|
|
14
|
+
onTorchState: _onTorchState,
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
17
|
+
const callback = useRef(onScanError);
|
|
18
|
+
callback.current = onScanError;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
callback.current?.(unsupportedScanError());
|
|
21
|
+
}, []);
|
|
22
|
+
return /*#__PURE__*/_jsx(View, {
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=HmsScanView.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","View","unsupportedScanError","jsx","_jsx","HmsScanView","onScanError","formats","_formats","paused","_paused","torch","_torch","continuous","_continuous","onScanResult","_onScanResult","onTorchState","_onTorchState","props","callback","current"],"sourceRoot":"../../../src","sources":["HmsScanView/HmsScanView.web.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACzC,SAASC,IAAI,QAAQ,cAAc;AACnC,SAASC,oBAAoB,QAAQ,cAAW;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAGjD,OAAO,SAASC,WAAWA,CAAC;EAC1BC,WAAW;EACXC,OAAO,EAAEC,QAAQ;EACjBC,MAAM,EAAEC,OAAO;EACfC,KAAK,EAAEC,MAAM;EACbC,UAAU,EAAEC,WAAW;EACvBC,YAAY,EAAEC,aAAa;EAC3BC,YAAY,EAAEC,aAAa;EAC3B,GAAGC;AACa,CAAC,EAAE;EACnB,MAAMC,QAAQ,GAAGpB,MAAM,CAACM,WAAW,CAAC;EACpCc,QAAQ,CAACC,OAAO,GAAGf,WAAW;EAC9BP,SAAS,CAAC,MAAM;IACdqB,QAAQ,CAACC,OAAO,GAAGnB,oBAAoB,CAAC,CAAC,CAAC;EAC5C,CAAC,EAAE,EAAE,CAAC;EACN,oBAAOE,IAAA,CAACH,IAAI;IAAA,GAAKkB;EAAK,CAAG,CAAC;AAC5B","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../../src","sources":["HmsScanView/types.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -7,7 +7,7 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati
|
|
|
7
7
|
|
|
8
8
|
// RN codegen Fabric 组件规范(注册名 "HmsScanView")。
|
|
9
9
|
// 事件 payload 都用基础类型 / 单字符串,绕开 codegen 对复杂事件结构的限制:
|
|
10
|
-
// 扫码结果以 JSON 字符串回传(由
|
|
10
|
+
// 扫码结果以 JSON 字符串回传(由 HmsScanView/HmsScanView.tsx 解析成 ScanResult[])。
|
|
11
11
|
|
|
12
12
|
type ScanResultEvent = Readonly<{
|
|
13
13
|
/** JSON 编码的 ScanResult[]。 */
|
|
@@ -19,15 +19,17 @@ type ScanErrorEvent = Readonly<{
|
|
|
19
19
|
message: string;
|
|
20
20
|
}>;
|
|
21
21
|
|
|
22
|
-
type
|
|
23
|
-
/** 环境是否暗到建议显示手电按钮(Android OnLightVisibleCallBack)。 */
|
|
22
|
+
type TorchStateEvent = Readonly<{
|
|
24
23
|
available: boolean;
|
|
24
|
+
hasAvailable: boolean;
|
|
25
|
+
lowLight: boolean;
|
|
26
|
+
hasLowLight: boolean;
|
|
25
27
|
/** 手电当前是否点亮。 */
|
|
26
28
|
on: boolean;
|
|
27
29
|
}>;
|
|
28
30
|
|
|
29
31
|
export interface NativeProps extends ViewProps {
|
|
30
|
-
/** 限定码制(逗号分隔的
|
|
32
|
+
/** 限定码制(逗号分隔的 ScanFormat),空串 = 全部。 */
|
|
31
33
|
formatsCsv?: WithDefault<string, ''>;
|
|
32
34
|
/** 连续扫码(命中后继续,不自动停)。 */
|
|
33
35
|
continuous?: WithDefault<boolean, true>;
|
|
@@ -38,7 +40,7 @@ export interface NativeProps extends ViewProps {
|
|
|
38
40
|
|
|
39
41
|
onScanResult?: DirectEventHandler<ScanResultEvent>;
|
|
40
42
|
onScanError?: DirectEventHandler<ScanErrorEvent>;
|
|
41
|
-
|
|
43
|
+
onTorchState?: DirectEventHandler<TorchStateEvent>;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
export default codegenNativeComponent<NativeProps>('HmsScanView');
|
|
@@ -7,5 +7,5 @@ import { TurboModuleRegistry } from 'react-native';
|
|
|
7
7
|
// decodeImage 返回 JSON 编码的 ScanResult[](由 src/format.ts 解析回强类型),
|
|
8
8
|
// 权限状态返回字符串(由 src/permissions.ts 归一)。
|
|
9
9
|
|
|
10
|
-
export default TurboModuleRegistry.
|
|
10
|
+
export default TurboModuleRegistry.get('HmsScan');
|
|
11
11
|
//# sourceMappingURL=NativeHmsScan.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","get"],"sourceRoot":"../../src","sources":["NativeHmsScan.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;;AAElD;AACA;AACA;AACA;;AAiBA,eAAeA,mBAAmB,CAACC,GAAG,CAAO,SAAS,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export class ScanError extends Error {
|
|
4
|
+
constructor(error) {
|
|
5
|
+
super(error.message);
|
|
6
|
+
this.name = 'ScanError';
|
|
7
|
+
this.reason = error.reason;
|
|
8
|
+
this.sourceCode = error.sourceCode;
|
|
9
|
+
Object.setPrototypeOf(this, ScanError.prototype);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ScanError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ScanError","Error","constructor","error","message","name","reason","sourceCode","Object","setPrototypeOf","prototype"],"sourceRoot":"../../src","sources":["ScanError.ts"],"mappings":";;AAEA,OAAO,MAAMA,SAAS,SAASC,KAAK,CAAwB;EAG1DC,WAAWA,CAACC,KAA4B,EAAE;IACxC,KAAK,CAACA,KAAK,CAACC,OAAO,CAAC;IACpB,IAAI,CAACC,IAAI,GAAG,WAAW;IACvB,IAAI,CAACC,MAAM,GAAGH,KAAK,CAACG,MAAM;IAC1B,IAAI,CAACC,UAAU,GAAGJ,KAAK,CAACI,UAAU;IAClCC,MAAM,CAACC,cAAc,CAAC,IAAI,EAAET,SAAS,CAACU,SAAS,CAAC;EAClD;AACF","ignoreList":[]}
|
|
@@ -14,7 +14,7 @@ export function DeniedOverlay({
|
|
|
14
14
|
children: [/*#__PURE__*/_jsx(Empty, {
|
|
15
15
|
icon: "permission-denied",
|
|
16
16
|
title: "\u9700\u8981\u76F8\u673A\u6743\u9650",
|
|
17
|
-
desc: "\u5F00\u542F\u76F8\u673A\u540E\uFF0C\u624D\u80FD\u626B\u63CF\
|
|
17
|
+
desc: "\u5F00\u542F\u76F8\u673A\u540E\uFF0C\u624D\u80FD\u626B\u63CF\u6761\u7801\u4E0E\u4E8C\u7EF4\u7801\u3002\u8BF7\u524D\u5F80\u7CFB\u7EDF\u8BBE\u7F6E\u6388\u6743\u3002"
|
|
18
18
|
}), /*#__PURE__*/_jsxs(View, {
|
|
19
19
|
style: styles.row,
|
|
20
20
|
children: [onClose && /*#__PURE__*/_jsx(Button, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["StyleSheet","View","Button","Empty","useThemedStyles","r","jsx","_jsx","jsxs","_jsxs","DeniedOverlay","onClose","onSettings","s","makeStyles","style","overlay","children","icon","title","desc","styles","row","label","variant","block","onPress","leftIcon","create","flexDirection","columnGap","marginTop","c","position","top","left","right","bottom","zIndex","backgroundColor","background","alignItems","justifyContent","paddingHorizontal","rowGap"],"sourceRoot":"../../../src","sources":["Scanner/DeniedOverlay.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAC/C,SACEC,MAAM,EACNC,KAAK,EACLC,eAAe,EACfC,CAAC,QAEI,2BAA2B;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAOnC;AACA,OAAO,SAASC,aAAaA,CAAC;EAAEC,OAAO;EAAEC;AAA+B,CAAC,EAAE;EACzE,MAAMC,CAAC,GAAGT,eAAe,CAACU,UAAU,CAAC;EACrC,oBACEL,KAAA,CAACR,IAAI;IAACc,KAAK,EAAEF,CAAC,CAACG,OAAQ;IAAAC,QAAA,gBACrBV,IAAA,CAACJ,KAAK;MACJe,IAAI,EAAC,mBAAmB;MACxBC,KAAK,EAAC,sCAAQ;MACdC,IAAI,EAAC;
|
|
1
|
+
{"version":3,"names":["StyleSheet","View","Button","Empty","useThemedStyles","r","jsx","_jsx","jsxs","_jsxs","DeniedOverlay","onClose","onSettings","s","makeStyles","style","overlay","children","icon","title","desc","styles","row","label","variant","block","onPress","leftIcon","create","flexDirection","columnGap","marginTop","c","position","top","left","right","bottom","zIndex","backgroundColor","background","alignItems","justifyContent","paddingHorizontal","rowGap"],"sourceRoot":"../../../src","sources":["Scanner/DeniedOverlay.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAC/C,SACEC,MAAM,EACNC,KAAK,EACLC,eAAe,EACfC,CAAC,QAEI,2BAA2B;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAOnC;AACA,OAAO,SAASC,aAAaA,CAAC;EAAEC,OAAO;EAAEC;AAA+B,CAAC,EAAE;EACzE,MAAMC,CAAC,GAAGT,eAAe,CAACU,UAAU,CAAC;EACrC,oBACEL,KAAA,CAACR,IAAI;IAACc,KAAK,EAAEF,CAAC,CAACG,OAAQ;IAAAC,QAAA,gBACrBV,IAAA,CAACJ,KAAK;MACJe,IAAI,EAAC,mBAAmB;MACxBC,KAAK,EAAC,sCAAQ;MACdC,IAAI,EAAC;IAA6B,CACnC,CAAC,eAGFX,KAAA,CAACR,IAAI;MAACc,KAAK,EAAEM,MAAM,CAACC,GAAI;MAAAL,QAAA,GACrBN,OAAO,iBACNJ,IAAA,CAACL,MAAM;QAACqB,KAAK,EAAC,cAAI;QAACC,OAAO,EAAC,OAAO;QAACC,KAAK;QAACC,OAAO,EAAEf;MAAQ,CAAE,CAC7D,eACDJ,IAAA,CAACL,MAAM;QACLqB,KAAK,EAAC,gCAAO;QACbC,OAAO,EAAC,SAAS;QACjBG,QAAQ,EAAC,UAAU;QACnBF,KAAK;QACLC,OAAO,EAAEd;MAAW,CACrB,CAAC;IAAA,CACE,CAAC;EAAA,CACH,CAAC;AAEX;AAEA,MAAMS,MAAM,GAAGrB,UAAU,CAAC4B,MAAM,CAAC;EAC/BN,GAAG,EAAE;IAAEO,aAAa,EAAE,KAAK;IAAEC,SAAS,EAAEzB,CAAC,CAAC,EAAE,CAAC;IAAE0B,SAAS,EAAE1B,CAAC,CAAC,CAAC;EAAE;AACjE,CAAC,CAAC;AAEF,MAAMS,UAAU,GAAIkB,CAAc,IAChChC,UAAU,CAAC4B,MAAM,CAAC;EAChBZ,OAAO,EAAE;IACPiB,QAAQ,EAAE,UAAU;IACpBC,GAAG,EAAE,CAAC;IACNC,IAAI,EAAE,CAAC;IACPC,KAAK,EAAE,CAAC;IACRC,MAAM,EAAE,CAAC;IACTC,MAAM,EAAE,EAAE;IACVC,eAAe,EAAEP,CAAC,CAACQ,UAAU;IAC7BC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE,QAAQ;IACxBC,iBAAiB,EAAEtC,CAAC,CAAC,EAAE,CAAC;IACxBuC,MAAM,EAAEvC,CAAC,CAAC,CAAC;EACb;AACF,CAAC,CAAC","ignoreList":[]}
|
|
@@ -8,6 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
// 聚焦款不加背景遮罩,与浮层确认卡保持一致。
|
|
9
9
|
export function ResultFail({
|
|
10
10
|
bottomInset,
|
|
11
|
+
failed,
|
|
11
12
|
onRescan
|
|
12
13
|
}) {
|
|
13
14
|
const s = useThemedStyles(makeStyles);
|
|
@@ -36,8 +37,8 @@ export function ResultFail({
|
|
|
36
37
|
}],
|
|
37
38
|
children: [/*#__PURE__*/_jsx(Empty, {
|
|
38
39
|
icon: "error-alert",
|
|
39
|
-
title:
|
|
40
|
-
desc:
|
|
40
|
+
title: failed ? '图片识别失败' : '未识别到条码',
|
|
41
|
+
desc: failed ? '无法读取或解码图片,请重试。' : '请将条码完整置于框内、保持平整并对准光线后重试。'
|
|
41
42
|
}), /*#__PURE__*/_jsx(Button, {
|
|
42
43
|
label: "\u91CD\u626B",
|
|
43
44
|
variant: "primary",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","Animated","StyleSheet","View","Button","Empty","useThemedStyles","r","jsx","_jsx","jsxs","_jsxs","ResultFail","bottomInset","onRescan","s","makeStyles","anim","Value","current","timing","toValue","duration","useNativeDriver","start","style","sheet","transform","translateY","interpolate","inputRange","outputRange","children","grabber","styles","inner","paddingBottom","icon","title","desc","label","variant","block","onPress","create","paddingHorizontal","paddingTop","rowGap","c","shadow","position","left","right","bottom","zIndex","backgroundColor","surface","borderTopLeftRadius","borderTopRightRadius","floating","width","height","borderRadius","surfaceContainerHighest","alignSelf"],"sourceRoot":"../../../src","sources":["Scanner/ResultFail.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACzC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AACzD,SACEC,MAAM,EACNC,KAAK,EACLC,eAAe,EACfC,CAAC,QAGI,2BAA2B;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","Animated","StyleSheet","View","Button","Empty","useThemedStyles","r","jsx","_jsx","jsxs","_jsxs","ResultFail","bottomInset","failed","onRescan","s","makeStyles","anim","Value","current","timing","toValue","duration","useNativeDriver","start","style","sheet","transform","translateY","interpolate","inputRange","outputRange","children","grabber","styles","inner","paddingBottom","icon","title","desc","label","variant","block","onPress","create","paddingHorizontal","paddingTop","rowGap","c","shadow","position","left","right","bottom","zIndex","backgroundColor","surface","borderTopLeftRadius","borderTopRightRadius","floating","width","height","borderRadius","surfaceContainerHighest","alignSelf"],"sourceRoot":"../../../src","sources":["Scanner/ResultFail.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { ScrollView, Text, View } from 'react-native';
|
|
4
|
+
import { Button, Card, useColors, useThemedStyles, r } from '@unif/react-native-design';
|
|
5
|
+
import { styles, makeStyles } from "./styles.js";
|
|
6
|
+
|
|
7
|
+
/** A raw result is selected here; interpreting it belongs to the consumer. */
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
export function ResultFocus({
|
|
10
|
+
result,
|
|
11
|
+
bottomInset,
|
|
12
|
+
onRescan,
|
|
13
|
+
onConfirm
|
|
14
|
+
}) {
|
|
15
|
+
const colors = useColors();
|
|
16
|
+
const themed = useThemedStyles(makeStyles);
|
|
17
|
+
return /*#__PURE__*/_jsx(View, {
|
|
18
|
+
style: [styles.wrap, {
|
|
19
|
+
bottom: bottomInset + r(18)
|
|
20
|
+
}],
|
|
21
|
+
children: /*#__PURE__*/_jsxs(Card, {
|
|
22
|
+
borderColor: colors.primary,
|
|
23
|
+
borderWidth: 2,
|
|
24
|
+
borderRadius: r(16),
|
|
25
|
+
padding: r(14),
|
|
26
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
27
|
+
style: themed.badge,
|
|
28
|
+
children: "\u5DF2\u8BC6\u522B"
|
|
29
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
30
|
+
style: themed.format,
|
|
31
|
+
children: result.format
|
|
32
|
+
}), /*#__PURE__*/_jsx(ScrollView, {
|
|
33
|
+
style: styles.content,
|
|
34
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
35
|
+
selectable: true,
|
|
36
|
+
style: themed.value,
|
|
37
|
+
children: result.value
|
|
38
|
+
})
|
|
39
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
40
|
+
style: styles.actions,
|
|
41
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
42
|
+
label: "\u91CD\u626B",
|
|
43
|
+
variant: "secondary",
|
|
44
|
+
block: true,
|
|
45
|
+
onPress: onRescan
|
|
46
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
47
|
+
label: "\u9009\u7528",
|
|
48
|
+
variant: "primary",
|
|
49
|
+
block: true,
|
|
50
|
+
onPress: onConfirm
|
|
51
|
+
})]
|
|
52
|
+
})]
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=ResultFocus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["ScrollView","Text","View","Button","Card","useColors","useThemedStyles","r","styles","makeStyles","jsx","_jsx","jsxs","_jsxs","ResultFocus","result","bottomInset","onRescan","onConfirm","colors","themed","style","wrap","bottom","children","borderColor","primary","borderWidth","borderRadius","padding","badge","format","content","selectable","value","actions","label","variant","block","onPress"],"sourceRoot":"../../../../src","sources":["Scanner/ResultFocus/ResultFocus.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,IAAI,EAAEC,IAAI,QAAQ,cAAc;AACrD,SACEC,MAAM,EACNC,IAAI,EACJC,SAAS,EACTC,eAAe,EACfC,CAAC,QACI,2BAA2B;AAElC,SAASC,MAAM,EAAEC,UAAU,QAAQ,aAAU;;AAE7C;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AACA,OAAO,SAASC,WAAWA,CAAC;EAC1BC,MAAM;EACNC,WAAW;EACXC,QAAQ;EACRC;AACgB,CAAC,EAAE;EACnB,MAAMC,MAAM,GAAGd,SAAS,CAAC,CAAC;EAC1B,MAAMe,MAAM,GAAGd,eAAe,CAACG,UAAU,CAAC;EAC1C,oBACEE,IAAA,CAACT,IAAI;IAACmB,KAAK,EAAE,CAACb,MAAM,CAACc,IAAI,EAAE;MAAEC,MAAM,EAAEP,WAAW,GAAGT,CAAC,CAAC,EAAE;IAAE,CAAC,CAAE;IAAAiB,QAAA,eAC1DX,KAAA,CAACT,IAAI;MACHqB,WAAW,EAAEN,MAAM,CAACO,OAAQ;MAC5BC,WAAW,EAAE,CAAE;MACfC,YAAY,EAAErB,CAAC,CAAC,EAAE,CAAE;MACpBsB,OAAO,EAAEtB,CAAC,CAAC,EAAE,CAAE;MAAAiB,QAAA,gBAEfb,IAAA,CAACV,IAAI;QAACoB,KAAK,EAAED,MAAM,CAACU,KAAM;QAAAN,QAAA,EAAC;MAAG,CAAM,CAAC,eACrCb,IAAA,CAACV,IAAI;QAACoB,KAAK,EAAED,MAAM,CAACW,MAAO;QAAAP,QAAA,EAAET,MAAM,CAACgB;MAAM,CAAO,CAAC,eAClDpB,IAAA,CAACX,UAAU;QAACqB,KAAK,EAAEb,MAAM,CAACwB,OAAQ;QAAAR,QAAA,eAChCb,IAAA,CAACV,IAAI;UAACgC,UAAU;UAACZ,KAAK,EAAED,MAAM,CAACc,KAAM;UAAAV,QAAA,EAClCT,MAAM,CAACmB;QAAK,CACT;MAAC,CACG,CAAC,eACbrB,KAAA,CAACX,IAAI;QAACmB,KAAK,EAAEb,MAAM,CAAC2B,OAAQ;QAAAX,QAAA,gBAC1Bb,IAAA,CAACR,MAAM;UAACiC,KAAK,EAAC,cAAI;UAACC,OAAO,EAAC,WAAW;UAACC,KAAK;UAACC,OAAO,EAAEtB;QAAS,CAAE,CAAC,eAClEN,IAAA,CAACR,MAAM;UAACiC,KAAK,EAAC,cAAI;UAACC,OAAO,EAAC,SAAS;UAACC,KAAK;UAACC,OAAO,EAAErB;QAAU,CAAE,CAAC;MAAA,CAC7D,CAAC;IAAA,CACH;EAAC,CACH,CAAC;AAEX","ignoreList":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { StyleSheet } from 'react-native';
|
|
4
|
+
import { r, rf, fw, fontMono } from '@unif/react-native-design';
|
|
5
|
+
export const styles = StyleSheet.create({
|
|
6
|
+
wrap: {
|
|
7
|
+
position: 'absolute',
|
|
8
|
+
left: r(16),
|
|
9
|
+
right: r(16),
|
|
10
|
+
zIndex: 50
|
|
11
|
+
},
|
|
12
|
+
content: {
|
|
13
|
+
maxHeight: r(220),
|
|
14
|
+
marginVertical: r(14)
|
|
15
|
+
},
|
|
16
|
+
actions: {
|
|
17
|
+
flexDirection: 'row',
|
|
18
|
+
columnGap: r(10)
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
export const makeStyles = colors => StyleSheet.create({
|
|
22
|
+
badge: {
|
|
23
|
+
fontSize: rf(13),
|
|
24
|
+
fontWeight: fw.semi,
|
|
25
|
+
color: colors.foreground
|
|
26
|
+
},
|
|
27
|
+
format: {
|
|
28
|
+
fontSize: rf(12),
|
|
29
|
+
color: colors.foregroundMuted,
|
|
30
|
+
fontFamily: fontMono,
|
|
31
|
+
marginTop: r(4)
|
|
32
|
+
},
|
|
33
|
+
value: {
|
|
34
|
+
fontSize: rf(16),
|
|
35
|
+
lineHeight: rf(21),
|
|
36
|
+
color: colors.foreground
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=styles.js.map
|