@amafil/react-native-pdf-toolkit 1.0.11 → 1.1.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.
@@ -62,6 +62,21 @@ public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManag
62
62
  case "enableDoubleTapZoom":
63
63
  mViewManager.setEnableDoubleTapZoom(view, value == null ? false : (boolean) value);
64
64
  break;
65
+ case "annotations":
66
+ mViewManager.setAnnotations(view, value == null ? null : (String) value);
67
+ break;
68
+ case "annotationMode":
69
+ mViewManager.setAnnotationMode(view, value == null ? false : (boolean) value);
70
+ break;
71
+ case "annotationTool":
72
+ mViewManager.setAnnotationTool(view, value == null ? null : (String) value);
73
+ break;
74
+ case "annotationEditable":
75
+ mViewManager.setAnnotationEditable(view, value == null ? false : (boolean) value);
76
+ break;
77
+ case "annotationIdMode":
78
+ mViewManager.setAnnotationIdMode(view, value == null ? null : (String) value);
79
+ break;
65
80
  case "enableAntialiasing":
66
81
  mViewManager.setEnableAntialiasing(view, value == null ? false : (boolean) value);
67
82
  break;
@@ -87,6 +102,9 @@ public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManag
87
102
  case "setNativePage":
88
103
  mViewManager.setNativePage(view, args.getInt(0));
89
104
  break;
105
+ case "saveAnnotations":
106
+ mViewManager.saveAnnotations(view);
107
+ break;
90
108
  }
91
109
  }
92
110
  }
@@ -26,10 +26,16 @@ public interface RNPDFPdfViewManagerInterface<T extends View> {
26
26
  void setEnableRTL(T view, boolean value);
27
27
  void setEnableAnnotationRendering(T view, boolean value);
28
28
  void setEnableDoubleTapZoom(T view, boolean value);
29
+ void setAnnotations(T view, @Nullable String value);
30
+ void setAnnotationMode(T view, boolean value);
31
+ void setAnnotationTool(T view, @Nullable String value);
32
+ void setAnnotationEditable(T view, boolean value);
33
+ void setAnnotationIdMode(T view, @Nullable String value);
29
34
  void setEnableAntialiasing(T view, boolean value);
30
35
  void setFitPolicy(T view, int value);
31
36
  void setSpacing(T view, int value);
32
37
  void setPassword(T view, @Nullable String value);
33
38
  void setSinglePage(T view, boolean value);
34
39
  void setNativePage(T view, int page);
40
+ void saveAnnotations(T view);
35
41
  }
@@ -30,6 +30,11 @@
30
30
  fitPolicy: ?Int32,
31
31
  spacing: ?Int32,
32
32
  password: ?string,
33
+ annotations: ?string,
34
+ annotationMode: ?boolean,
35
+ annotationTool: ?string,
36
+ annotationEditable: ?boolean,
37
+ annotationIdMode: ?string,
33
38
  onChange: ?BubblingEventHandler<ChangeEvent>,
34
39
  singlePage: ?boolean,
35
40
  |}>;
@@ -47,10 +52,13 @@
47
52
  +stopNativeAutoScroll: (
48
53
  viewRef: React.ElementRef<ComponentType>,
49
54
  ) => void;
55
+ +saveAnnotations: (
56
+ viewRef: React.ElementRef<ComponentType>,
57
+ ) => void;
50
58
  }
51
59
 
52
60
  export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
53
- supportedCommands: ['setNativePage', 'startNativeAutoScroll', 'stopNativeAutoScroll'],
61
+ supportedCommands: ['setNativePage', 'startNativeAutoScroll', 'stopNativeAutoScroll', 'saveAnnotations'],
54
62
  });
55
63
 
56
64
  export default codegenNativeComponent<NativeProps>('RNPDFPdfView');
package/index.d.ts CHANGED
@@ -27,6 +27,68 @@ export type Source = {
27
27
  method?: string;
28
28
  };
29
29
 
30
+ export type AnnotationRotation = 0 | 90 | 180 | 270;
31
+ export type AnnotationIdMode = 'auto' | 'manual';
32
+ export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight' | 'underline' | 'strikeout';
33
+ export type AnnotationTextAlign = 'left' | 'center' | 'right';
34
+
35
+ export type AnnotationPoint = {
36
+ x: number,
37
+ y: number,
38
+ pressure?: number,
39
+ };
40
+
41
+ export type AnnotationBounds = {
42
+ x: number,
43
+ y: number,
44
+ width: number,
45
+ height: number,
46
+ };
47
+
48
+ export type AnnotationStyle = {
49
+ color?: string,
50
+ thickness?: number,
51
+ fontFamily?: string,
52
+ fontSize?: number,
53
+ textAlign?: AnnotationTextAlign,
54
+ rotation?: AnnotationRotation,
55
+ };
56
+
57
+ export type AnnotationBase = {
58
+ id: string,
59
+ page: number,
60
+ locked?: boolean,
61
+ createdAt?: number,
62
+ updatedAt?: number,
63
+ };
64
+
65
+ export type InkAnnotation = AnnotationBase & {
66
+ type: 'ink',
67
+ points: AnnotationPoint[],
68
+ style?: AnnotationStyle,
69
+ };
70
+
71
+ export type TextAnnotation = AnnotationBase & {
72
+ type: 'text',
73
+ bounds: AnnotationBounds,
74
+ text: string,
75
+ style?: AnnotationStyle,
76
+ };
77
+
78
+ export type MarkupAnnotation = AnnotationBase & {
79
+ type: 'highlight' | 'underline' | 'strikeout',
80
+ bounds: AnnotationBounds,
81
+ style?: AnnotationStyle,
82
+ };
83
+
84
+ export type Annotation = InkAnnotation | TextAnnotation | MarkupAnnotation;
85
+
86
+ export type AnnotationDocument = {
87
+ editable?: boolean,
88
+ idMode?: AnnotationIdMode,
89
+ annotations: Annotation[],
90
+ };
91
+
30
92
  export type TextSelectionChangeEvent = {
31
93
  nativeEvent:
32
94
  | {
@@ -58,6 +120,11 @@ export interface PdfProps {
58
120
  enableRTL?: boolean,
59
121
  enableAnnotationRendering?: boolean,
60
122
  enableDoubleTapZoom?: boolean;
123
+ annotations?: AnnotationDocument,
124
+ annotationMode?: boolean,
125
+ annotationTool?: AnnotationTool,
126
+ annotationEditable?: boolean,
127
+ annotationIdMode?: AnnotationIdMode,
61
128
  /**
62
129
  * Only works on iOS. Defaults to `true`.
63
130
  */
@@ -80,11 +147,11 @@ export interface PdfProps {
80
147
  onPressLink?: (url: string) => void,
81
148
  onAutoScrollEnd?: () => void,
82
149
  onTextSelectionChange?: (event: TextSelectionChangeEvent) => void,
83
- onAutoScrollEnd?: () => void,
84
150
  }
85
151
 
86
152
  export interface PdfRef {
87
153
  setPage(pageNumber: number): void
154
+ saveAnnotations(): Promise<AnnotationDocument>
88
155
  /**
89
156
  * Start smooth automatic vertical scrolling using the display refresh rate.
90
157
  * @param dpPerSecond - Scroll speed in density-independent pixels (dp) per second (default: 15). Produces consistent physical speed across screen densities.
package/index.js CHANGED
@@ -57,6 +57,11 @@ export default class Pdf extends Component {
57
57
  fitPolicy: PropTypes.number,
58
58
  trustAllCerts: PropTypes.bool,
59
59
  singlePage: PropTypes.bool,
60
+ annotations: PropTypes.object,
61
+ annotationMode: PropTypes.bool,
62
+ annotationTool: PropTypes.oneOf(['select', 'ink', 'text', 'highlight', 'underline', 'strikeout']),
63
+ annotationEditable: PropTypes.bool,
64
+ annotationIdMode: PropTypes.oneOf(['auto', 'manual']),
60
65
  onLoadComplete: PropTypes.func,
61
66
  onPageChanged: PropTypes.func,
62
67
  onError: PropTypes.func,
@@ -96,6 +101,11 @@ export default class Pdf extends Component {
96
101
  trustAllCerts: true,
97
102
  usePDFKit: true,
98
103
  singlePage: false,
104
+ annotations: null,
105
+ annotationMode: false,
106
+ annotationTool: 'select',
107
+ annotationEditable: true,
108
+ annotationIdMode: 'auto',
99
109
  onLoadProgress: (percent) => {
100
110
  },
101
111
  onLoadComplete: (numberOfPages, path) => {
@@ -127,6 +137,7 @@ export default class Pdf extends Component {
127
137
  };
128
138
 
129
139
  this.lastRNBFTask = null;
140
+ this._annotationSavePromise = null;
130
141
 
131
142
  }
132
143
 
@@ -156,6 +167,10 @@ export default class Pdf extends Component {
156
167
  componentWillUnmount() {
157
168
  this._mounted = false;
158
169
  this.stopAutoScroll();
170
+ if (this._annotationSavePromise) {
171
+ this._annotationSavePromise.reject(new Error('Pdf unmounted before annotation save completed'));
172
+ this._annotationSavePromise = null;
173
+ }
159
174
  if (this.lastRNBFTask) {
160
175
  // this.lastRNBFTask.cancel(err => {
161
176
  // });
@@ -372,6 +387,42 @@ export default class Pdf extends Component {
372
387
 
373
388
  }
374
389
 
390
+ saveAnnotations() {
391
+ if (this._annotationSavePromise) {
392
+ return Promise.reject(new Error('An annotation save is already in progress'));
393
+ }
394
+
395
+ return new Promise((resolve, reject) => {
396
+ if (!this._root) {
397
+ reject(new Error('Pdf is not mounted'));
398
+ return;
399
+ }
400
+
401
+ this._annotationSavePromise = {resolve, reject};
402
+
403
+ if (!!global?.nativeFabricUIManager) {
404
+ if (PdfViewCommands.saveAnnotations) {
405
+ PdfViewCommands.saveAnnotations(this._root);
406
+ } else {
407
+ this._annotationSavePromise = null;
408
+ reject(new Error('Annotation save command is not available'));
409
+ }
410
+ } else {
411
+ const ReactNative = require('react-native');
412
+ try {
413
+ ReactNative.UIManager.dispatchViewManagerCommand(
414
+ ReactNative.findNodeHandle(this._root),
415
+ 'saveAnnotations',
416
+ [],
417
+ );
418
+ } catch (error) {
419
+ this._annotationSavePromise = null;
420
+ reject(error);
421
+ }
422
+ }
423
+ });
424
+ }
425
+
375
426
  startAutoScroll( dpPerSecond = 15, resumeDelay = 3000 ) {
376
427
  this._isAutoScrollActive = true;
377
428
  if (!!global?.nativeFabricUIManager) {
@@ -465,6 +516,27 @@ export default class Pdf extends Component {
465
516
  } else if (message[0] === 'autoScrollEnd') {
466
517
  this._isAutoScrollActive = false;
467
518
  this.props.onAutoScrollEnd && this.props.onAutoScrollEnd();
519
+ } else if (message[0] === 'annotationSaveComplete') {
520
+ message[1] = message.slice(1).join('|');
521
+
522
+ let annotationDocument;
523
+ try {
524
+ annotationDocument = message[1] ? JSON.parse(message[1]) : null;
525
+ } catch (e) {
526
+ annotationDocument = message[1];
527
+ }
528
+
529
+ if (this._annotationSavePromise) {
530
+ this._annotationSavePromise.resolve(annotationDocument);
531
+ this._annotationSavePromise = null;
532
+ }
533
+ } else if (message[0] === 'annotationSaveError') {
534
+ message[1] = message.slice(1).join('|');
535
+
536
+ if (this._annotationSavePromise) {
537
+ this._annotationSavePromise.reject(new Error(message[1] || 'Annotation save failed'));
538
+ this._annotationSavePromise = null;
539
+ }
468
540
  }
469
541
  }
470
542
 
@@ -476,7 +548,22 @@ export default class Pdf extends Component {
476
548
 
477
549
  };
478
550
 
551
+ _getNativeAnnotations = () => {
552
+ if (!this.props.annotations) {
553
+ return null;
554
+ }
555
+
556
+ try {
557
+ return JSON.stringify(this.props.annotations);
558
+ } catch (error) {
559
+ this._onError(error);
560
+ return null;
561
+ }
562
+ };
563
+
479
564
  render() {
565
+ const nativeAnnotations = this._getNativeAnnotations();
566
+
480
567
  if (Platform.OS === "android" || Platform.OS === "ios" || Platform.OS === "windows") {
481
568
  return (
482
569
  <View style={[this.props.style,{overflow: 'hidden'}]}>
@@ -492,6 +579,7 @@ export default class Pdf extends Component {
492
579
  <PdfCustom
493
580
  ref={component => (this._root = component)}
494
581
  {...this.props}
582
+ annotations={nativeAnnotations}
495
583
  style={[{flex:1,backgroundColor: '#EEE'}, this.props.style]}
496
584
  path={this.state.path}
497
585
  onChange={this._onChange}
@@ -501,6 +589,7 @@ export default class Pdf extends Component {
501
589
  <PdfCustom
502
590
  ref={component => (this._root = component)}
503
591
  {...this.props}
592
+ annotations={nativeAnnotations}
504
593
  style={[{backgroundColor: '#EEE',overflow: 'hidden'}, this.props.style]}
505
594
  path={this.state.path}
506
595
  onChange={this._onChange}
package/index.js.flow CHANGED
@@ -24,6 +24,68 @@ export type Source = {
24
24
  uri: string
25
25
  };
26
26
 
27
+ export type AnnotationRotation = 0 | 90 | 180 | 270;
28
+ export type AnnotationIdMode = 'auto' | 'manual';
29
+ export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight' | 'underline' | 'strikeout';
30
+ export type AnnotationTextAlign = 'left' | 'center' | 'right';
31
+
32
+ export type AnnotationPoint = {
33
+ x: number,
34
+ y: number,
35
+ pressure?: number,
36
+ };
37
+
38
+ export type AnnotationBounds = {
39
+ x: number,
40
+ y: number,
41
+ width: number,
42
+ height: number,
43
+ };
44
+
45
+ export type AnnotationStyle = {
46
+ color?: string,
47
+ thickness?: number,
48
+ fontFamily?: string,
49
+ fontSize?: number,
50
+ textAlign?: AnnotationTextAlign,
51
+ rotation?: AnnotationRotation,
52
+ };
53
+
54
+ export type AnnotationBase = {
55
+ id: string,
56
+ page: number,
57
+ locked?: boolean,
58
+ createdAt?: number,
59
+ updatedAt?: number,
60
+ };
61
+
62
+ export type InkAnnotation = AnnotationBase & {
63
+ type: 'ink',
64
+ points: Array<AnnotationPoint>,
65
+ style?: AnnotationStyle,
66
+ };
67
+
68
+ export type TextAnnotation = AnnotationBase & {
69
+ type: 'text',
70
+ bounds: AnnotationBounds,
71
+ text: string,
72
+ style?: AnnotationStyle,
73
+ };
74
+
75
+ export type MarkupAnnotation = AnnotationBase & {
76
+ type: 'highlight' | 'underline' | 'strikeout',
77
+ bounds: AnnotationBounds,
78
+ style?: AnnotationStyle,
79
+ };
80
+
81
+ export type Annotation = InkAnnotation | TextAnnotation | MarkupAnnotation;
82
+
83
+ export type AnnotationDocument = {
84
+ editable?: boolean,
85
+ idMode?: AnnotationIdMode,
86
+ annotations: Array<Annotation>,
87
+ };
88
+
27
89
  export type TableContent = {
28
90
  children: TableContent[],
29
91
  mNativePtr: number,
@@ -33,6 +95,11 @@ export type TableContent = {
33
95
 
34
96
  export type Props = {
35
97
  renderActivityIndicator?: (progress: number) => Node,
98
+ annotations?: AnnotationDocument,
99
+ annotationMode?: boolean,
100
+ annotationTool?: AnnotationTool,
101
+ annotationEditable?: boolean,
102
+ annotationIdMode?: AnnotationIdMode,
36
103
  enableAnnotationRendering?: boolean,
37
104
  enableAntialiasing?: boolean,
38
105
  enablePaging?: boolean,
@@ -64,4 +131,5 @@ export type Props = {
64
131
 
65
132
  declare export default class Pdf extends Component<Props> {
66
133
  setPage: (pageNumber: number) => void;
134
+ saveAnnotations: () => Promise<AnnotationDocument>;
67
135
  }
@@ -49,6 +49,11 @@ UIView
49
49
  @property(nonatomic) BOOL enableRTL;
50
50
  @property(nonatomic) BOOL enableAnnotationRendering;
51
51
  @property(nonatomic) BOOL enableDoubleTapZoom;
52
+ @property(nonatomic, strong) NSString *annotations;
53
+ @property(nonatomic) BOOL annotationMode;
54
+ @property(nonatomic, strong) NSString *annotationTool;
55
+ @property(nonatomic) BOOL annotationEditable;
56
+ @property(nonatomic, strong) NSString *annotationIdMode;
52
57
  @property(nonatomic) int fitPolicy;
53
58
  @property(nonatomic) int spacing;
54
59
  @property(nonatomic, strong) NSString *password;
@@ -56,6 +61,8 @@ UIView
56
61
 
57
62
  @property(nonatomic, copy) RCTBubblingEventBlock onChange;
58
63
 
64
+ - (void)saveAnnotations;
65
+
59
66
  @property(nonatomic, strong) NSString *selectedText;
60
67
  @property(nonatomic) BOOL enableTextSelection;
61
68
  @property(nonatomic, strong) PDFSelection *currentPDFSelection;