react-native-timacare 3.3.11 → 3.3.12

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 (43) hide show
  1. package/lib/commonjs/RNTimacare.js +1 -1
  2. package/lib/commonjs/RNTimacare.js.flow +2 -2
  3. package/lib/commonjs/RNTimacare.js.map +1 -1
  4. package/lib/commonjs/screens/camera/CCCDCameraScreen.js +1 -1
  5. package/lib/commonjs/screens/camera/CCCDCameraScreen.js.flow +248 -112
  6. package/lib/commonjs/screens/camera/CCCDCameraScreen.js.map +1 -1
  7. package/lib/commonjs/screens/nationalID/index.js +1 -1
  8. package/lib/commonjs/screens/nationalID/index.js.flow +4 -2
  9. package/lib/commonjs/screens/nationalID/index.js.map +1 -1
  10. package/lib/commonjs/screens/nationalIDBack/index.js +1 -1
  11. package/lib/commonjs/screens/nationalIDBack/index.js.flow +3 -1
  12. package/lib/commonjs/screens/nationalIDBack/index.js.map +1 -1
  13. package/lib/commonjs/screens/uploadVideo/index.js +1 -1
  14. package/lib/commonjs/screens/uploadVideo/index.js.flow +109 -61
  15. package/lib/commonjs/screens/uploadVideo/index.js.map +1 -1
  16. package/lib/commonjs/screens/uploadVideo/videoStore.js +1 -1
  17. package/lib/commonjs/screens/uploadVideo/videoStore.js.flow +4 -4
  18. package/lib/commonjs/screens/uploadVideo/videoStore.js.map +1 -1
  19. package/lib/module/RNTimacare.js +1 -1
  20. package/lib/module/RNTimacare.js.map +1 -1
  21. package/lib/module/screens/camera/CCCDCameraScreen.js +1 -1
  22. package/lib/module/screens/camera/CCCDCameraScreen.js.map +1 -1
  23. package/lib/module/screens/nationalID/index.js +1 -1
  24. package/lib/module/screens/nationalID/index.js.map +1 -1
  25. package/lib/module/screens/nationalIDBack/index.js +1 -1
  26. package/lib/module/screens/nationalIDBack/index.js.map +1 -1
  27. package/lib/module/screens/uploadVideo/index.js +1 -1
  28. package/lib/module/screens/uploadVideo/index.js.map +1 -1
  29. package/lib/module/screens/uploadVideo/videoStore.js +1 -1
  30. package/lib/module/screens/uploadVideo/videoStore.js.map +1 -1
  31. package/lib/typescript/RNTimacare.d.ts +1 -1
  32. package/lib/typescript/RNTimacare.d.ts.map +1 -1
  33. package/lib/typescript/screens/camera/CCCDCameraScreen.d.ts.map +1 -1
  34. package/lib/typescript/screens/nationalID/index.d.ts.map +1 -1
  35. package/lib/typescript/screens/nationalIDBack/index.d.ts.map +1 -1
  36. package/lib/typescript/screens/uploadVideo/index.d.ts.map +1 -1
  37. package/package.json +3 -2
  38. package/src/RNTimacare.tsx +2 -2
  39. package/src/screens/camera/CCCDCameraScreen.tsx +248 -112
  40. package/src/screens/nationalID/index.tsx +4 -2
  41. package/src/screens/nationalIDBack/index.tsx +3 -1
  42. package/src/screens/uploadVideo/index.tsx +109 -61
  43. package/src/screens/uploadVideo/videoStore.tsx +4 -4
@@ -1,2 +1,2 @@
1
- var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator"));var _initializerDefineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/initializerDefineProperty"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _applyDecoratedDescriptor2=_interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));var _initializerWarningHelper2=_interopRequireDefault(require("@babel/runtime/helpers/initializerWarningHelper"));var _mobx=require("mobx");var _reactNative=require("react-native");var _api=require("../../services/api");var _class,_descriptor;var Store=(_class=function(){function Store(){(0,_classCallCheck2.default)(this,Store);(0,_initializerDefineProperty2.default)(this,"isLoading",_descriptor,this);}(0,_createClass2.default)(Store,[{key:"uploadVideo",value:function uploadVideo(loanID,body,onSuccess,onError){var response;return _regenerator.default.async(function uploadVideo$(_context){while(1)switch(_context.prev=_context.next){case 0:_context.prev=0;this.isLoading=true;_context.next=4;return _regenerator.default.awrap(_api.Api.getInstance().uploadVideo(loanID,body));case 4:response=_context.sent;console.log(response);this.isLoading=false;if(response.kind==='ok'){if(response.data.meta.errorCode===200){if(onSuccess)onSuccess();}else{_reactNative.Alert.alert('Thông báo',response.data.meta.errorMessage);if(onError)onError();}}else{this.isLoading=false;_reactNative.Alert.alert('Thông báo','Lỗi đã xảy ra. Vui lòng thực hiện lại');if(onError)onError();}_context.next=14;break;case 10:_context.prev=10;_context.t0=_context["catch"](0);console.log(_context.t0);if(onError)onError();case 14:case"end":return _context.stop();}},null,this,[[0,10]],Promise);}}]);return Store;}(),(_descriptor=(0,_applyDecoratedDescriptor2.default)(_class.prototype,"isLoading",[_mobx.observable],{configurable:true,enumerable:true,writable:true,initializer:function initializer(){return false;}}),(0,_applyDecoratedDescriptor2.default)(_class.prototype,"uploadVideo",[_mobx.action],Object.getOwnPropertyDescriptor(_class.prototype,"uploadVideo"),_class.prototype)),_class);var videoStore=new Store();var _default=exports.default=videoStore;
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator"));var _initializerDefineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/initializerDefineProperty"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _applyDecoratedDescriptor2=_interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));var _initializerWarningHelper2=_interopRequireDefault(require("@babel/runtime/helpers/initializerWarningHelper"));var _mobx=require("mobx");var _reactNative=require("react-native");var _api=require("../../services/api");var _class,_descriptor;var Store=(_class=function(){function Store(){(0,_classCallCheck2.default)(this,Store);(0,_initializerDefineProperty2.default)(this,"isLoading",_descriptor,this);}(0,_createClass2.default)(Store,[{key:"uploadVideo",value:function uploadVideo(loanID,body,onSuccess,onError){var response;return _regenerator.default.async(function uploadVideo$(_context){while(1)switch(_context.prev=_context.next){case 0:this.isLoading=true;_context.prev=1;_context.next=4;return _regenerator.default.awrap(_api.Api.getInstance().uploadVideo(loanID,body));case 4:response=_context.sent;if(response.kind==='ok'){if(response.data.meta.errorCode===200){if(onSuccess)onSuccess();}else{_reactNative.Alert.alert('Thông báo',response.data.meta.errorMessage);if(onError)onError();}}else{_reactNative.Alert.alert('Thông báo','Lỗi đã xảy ra. Vui lòng thực hiện lại');if(onError)onError();}_context.next=13;break;case 8:_context.prev=8;_context.t0=_context["catch"](1);console.log(_context.t0);_reactNative.Alert.alert('Thông báo','Lỗi đã xảy ra. Vui lòng thực hiện lại');if(onError)onError();case 13:_context.prev=13;this.isLoading=false;return _context.finish(13);case 16:case"end":return _context.stop();}},null,this,[[1,8,13,16]],Promise);}}]);return Store;}(),(_descriptor=(0,_applyDecoratedDescriptor2.default)(_class.prototype,"isLoading",[_mobx.observable],{configurable:true,enumerable:true,writable:true,initializer:function initializer(){return false;}}),(0,_applyDecoratedDescriptor2.default)(_class.prototype,"uploadVideo",[_mobx.action],Object.getOwnPropertyDescriptor(_class.prototype,"uploadVideo"),_class.prototype)),_class);var videoStore=new Store();var _default=exports.default=videoStore;
2
2
  //# sourceMappingURL=videoStore.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_mobx","require","_reactNative","_api","_class","_descriptor","Store","_classCallCheck2","default","_initializerDefineProperty2","_createClass2","key","value","uploadVideo","loanID","body","onSuccess","onError","response","_regenerator","async","uploadVideo$","_context","prev","next","isLoading","awrap","Api","getInstance","sent","console","log","kind","data","meta","errorCode","Alert","alert","errorMessage","t0","stop","Promise","_applyDecoratedDescriptor2","prototype","observable","configurable","enumerable","writable","initializer","action","Object","getOwnPropertyDescriptor","videoStore","_default","exports"],"sourceRoot":"../../../../src","sources":["screens/uploadVideo/videoStore.tsx"],"mappings":"81BACA,IAAAA,KAAA,CAAAC,OAAA,SACA,IAAAC,YAAA,CAAAD,OAAA,iBACA,IAAAE,IAAA,CAAAF,OAAA,uBAAyC,IAAAG,MAAA,CAAAC,WAAA,IAEnC,CAAAC,KAAK,EAAAF,MAAA,qBAAAE,MAAA,KAAAC,gBAAA,CAAAC,OAAA,OAAAF,KAAA,KAAAG,2BAAA,CAAAD,OAAA,mBAAAH,WAAA,WAAAK,aAAA,CAAAF,OAAA,EAAAF,KAAA,GAAAK,GAAA,eAAAC,KAAA,CAGT,SAAAC,YACkBC,MAAM,CAAEC,IAAI,CAAEC,SAAU,CAAEC,OAAO,MAAAC,QAAA,QAAAC,YAAA,CAAAX,OAAA,CAAAY,KAAA,UAAAC,aAAAC,QAAA,iBAAAA,QAAA,CAAAC,IAAA,CAAAD,QAAA,CAAAE,IAAA,SAAAF,QAAA,CAAAC,IAAA,GAE/C,IAAI,CAACE,SAAS,CAAG,IAAI,CAACH,QAAA,CAAAE,IAAA,UAAAL,YAAA,CAAAX,OAAA,CAAAkB,KAAA,CACCC,QAAG,CAACC,WAAW,CAAC,CAAC,CAACf,WAAW,CAACC,MAAM,CAAEC,IAAI,CAAC,SAA5DG,QAAQ,CAAAI,QAAA,CAAAO,IAAA,CACdC,OAAO,CAACC,GAAG,CAACb,QAAQ,CAAC,CACrB,IAAI,CAACO,SAAS,CAAG,KAAK,CACtB,GAAIP,QAAQ,CAACc,IAAI,GAAK,IAAI,CAAE,CAC1B,GAAId,QAAQ,CAACe,IAAI,CAACC,IAAI,CAACC,SAAS,GAAK,GAAG,CAAE,CACxC,GAAInB,SAAS,CAAEA,SAAS,CAAC,CAAC,CAC5B,CAAC,IAAM,CACLoB,kBAAK,CAACC,KAAK,CAAC,WAAW,CAAEnB,QAAQ,CAACe,IAAI,CAACC,IAAI,CAACI,YAAY,CAAC,CACzD,GAAIrB,OAAO,CAAEA,OAAO,CAAC,CAAC,CACxB,CACF,CAAC,IAAM,CACL,IAAI,CAACQ,SAAS,CAAG,KAAK,CACtBW,kBAAK,CAACC,KAAK,CAAC,WAAW,CAAE,uCAAuC,CAAC,CACjE,GAAIpB,OAAO,CAAEA,OAAO,CAAC,CAAC,CACxB,CAACK,QAAA,CAAAE,IAAA,kBAAAF,QAAA,CAAAC,IAAA,IAAAD,QAAA,CAAAiB,EAAA,CAAAjB,QAAA,aAEDQ,OAAO,CAACC,GAAG,CAAAT,QAAA,CAAAiB,EAAM,CAAC,CAClB,GAAItB,OAAO,CAAEA,OAAO,CAAC,CAAC,CAAC,yBAAAK,QAAA,CAAAkB,IAAA,yBAAAC,OAAA,GAE1B,WAAAnC,KAAA,MAAAD,WAAA,IAAAqC,0BAAA,CAAAlC,OAAA,EAAAJ,MAAA,CAAAuC,SAAA,cAzBAC,gBAAU,GAAAC,YAAA,MAAAC,UAAA,MAAAC,QAAA,MAAAC,WAAA,UAAAA,YAAA,QAAa,MAAK,QAAAN,0BAAA,CAAAlC,OAAA,EAAAJ,MAAA,CAAAuC,SAAA,gBAE5BM,YAAM,EAAAC,MAAA,CAAAC,wBAAA,CAAA/C,MAAA,CAAAuC,SAAA,gBAAAvC,MAAA,CAAAuC,SAAA,GAAAvC,MAAA,EA0BT,GAAM,CAAAgD,UAAU,CAAG,GAAI,CAAA9C,KAAK,CAAC,CAAC,CAAC,IAAA+C,QAAA,CAAAC,OAAA,CAAA9C,OAAA,CAChB4C,UAAU"}
1
+ {"version":3,"names":["_mobx","require","_reactNative","_api","_class","_descriptor","Store","_classCallCheck2","default","_initializerDefineProperty2","_createClass2","key","value","uploadVideo","loanID","body","onSuccess","onError","response","_regenerator","async","uploadVideo$","_context","prev","next","isLoading","awrap","Api","getInstance","sent","kind","data","meta","errorCode","Alert","alert","errorMessage","t0","console","log","finish","stop","Promise","_applyDecoratedDescriptor2","prototype","observable","configurable","enumerable","writable","initializer","action","Object","getOwnPropertyDescriptor","videoStore","_default","exports"],"sourceRoot":"../../../../src","sources":["screens/uploadVideo/videoStore.tsx"],"mappings":"81BACA,IAAAA,KAAA,CAAAC,OAAA,SACA,IAAAC,YAAA,CAAAD,OAAA,iBACA,IAAAE,IAAA,CAAAF,OAAA,uBAAyC,IAAAG,MAAA,CAAAC,WAAA,IAEnC,CAAAC,KAAK,EAAAF,MAAA,qBAAAE,MAAA,KAAAC,gBAAA,CAAAC,OAAA,OAAAF,KAAA,KAAAG,2BAAA,CAAAD,OAAA,mBAAAH,WAAA,WAAAK,aAAA,CAAAF,OAAA,EAAAF,KAAA,GAAAK,GAAA,eAAAC,KAAA,CAGT,SAAAC,YACkBC,MAAM,CAAEC,IAAI,CAAEC,SAAU,CAAEC,OAAO,MAAAC,QAAA,QAAAC,YAAA,CAAAX,OAAA,CAAAY,KAAA,UAAAC,aAAAC,QAAA,iBAAAA,QAAA,CAAAC,IAAA,CAAAD,QAAA,CAAAE,IAAA,SACjD,IAAI,CAACC,SAAS,CAAG,IAAI,CAACH,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA,UAAAL,YAAA,CAAAX,OAAA,CAAAkB,KAAA,CAEGC,QAAG,CAACC,WAAW,CAAC,CAAC,CAACf,WAAW,CAACC,MAAM,CAAEC,IAAI,CAAC,SAA5DG,QAAQ,CAAAI,QAAA,CAAAO,IAAA,CACd,GAAIX,QAAQ,CAACY,IAAI,GAAK,IAAI,CAAE,CAC1B,GAAIZ,QAAQ,CAACa,IAAI,CAACC,IAAI,CAACC,SAAS,GAAK,GAAG,CAAE,CACxC,GAAIjB,SAAS,CAAEA,SAAS,CAAC,CAAC,CAC5B,CAAC,IAAM,CACLkB,kBAAK,CAACC,KAAK,CAAC,WAAW,CAAEjB,QAAQ,CAACa,IAAI,CAACC,IAAI,CAACI,YAAY,CAAC,CACzD,GAAInB,OAAO,CAAEA,OAAO,CAAC,CAAC,CACxB,CACF,CAAC,IAAM,CACLiB,kBAAK,CAACC,KAAK,CAAC,WAAW,CAAE,uCAAuC,CAAC,CACjE,GAAIlB,OAAO,CAAEA,OAAO,CAAC,CAAC,CACxB,CAACK,QAAA,CAAAE,IAAA,iBAAAF,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAe,EAAA,CAAAf,QAAA,aAEDgB,OAAO,CAACC,GAAG,CAAAjB,QAAA,CAAAe,EAAM,CAAC,CAClBH,kBAAK,CAACC,KAAK,CAAC,WAAW,CAAE,uCAAuC,CAAC,CACjE,GAAIlB,OAAO,CAAEA,OAAO,CAAC,CAAC,CAAC,QAAAK,QAAA,CAAAC,IAAA,IAEvB,IAAI,CAACE,SAAS,CAAG,KAAK,CAAC,OAAAH,QAAA,CAAAkB,MAAA,8BAAAlB,QAAA,CAAAmB,IAAA,8BAAAC,OAAA,GAE1B,WAAApC,KAAA,MAAAD,WAAA,IAAAsC,0BAAA,CAAAnC,OAAA,EAAAJ,MAAA,CAAAwC,SAAA,cAzBAC,gBAAU,GAAAC,YAAA,MAAAC,UAAA,MAAAC,QAAA,MAAAC,WAAA,UAAAA,YAAA,QAAa,MAAK,QAAAN,0BAAA,CAAAnC,OAAA,EAAAJ,MAAA,CAAAwC,SAAA,gBAE5BM,YAAM,EAAAC,MAAA,CAAAC,wBAAA,CAAAhD,MAAA,CAAAwC,SAAA,gBAAAxC,MAAA,CAAAwC,SAAA,GAAAxC,MAAA,EA0BT,GAAM,CAAAiD,UAAU,CAAG,GAAI,CAAA/C,KAAK,CAAC,CAAC,CAAC,IAAAgD,QAAA,CAAAC,OAAA,CAAA/C,OAAA,CAChB6C,UAAU"}
@@ -1,2 +1,2 @@
1
- export declare function RNTimacare(props: any): JSX.Element;
1
+ export declare function RNTimacare(): JSX.Element;
2
2
  //# sourceMappingURL=RNTimacare.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RNTimacare.d.ts","sourceRoot":"","sources":["../../src/RNTimacare.tsx"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,CAAC,KAAK,KAAA,eAW/B"}
1
+ {"version":3,"file":"RNTimacare.d.ts","sourceRoot":"","sources":["../../src/RNTimacare.tsx"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,gBAWzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"CCCDCameraScreen.d.ts","sourceRoot":"","sources":["../../../../src/screens/camera/CCCDCameraScreen.tsx"],"names":[],"mappings":"AA2BA,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,KAAA,eA4G7C"}
1
+ {"version":3,"file":"CCCDCameraScreen.d.ts","sourceRoot":"","sources":["../../../../src/screens/camera/CCCDCameraScreen.tsx"],"names":[],"mappings":"AAsCA,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,KAAA,eAyO7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/nationalID/index.tsx"],"names":[],"mappings":"AA4DA,eAAO,MAAM,UAAU,KAwPrB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/nationalID/index.tsx"],"names":[],"mappings":"AA6DA,eAAO,MAAM,UAAU,KAyPrB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/nationalIDBack/index.tsx"],"names":[],"mappings":"AA6CA,eAAO,MAAM,cAAc,KAmPzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/nationalIDBack/index.tsx"],"names":[],"mappings":"AA8CA,eAAO,MAAM,cAAc,KAoPzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/uploadVideo/index.tsx"],"names":[],"mappings":"AA6BA,eAAO,MAAM,KAAK,KAkLhB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/screens/uploadVideo/index.tsx"],"names":[],"mappings":"AAmCA,eAAO,MAAM,KAAK,KA4NhB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-timacare",
3
- "version": "3.3.11",
3
+ "version": "3.3.12",
4
4
  "description": "SDK Tima Care",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -42,10 +42,11 @@
42
42
  "react-native-blob-util": "*",
43
43
  "@react-native-camera-roll/camera-roll": "*",
44
44
  "@react-native-async-storage/async-storage": "*",
45
- "@react-native-community/image-editor": "*",
45
+ "@oguzhnatly/react-native-image-manipulator": "*",
46
46
  "@react-native-community/masked-view": "*",
47
47
  "@react-native-firebase/analytics": "*",
48
48
  "@react-navigation/native": "*",
49
+ "@react-navigation/native-stack": "*",
49
50
  "@react-native-ml-kit/text-recognition": "*",
50
51
  "@types/react-native-snap-carousel": "*",
51
52
  "@types/uuid": "*",
@@ -5,7 +5,7 @@ import { Platform } from 'react-native';
5
5
  import appStore from './AppStore';
6
6
  import { Settings } from 'react-native-fbsdk-next';
7
7
 
8
- export function RNTimacare(props) {
8
+ export function RNTimacare() {
9
9
  useEffect(() => {
10
10
  if (Platform.OS === 'android') {
11
11
  Settings.initializeSDK();
@@ -15,5 +15,5 @@ export function RNTimacare(props) {
15
15
  appStore.getAppId();
16
16
  appStore.getDevicePayload();
17
17
  }, []);
18
- return <PrimaryNavigator {...props} />;
18
+ return <PrimaryNavigator />;
19
19
  }
@@ -16,21 +16,37 @@ import {
16
16
  } from 'react-native-vision-camera';
17
17
  import { IconBackWhite, TakePhotoSvg } from '../../assets/icons';
18
18
  import { MText } from '../../components/MText';
19
- import ImageEditor from '@react-native-community/image-editor';
20
- import { CommonActions, useNavigation } from '@react-navigation/native';
21
- import DeviceInfo from 'react-native-device-info';
19
+ import { useNavigation } from '@react-navigation/native';
20
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
21
+ import RNImageManipulator from '@oguzhnatly/react-native-image-manipulator';
22
22
 
23
23
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
24
- const frameWidth = screenWidth * 0.85;
25
- const frameHeight = frameWidth * 0.63; // tỷ lệ giống CCCD
26
- const frameLeft = (screenWidth - frameWidth) / 2;
27
- const frameTop = ((screenWidth * 4) / 3 - frameHeight) / 2;
24
+
25
+ const getImageSize = (
26
+ uri: string
27
+ ): Promise<{ width: number; height: number }> =>
28
+ new Promise((resolve, reject) => {
29
+ Image.getSize(
30
+ uri,
31
+ (width, height) => resolve({ width, height }),
32
+ (err) => reject(err)
33
+ );
34
+ });
35
+
36
+ const clamp = (value: number, min: number, max: number) =>
37
+ Math.min(Math.max(value, min), max);
38
+
28
39
  export default function CCCDCameraScreen(props) {
40
+ const insets = useSafeAreaInsets();
29
41
  const navigation = useNavigation();
30
42
  const camera = useRef(null);
31
43
  const device = useCameraDevice('back');
32
44
  const [cameraActive, setCameraActive] = useState(true);
33
45
  const { hasPermission, requestPermission } = useCameraPermission();
46
+ const [previewLayout, setPreviewLayout] = useState({
47
+ width: screenWidth,
48
+ height: screenHeight,
49
+ });
34
50
 
35
51
  useEffect(() => {
36
52
  if (!hasPermission) requestPermission();
@@ -43,79 +59,199 @@ export default function CCCDCameraScreen(props) {
43
59
  skipMetadata: true,
44
60
  });
45
61
 
46
- Image.getSize(`file://${photo.path}`, async (width, height) => {
47
- const previewHeight = (screenWidth * 4) / 3; // Tỷ lệ khung preview camera
62
+ try {
63
+ const imageUri = `file://${photo.path}`;
64
+ const { width, height } = await getImageSize(imageUri);
65
+ const previewWidth = previewLayout.width || screenWidth;
66
+ const previewHeight = previewLayout.height || screenHeight;
67
+
68
+ const frameWidth = previewWidth * 0.85;
69
+ const frameHeight = frameWidth * 0.63; // tỷ lệ giống CCCD
70
+ const frameX = (previewWidth - frameWidth) / 2;
71
+ const frameY = (previewHeight - frameHeight) / 2;
72
+
73
+ // Tính scale dựa trên `resizeMode="cover"` mặc định của Vision Camera phủ kín màn hình
74
+ const scale = Math.max(previewWidth / width, previewHeight / height);
75
+
76
+ // Kích thước của ảnh nếu được hiển thị và zoom lên để cover màn hình
77
+ const renderedWidth = width * scale;
78
+ const renderedHeight = height * scale;
48
79
 
49
- // Tính scale giữa ảnh thật khung preview
50
- const scaleX = width / screenWidth;
51
- const scaleY = height / previewHeight;
80
+ // Độ phân giải của các phần bị tràn ra khỏi màn hình (do cover)
81
+ const offsetX = (renderedWidth - previewWidth) / 2;
82
+ const offsetY = (renderedHeight - previewHeight) / 2;
83
+
84
+ // Tính tọa độ vùng cần crop trên ảnh gốc dựa vào toạ độ của khung UI
85
+ const cropX = (frameX + offsetX) / scale;
86
+ const cropY = (frameY + offsetY) / scale;
87
+ const cropWidth = frameWidth / scale;
88
+ const cropHeight = frameHeight / scale;
89
+
90
+ const cropXInt = Math.floor(clamp(cropX, 0, Math.max(0, width - 1)));
91
+ const cropYInt = Math.floor(clamp(cropY, 0, Math.max(0, height - 1)));
92
+ const cropWidthInt = Math.floor(
93
+ clamp(cropWidth, 1, Math.max(1, width - cropXInt))
94
+ );
95
+ const cropHeightInt = Math.floor(
96
+ clamp(cropHeight, 1, Math.max(1, height - cropYInt))
97
+ );
52
98
 
53
- // Tính tọa độ vùng cần crop trên ảnh gốc
54
99
  const cropData = {
55
100
  offset: {
56
- x: frameLeft * scaleX,
57
- y: frameTop * scaleY,
101
+ x: cropXInt,
102
+ y: cropYInt,
58
103
  },
59
104
  size: {
60
- width: frameWidth * scaleX,
61
- height: frameHeight * scaleY,
62
- },
63
- displaySize: {
64
- width: frameWidth * scaleX,
65
- height: frameHeight * scaleY,
105
+ width: cropWidthInt,
106
+ height: cropHeightInt,
66
107
  },
67
- resizeMode: 'contain',
68
108
  };
69
109
 
70
- try {
71
- const croppedUri = await ImageEditor.cropImage(
72
- `file://${photo.path}`,
73
- cropData
74
- );
75
- setCameraActive(false);
76
- navigation.goBack();
77
- if (props.route.params.callback) {
78
- props.route.params.callback(croppedUri.uri);
79
- }
80
- } catch (err) {
81
- console.error(err);
110
+ const result = await RNImageManipulator.manipulate(
111
+ imageUri,
112
+ [
113
+ {
114
+ crop: {
115
+ originX: cropXInt,
116
+ originY: cropYInt,
117
+ width: cropWidthInt,
118
+ height: cropHeightInt,
119
+ },
120
+ },
121
+ ],
122
+ { format: 'jpg', compress: 1 }
123
+ );
124
+ setCameraActive(false);
125
+ navigation.goBack();
126
+
127
+ if (props.route?.params?.callback) {
128
+ props.route.params.callback(result?.uri);
82
129
  }
83
- });
130
+ } catch (err) {
131
+ console.error(err);
132
+ }
84
133
  };
85
134
 
86
135
  if (!device || !hasPermission)
87
136
  return <View style={{ flex: 1, backgroundColor: '#000' }} />;
137
+
138
+ const frameWidth = previewLayout.width * 0.85;
139
+ const frameHeight = frameWidth * 0.63;
140
+ const frameX = (previewLayout.width - frameWidth) / 2;
141
+ const frameY = (previewLayout.height - frameHeight) / 2;
142
+
88
143
  return (
89
- <View style={styles.container}>
90
- <View style={styles.topContainer}>
91
- <TouchableOpacity
92
- onPress={() => {
93
- navigation.goBack();
94
- }}
95
- style={[
96
- { width: 48, height: 48, zIndex: 1000, alignItems: 'center' },
97
- ]}
98
- >
99
- <IconBackWhite />
100
- </TouchableOpacity>
101
- </View>
144
+ <View
145
+ style={$container}
146
+ onLayout={(e) => {
147
+ const { width, height } = e.nativeEvent.layout;
148
+ if (width > 0 && height > 0) setPreviewLayout({ width, height });
149
+ }}
150
+ >
102
151
  <Camera
103
- style={styles.camera}
152
+ style={{ flex: 1 }}
104
153
  device={device}
105
154
  isActive={cameraActive}
106
155
  photo={true}
107
156
  ref={camera}
108
157
  />
109
- <View style={styles.overlay}>
110
- <View style={styles.darkOverlayTop} />
111
- <View style={styles.row}>
112
- <View style={styles.darkOverlaySide} />
113
- <View style={styles.frameBorder} />
114
- <View style={styles.darkOverlaySide} />
158
+ <View style={$overlay} pointerEvents="none">
159
+ <View style={[$darkOverlayTop, { height: frameY }]} />
160
+ <View style={$row}>
161
+ <View
162
+ style={[$darkOverlaySide, { width: frameX, height: frameHeight }]}
163
+ />
164
+ <View
165
+ style={[$frameBorder, { width: frameWidth, height: frameHeight }]}
166
+ >
167
+ {/* Top Left */}
168
+ <Corner
169
+ style={{
170
+ top: 0,
171
+ left: 0,
172
+ borderTopWidth: CORNER_WIDTH,
173
+ borderLeftWidth: CORNER_WIDTH,
174
+ borderColor: BORDER_COLOR,
175
+ }}
176
+ />
177
+
178
+ {/* Top Right */}
179
+ <Corner
180
+ style={{
181
+ top: 0,
182
+ right: 0,
183
+ borderTopWidth: CORNER_WIDTH,
184
+ borderRightWidth: CORNER_WIDTH,
185
+ borderColor: BORDER_COLOR,
186
+ }}
187
+ />
188
+
189
+ {/* Bottom Left */}
190
+ <Corner
191
+ style={{
192
+ bottom: 0,
193
+ left: 0,
194
+ borderBottomWidth: CORNER_WIDTH,
195
+ borderLeftWidth: CORNER_WIDTH,
196
+ borderColor: BORDER_COLOR,
197
+ }}
198
+ />
199
+
200
+ {/* Bottom Right */}
201
+ <Corner
202
+ style={{
203
+ bottom: 0,
204
+ right: 0,
205
+ borderBottomWidth: CORNER_WIDTH,
206
+ borderRightWidth: CORNER_WIDTH,
207
+ borderColor: BORDER_COLOR,
208
+ }}
209
+ />
210
+ </View>
211
+ <View
212
+ style={[$darkOverlaySide, { width: frameX, height: frameHeight }]}
213
+ />
115
214
  </View>
116
- <View style={styles.darkOverlayBottom} />
215
+ <View style={[$darkOverlayBottom, { height: frameY }]} />
117
216
  </View>
118
- <View style={styles.captureButton}>
217
+ <View style={[$back, { top: insets.top + 16 }]}>
218
+ <TouchableOpacity
219
+ onPress={() => {
220
+ navigation.goBack();
221
+ }}
222
+ style={{
223
+ position: 'absolute',
224
+ left: 0,
225
+ width: 48,
226
+ height: 48,
227
+ zIndex: 1000,
228
+ alignItems: 'center',
229
+ }}
230
+ >
231
+ <IconBackWhite />
232
+ </TouchableOpacity>
233
+ <MText
234
+ style={{
235
+ textAlign: 'center',
236
+ zIndex: 10,
237
+ color: '#FFFFFF',
238
+ fontSize: 16,
239
+ }}
240
+ >
241
+ {props?.route?.params?.front
242
+ ? 'Chụp CMND/ CCCD mặt trước'
243
+ : 'Chụp CMND/ CCCD mặt sau'}
244
+ </MText>
245
+ </View>
246
+ <View
247
+ style={{
248
+ position: 'absolute',
249
+ bottom: 24 + insets.bottom,
250
+ alignSelf: 'center',
251
+ flexDirection: 'column',
252
+ alignItems: 'center',
253
+ }}
254
+ >
119
255
  <MText
120
256
  style={{
121
257
  color: '#fff',
@@ -135,59 +271,59 @@ export default function CCCDCameraScreen(props) {
135
271
  );
136
272
  }
137
273
 
274
+ const CORNER_SIZE = 20;
275
+ const CORNER_WIDTH = 2;
276
+ const BORDER_COLOR = '#FDFDFD';
277
+
278
+ const Corner = ({ style }: { style: ViewStyle }) => (
279
+ <View
280
+ style={[
281
+ style,
282
+ {
283
+ position: 'absolute',
284
+ width: CORNER_SIZE,
285
+ height: CORNER_SIZE,
286
+ },
287
+ ]}
288
+ />
289
+ );
290
+
138
291
  const overlayColor = 'rgba(22, 22, 22, 0.7)';
139
- const styles = StyleSheet.create({
140
- container: { flex: 1, backgroundColor: '#000' },
141
- camera: { flex: 1 },
142
- overlay: {
143
- ...StyleSheet.absoluteFillObject,
144
- justifyContent: 'center',
145
- alignItems: 'center',
146
- },
147
- frameBorder: {
148
- width: frameWidth,
149
- height: frameHeight,
150
- borderColor: '#FDFDFD',
151
- borderWidth: 2,
152
- },
153
- row: {
154
- flexDirection: 'row',
155
- alignItems: 'center',
156
- },
157
- darkOverlayTop: {
158
- width: '100%',
159
- height: (screenHeight - frameHeight) / 2,
160
- backgroundColor: overlayColor,
161
- },
162
- darkOverlayBottom: {
163
- width: '100%',
164
- height: (screenHeight - frameHeight) / 2,
165
- backgroundColor: overlayColor,
166
- },
167
- darkOverlaySide: {
168
- width: (screenWidth - frameWidth) / 2,
169
- height: frameHeight,
170
- backgroundColor: overlayColor,
171
- },
172
- captureContainer: {
173
- position: 'absolute',
174
- bottom: 40,
175
- width: '100%',
176
- alignItems: 'center',
177
- },
178
- captureButton: {
179
- position: 'absolute',
180
- bottom: 30,
181
- alignSelf: 'center',
182
- flexDirection: 'column',
183
- alignItems: 'center',
184
- },
185
- topContainer: {
186
- position: 'absolute',
187
- top: DeviceInfo.hasNotch() ? 60 : 24,
188
- },
189
- textContainer: {
190
- position: 'absolute',
191
- top: DeviceInfo.hasNotch() ? 60 : 24,
192
- },
193
- });
292
+ const $back: ViewStyle = {
293
+ position: 'absolute',
294
+ left: 0,
295
+ right: 0,
296
+ };
297
+
298
+ const $overlay: ViewStyle = {
299
+ ...StyleSheet.absoluteFillObject,
300
+ justifyContent: 'center',
301
+ alignItems: 'center',
302
+ };
303
+
304
+ const $container: ViewStyle = {
305
+ flex: 1,
306
+ backgroundColor: '#000',
307
+ };
308
+
309
+ const $row: ViewStyle = {
310
+ flexDirection: 'row',
311
+ alignItems: 'center',
312
+ };
313
+
314
+ const $darkOverlayTop: ViewStyle = {
315
+ width: '100%',
316
+ backgroundColor: overlayColor,
317
+ };
318
+
319
+ const $darkOverlayBottom: ViewStyle = {
320
+ width: '100%',
321
+ backgroundColor: overlayColor,
322
+ };
323
+ const $darkOverlaySide: ViewStyle = {
324
+ backgroundColor: overlayColor,
325
+ };
326
+ const $frameBorder: ViewStyle = {
327
+ // borderColor: '#FDFDFD',
328
+ // borderWidth: 2,
329
+ };
@@ -57,6 +57,7 @@ const logoView: ImageStyle = {
57
57
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
58
58
  const frameWidth = screenWidth * 0.85;
59
59
  const frameHeight = frameWidth * 0.63; // tỷ lệ giống CCCD
60
+ const frameAspectRatio = frameWidth / frameHeight;
60
61
 
61
62
  export const NationalID = observer(function NationalID(props: any) {
62
63
  const navigation = useNavigation();
@@ -99,7 +100,7 @@ export const NationalID = observer(function NationalID(props: any) {
99
100
  (data) => {
100
101
  if (data === 1) {
101
102
  navigation.push(ScreenNames.CCCDCameraScreen, {
102
- front: false,
103
+ front: true,
103
104
  callback: (photo) => {
104
105
  setPhoto(photo);
105
106
  },
@@ -163,7 +164,7 @@ export const NationalID = observer(function NationalID(props: any) {
163
164
  <View
164
165
  style={{
165
166
  width: '100%',
166
- height: frameHeight,
167
+ aspectRatio: frameAspectRatio,
167
168
  borderWidth: 8,
168
169
  borderRadius: 6,
169
170
  borderColor: '#FFFFFF',
@@ -179,6 +180,7 @@ export const NationalID = observer(function NationalID(props: any) {
179
180
  style={{
180
181
  width: '100%',
181
182
  height: '100%',
183
+ resizeMode: 'cover',
182
184
  }}
183
185
  />
184
186
  </View>
@@ -42,6 +42,7 @@ const logoView: ImageStyle = {
42
42
  const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
43
43
  const frameWidth = screenWidth * 0.85;
44
44
  const frameHeight = frameWidth * 0.63; // tỷ lệ giống CCCD
45
+ const frameAspectRatio = frameWidth / frameHeight;
45
46
 
46
47
  export const NationalIDBack = observer(function NationalIDBack(props: any) {
47
48
  const navigation = useNavigation();
@@ -143,7 +144,7 @@ export const NationalIDBack = observer(function NationalIDBack(props: any) {
143
144
  <View
144
145
  style={{
145
146
  width: '100%',
146
- height: frameHeight,
147
+ aspectRatio: frameAspectRatio,
147
148
  borderWidth: 8,
148
149
  borderRadius: 6,
149
150
  borderColor: '#FFFFFF',
@@ -159,6 +160,7 @@ export const NationalIDBack = observer(function NationalIDBack(props: any) {
159
160
  style={{
160
161
  width: '100%',
161
162
  height: '100%',
163
+ resizeMode: 'cover',
162
164
  }}
163
165
  />
164
166
  </View>