@unif/react-native-hms-scan 0.2.1 → 0.3.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 +29 -12
- package/ios/HmsScanView.mm +42 -8
- package/lib/module/Scanner/ScanToolbar.js +2 -2
- package/lib/module/Scanner/ScanToolbar.js.map +1 -1
- package/lib/module/Scanner/Scanner.js +4 -3
- package/lib/module/Scanner/Scanner.js.map +1 -1
- package/lib/typescript/src/Scanner/ScanToolbar.d.ts +4 -2
- package/lib/typescript/src/Scanner/ScanToolbar.d.ts.map +1 -1
- package/lib/typescript/src/Scanner/Scanner.d.ts +3 -1
- package/lib/typescript/src/Scanner/Scanner.d.ts.map +1 -1
- package/package.json +11 -1
- package/src/Scanner/ScanToolbar.tsx +13 -9
- package/src/Scanner/Scanner.tsx +7 -4
package/README.md
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@unif/react-native-hms-scan)
|
|
4
4
|
[](https://github.com/unif-design/react-native-hms-scan/actions/workflows/ci.yml)
|
|
5
|
-
[](
|
|
5
|
+
[](LICENSE)
|
|
6
6
|
[](https://unif-design.github.io/react-native-hms-scan/)
|
|
7
7
|
|
|
8
|
-
华为 **HMS
|
|
8
|
+
华为 **HMS 统一扫码(HUAWEI Scan Kit)** 的 React Native 封装,面向 RN 0.85 新架构(Fabric + TurboModule):成品扫一扫页、headless 自定义扫码 UI、从图片识别条码 / 二维码。
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
## 特性
|
|
11
|
+
|
|
12
|
+
- **三种用法** — 成品 `<Scanner>` 扫一扫页(自带权限流 / 状态机 / 主题)、headless `<HmsScanView>` 相机组件(自定义 UI)、`decodeImage(uri)` 从本地图片识别。
|
|
13
|
+
- **Android 内置引擎** — 用 Scan SDK-Plus,**非华为机型可用**,不依赖设备装 HMS Core APK;华为 maven 与依赖已内置在库里,宿主无需改 gradle。
|
|
14
|
+
- **零云端配置** — 两端**都不需要 AppGallery Connect / agconnect / API Key**。
|
|
15
|
+
- **14 种码制** — `QR_CODE` / `EAN_13` / `CODE_128` / `PDF417` / `DATA_MATRIX` 等,默认识别全部。
|
|
16
|
+
- 仅支持 **RN 新架构**;`@unif/react-native-design` 风格统一。
|
|
12
17
|
|
|
13
18
|
## 安装
|
|
14
19
|
|
|
@@ -17,9 +22,11 @@ yarn add @unif/react-native-hms-scan react-native-svg
|
|
|
17
22
|
cd ios && pod install
|
|
18
23
|
```
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
`react-native-svg` 是 peer 依赖(`<Scanner>` 图标用它绘制);`<Scanner>` 还依赖 peer `@unif/react-native-design`。宿主需开启新架构。Android 权限、iOS `NSCameraUsageDescription` 等见[文档站 · 安装](https://unif-design.github.io/react-native-hms-scan/docs/getting-started/installation)。
|
|
26
|
+
|
|
27
|
+
## 快速开始
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
成品「扫一扫」页 —— 扫到条码后由宿主解析商品、确认带回:
|
|
23
30
|
|
|
24
31
|
```tsx
|
|
25
32
|
import { Scanner, type ScanResult, type ScanProduct } from '@unif/react-native-hms-scan';
|
|
@@ -30,18 +37,28 @@ function ScanScreen({ navigation }) {
|
|
|
30
37
|
title="扫一扫"
|
|
31
38
|
onClose={() => navigation.goBack()}
|
|
32
39
|
resolveProduct={async (r: ScanResult): Promise<ScanProduct | null> => {
|
|
33
|
-
const p = await api.lookupByBarcode(r.value);
|
|
34
|
-
return p
|
|
35
|
-
? { name: p.name, brand: p.brand, price: `¥${p.price}`, barcode: r.value }
|
|
36
|
-
: null;
|
|
40
|
+
const p = await api.lookupByBarcode(r.value); // 你来解析;返回 null = 未识别
|
|
41
|
+
return p ? { name: p.name, brand: p.brand, price: `¥${p.price}`, barcode: r.value } : null;
|
|
37
42
|
}}
|
|
38
|
-
onConfirm={(product, result) => navigation.navigate('Order', { product })}
|
|
43
|
+
onConfirm={(product, result) => navigation.navigate('Order', { product, barcode: result.value })}
|
|
39
44
|
/>
|
|
40
45
|
);
|
|
41
46
|
}
|
|
42
47
|
```
|
|
43
48
|
|
|
44
|
-
headless `<HmsScanView
|
|
49
|
+
headless `<HmsScanView>`(完全自定义 UI)、图片识别 `decodeImage`、权限、平台差异 —— 见[文档站](https://unif-design.github.io/react-native-hms-scan/)。
|
|
50
|
+
|
|
51
|
+
## 文档
|
|
52
|
+
|
|
53
|
+
- **完整文档**(安装 · 平台配置 · API · 平台差异 · 故障排查):https://unif-design.github.io/react-native-hms-scan/
|
|
54
|
+
- **AI / Agent**(按需 fetch,别凭记忆猜 API):[llms.txt](https://unif-design.github.io/react-native-hms-scan/llms.txt) · [llms-full.txt](https://unif-design.github.io/react-native-hms-scan/llms-full.txt)
|
|
55
|
+
- **Agent Skill** `using-unif-hms-scan`(`unif-react-native` plugin):`/plugin marketplace add unif-design/react-native-skills` → `/plugin install unif-react-native@unif-react-native-skills`
|
|
56
|
+
|
|
57
|
+
## 兼容性
|
|
58
|
+
|
|
59
|
+
- **React Native** 新架构(Fabric + TurboModule)**必须开启**;在 RN 0.85 上开发与验证。
|
|
60
|
+
- **Android** minSdkVersion ≥ 24(Android 7.0)。
|
|
61
|
+
- **iOS** `ScanKitFrameWork` 扫码功能**仅真机**(模拟器可编译,相机要真机)。
|
|
45
62
|
|
|
46
63
|
## 许可
|
|
47
64
|
|
package/ios/HmsScanView.mm
CHANGED
|
@@ -202,32 +202,60 @@ using namespace facebook::react;
|
|
|
202
202
|
[self emitTorchStatusAvailable:available on:torchOn];
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
// 优先取「带手电的后置广角相机」(这通常就是华为扫码用的那颗);取不到再退回
|
|
206
|
+
// 默认 video 设备。比已弃用的 defaultDeviceWithMediaType 更可能命中正确设备。
|
|
207
|
+
- (AVCaptureDevice *)torchCaptureDevice {
|
|
208
|
+
AVCaptureDeviceDiscoverySession *session =
|
|
209
|
+
[AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[ AVCaptureDeviceTypeBuiltInWideAngleCamera ]
|
|
210
|
+
mediaType:AVMediaTypeVideo
|
|
211
|
+
position:AVCaptureDevicePositionBack];
|
|
212
|
+
for (AVCaptureDevice *d in session.devices) {
|
|
213
|
+
if (d.hasTorch) {
|
|
214
|
+
return d;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
|
218
|
+
}
|
|
219
|
+
|
|
205
220
|
// Mutates the capture device's torch. Returns the resulting on-state and writes
|
|
206
221
|
// hardware availability into `available`. Does NOT emit any event (so it can be
|
|
207
222
|
// reused on teardown/recycle without firing onTorchStatus on a stale emitter).
|
|
223
|
+
//
|
|
224
|
+
// best-effort:华为独占相机会话且无手电 API,这里直接操作设备硬件。可能因华为
|
|
225
|
+
// 持有配置锁(lockForConfiguration 失败)或用了别的设备而不生效。DEBUG 日志会
|
|
226
|
+
// 打印到底卡在哪一步,真机调试时看 Xcode console。
|
|
208
227
|
- (BOOL)setTorchHardwareOn:(BOOL)on available:(BOOL *)available {
|
|
209
|
-
AVCaptureDevice *device = [
|
|
210
|
-
BOOL
|
|
228
|
+
AVCaptureDevice *device = [self torchCaptureDevice];
|
|
229
|
+
BOOL hasTorch = (device != nil && device.hasTorch);
|
|
211
230
|
if (available != NULL) {
|
|
212
|
-
*available =
|
|
231
|
+
*available = hasTorch;
|
|
213
232
|
}
|
|
214
|
-
if (!
|
|
233
|
+
if (!hasTorch) {
|
|
234
|
+
#if DEBUG
|
|
235
|
+
NSLog(@"[HmsScanView] torch: 无带手电的相机设备 (device=%@)", device);
|
|
236
|
+
#endif
|
|
215
237
|
return NO;
|
|
216
238
|
}
|
|
217
239
|
|
|
218
240
|
BOOL torchOn = NO;
|
|
219
241
|
NSError *error = nil;
|
|
220
242
|
if ([device lockForConfiguration:&error]) {
|
|
221
|
-
if (on && [device isTorchModeSupported:AVCaptureTorchModeOn]) {
|
|
243
|
+
if (on && device.isTorchAvailable && [device isTorchModeSupported:AVCaptureTorchModeOn]) {
|
|
222
244
|
device.torchMode = AVCaptureTorchModeOn;
|
|
223
|
-
torchOn = YES;
|
|
224
245
|
} else {
|
|
225
246
|
device.torchMode = AVCaptureTorchModeOff;
|
|
226
|
-
torchOn = NO;
|
|
227
247
|
}
|
|
248
|
+
torchOn = device.isTorchActive; // 反映硬件真实状态,而非乐观假设
|
|
228
249
|
[device unlockForConfiguration];
|
|
250
|
+
#if DEBUG
|
|
251
|
+
NSLog(@"[HmsScanView] torch 请求 on=%d -> isTorchActive=%d isTorchAvailable=%d", on, device.isTorchActive,
|
|
252
|
+
device.isTorchAvailable);
|
|
253
|
+
#endif
|
|
254
|
+
} else {
|
|
255
|
+
#if DEBUG
|
|
256
|
+
NSLog(@"[HmsScanView] torch lockForConfiguration 失败(华为可能占用了设备配置锁): %@", error);
|
|
257
|
+
#endif
|
|
229
258
|
}
|
|
230
|
-
// On lock failure we silently ignore (best-effort) and report torchOn = NO.
|
|
231
259
|
return torchOn;
|
|
232
260
|
}
|
|
233
261
|
|
|
@@ -303,3 +331,9 @@ using namespace facebook::react;
|
|
|
303
331
|
}
|
|
304
332
|
|
|
305
333
|
@end
|
|
334
|
+
|
|
335
|
+
// Fabric 组件注册钩子。RN codegen 生成的 RCTThirdPartyFabricComponentsProvider 用
|
|
336
|
+
// {"HmsScanView", HmsScanViewCls} 建表并调用本函数拿到视图类(见
|
|
337
|
+
// @react-native/codegen 的 GenerateThirdPartyFabricComponentsProviderObjCpp)。
|
|
338
|
+
// 缺这个函数 → 组件注册不上 → JS 端报 "Unimplemented component: <HmsScanView>"。
|
|
339
|
+
Class<RCTComponentViewProtocol> HmsScanViewCls(void) { return HmsScanView.class; }
|
|
@@ -17,12 +17,12 @@ export function ScanToolbar({
|
|
|
17
17
|
bottom: bottomInset + r(50)
|
|
18
18
|
}],
|
|
19
19
|
pointerEvents: "box-none",
|
|
20
|
-
children: [/*#__PURE__*/_jsx(ToolbarItem, {
|
|
20
|
+
children: [onFlash && /*#__PURE__*/_jsx(ToolbarItem, {
|
|
21
21
|
icon: flash ? 'flash-on' : 'flash-off',
|
|
22
22
|
label: flash ? '已开灯' : '手电筒',
|
|
23
23
|
activeColor: flash ? c.primary : undefined,
|
|
24
24
|
onPress: onFlash
|
|
25
|
-
}), /*#__PURE__*/_jsx(ToolbarItem, {
|
|
25
|
+
}), onAlbum && /*#__PURE__*/_jsx(ToolbarItem, {
|
|
26
26
|
icon: "image",
|
|
27
27
|
label: "\u76F8\u518C",
|
|
28
28
|
onPress: onAlbum
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Pressable","StyleSheet","Text","View","Icon","useColors","r","rf","fw","scanChrome","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","ScanToolbar","flash","bottomInset","onFlash","onAlbum","c","style","styles","bar","bottom","pointerEvents","children","ToolbarItem","icon","label","activeColor","primary","undefined","onPress","item","accessibilityRole","accessibilityLabel","pressed","circle","backgroundColor","borderColor","glassBorderActive","glassDisc2","glassBorder","opacity","name","size","color","white","create","position","left","right","zIndex","flexDirection","justifyContent","columnGap","width","alignItems","rowGap","height","borderRadius","borderWidth","hairlineWidth","fontSize","fontWeight","medium","toolbarLabel","textShadowColor","textShadowOffset","textShadowRadius"],"sourceRoot":"../../../src","sources":["Scanner/ScanToolbar.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,UAAU,EAAEC,IAAI,EAAEC,IAAI,QAAQ,cAAc;AAChE,SAASC,IAAI,EAAEC,SAAS,EAAEC,CAAC,EAAEC,EAAE,EAAEC,EAAE,QAAuB,2BAA2B;AACrF,SAASC,UAAU,QAAQ,iBAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA,EAAAC,QAAA,IAAAC,SAAA;
|
|
1
|
+
{"version":3,"names":["Pressable","StyleSheet","Text","View","Icon","useColors","r","rf","fw","scanChrome","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","ScanToolbar","flash","bottomInset","onFlash","onAlbum","c","style","styles","bar","bottom","pointerEvents","children","ToolbarItem","icon","label","activeColor","primary","undefined","onPress","item","accessibilityRole","accessibilityLabel","pressed","circle","backgroundColor","borderColor","glassBorderActive","glassDisc2","glassBorder","opacity","name","size","color","white","create","position","left","right","zIndex","flexDirection","justifyContent","columnGap","width","alignItems","rowGap","height","borderRadius","borderWidth","hairlineWidth","fontSize","fontWeight","medium","toolbarLabel","textShadowColor","textShadowOffset","textShadowRadius"],"sourceRoot":"../../../src","sources":["Scanner/ScanToolbar.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -34,6 +34,7 @@ function ScannerInner({
|
|
|
34
34
|
hintText = DEFAULT_HINT,
|
|
35
35
|
topInset = 54,
|
|
36
36
|
bottomInset = 34,
|
|
37
|
+
showTorch = true,
|
|
37
38
|
onClose,
|
|
38
39
|
resolveProduct,
|
|
39
40
|
onConfirm,
|
|
@@ -155,11 +156,11 @@ function ScannerInner({
|
|
|
155
156
|
title: title,
|
|
156
157
|
topInset: topInset,
|
|
157
158
|
onClose: onClose
|
|
158
|
-
}), showChrome && /*#__PURE__*/_jsx(ScanToolbar, {
|
|
159
|
+
}), showChrome && (showTorch || !!pickImage) && /*#__PURE__*/_jsx(ScanToolbar, {
|
|
159
160
|
flash: torch,
|
|
160
161
|
bottomInset: bottomInset,
|
|
161
|
-
onFlash: () => setTorch(t => !t),
|
|
162
|
-
onAlbum: onAlbum
|
|
162
|
+
onFlash: showTorch ? () => setTorch(t => !t) : undefined,
|
|
163
|
+
onAlbum: pickImage ? onAlbum : undefined
|
|
163
164
|
}), phase === 'success' && product && /*#__PURE__*/_jsx(ResultFocus, {
|
|
164
165
|
product: product,
|
|
165
166
|
detectMs: detectMs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","Linking","StyleSheet","View","ThemeProvider","ToastHost","toast","HmsScanView","decodeImage","getCameraPermissionStatus","requestCameraPermission","scanChrome","Viewfinder","ScanTopBar","ScanToolbar","ResultFocus","ResultFail","DeniedOverlay","jsx","_jsx","jsxs","_jsxs","VF_SIZE","DEFAULT_HINT","Scanner","props","children","ScannerInner","title","formats","hintText","topInset","bottomInset","onClose","resolveProduct","onConfirm","pickImage","phase","setPhase","torch","setTorch","product","setProduct","detectMs","setDetectMs","handlingRef","detectStartRef","lastResultRef","mountedRef","current","status","reset","finalize","result","resolved","name","value","barcode","Date","now","onCameraResult","results","first","onScanError","error","code","onAlbum","uri","undefined","onConfirmPress","r","p","success","showChrome","style","styles","root","absoluteFill","paused","onScanResult","size","detecting","flash","onFlash","t","onContinue","onRetry","onSettings","openSettings","create","flex","backgroundColor","cameraBg"],"sourceRoot":"../../../src","sources":["Scanner/Scanner.tsx"],"mappings":";;AAAA,SAASA,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAChE,SAASC,OAAO,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AACxD,SAASC,aAAa,EAAEC,SAAS,EAAEC,KAAK,QAAQ,2BAA2B;AAC3E,SAASC,WAAW,QAAQ,mBAAgB;AAC5C,SAASC,WAAW,QAAQ,mBAAgB;AAC5C,SACEC,yBAAyB,EACzBC,uBAAuB,QAClB,mBAAgB;AAEvB,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,WAAW,QAAQ,kBAAe;AAC3C,SAASC,WAAW,QAAQ,kBAAe;AAC3C,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,aAAa,QAAQ,oBAAiB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAIhD,MAAMC,OAAO,GAAG,GAAG;AACnB,MAAMC,YAAY,GAAG,oBAAoB;
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","Linking","StyleSheet","View","ThemeProvider","ToastHost","toast","HmsScanView","decodeImage","getCameraPermissionStatus","requestCameraPermission","scanChrome","Viewfinder","ScanTopBar","ScanToolbar","ResultFocus","ResultFail","DeniedOverlay","jsx","_jsx","jsxs","_jsxs","VF_SIZE","DEFAULT_HINT","Scanner","props","children","ScannerInner","title","formats","hintText","topInset","bottomInset","showTorch","onClose","resolveProduct","onConfirm","pickImage","phase","setPhase","torch","setTorch","product","setProduct","detectMs","setDetectMs","handlingRef","detectStartRef","lastResultRef","mountedRef","current","status","reset","finalize","result","resolved","name","value","barcode","Date","now","onCameraResult","results","first","onScanError","error","code","onAlbum","uri","undefined","onConfirmPress","r","p","success","showChrome","style","styles","root","absoluteFill","paused","onScanResult","size","detecting","flash","onFlash","t","onContinue","onRetry","onSettings","openSettings","create","flex","backgroundColor","cameraBg"],"sourceRoot":"../../../src","sources":["Scanner/Scanner.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
interface ScanToolbarProps {
|
|
2
2
|
flash: boolean;
|
|
3
3
|
bottomInset: number;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/** 不传则不显示手电筒按钮。 */
|
|
5
|
+
onFlash?: () => void;
|
|
6
|
+
/** 不传则不显示相册按钮(库不内置图片选择器,需宿主提供 pickImage)。 */
|
|
7
|
+
onAlbum?: () => void;
|
|
6
8
|
}
|
|
7
9
|
export declare function ScanToolbar({ flash, bottomInset, onFlash, onAlbum }: ScanToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
8
10
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScanToolbar.d.ts","sourceRoot":"","sources":["../../../../src/Scanner/ScanToolbar.tsx"],"names":[],"mappings":"AAIA,UAAU,gBAAgB;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ScanToolbar.d.ts","sourceRoot":"","sources":["../../../../src/Scanner/ScanToolbar.tsx"],"names":[],"mappings":"AAIA,UAAU,gBAAgB;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAGD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CAerF"}
|
|
@@ -10,6 +10,8 @@ export interface ScannerProps {
|
|
|
10
10
|
topInset?: number;
|
|
11
11
|
/** 底部安全区(默认 34)。 */
|
|
12
12
|
bottomInset?: number;
|
|
13
|
+
/** 是否显示手电筒按钮,默认 true。手电由库内自管(Android 可用;iOS 为 best-effort,可在 iOS 上关掉)。 */
|
|
14
|
+
showTorch?: boolean;
|
|
13
15
|
/** 左上角关闭。 */
|
|
14
16
|
onClose?: () => void;
|
|
15
17
|
/**
|
|
@@ -21,7 +23,7 @@ export interface ScannerProps {
|
|
|
21
23
|
onConfirm?: (product: ScanProduct, result: ScanResult) => void;
|
|
22
24
|
/**
|
|
23
25
|
* 点"相册":宿主用自己的图片选择器选图并返回本地 uri(取消则返回 null)。
|
|
24
|
-
*
|
|
26
|
+
* 库不内置图片选择器(遵循 RN 惯例):**传了才显示相册按钮**,不传则隐藏。
|
|
25
27
|
*/
|
|
26
28
|
pickImage?: () => Promise<string | null>;
|
|
27
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scanner.d.ts","sourceRoot":"","sources":["../../../../src/Scanner/Scanner.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAcvE,MAAM,WAAW,YAAY;IAC3B,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa;IACb,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,UAAU,KACf,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC9E,oCAAoC;IACpC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CAO1C"}
|
|
1
|
+
{"version":3,"file":"Scanner.d.ts","sourceRoot":"","sources":["../../../../src/Scanner/Scanner.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAcvE,MAAM,WAAW,YAAY;IAC3B,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa;IACb,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,UAAU,KACf,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC9E,oCAAoC;IACpC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CAO1C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unif/react-native-hms-scan",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "华为 HMS 统一扫码服务 React Native bridge:定制视图扫码 + 图片识别 (Scan SDK-Plus / ScanKitFrameWork,@unif 私有)",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -127,6 +127,11 @@
|
|
|
127
127
|
"name": "ReactNativeHmsScanSpec",
|
|
128
128
|
"type": "all",
|
|
129
129
|
"jsSrcsDir": "src",
|
|
130
|
+
"ios": {
|
|
131
|
+
"componentProvider": {
|
|
132
|
+
"HmsScanView": "HmsScanView"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
130
135
|
"android": {
|
|
131
136
|
"javaPackageName": "com.unif.reactnativehmsscan"
|
|
132
137
|
}
|
|
@@ -184,6 +189,11 @@
|
|
|
184
189
|
],
|
|
185
190
|
"setupFiles": [
|
|
186
191
|
"./jest.setup.ts"
|
|
192
|
+
],
|
|
193
|
+
"testPathIgnorePatterns": [
|
|
194
|
+
"<rootDir>/node_modules/",
|
|
195
|
+
"<rootDir>/website/",
|
|
196
|
+
"<rootDir>/lib/"
|
|
187
197
|
]
|
|
188
198
|
},
|
|
189
199
|
"prettier": {
|
|
@@ -5,8 +5,10 @@ import { scanChrome } from './scanChrome';
|
|
|
5
5
|
interface ScanToolbarProps {
|
|
6
6
|
flash: boolean;
|
|
7
7
|
bottomInset: number;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/** 不传则不显示手电筒按钮。 */
|
|
9
|
+
onFlash?: () => void;
|
|
10
|
+
/** 不传则不显示相册按钮(库不内置图片选择器,需宿主提供 pickImage)。 */
|
|
11
|
+
onAlbum?: () => void;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
// 底部工具栏:手电筒 · 相册(按定稿,去掉了搜索 / 输入码)。点亮态用主题主色。
|
|
@@ -14,13 +16,15 @@ export function ScanToolbar({ flash, bottomInset, onFlash, onAlbum }: ScanToolba
|
|
|
14
16
|
const c = useColors();
|
|
15
17
|
return (
|
|
16
18
|
<View style={[styles.bar, { bottom: bottomInset + r(50) }]} pointerEvents="box-none">
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
{onFlash && (
|
|
20
|
+
<ToolbarItem
|
|
21
|
+
icon={flash ? 'flash-on' : 'flash-off'}
|
|
22
|
+
label={flash ? '已开灯' : '手电筒'}
|
|
23
|
+
activeColor={flash ? c.primary : undefined}
|
|
24
|
+
onPress={onFlash}
|
|
25
|
+
/>
|
|
26
|
+
)}
|
|
27
|
+
{onAlbum && <ToolbarItem icon="image" label="相册" onPress={onAlbum} />}
|
|
24
28
|
</View>
|
|
25
29
|
);
|
|
26
30
|
}
|
package/src/Scanner/Scanner.tsx
CHANGED
|
@@ -32,6 +32,8 @@ export interface ScannerProps {
|
|
|
32
32
|
topInset?: number;
|
|
33
33
|
/** 底部安全区(默认 34)。 */
|
|
34
34
|
bottomInset?: number;
|
|
35
|
+
/** 是否显示手电筒按钮,默认 true。手电由库内自管(Android 可用;iOS 为 best-effort,可在 iOS 上关掉)。 */
|
|
36
|
+
showTorch?: boolean;
|
|
35
37
|
/** 左上角关闭。 */
|
|
36
38
|
onClose?: () => void;
|
|
37
39
|
/**
|
|
@@ -45,7 +47,7 @@ export interface ScannerProps {
|
|
|
45
47
|
onConfirm?: (product: ScanProduct, result: ScanResult) => void;
|
|
46
48
|
/**
|
|
47
49
|
* 点"相册":宿主用自己的图片选择器选图并返回本地 uri(取消则返回 null)。
|
|
48
|
-
*
|
|
50
|
+
* 库不内置图片选择器(遵循 RN 惯例):**传了才显示相册按钮**,不传则隐藏。
|
|
49
51
|
*/
|
|
50
52
|
pickImage?: () => Promise<string | null>;
|
|
51
53
|
}
|
|
@@ -70,6 +72,7 @@ function ScannerInner({
|
|
|
70
72
|
hintText = DEFAULT_HINT,
|
|
71
73
|
topInset = 54,
|
|
72
74
|
bottomInset = 34,
|
|
75
|
+
showTorch = true,
|
|
73
76
|
onClose,
|
|
74
77
|
resolveProduct,
|
|
75
78
|
onConfirm,
|
|
@@ -205,12 +208,12 @@ function ScannerInner({
|
|
|
205
208
|
<ScanTopBar title={title} topInset={topInset} onClose={onClose} />
|
|
206
209
|
)}
|
|
207
210
|
|
|
208
|
-
{showChrome && (
|
|
211
|
+
{showChrome && (showTorch || !!pickImage) && (
|
|
209
212
|
<ScanToolbar
|
|
210
213
|
flash={torch}
|
|
211
214
|
bottomInset={bottomInset}
|
|
212
|
-
onFlash={() => setTorch((t) => !t)}
|
|
213
|
-
onAlbum={onAlbum}
|
|
215
|
+
onFlash={showTorch ? () => setTorch((t) => !t) : undefined}
|
|
216
|
+
onAlbum={pickImage ? onAlbum : undefined}
|
|
214
217
|
/>
|
|
215
218
|
)}
|
|
216
219
|
|