react-native-rectangle-doc-scanner 0.52.0 → 0.54.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.
@@ -61,6 +61,26 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
61
61
  height: react_native_1.Dimensions.get('window').height,
62
62
  });
63
63
  const [isImageLoading, setIsImageLoading] = (0, react_1.useState)(true);
64
+ const [loadError, setLoadError] = (0, react_1.useState)(null);
65
+ (0, react_1.useEffect)(() => {
66
+ console.log('[CropEditor] Document path:', document.path);
67
+ console.log('[CropEditor] Document dimensions:', document.width, 'x', document.height);
68
+ console.log('[CropEditor] Document quad:', document.quad);
69
+ // Load image size using Image.getSize
70
+ const imageUri = `file://${document.path}`;
71
+ react_native_1.Image.getSize(imageUri, (width, height) => {
72
+ console.log('[CropEditor] Image.getSize success:', { width, height });
73
+ setImageSize({ width, height });
74
+ setIsImageLoading(false);
75
+ setLoadError(null);
76
+ }, (error) => {
77
+ console.error('[CropEditor] Image.getSize error:', error);
78
+ // Fallback to document dimensions
79
+ console.log('[CropEditor] Using fallback dimensions:', document.width, 'x', document.height);
80
+ setImageSize({ width: document.width, height: document.height });
81
+ setIsImageLoading(false);
82
+ });
83
+ }, [document]);
64
84
  // Get initial rectangle from detected quad or use default
65
85
  const getInitialRectangle = (0, react_1.useCallback)(() => {
66
86
  if (!document.quad || !imageSize) {
@@ -75,10 +95,8 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
75
95
  return scaled;
76
96
  }, [document.quad, document.width, document.height, imageSize]);
77
97
  const handleImageLoad = (0, react_1.useCallback)((event) => {
78
- const { width, height } = event.nativeEvent.source;
79
- console.log('Image loaded with size:', { width, height });
80
- setImageSize({ width, height });
81
- setIsImageLoading(false);
98
+ // This is just for debugging - actual size is loaded via Image.getSize in useEffect
99
+ console.log('[CropEditor] Image onLoad event triggered');
82
100
  }, []);
83
101
  const handleLayout = (0, react_1.useCallback)((event) => {
84
102
  const { width, height } = event.nativeEvent.layout;
@@ -97,13 +115,12 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
97
115
  };
98
116
  onCropChange?.(rect);
99
117
  }, [imageSize, onCropChange]);
100
- return (react_1.default.createElement(react_native_1.View, { style: styles.container, onLayout: handleLayout },
101
- react_1.default.createElement(react_native_1.Image, { source: { uri: `file://${document.path}` }, style: styles.hiddenImage, onLoad: handleImageLoad, onError: (error) => {
102
- console.error('Image load error:', error);
103
- setIsImageLoading(false);
104
- }, resizeMode: "contain" }),
105
- !imageSize || isImageLoading ? (react_1.default.createElement(react_native_1.View, { style: styles.loadingContainer },
106
- react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: handlerColor }))) : (react_1.default.createElement(react_native_perspective_image_cropper_1.default, { height: displaySize.height, width: displaySize.width, image: `file://${document.path}`, rectangleCoordinates: getInitialRectangle(), overlayColor: overlayColor, overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, enablePanStrict: enablePanStrict, onDragEnd: handleDragEnd }))));
118
+ const imageUri = `file://${document.path}`;
119
+ return (react_1.default.createElement(react_native_1.View, { style: styles.container, onLayout: handleLayout }, loadError ? (react_1.default.createElement(react_native_1.View, { style: styles.errorContainer },
120
+ react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, "Failed to load image"),
121
+ react_1.default.createElement(react_native_1.Text, { style: styles.errorPath }, imageUri))) : !imageSize || isImageLoading ? (react_1.default.createElement(react_native_1.View, { style: styles.loadingContainer },
122
+ react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: handlerColor }),
123
+ react_1.default.createElement(react_native_1.Text, { style: styles.loadingText }, "Loading image..."))) : (react_1.default.createElement(react_native_perspective_image_cropper_1.default, { height: displaySize.height, width: displaySize.width, image: imageUri, rectangleCoordinates: getInitialRectangle(), overlayColor: overlayColor, overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, enablePanStrict: enablePanStrict, onDragEnd: handleDragEnd }))));
107
124
  };
108
125
  exports.CropEditor = CropEditor;
109
126
  const styles = react_native_1.StyleSheet.create({
@@ -112,8 +129,31 @@ const styles = react_native_1.StyleSheet.create({
112
129
  backgroundColor: '#000',
113
130
  },
114
131
  loadingContainer: {
132
+ flex: 1,
133
+ justifyContent: 'center',
134
+ alignItems: 'center',
135
+ },
136
+ loadingText: {
137
+ color: '#fff',
138
+ marginTop: 16,
139
+ fontSize: 16,
140
+ },
141
+ errorContainer: {
142
+ flex: 1,
115
143
  justifyContent: 'center',
116
144
  alignItems: 'center',
145
+ padding: 20,
146
+ },
147
+ errorText: {
148
+ color: '#ff4444',
149
+ fontSize: 18,
150
+ fontWeight: 'bold',
151
+ marginBottom: 10,
152
+ },
153
+ errorPath: {
154
+ color: '#999',
155
+ fontSize: 12,
156
+ textAlign: 'center',
117
157
  },
118
158
  hiddenImage: {
119
159
  width: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "0.52.0",
3
+ "version": "0.54.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {
@@ -1,5 +1,5 @@
1
- import React, { useState, useCallback } from 'react';
2
- import { View, StyleSheet, Image, Dimensions, ActivityIndicator } from 'react-native';
1
+ import React, { useState, useCallback, useEffect } from 'react';
2
+ import { View, StyleSheet, Image, Dimensions, ActivityIndicator, Text } from 'react-native';
3
3
  import CustomImageCropper from 'react-native-perspective-image-cropper';
4
4
  import type { Rectangle as CropperRectangle } from 'react-native-perspective-image-cropper';
5
5
  import type { Point, Rectangle, CapturedDocument } from './types';
@@ -41,6 +41,32 @@ export const CropEditor: React.FC<CropEditorProps> = ({
41
41
  height: Dimensions.get('window').height,
42
42
  });
43
43
  const [isImageLoading, setIsImageLoading] = useState(true);
44
+ const [loadError, setLoadError] = useState<string | null>(null);
45
+
46
+ useEffect(() => {
47
+ console.log('[CropEditor] Document path:', document.path);
48
+ console.log('[CropEditor] Document dimensions:', document.width, 'x', document.height);
49
+ console.log('[CropEditor] Document quad:', document.quad);
50
+
51
+ // Load image size using Image.getSize
52
+ const imageUri = `file://${document.path}`;
53
+ Image.getSize(
54
+ imageUri,
55
+ (width, height) => {
56
+ console.log('[CropEditor] Image.getSize success:', { width, height });
57
+ setImageSize({ width, height });
58
+ setIsImageLoading(false);
59
+ setLoadError(null);
60
+ },
61
+ (error) => {
62
+ console.error('[CropEditor] Image.getSize error:', error);
63
+ // Fallback to document dimensions
64
+ console.log('[CropEditor] Using fallback dimensions:', document.width, 'x', document.height);
65
+ setImageSize({ width: document.width, height: document.height });
66
+ setIsImageLoading(false);
67
+ }
68
+ );
69
+ }, [document]);
44
70
 
45
71
  // Get initial rectangle from detected quad or use default
46
72
  const getInitialRectangle = useCallback((): CropperRectangle | undefined => {
@@ -66,10 +92,8 @@ export const CropEditor: React.FC<CropEditorProps> = ({
66
92
  }, [document.quad, document.width, document.height, imageSize]);
67
93
 
68
94
  const handleImageLoad = useCallback((event: any) => {
69
- const { width, height } = event.nativeEvent.source;
70
- console.log('Image loaded with size:', { width, height });
71
- setImageSize({ width, height });
72
- setIsImageLoading(false);
95
+ // This is just for debugging - actual size is loaded via Image.getSize in useEffect
96
+ console.log('[CropEditor] Image onLoad event triggered');
73
97
  }, []);
74
98
 
75
99
  const handleLayout = useCallback((event: any) => {
@@ -93,30 +117,26 @@ export const CropEditor: React.FC<CropEditorProps> = ({
93
117
  onCropChange?.(rect);
94
118
  }, [imageSize, onCropChange]);
95
119
 
120
+ const imageUri = `file://${document.path}`;
121
+
96
122
  return (
97
123
  <View style={styles.container} onLayout={handleLayout}>
98
- {/* Always load the hidden image to get dimensions */}
99
- <Image
100
- source={{ uri: `file://${document.path}` }}
101
- style={styles.hiddenImage}
102
- onLoad={handleImageLoad}
103
- onError={(error) => {
104
- console.error('Image load error:', error);
105
- setIsImageLoading(false);
106
- }}
107
- resizeMode="contain"
108
- />
109
-
110
- {/* Show loading or cropper */}
111
- {!imageSize || isImageLoading ? (
124
+ {/* Show loading, error, or cropper */}
125
+ {loadError ? (
126
+ <View style={styles.errorContainer}>
127
+ <Text style={styles.errorText}>Failed to load image</Text>
128
+ <Text style={styles.errorPath}>{imageUri}</Text>
129
+ </View>
130
+ ) : !imageSize || isImageLoading ? (
112
131
  <View style={styles.loadingContainer}>
113
132
  <ActivityIndicator size="large" color={handlerColor} />
133
+ <Text style={styles.loadingText}>Loading image...</Text>
114
134
  </View>
115
135
  ) : (
116
136
  <CustomImageCropper
117
137
  height={displaySize.height}
118
138
  width={displaySize.width}
119
- image={`file://${document.path}`}
139
+ image={imageUri}
120
140
  rectangleCoordinates={getInitialRectangle()}
121
141
  overlayColor={overlayColor}
122
142
  overlayStrokeColor={overlayStrokeColor}
@@ -135,9 +155,32 @@ const styles = StyleSheet.create({
135
155
  backgroundColor: '#000',
136
156
  },
137
157
  loadingContainer: {
158
+ flex: 1,
138
159
  justifyContent: 'center',
139
160
  alignItems: 'center',
140
161
  },
162
+ loadingText: {
163
+ color: '#fff',
164
+ marginTop: 16,
165
+ fontSize: 16,
166
+ },
167
+ errorContainer: {
168
+ flex: 1,
169
+ justifyContent: 'center',
170
+ alignItems: 'center',
171
+ padding: 20,
172
+ },
173
+ errorText: {
174
+ color: '#ff4444',
175
+ fontSize: 18,
176
+ fontWeight: 'bold',
177
+ marginBottom: 10,
178
+ },
179
+ errorPath: {
180
+ color: '#999',
181
+ fontSize: 12,
182
+ textAlign: 'center',
183
+ },
141
184
  hiddenImage: {
142
185
  width: 1,
143
186
  height: 1,