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.
Files changed (30) hide show
  1. package/lib/commonjs/screens/home/index.js +1 -1
  2. package/lib/commonjs/screens/home/index.js.flow +32 -18
  3. package/lib/commonjs/screens/home/index.js.map +1 -1
  4. package/lib/commonjs/screens/toan-trinh-so/OCR.js +1 -1
  5. package/lib/commonjs/screens/toan-trinh-so/OCR.js.flow +9 -1
  6. package/lib/commonjs/screens/toan-trinh-so/OCR.js.map +1 -1
  7. package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js +1 -1
  8. package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.flow +7 -1
  9. package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
  10. package/lib/commonjs/utils/cameraCrop.js +1 -1
  11. package/lib/commonjs/utils/cameraCrop.js.flow +29 -30
  12. package/lib/commonjs/utils/cameraCrop.js.map +1 -1
  13. package/lib/module/screens/home/index.js +1 -1
  14. package/lib/module/screens/home/index.js.map +1 -1
  15. package/lib/module/screens/toan-trinh-so/OCR.js +1 -1
  16. package/lib/module/screens/toan-trinh-so/OCR.js.map +1 -1
  17. package/lib/module/screens/toan-trinh-so/VehicleCamera.js +1 -1
  18. package/lib/module/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
  19. package/lib/module/utils/cameraCrop.js +1 -1
  20. package/lib/module/utils/cameraCrop.js.map +1 -1
  21. package/lib/typescript/screens/home/index.d.ts.map +1 -1
  22. package/lib/typescript/screens/toan-trinh-so/OCR.d.ts.map +1 -1
  23. package/lib/typescript/screens/toan-trinh-so/VehicleCamera.d.ts.map +1 -1
  24. package/lib/typescript/utils/cameraCrop.d.ts +13 -19
  25. package/lib/typescript/utils/cameraCrop.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/screens/home/index.tsx +32 -18
  28. package/src/screens/toan-trinh-so/OCR.tsx +9 -1
  29. package/src/screens/toan-trinh-so/VehicleCamera.tsx +7 -1
  30. 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`). Làm việc hoàn
26
- * toàn trong hệ toạ độ ảnh đã dựng đứng (upright):
27
- * - Lấy kích thước hiển thị từ photo.orientation (không dùng Image.getSize
28
- * trả về khác nhau giữa iOS/Android tuỳ EXIF).
29
- * - Chèn action `resize` để "bung" EXIF orientation về upright: bắt buộc cho
30
- * iOS (thư viện crop trên buffer gốc chưa xoay), no-op trên Android
31
- * (Fresco đã tự xoay khi decode). Sau đó crop trong cùng hệ toạ độ upright.
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 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;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;CAO1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;CAkB7B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,2CAgB7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,0CAelC,CAAC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-timacare",
3
- "version": "3.3.58-cccd",
3
+ "version": "3.3.60-cccd",
4
4
  "description": "SDK Tima Care",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -2647,26 +2647,40 @@ export const Home = observer(function Home() {
2647
2647
  }}
2648
2648
  />
2649
2649
  </View>
2650
- <MText
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
- "Thông báo kết quả phê duyệt kết nối vay"
2665
- </MText>{' '}
2666
- đến Đại lý/ Showroom nơi bạn hợp đồng mua xe Ô để hoàn tất
2667
- thủ tục giải ngân. Sau khi chuyển giao dữ liệu, Tima bên kiểm
2668
- soát xử dữ liệu cá nhân.
2669
- </MText>
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ử chia sẻ dữ liệu 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 || taking) return;
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 || taking) return;
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',
@@ -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`). Làm việc hoàn
48
- * toàn trong hệ toạ độ ảnh đã dựng đứng (upright):
49
- * - Lấy kích thước hiển thị từ photo.orientation (không dùng Image.getSize
50
- * trả về khác nhau giữa iOS/Android tuỳ EXIF).
51
- * - Chèn action `resize` để "bung" EXIF orientation về upright: bắt buộc cho
52
- * iOS (thư viện crop trên buffer gốc chưa xoay), no-op trên Android
53
- * (Fresco đã tự xoay khi decode). Sau đó crop trong cùng hệ toạ độ upright.
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 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
- const result = await RNImageManipulator.manipulate(
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: dispW, height: dispH } }, { crop }],
65
- { compress: 0.9, format: 'jpeg' }
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) {