react-native-rectangle-doc-scanner 3.36.0 → 3.38.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.
@@ -32,14 +32,10 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.CropEditor = void 0;
40
37
  const react_1 = __importStar(require("react"));
41
38
  const react_native_1 = require("react-native");
42
- const react_native_perspective_image_cropper_1 = __importDefault(require("react-native-perspective-image-cropper"));
43
39
  const coordinate_1 = require("./utils/coordinate");
44
40
  /**
45
41
  * CropEditor Component
@@ -117,12 +113,25 @@ const CropEditor = ({ document, overlayColor = 'rgba(0,0,0,0.5)', overlayStrokeC
117
113
  };
118
114
  onCropChange?.(rect);
119
115
  }, [imageSize, onCropChange]);
120
- const imageUri = `file://${document.path}`;
116
+ // Ensure proper file URI format
117
+ const imageUri = document.path.startsWith('file://')
118
+ ? document.path
119
+ : `file://${document.path}`;
120
+ const initialRect = getInitialRectangle();
121
+ console.log('[CropEditor] Rendering with:', {
122
+ imageUri,
123
+ imageSize,
124
+ displaySize,
125
+ initialRect,
126
+ isLoading: isImageLoading,
127
+ hasError: !!loadError,
128
+ });
121
129
  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 },
122
130
  react_1.default.createElement(react_native_1.Text, { style: styles.errorText }, "Failed to load image"),
123
131
  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 },
124
132
  react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: handlerColor }),
125
- 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 }))));
133
+ react_1.default.createElement(react_native_1.Text, { style: styles.loadingText }, "Loading image..."))) : (react_1.default.createElement(react_1.default.Fragment, null,
134
+ react_1.default.createElement(react_native_1.Image, { source: { uri: imageUri }, style: styles.fullImage, resizeMode: "contain", onLoad: () => console.log('[CropEditor] Image loaded successfully'), onError: (e) => console.error('[CropEditor] Image load error:', e.nativeEvent.error) })))));
126
135
  };
127
136
  exports.CropEditor = CropEditor;
128
137
  const styles = react_native_1.StyleSheet.create({
@@ -157,10 +166,8 @@ const styles = react_native_1.StyleSheet.create({
157
166
  fontSize: 12,
158
167
  textAlign: 'center',
159
168
  },
160
- hiddenImage: {
161
- width: 1,
162
- height: 1,
163
- opacity: 0,
164
- position: 'absolute',
169
+ fullImage: {
170
+ width: '100%',
171
+ height: '100%',
165
172
  },
166
173
  });
@@ -69,13 +69,13 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
69
69
  const processingCaptureRef = (0, react_1.useRef)(false);
70
70
  const cropInitializedRef = (0, react_1.useRef)(false);
71
71
  const mergedStrings = (0, react_1.useMemo)(() => ({
72
- captureHint: strings?.captureHint ?? 'Align the document within the frame.',
73
- manualHint: strings?.manualHint ?? 'Tap the button below to capture.',
74
- cancel: strings?.cancel ?? 'Cancel',
75
- confirm: strings?.confirm ?? 'Use photo',
76
- retake: strings?.retake ?? 'Retake',
77
- cropTitle: strings?.cropTitle ?? 'Adjust the corners',
78
- processing: strings?.processing ?? 'Processing…',
72
+ captureHint: strings?.captureHint ?? '',
73
+ manualHint: strings?.manualHint ?? '',
74
+ cancel: strings?.cancel ?? '',
75
+ confirm: strings?.confirm ?? '',
76
+ retake: strings?.retake ?? '',
77
+ cropTitle: strings?.cropTitle ?? '',
78
+ processing: strings?.processing ?? '',
79
79
  }), [strings]);
80
80
  (0, react_1.useEffect)(() => {
81
81
  if (!capturedDoc) {
@@ -224,20 +224,25 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
224
224
  console.log('[FullDocScanner] Already processing, skipping manual capture');
225
225
  return;
226
226
  }
227
+ // Reset DocScanner state before capturing
228
+ docScannerRef.current?.reset();
227
229
  console.log('[FullDocScanner] Setting manualCapturePending to true');
228
230
  manualCapturePending.current = true;
229
- const capturePromise = docScannerRef.current?.capture();
230
- console.log('[FullDocScanner] capturePromise:', !!capturePromise);
231
- if (capturePromise && typeof capturePromise.catch === 'function') {
232
- capturePromise.catch((error) => {
231
+ // Small delay to ensure reset completes
232
+ setTimeout(() => {
233
+ const capturePromise = docScannerRef.current?.capture();
234
+ console.log('[FullDocScanner] capturePromise:', !!capturePromise);
235
+ if (capturePromise && typeof capturePromise.catch === 'function') {
236
+ capturePromise.catch((error) => {
237
+ manualCapturePending.current = false;
238
+ console.warn('[FullDocScanner] manual capture failed', error);
239
+ });
240
+ }
241
+ else if (!capturePromise) {
242
+ console.warn('[FullDocScanner] No capture promise returned');
233
243
  manualCapturePending.current = false;
234
- console.warn('[FullDocScanner] manual capture failed', error);
235
- });
236
- }
237
- else if (!capturePromise) {
238
- console.warn('[FullDocScanner] No capture promise returned');
239
- manualCapturePending.current = false;
240
- }
244
+ }
245
+ }, 100);
241
246
  }, []);
242
247
  const performCrop = (0, react_1.useCallback)(async () => {
243
248
  if (!capturedDoc) {
@@ -315,24 +320,24 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
315
320
  return (react_1.default.createElement(react_native_1.View, { style: styles.container },
316
321
  screen === 'scanner' && (react_1.default.createElement(react_native_1.View, { style: styles.flex },
317
322
  react_1.default.createElement(DocScanner_1.DocScanner, { ref: docScannerRef, autoCapture: !manualCapture, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture, showManualCaptureButton: false },
318
- react_1.default.createElement(react_native_1.View, { style: styles.overlay, pointerEvents: "box-none" },
323
+ react_1.default.createElement(react_native_1.View, { style: styles.overlayTop, pointerEvents: "box-none" },
319
324
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.closeButton, onPress: handleClose, accessibilityLabel: mergedStrings.cancel, accessibilityRole: "button" },
320
- react_1.default.createElement(react_native_1.Text, { style: styles.closeButtonLabel }, "\u00D7")),
321
- react_1.default.createElement(react_native_1.View, { style: styles.instructions, pointerEvents: "none" },
322
- react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.captureHint),
323
- react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.manualHint)),
325
+ react_1.default.createElement(react_native_1.Text, { style: styles.closeButtonLabel }, "\u00D7"))),
326
+ (mergedStrings.captureHint || mergedStrings.manualHint) && (react_1.default.createElement(react_native_1.View, { style: styles.instructionsContainer, pointerEvents: "none" },
327
+ react_1.default.createElement(react_native_1.View, { style: styles.instructions },
328
+ mergedStrings.captureHint && (react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.captureHint)),
329
+ mergedStrings.manualHint && (react_1.default.createElement(react_native_1.Text, { style: styles.captureText }, mergedStrings.manualHint))))),
330
+ react_1.default.createElement(react_native_1.View, { style: styles.shutterContainer, pointerEvents: "box-none" },
324
331
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.shutterButton, processing && styles.shutterButtonDisabled], onPress: triggerManualCapture, disabled: processing, accessibilityLabel: mergedStrings.manualHint, accessibilityRole: "button" },
325
332
  react_1.default.createElement(react_native_1.View, { style: styles.shutterInner })))))),
326
333
  screen === 'crop' && capturedDoc && (react_1.default.createElement(react_native_1.View, { style: styles.flex },
327
334
  react_1.default.createElement(CropEditor_1.CropEditor, { document: capturedDoc, overlayColor: "rgba(0,0,0,0.6)", overlayStrokeColor: overlayStrokeColor, handlerColor: handlerColor, onCropChange: handleCropChange }),
328
335
  react_1.default.createElement(react_native_1.View, { style: styles.cropFooter },
329
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.secondaryButton], onPress: handleRetake },
330
- react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.retake)),
331
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.primaryButton], onPress: handleConfirm },
332
- react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.confirm))))),
336
+ react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.secondaryButton], onPress: handleRetake }, mergedStrings.retake && react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.retake)),
337
+ react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.actionButton, styles.primaryButton], onPress: handleConfirm }, mergedStrings.confirm && react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, mergedStrings.confirm))))),
333
338
  processing && (react_1.default.createElement(react_native_1.View, { style: styles.processingOverlay },
334
339
  react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: overlayStrokeColor }),
335
- react_1.default.createElement(react_native_1.Text, { style: styles.processingText }, mergedStrings.processing)))));
340
+ mergedStrings.processing && (react_1.default.createElement(react_native_1.Text, { style: styles.processingText }, mergedStrings.processing))))));
336
341
  };
337
342
  exports.FullDocScanner = FullDocScanner;
338
343
  const styles = react_native_1.StyleSheet.create({
@@ -343,12 +348,27 @@ const styles = react_native_1.StyleSheet.create({
343
348
  flex: {
344
349
  flex: 1,
345
350
  },
346
- overlay: {
347
- ...react_native_1.StyleSheet.absoluteFillObject,
348
- justifyContent: 'space-between',
349
- paddingTop: 48,
350
- paddingBottom: 64,
351
- paddingHorizontal: 24,
351
+ overlayTop: {
352
+ position: 'absolute',
353
+ top: 48,
354
+ right: 24,
355
+ zIndex: 10,
356
+ },
357
+ instructionsContainer: {
358
+ position: 'absolute',
359
+ top: '40%',
360
+ left: 0,
361
+ right: 0,
362
+ alignItems: 'center',
363
+ zIndex: 5,
364
+ },
365
+ shutterContainer: {
366
+ position: 'absolute',
367
+ bottom: 64,
368
+ left: 0,
369
+ right: 0,
370
+ alignItems: 'center',
371
+ zIndex: 10,
352
372
  },
353
373
  closeButton: {
354
374
  width: 40,
@@ -357,7 +377,6 @@ const styles = react_native_1.StyleSheet.create({
357
377
  backgroundColor: 'rgba(0,0,0,0.5)',
358
378
  justifyContent: 'center',
359
379
  alignItems: 'center',
360
- alignSelf: 'flex-end',
361
380
  },
362
381
  closeButtonLabel: {
363
382
  color: '#fff',
@@ -366,7 +385,6 @@ const styles = react_native_1.StyleSheet.create({
366
385
  marginTop: -3,
367
386
  },
368
387
  instructions: {
369
- alignSelf: 'center',
370
388
  backgroundColor: 'rgba(0,0,0,0.55)',
371
389
  borderRadius: 16,
372
390
  paddingHorizontal: 20,
@@ -378,7 +396,6 @@ const styles = react_native_1.StyleSheet.create({
378
396
  textAlign: 'center',
379
397
  },
380
398
  shutterButton: {
381
- alignSelf: 'center',
382
399
  width: 80,
383
400
  height: 80,
384
401
  borderRadius: 40,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.36.0",
3
+ "version": "3.38.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/danchew90/react-native-rectangle-doc-scanner.git"
10
+ "url": "git+https://github.com/danchew90/react-native-rectangle-doc-scanner.git"
11
11
  },
12
12
  "homepage": "https://github.com/danchew90/react-native-rectangle-doc-scanner",
13
13
  "bugs": {
@@ -120,7 +120,21 @@ export const CropEditor: React.FC<CropEditorProps> = ({
120
120
  onCropChange?.(rect);
121
121
  }, [imageSize, onCropChange]);
122
122
 
123
- const imageUri = `file://${document.path}`;
123
+ // Ensure proper file URI format
124
+ const imageUri = document.path.startsWith('file://')
125
+ ? document.path
126
+ : `file://${document.path}`;
127
+
128
+ const initialRect = getInitialRectangle();
129
+
130
+ console.log('[CropEditor] Rendering with:', {
131
+ imageUri,
132
+ imageSize,
133
+ displaySize,
134
+ initialRect,
135
+ isLoading: isImageLoading,
136
+ hasError: !!loadError,
137
+ });
124
138
 
125
139
  return (
126
140
  <View style={styles.container} onLayout={handleLayout}>
@@ -136,17 +150,28 @@ export const CropEditor: React.FC<CropEditorProps> = ({
136
150
  <Text style={styles.loadingText}>Loading image...</Text>
137
151
  </View>
138
152
  ) : (
139
- <CustomImageCropper
140
- height={displaySize.height}
141
- width={displaySize.width}
142
- image={imageUri}
143
- rectangleCoordinates={getInitialRectangle()}
144
- overlayColor={overlayColor}
145
- overlayStrokeColor={overlayStrokeColor}
146
- handlerColor={handlerColor}
147
- enablePanStrict={enablePanStrict}
148
- onDragEnd={handleDragEnd}
149
- />
153
+ <>
154
+ {/* Full screen image */}
155
+ <Image
156
+ source={{ uri: imageUri }}
157
+ style={styles.fullImage}
158
+ resizeMode="contain"
159
+ onLoad={() => console.log('[CropEditor] Image loaded successfully')}
160
+ onError={(e) => console.error('[CropEditor] Image load error:', e.nativeEvent.error)}
161
+ />
162
+ {/* Temporarily disabled CustomImageCropper - showing image only */}
163
+ {/* <CustomImageCropper
164
+ height={displaySize.height}
165
+ width={displaySize.width}
166
+ image={imageUri}
167
+ rectangleCoordinates={initialRect}
168
+ overlayColor={overlayColor}
169
+ overlayStrokeColor={overlayStrokeColor}
170
+ handlerColor={handlerColor}
171
+ enablePanStrict={enablePanStrict}
172
+ onDragEnd={handleDragEnd}
173
+ /> */}
174
+ </>
150
175
  )}
151
176
  </View>
152
177
  );
@@ -184,10 +209,8 @@ const styles = StyleSheet.create({
184
209
  fontSize: 12,
185
210
  textAlign: 'center',
186
211
  },
187
- hiddenImage: {
188
- width: 1,
189
- height: 1,
190
- opacity: 0,
191
- position: 'absolute',
212
+ fullImage: {
213
+ width: '100%',
214
+ height: '100%',
192
215
  },
193
216
  });
@@ -122,15 +122,15 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
122
122
  const processingCaptureRef = useRef(false);
123
123
  const cropInitializedRef = useRef(false);
124
124
 
125
- const mergedStrings = useMemo<Required<FullDocScannerStrings>>(
125
+ const mergedStrings = useMemo(
126
126
  () => ({
127
- captureHint: strings?.captureHint ?? 'Align the document within the frame.',
128
- manualHint: strings?.manualHint ?? 'Tap the button below to capture.',
129
- cancel: strings?.cancel ?? 'Cancel',
130
- confirm: strings?.confirm ?? 'Use photo',
131
- retake: strings?.retake ?? 'Retake',
132
- cropTitle: strings?.cropTitle ?? 'Adjust the corners',
133
- processing: strings?.processing ?? 'Processing…',
127
+ captureHint: strings?.captureHint ?? '',
128
+ manualHint: strings?.manualHint ?? '',
129
+ cancel: strings?.cancel ?? '',
130
+ confirm: strings?.confirm ?? '',
131
+ retake: strings?.retake ?? '',
132
+ cropTitle: strings?.cropTitle ?? '',
133
+ processing: strings?.processing ?? '',
134
134
  }),
135
135
  [strings],
136
136
  );
@@ -347,19 +347,27 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
347
347
  console.log('[FullDocScanner] Already processing, skipping manual capture');
348
348
  return;
349
349
  }
350
+
351
+ // Reset DocScanner state before capturing
352
+ docScannerRef.current?.reset();
353
+
350
354
  console.log('[FullDocScanner] Setting manualCapturePending to true');
351
355
  manualCapturePending.current = true;
352
- const capturePromise = docScannerRef.current?.capture();
353
- console.log('[FullDocScanner] capturePromise:', !!capturePromise);
354
- if (capturePromise && typeof capturePromise.catch === 'function') {
355
- capturePromise.catch((error: unknown) => {
356
+
357
+ // Small delay to ensure reset completes
358
+ setTimeout(() => {
359
+ const capturePromise = docScannerRef.current?.capture();
360
+ console.log('[FullDocScanner] capturePromise:', !!capturePromise);
361
+ if (capturePromise && typeof capturePromise.catch === 'function') {
362
+ capturePromise.catch((error: unknown) => {
363
+ manualCapturePending.current = false;
364
+ console.warn('[FullDocScanner] manual capture failed', error);
365
+ });
366
+ } else if (!capturePromise) {
367
+ console.warn('[FullDocScanner] No capture promise returned');
356
368
  manualCapturePending.current = false;
357
- console.warn('[FullDocScanner] manual capture failed', error);
358
- });
359
- } else if (!capturePromise) {
360
- console.warn('[FullDocScanner] No capture promise returned');
361
- manualCapturePending.current = false;
362
- }
369
+ }
370
+ }, 100);
363
371
  }, []);
364
372
 
365
373
  const performCrop = useCallback(async (): Promise<{ base64: string; rectangle: Rectangle }> => {
@@ -479,7 +487,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
479
487
  onCapture={handleCapture}
480
488
  showManualCaptureButton={false}
481
489
  >
482
- <View style={styles.overlay} pointerEvents="box-none">
490
+ <View style={styles.overlayTop} pointerEvents="box-none">
483
491
  <TouchableOpacity
484
492
  style={styles.closeButton}
485
493
  onPress={handleClose}
@@ -488,10 +496,20 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
488
496
  >
489
497
  <Text style={styles.closeButtonLabel}>×</Text>
490
498
  </TouchableOpacity>
491
- <View style={styles.instructions} pointerEvents="none">
492
- <Text style={styles.captureText}>{mergedStrings.captureHint}</Text>
493
- <Text style={styles.captureText}>{mergedStrings.manualHint}</Text>
499
+ </View>
500
+ {(mergedStrings.captureHint || mergedStrings.manualHint) && (
501
+ <View style={styles.instructionsContainer} pointerEvents="none">
502
+ <View style={styles.instructions}>
503
+ {mergedStrings.captureHint && (
504
+ <Text style={styles.captureText}>{mergedStrings.captureHint}</Text>
505
+ )}
506
+ {mergedStrings.manualHint && (
507
+ <Text style={styles.captureText}>{mergedStrings.manualHint}</Text>
508
+ )}
509
+ </View>
494
510
  </View>
511
+ )}
512
+ <View style={styles.shutterContainer} pointerEvents="box-none">
495
513
  <TouchableOpacity
496
514
  style={[styles.shutterButton, processing && styles.shutterButtonDisabled]}
497
515
  onPress={triggerManualCapture}
@@ -517,10 +535,10 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
517
535
  />
518
536
  <View style={styles.cropFooter}>
519
537
  <TouchableOpacity style={[styles.actionButton, styles.secondaryButton]} onPress={handleRetake}>
520
- <Text style={styles.buttonText}>{mergedStrings.retake}</Text>
538
+ {mergedStrings.retake && <Text style={styles.buttonText}>{mergedStrings.retake}</Text>}
521
539
  </TouchableOpacity>
522
540
  <TouchableOpacity style={[styles.actionButton, styles.primaryButton]} onPress={handleConfirm}>
523
- <Text style={styles.buttonText}>{mergedStrings.confirm}</Text>
541
+ {mergedStrings.confirm && <Text style={styles.buttonText}>{mergedStrings.confirm}</Text>}
524
542
  </TouchableOpacity>
525
543
  </View>
526
544
  </View>
@@ -529,7 +547,9 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
529
547
  {processing && (
530
548
  <View style={styles.processingOverlay}>
531
549
  <ActivityIndicator size="large" color={overlayStrokeColor} />
532
- <Text style={styles.processingText}>{mergedStrings.processing}</Text>
550
+ {mergedStrings.processing && (
551
+ <Text style={styles.processingText}>{mergedStrings.processing}</Text>
552
+ )}
533
553
  </View>
534
554
  )}
535
555
  </View>
@@ -544,12 +564,27 @@ const styles = StyleSheet.create({
544
564
  flex: {
545
565
  flex: 1,
546
566
  },
547
- overlay: {
548
- ...StyleSheet.absoluteFillObject,
549
- justifyContent: 'space-between',
550
- paddingTop: 48,
551
- paddingBottom: 64,
552
- paddingHorizontal: 24,
567
+ overlayTop: {
568
+ position: 'absolute',
569
+ top: 48,
570
+ right: 24,
571
+ zIndex: 10,
572
+ },
573
+ instructionsContainer: {
574
+ position: 'absolute',
575
+ top: '40%',
576
+ left: 0,
577
+ right: 0,
578
+ alignItems: 'center',
579
+ zIndex: 5,
580
+ },
581
+ shutterContainer: {
582
+ position: 'absolute',
583
+ bottom: 64,
584
+ left: 0,
585
+ right: 0,
586
+ alignItems: 'center',
587
+ zIndex: 10,
553
588
  },
554
589
  closeButton: {
555
590
  width: 40,
@@ -558,7 +593,6 @@ const styles = StyleSheet.create({
558
593
  backgroundColor: 'rgba(0,0,0,0.5)',
559
594
  justifyContent: 'center',
560
595
  alignItems: 'center',
561
- alignSelf: 'flex-end',
562
596
  },
563
597
  closeButtonLabel: {
564
598
  color: '#fff',
@@ -567,7 +601,6 @@ const styles = StyleSheet.create({
567
601
  marginTop: -3,
568
602
  },
569
603
  instructions: {
570
- alignSelf: 'center',
571
604
  backgroundColor: 'rgba(0,0,0,0.55)',
572
605
  borderRadius: 16,
573
606
  paddingHorizontal: 20,
@@ -579,7 +612,6 @@ const styles = StyleSheet.create({
579
612
  textAlign: 'center',
580
613
  },
581
614
  shutterButton: {
582
- alignSelf: 'center',
583
615
  width: 80,
584
616
  height: 80,
585
617
  borderRadius: 40,