react-native-timacare 3.3.58-cccd → 3.3.60-cccd
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/lib/commonjs/screens/home/index.js +1 -1
- package/lib/commonjs/screens/home/index.js.flow +32 -18
- package/lib/commonjs/screens/home/index.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.flow +9 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.flow +7 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/commonjs/utils/cameraCrop.js +1 -1
- package/lib/commonjs/utils/cameraCrop.js.flow +29 -30
- package/lib/commonjs/utils/cameraCrop.js.map +1 -1
- package/lib/module/screens/home/index.js +1 -1
- package/lib/module/screens/home/index.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/module/utils/cameraCrop.js +1 -1
- package/lib/module/utils/cameraCrop.js.map +1 -1
- package/lib/typescript/screens/home/index.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/OCR.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/VehicleCamera.d.ts.map +1 -1
- package/lib/typescript/utils/cameraCrop.d.ts +13 -19
- package/lib/typescript/utils/cameraCrop.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/screens/home/index.tsx +32 -18
- package/src/screens/toan-trinh-so/OCR.tsx +9 -1
- package/src/screens/toan-trinh-so/VehicleCamera.tsx +7 -1
- package/src/utils/cameraCrop.ts +29 -30
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kích thước hiển thị (upright) của ảnh chụp từ VisionCamera.
|
|
3
|
-
*
|
|
4
|
-
* photo.width/height là kích thước buffer gốc của cảm biến (luôn landscape).
|
|
5
|
-
* photo.orientation cho biết ảnh cần xoay bao nhiêu để hiển thị đúng chiều:
|
|
6
|
-
* khi là 'landscape-left'/'landscape-right' (điện thoại cầm dọc) thì ảnh hiển
|
|
7
|
-
* thị bị xoay 90° so với buffer -> phải hoán đổi W/H.
|
|
8
|
-
*/
|
|
9
|
-
export declare const getDisplaySize: (photo: any) => {
|
|
10
|
-
width: any;
|
|
11
|
-
height: any;
|
|
12
|
-
};
|
|
13
1
|
/**
|
|
14
2
|
* Vùng cắt chính giữa theo đúng tỉ lệ khung (aspect = W/H), tính trong hệ toạ
|
|
15
3
|
* độ ảnh đã dựng đứng (upright). VisionCamera fill khung kiểu "cover" nên vùng
|
|
@@ -22,13 +10,19 @@ export declare const computeCenterCrop: (dispW: any, dispH: any, aspect: any) =>
|
|
|
22
10
|
height: any;
|
|
23
11
|
};
|
|
24
12
|
/**
|
|
25
|
-
* Cắt ảnh chụp cho vừa đúng khung preview (theo tỉ lệ `aspect`).
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
13
|
+
* Cắt ảnh chụp cho vừa đúng khung preview (theo tỉ lệ `aspect`).
|
|
14
|
+
*
|
|
15
|
+
* Làm 2 bước để đúng trên CẢ iOS lẫn Android (không méo, không lệch):
|
|
16
|
+
*
|
|
17
|
+
* Bước 1 – resize CHỈ theo `width` (không truyền height):
|
|
18
|
+
* - Thư viện tự tính height theo tỉ lệ THẬT của ảnh -> giữ nguyên tỉ lệ, KHÔNG
|
|
19
|
+
* kéo giãn (đây là nguyên nhân méo trên Android khi trước đó ép cả W lẫn H).
|
|
20
|
+
* - Trên iOS bước này còn "dựng đứng" ảnh theo EXIF (thư viện crop chạy trên
|
|
21
|
+
* buffer gốc chưa xoay), Android/Fresco thì đã tự xoay khi decode.
|
|
22
|
+
* - Đọc kích thước THẬT (result.width/height) sau khi dựng để tính vùng crop.
|
|
23
|
+
*
|
|
24
|
+
* Bước 2 – crop chính giữa theo đúng tỉ lệ khung, dựa trên kích thước thật đó.
|
|
25
|
+
*
|
|
32
26
|
* Trả về uri ảnh đã cắt; nếu lỗi thì trả ảnh gốc để vẫn dùng được.
|
|
33
27
|
*/
|
|
34
28
|
export declare const cropPhotoToAspect: (photo: any, aspect: any) => Promise<any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cameraCrop.d.ts","sourceRoot":"","sources":["../../../src/utils/cameraCrop.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"cameraCrop.d.ts","sourceRoot":"","sources":["../../../src/utils/cameraCrop.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;CAkB7B,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,2CA0B7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,0CAelC,CAAC"}
|
package/package.json
CHANGED
|
@@ -2647,26 +2647,40 @@ export const Home = observer(function Home() {
|
|
|
2647
2647
|
}}
|
|
2648
2648
|
/>
|
|
2649
2649
|
</View>
|
|
2650
|
-
|
|
2651
|
-
style={{ color: '#828282', textAlign: 'center', marginTop: 16 }}
|
|
2652
|
-
>
|
|
2653
|
-
Tima sẽ chuyển thông tin của bạn đến Ngân hàng TNHH MTV CIMB Việt
|
|
2654
|
-
Nam (CIMB) để xem xét phê duyệt khoản vay. Khi chọn "Đồng ý & Tiếp
|
|
2655
|
-
tục", bạn đồng ý cho các bên liên quan thu thập, sử dụng, xử lý và
|
|
2656
|
-
chia sẻ dữ liệu cá nhân theo quy định của pháp luật; đồng thời cho
|
|
2657
|
-
phép Tima gửi{' '}
|
|
2650
|
+
{loanTCCIMB?.typeLoan === 7 ? (
|
|
2658
2651
|
<MText
|
|
2659
|
-
style={{
|
|
2660
|
-
fontWeight: '600',
|
|
2661
|
-
fontFamily: 'BeVietnamPro-SemiBold',
|
|
2662
|
-
}}
|
|
2652
|
+
style={{ color: '#828282', textAlign: 'center', marginTop: 16 }}
|
|
2663
2653
|
>
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2654
|
+
Tima sẽ chuyển thông tin của bạn đến Ngân hàng TNHH MTV CIMB
|
|
2655
|
+
Việt Nam (CIMB) để xem xét phê duyệt khoản vay. Khi chọn "Đồng ý
|
|
2656
|
+
& Tiếp tục", bạn đồng ý cho các bên liên quan thu thập, sử dụng,
|
|
2657
|
+
xử lý và chia sẻ dữ liệu cá nhân theo quy định của pháp luật;
|
|
2658
|
+
đồng thời cho phép Tima gửi{' '}
|
|
2659
|
+
<MText
|
|
2660
|
+
style={{
|
|
2661
|
+
fontWeight: '600',
|
|
2662
|
+
fontFamily: 'BeVietnamPro-SemiBold',
|
|
2663
|
+
}}
|
|
2664
|
+
>
|
|
2665
|
+
"Thông báo kết quả phê duyệt kết nối vay"
|
|
2666
|
+
</MText>{' '}
|
|
2667
|
+
đến Đại lý/ Showroom nơi bạn ký hợp đồng mua xe Ô tô để hoàn tất
|
|
2668
|
+
thủ tục giải ngân. Sau khi chuyển giao dữ liệu, Tima là bên kiểm
|
|
2669
|
+
soát và xử lý dữ liệu cá nhân.
|
|
2670
|
+
</MText>
|
|
2671
|
+
) : (
|
|
2672
|
+
<MText
|
|
2673
|
+
style={{ color: '#828282', textAlign: 'center', marginTop: 16 }}
|
|
2674
|
+
>
|
|
2675
|
+
Tima sẽ chuyển thông tin của bạn đến Ngân hàng TNHH MTV CIMB
|
|
2676
|
+
Việt Nam (CIMB) để xem xét phê duyệt khoản vay. Khi chọn "Đồng ý
|
|
2677
|
+
& Tiếp tục", bạn đồng ý cho các bên liên quan thu thập, sử dụng,
|
|
2678
|
+
xử lý và chia sẻ dữ liệu cá nhân theo quy định của pháp luật.
|
|
2679
|
+
Sau khi chuyển giao dữ liệu, Tima là bên kiểm soát và xử lý dữ
|
|
2680
|
+
liệu cá nhân.
|
|
2681
|
+
</MText>
|
|
2682
|
+
)}
|
|
2683
|
+
|
|
2670
2684
|
<View
|
|
2671
2685
|
style={{
|
|
2672
2686
|
flexDirection: 'row',
|
|
@@ -58,6 +58,9 @@ export const OCR = observer(function OCR(props: any) {
|
|
|
58
58
|
const myCamera = useRef(null);
|
|
59
59
|
const frameSize = useRef({ width: 0, height: 0 });
|
|
60
60
|
const focusTimer = useRef(null);
|
|
61
|
+
// Cờ đồng bộ chặn bấm chụp nhiều lần (state `taking` cập nhật bất đồng bộ nên
|
|
62
|
+
// 2 lần bấm nhanh trong cùng 1 render vẫn lọt qua). Crop có delay -> cần ref.
|
|
63
|
+
const takingRef = useRef(false);
|
|
61
64
|
|
|
62
65
|
// Chọn ống kính sau lấy nét gần nhất (macro) để chụp cận thẻ mà không mờ
|
|
63
66
|
const devices = useCameraDevices();
|
|
@@ -213,7 +216,8 @@ export const OCR = observer(function OCR(props: any) {
|
|
|
213
216
|
};
|
|
214
217
|
|
|
215
218
|
const takePhoto = async () => {
|
|
216
|
-
if (myCamera.current == null ||
|
|
219
|
+
if (myCamera.current == null || takingRef.current) return;
|
|
220
|
+
takingRef.current = true;
|
|
217
221
|
setTaking(true);
|
|
218
222
|
try {
|
|
219
223
|
// Lấy nét giữa khung trước khi chụp để tài liệu ở gần vẫn nét
|
|
@@ -228,10 +232,12 @@ export const OCR = observer(function OCR(props: any) {
|
|
|
228
232
|
});
|
|
229
233
|
// Cắt ảnh vừa đúng khung theo tỉ lệ thẻ (xử lý orientation trong util)
|
|
230
234
|
const uri = await cropPhotoToAspect(data, CARD_ASPECT_RATIO);
|
|
235
|
+
takingRef.current = false;
|
|
231
236
|
setTaking(false);
|
|
232
237
|
goNextWithUri(uri);
|
|
233
238
|
} catch (e) {
|
|
234
239
|
console.error(e);
|
|
240
|
+
takingRef.current = false;
|
|
235
241
|
setTaking(false);
|
|
236
242
|
AlertGlobal.show({
|
|
237
243
|
type: 'warning',
|
|
@@ -243,6 +249,7 @@ export const OCR = observer(function OCR(props: any) {
|
|
|
243
249
|
};
|
|
244
250
|
|
|
245
251
|
const pickImageFromGallery = async () => {
|
|
252
|
+
if (takingRef.current) return; // đang chụp/xử lý -> chặn để không điều hướng 2 lần
|
|
246
253
|
if (Platform.OS === 'android') {
|
|
247
254
|
const result = await launchImageLibrary({ mediaType: 'photo' });
|
|
248
255
|
if (result.assets) {
|
|
@@ -316,6 +323,7 @@ export const OCR = observer(function OCR(props: any) {
|
|
|
316
323
|
<TouchableOpacity
|
|
317
324
|
style={styles.galleryButton}
|
|
318
325
|
onPress={pickImageFromGallery}
|
|
326
|
+
disabled={taking}
|
|
319
327
|
>
|
|
320
328
|
<IconUpload />
|
|
321
329
|
<MText style={styles.galleryText}>Tải ảnh từ thư viện</MText>
|
|
@@ -69,6 +69,9 @@ export default function VehicleCamera(props: any) {
|
|
|
69
69
|
const myCamera = useRef(null);
|
|
70
70
|
const frameSize = useRef({ width: 0, height: 0 });
|
|
71
71
|
const focusTimer = useRef(null);
|
|
72
|
+
// Cờ đồng bộ chặn bấm chụp nhiều lần (state `taking` cập nhật bất đồng bộ nên
|
|
73
|
+
// 2 lần bấm nhanh trong cùng 1 render vẫn lọt qua). Crop có delay -> cần ref.
|
|
74
|
+
const takingRef = useRef(false);
|
|
72
75
|
|
|
73
76
|
// Chọn ống kính sau lấy nét gần nhất (macro) để chụp cận thẻ mà không mờ
|
|
74
77
|
const devices = useCameraDevices();
|
|
@@ -113,7 +116,8 @@ export default function VehicleCamera(props: any) {
|
|
|
113
116
|
};
|
|
114
117
|
|
|
115
118
|
const takePhoto = async () => {
|
|
116
|
-
if (myCamera.current == null ||
|
|
119
|
+
if (myCamera.current == null || takingRef.current) return;
|
|
120
|
+
takingRef.current = true;
|
|
117
121
|
setTaking(true);
|
|
118
122
|
try {
|
|
119
123
|
// Lấy nét giữa khung trước khi chụp để tài liệu ở gần vẫn nét
|
|
@@ -128,10 +132,12 @@ export default function VehicleCamera(props: any) {
|
|
|
128
132
|
});
|
|
129
133
|
// Cắt ảnh vừa đúng khung theo tỉ lệ thẻ (xử lý orientation trong util)
|
|
130
134
|
const uri = await cropPhotoToAspect(data, CARD_ASPECT_RATIO);
|
|
135
|
+
takingRef.current = false;
|
|
131
136
|
setTaking(false);
|
|
132
137
|
goNextWithUri(uri);
|
|
133
138
|
} catch (e) {
|
|
134
139
|
console.error(e);
|
|
140
|
+
takingRef.current = false;
|
|
135
141
|
setTaking(false);
|
|
136
142
|
AlertGlobal.show({
|
|
137
143
|
type: 'warning',
|
package/src/utils/cameraCrop.ts
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import RNImageManipulator from '@oguzhnatly/react-native-image-manipulator';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Kích thước hiển thị (upright) của ảnh chụp từ VisionCamera.
|
|
6
|
-
*
|
|
7
|
-
* photo.width/height là kích thước buffer gốc của cảm biến (luôn landscape).
|
|
8
|
-
* photo.orientation cho biết ảnh cần xoay bao nhiêu để hiển thị đúng chiều:
|
|
9
|
-
* khi là 'landscape-left'/'landscape-right' (điện thoại cầm dọc) thì ảnh hiển
|
|
10
|
-
* thị bị xoay 90° so với buffer -> phải hoán đổi W/H.
|
|
11
|
-
*/
|
|
12
|
-
export const getDisplaySize = (photo) => {
|
|
13
|
-
const needsSwap =
|
|
14
|
-
photo?.orientation === 'landscape-left' ||
|
|
15
|
-
photo?.orientation === 'landscape-right';
|
|
16
|
-
return needsSwap
|
|
17
|
-
? { width: photo.height, height: photo.width }
|
|
18
|
-
: { width: photo.width, height: photo.height };
|
|
19
|
-
};
|
|
20
|
-
|
|
21
4
|
/**
|
|
22
5
|
* Vùng cắt chính giữa theo đúng tỉ lệ khung (aspect = W/H), tính trong hệ toạ
|
|
23
6
|
* độ ảnh đã dựng đứng (upright). VisionCamera fill khung kiểu "cover" nên vùng
|
|
@@ -44,25 +27,41 @@ export const computeCenterCrop = (dispW, dispH, aspect) => {
|
|
|
44
27
|
};
|
|
45
28
|
|
|
46
29
|
/**
|
|
47
|
-
* Cắt ảnh chụp cho vừa đúng khung preview (theo tỉ lệ `aspect`).
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
30
|
+
* Cắt ảnh chụp cho vừa đúng khung preview (theo tỉ lệ `aspect`).
|
|
31
|
+
*
|
|
32
|
+
* Làm 2 bước để đúng trên CẢ iOS lẫn Android (không méo, không lệch):
|
|
33
|
+
*
|
|
34
|
+
* Bước 1 – resize CHỈ theo `width` (không truyền height):
|
|
35
|
+
* - Thư viện tự tính height theo tỉ lệ THẬT của ảnh -> giữ nguyên tỉ lệ, KHÔNG
|
|
36
|
+
* kéo giãn (đây là nguyên nhân méo trên Android khi trước đó ép cả W lẫn H).
|
|
37
|
+
* - Trên iOS bước này còn "dựng đứng" ảnh theo EXIF (thư viện crop chạy trên
|
|
38
|
+
* buffer gốc chưa xoay), Android/Fresco thì đã tự xoay khi decode.
|
|
39
|
+
* - Đọc kích thước THẬT (result.width/height) sau khi dựng để tính vùng crop.
|
|
40
|
+
*
|
|
41
|
+
* Bước 2 – crop chính giữa theo đúng tỉ lệ khung, dựa trên kích thước thật đó.
|
|
42
|
+
*
|
|
54
43
|
* Trả về uri ảnh đã cắt; nếu lỗi thì trả ảnh gốc để vẫn dùng được.
|
|
55
44
|
*/
|
|
56
45
|
export const cropPhotoToAspect = async (photo, aspect) => {
|
|
57
46
|
const uri = 'file://' + photo.path;
|
|
58
|
-
const { width: dispW, height: dispH } = getDisplaySize(photo);
|
|
59
|
-
if (!dispW || !dispH) return uri;
|
|
60
|
-
const crop = computeCenterCrop(dispW, dispH, aspect);
|
|
61
47
|
try {
|
|
62
|
-
|
|
48
|
+
// Dùng cạnh dài của buffer làm width mục tiêu để không giảm độ phân giải chi
|
|
49
|
+
// tiết; resize giữ nguyên tỉ lệ nên không méo.
|
|
50
|
+
const targetWidth = Math.max(photo?.width || 0, photo?.height || 0) || 1080;
|
|
51
|
+
const normalized = await RNImageManipulator.manipulate(
|
|
63
52
|
uri,
|
|
64
|
-
[{ resize: { width:
|
|
65
|
-
{ compress:
|
|
53
|
+
[{ resize: { width: targetWidth } }],
|
|
54
|
+
{ compress: 1, format: 'jpeg' }
|
|
55
|
+
);
|
|
56
|
+
const dispW = normalized.width;
|
|
57
|
+
const dispH = normalized.height;
|
|
58
|
+
if (!dispW || !dispH) return normalized.uri;
|
|
59
|
+
|
|
60
|
+
const crop = computeCenterCrop(dispW, dispH, aspect);
|
|
61
|
+
const result = await RNImageManipulator.manipulate(
|
|
62
|
+
normalized.uri,
|
|
63
|
+
[{ crop }],
|
|
64
|
+
{ compress: 1, format: 'jpeg' }
|
|
66
65
|
);
|
|
67
66
|
return result.uri;
|
|
68
67
|
} catch (e) {
|