@amafil/react-native-pdf-toolkit 1.1.0 → 1.1.1
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.
- package/README.md +57 -0
- package/android/src/main/java/org/wonday/pdf/PdfManager.java +24 -0
- package/android/src/main/java/org/wonday/pdf/PdfView.java +80 -49
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java +12 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java +4 -0
- package/annotationDocumentUtils.js +74 -0
- package/fabric/RNPDFPdfNativeComponent.js +9 -1
- package/index.d.ts +36 -2
- package/index.js +42 -21
- package/index.js.flow +6 -2
- package/ios/RNPDFPdf/RNPDFPdfView.h +4 -0
- package/ios/RNPDFPdf/RNPDFPdfView.mm +107 -61
- package/ios/RNPDFPdf/RNPDFPdfViewManager.mm +22 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -13,6 +13,63 @@ A react native PDF view component (cross-platform support)
|
|
|
13
13
|
* support password protected pdf
|
|
14
14
|
* jump to a specific page in the pdf
|
|
15
15
|
* auto scroll with configurable speed (ideal for music sheets)
|
|
16
|
+
* annotate pages with ink, text, and highlight tools
|
|
17
|
+
|
|
18
|
+
### Annotation editing
|
|
19
|
+
|
|
20
|
+
The component accepts an annotation document through the `annotations` prop together with `annotationMode`, `annotationTool`, `annotationEditable`, and `annotationIdMode`. Ink defaults can be controlled with `annotationInkColor` and `annotationInkThickness`.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
const annotations = {
|
|
24
|
+
editable: true,
|
|
25
|
+
idMode: 'auto',
|
|
26
|
+
annotations: [
|
|
27
|
+
{
|
|
28
|
+
id: 'note-1',
|
|
29
|
+
page: 1,
|
|
30
|
+
type: 'text',
|
|
31
|
+
bounds: {x: 0.15, y: 0.24, width: 0.28, height: 0.12},
|
|
32
|
+
text: 'Reminder for page one',
|
|
33
|
+
style: {color: '#2244aa', fontSize: 15, textAlign: 'left'},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'stroke-1',
|
|
37
|
+
page: 2,
|
|
38
|
+
type: 'ink',
|
|
39
|
+
points: [
|
|
40
|
+
{x: 0.12, y: 0.18},
|
|
41
|
+
{x: 0.26, y: 0.22},
|
|
42
|
+
{x: 0.34, y: 0.19},
|
|
43
|
+
],
|
|
44
|
+
style: {color: '#111111', thickness: 2},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
<Pdf
|
|
50
|
+
ref={pdfRef}
|
|
51
|
+
source={source}
|
|
52
|
+
annotations={annotations}
|
|
53
|
+
annotationMode
|
|
54
|
+
annotationTool="ink"
|
|
55
|
+
annotationInkColor="#1d4ed8"
|
|
56
|
+
annotationInkThickness={4}
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Supported tools are `select`, `ink`, `text`, and `highlight`.
|
|
61
|
+
|
|
62
|
+
In `select` mode, tap an annotation to select it, drag to move it, and use the resize handle to resize text and highlight annotations. Deletion is host-controlled: call `pdfRef.current.deleteSelectedAnnotation()` or `pdfRef.current.deleteAllAnnotations()` from your own UI.
|
|
63
|
+
|
|
64
|
+
Call `await pdfRef.current.saveAnnotations()` to receive the current document back from native as `{ editable, idMode, annotations }`.
|
|
65
|
+
|
|
66
|
+
Legacy `underline` and `strikeout` annotations are normalized to `highlight` when loading and saving.
|
|
67
|
+
|
|
68
|
+
Notes:
|
|
69
|
+
|
|
70
|
+
* Editing currently targets the default vertical viewer flow.
|
|
71
|
+
* Android editing is disabled when `horizontal`, `enablePaging`, `enableRTL`, or `singlePage` are enabled.
|
|
72
|
+
* iOS editing uses PDFKit when `usePDFKit` is true.
|
|
16
73
|
|
|
17
74
|
### Supported versions
|
|
18
75
|
We use [`react-native-blob-util`](https://github.com/RonRadtke/react-native-blob-util) to handle file system access in this package,
|
|
@@ -164,6 +164,16 @@ public class PdfManager extends SimpleViewManager<PdfView> implements RNPDFPdfVi
|
|
|
164
164
|
pdfView.setAnnotationIdMode(annotationIdMode);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
@ReactProp(name = "annotationInkColor")
|
|
168
|
+
public void setAnnotationInkColor(PdfView pdfView, @Nullable String annotationInkColor) {
|
|
169
|
+
pdfView.setAnnotationInkColor(annotationInkColor);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@ReactProp(name = "annotationInkThickness")
|
|
173
|
+
public void setAnnotationInkThickness(PdfView pdfView, float annotationInkThickness) {
|
|
174
|
+
pdfView.setAnnotationInkThickness(annotationInkThickness);
|
|
175
|
+
}
|
|
176
|
+
|
|
167
177
|
@ReactProp(name = "enablePaging")
|
|
168
178
|
public void setEnablePaging(PdfView pdfView, boolean enablePaging) {
|
|
169
179
|
pdfView.setEnablePaging(enablePaging);
|
|
@@ -211,6 +221,10 @@ public class PdfManager extends SimpleViewManager<PdfView> implements RNPDFPdfVi
|
|
|
211
221
|
stopNativeAutoScroll(root);
|
|
212
222
|
} else if ("saveAnnotations".equals(commandId)) {
|
|
213
223
|
saveAnnotations(root);
|
|
224
|
+
} else if ("deleteSelectedAnnotation".equals(commandId)) {
|
|
225
|
+
deleteSelectedAnnotation(root);
|
|
226
|
+
} else if ("deleteAllAnnotations".equals(commandId)) {
|
|
227
|
+
deleteAllAnnotations(root);
|
|
214
228
|
}
|
|
215
229
|
}
|
|
216
230
|
|
|
@@ -219,6 +233,16 @@ public class PdfManager extends SimpleViewManager<PdfView> implements RNPDFPdfVi
|
|
|
219
233
|
view.saveAnnotations();
|
|
220
234
|
}
|
|
221
235
|
|
|
236
|
+
@Override
|
|
237
|
+
public void deleteSelectedAnnotation(PdfView view) {
|
|
238
|
+
view.deleteSelectedAnnotation();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@Override
|
|
242
|
+
public void deleteAllAnnotations(PdfView view) {
|
|
243
|
+
view.deleteAllAnnotations();
|
|
244
|
+
}
|
|
245
|
+
|
|
222
246
|
@Override
|
|
223
247
|
public void onAfterUpdateTransaction(PdfView pdfView) {
|
|
224
248
|
super.onAfterUpdateTransaction(pdfView);
|
|
@@ -97,6 +97,8 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
97
97
|
private String annotationTool = "select";
|
|
98
98
|
private boolean annotationEditable = true;
|
|
99
99
|
private String annotationIdMode = "auto";
|
|
100
|
+
private String annotationInkColor = "#111111";
|
|
101
|
+
private float annotationInkThickness = 2f;
|
|
100
102
|
private AnnotationOverlayView annotationOverlayView;
|
|
101
103
|
|
|
102
104
|
private boolean enablePaging = false;
|
|
@@ -494,6 +496,16 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
494
496
|
updateAnnotationOverlayConfig();
|
|
495
497
|
}
|
|
496
498
|
|
|
499
|
+
public void setAnnotationInkColor(String annotationInkColor) {
|
|
500
|
+
this.annotationInkColor = TextUtils.isEmpty(annotationInkColor) ? "#111111" : annotationInkColor;
|
|
501
|
+
updateAnnotationOverlayConfig();
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
public void setAnnotationInkThickness(float annotationInkThickness) {
|
|
505
|
+
this.annotationInkThickness = annotationInkThickness > 0f ? annotationInkThickness : 2f;
|
|
506
|
+
updateAnnotationOverlayConfig();
|
|
507
|
+
}
|
|
508
|
+
|
|
497
509
|
public void setPath(String path) {
|
|
498
510
|
this.path = path;
|
|
499
511
|
}
|
|
@@ -594,7 +606,9 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
594
606
|
this.annotationTool,
|
|
595
607
|
this.annotationEditable,
|
|
596
608
|
this.annotationIdMode,
|
|
597
|
-
isAnnotationEditingSupported()
|
|
609
|
+
isAnnotationEditingSupported(),
|
|
610
|
+
this.annotationInkColor,
|
|
611
|
+
this.annotationInkThickness
|
|
598
612
|
);
|
|
599
613
|
}
|
|
600
614
|
}
|
|
@@ -622,6 +636,8 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
622
636
|
private boolean editable = true;
|
|
623
637
|
private String idMode = "auto";
|
|
624
638
|
private boolean supported = true;
|
|
639
|
+
private String inkColor = "#111111";
|
|
640
|
+
private float inkThickness = 2f;
|
|
625
641
|
|
|
626
642
|
AnnotationOverlayView(Context context) {
|
|
627
643
|
super(context);
|
|
@@ -631,12 +647,14 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
631
647
|
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
|
632
648
|
}
|
|
633
649
|
|
|
634
|
-
void setConfiguration(boolean annotationMode, String annotationTool, boolean annotationEditable, String annotationIdMode, boolean annotationEditingSupported) {
|
|
650
|
+
void setConfiguration(boolean annotationMode, String annotationTool, boolean annotationEditable, String annotationIdMode, boolean annotationEditingSupported, String annotationInkColor, float annotationInkThickness) {
|
|
635
651
|
annotationModeEnabled = annotationMode;
|
|
636
|
-
tool = annotationTool == null ? "select" : annotationTool;
|
|
652
|
+
tool = normalizeAnnotationType(annotationTool == null ? "select" : annotationTool);
|
|
637
653
|
editable = annotationEditable;
|
|
638
654
|
idMode = annotationIdMode == null ? "auto" : annotationIdMode;
|
|
639
655
|
supported = annotationEditingSupported;
|
|
656
|
+
inkColor = TextUtils.isEmpty(annotationInkColor) ? "#111111" : annotationInkColor;
|
|
657
|
+
inkThickness = annotationInkThickness > 0f ? annotationInkThickness : 2f;
|
|
640
658
|
|
|
641
659
|
if (!annotationModeEnabled || !editable || !supported) {
|
|
642
660
|
commitTextEditingIfNeeded();
|
|
@@ -649,6 +667,21 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
649
667
|
invalidate();
|
|
650
668
|
}
|
|
651
669
|
|
|
670
|
+
void deleteSelectedAnnotation() {
|
|
671
|
+
JSONObject selectedAnnotation = getSelectedAnnotation();
|
|
672
|
+
if (selectedAnnotation != null) {
|
|
673
|
+
deleteAnnotation(selectedAnnotation);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
void deleteAllAnnotations() {
|
|
678
|
+
commitTextEditingIfNeeded();
|
|
679
|
+
draftAnnotations.clear();
|
|
680
|
+
selectedAnnotationId = null;
|
|
681
|
+
clearSelectionInteraction();
|
|
682
|
+
invalidate();
|
|
683
|
+
}
|
|
684
|
+
|
|
652
685
|
void replaceAnnotations(String json) {
|
|
653
686
|
draftAnnotations.clear();
|
|
654
687
|
clearSelectionInteraction();
|
|
@@ -677,6 +710,10 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
677
710
|
}
|
|
678
711
|
|
|
679
712
|
JSONObject annotation = new JSONObject(source.toString());
|
|
713
|
+
String type = normalizeAnnotationType(annotation.optString("type", null));
|
|
714
|
+
if (!TextUtils.isEmpty(type)) {
|
|
715
|
+
annotation.put("type", type);
|
|
716
|
+
}
|
|
680
717
|
if (!annotation.has("id")) {
|
|
681
718
|
annotation.put("id", nextLocalAnnotationId());
|
|
682
719
|
}
|
|
@@ -764,7 +801,7 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
764
801
|
endInk();
|
|
765
802
|
return true;
|
|
766
803
|
}
|
|
767
|
-
} else if ("highlight".equals(currentTool)
|
|
804
|
+
} else if ("highlight".equals(currentTool)) {
|
|
768
805
|
if (action == MotionEvent.ACTION_DOWN) {
|
|
769
806
|
AnnotationHit hit = hitTest(event.getX(), event.getY());
|
|
770
807
|
if (hit == null) {
|
|
@@ -813,7 +850,7 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
813
850
|
continue;
|
|
814
851
|
}
|
|
815
852
|
|
|
816
|
-
String type = annotation.optString("type", "");
|
|
853
|
+
String type = normalizeAnnotationType(annotation.optString("type", ""));
|
|
817
854
|
RectF rect = viewRectForAnnotation(annotation, pageIndex);
|
|
818
855
|
if (rect == null && !"ink".equals(type)) {
|
|
819
856
|
continue;
|
|
@@ -864,17 +901,9 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
864
901
|
textPaint.setTextAlign(Paint.Align.LEFT);
|
|
865
902
|
String text = annotation.optString("text", "");
|
|
866
903
|
canvas.drawText(text, rect.left + 8f, rect.top + Math.max(20f, textPaint.getTextSize() + 6f), textPaint);
|
|
867
|
-
} else if ("highlight".equals(type)
|
|
904
|
+
} else if ("highlight".equals(type)) {
|
|
868
905
|
fillPaint.setColor(annotationColor(annotation, annotationFillColor(type)));
|
|
869
906
|
canvas.drawRect(rect, fillPaint);
|
|
870
|
-
|
|
871
|
-
if ("underline".equals(type) || "strikeout".equals(type)) {
|
|
872
|
-
strokePaint.setStyle(Paint.Style.STROKE);
|
|
873
|
-
strokePaint.setStrokeWidth(Math.max(1f, rect.height() * 0.15f));
|
|
874
|
-
strokePaint.setColor(annotationColor(annotation, annotationFillColor(type)));
|
|
875
|
-
float y = "underline".equals(type) ? rect.bottom - 2f : rect.centerY();
|
|
876
|
-
canvas.drawLine(rect.left, y, rect.right, y, strokePaint);
|
|
877
|
-
}
|
|
878
907
|
}
|
|
879
908
|
}
|
|
880
909
|
|
|
@@ -895,7 +924,7 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
895
924
|
selectAnnotation(hit.annotation);
|
|
896
925
|
activeSelectionAnnotation = hit.annotation;
|
|
897
926
|
activeSelectionHandle = hit.hitPart;
|
|
898
|
-
activeSelectionMode = "
|
|
927
|
+
activeSelectionMode = "resize".equals(hit.hitPart) ? "resize" : "move";
|
|
899
928
|
activeSelectionPageIndex = hit.pageIndex;
|
|
900
929
|
activeSelectionStartBounds = normalizedBoundsForAnnotation(hit.annotation);
|
|
901
930
|
activeSelectionStartPoints = copyPointsForAnnotation(hit.annotation);
|
|
@@ -903,12 +932,6 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
903
932
|
activeSelectionDownY = event.getY();
|
|
904
933
|
activeSelectionHasMoved = false;
|
|
905
934
|
|
|
906
|
-
if ("delete".equals(activeSelectionMode)) {
|
|
907
|
-
deleteAnnotation(hit.annotation);
|
|
908
|
-
clearSelectionInteraction();
|
|
909
|
-
return true;
|
|
910
|
-
}
|
|
911
|
-
|
|
912
935
|
return true;
|
|
913
936
|
}
|
|
914
937
|
|
|
@@ -972,13 +995,11 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
972
995
|
|
|
973
996
|
canvas.drawRoundRect(rect, 4f, 4f, outlinePaint);
|
|
974
997
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
fillPaint.setColor(Color.argb(235, 34, 68, 170));
|
|
981
|
-
canvas.drawRoundRect(resizeHandle, 2f, 2f, fillPaint);
|
|
998
|
+
if (annotationSupportsResize(annotation)) {
|
|
999
|
+
RectF resizeHandle = resizeHandleRect(rect);
|
|
1000
|
+
fillPaint.setColor(Color.argb(235, 34, 68, 170));
|
|
1001
|
+
canvas.drawRoundRect(resizeHandle, 2f, 2f, fillPaint);
|
|
1002
|
+
}
|
|
982
1003
|
}
|
|
983
1004
|
|
|
984
1005
|
private void clearSelectionInteraction() {
|
|
@@ -1212,11 +1233,6 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1212
1233
|
}
|
|
1213
1234
|
}
|
|
1214
1235
|
|
|
1215
|
-
private RectF deleteHandleRect(RectF rect) {
|
|
1216
|
-
float size = Math.max(18f, Math.min(rect.width(), rect.height()) * 0.18f);
|
|
1217
|
-
return new RectF(rect.right - size, rect.top - size, rect.right, rect.top);
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
1236
|
private RectF resizeHandleRect(RectF rect) {
|
|
1221
1237
|
float size = Math.max(18f, Math.min(rect.width(), rect.height()) * 0.18f);
|
|
1222
1238
|
return new RectF(rect.right - size, rect.bottom - size, rect.right, rect.bottom);
|
|
@@ -1246,12 +1262,8 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1246
1262
|
}
|
|
1247
1263
|
|
|
1248
1264
|
String hitPart = "body";
|
|
1249
|
-
if (includeHandles && selectedAnnotationId != null && selectedAnnotationId.equals(annotation.optString("id", null))) {
|
|
1250
|
-
|
|
1251
|
-
hitPart = "delete";
|
|
1252
|
-
} else if (resizeHandleRect(rect).contains(x, y)) {
|
|
1253
|
-
hitPart = "resize";
|
|
1254
|
-
}
|
|
1265
|
+
if (includeHandles && selectedAnnotationId != null && selectedAnnotationId.equals(annotation.optString("id", null)) && annotationSupportsResize(annotation) && resizeHandleRect(rect).contains(x, y)) {
|
|
1266
|
+
hitPart = "resize";
|
|
1255
1267
|
}
|
|
1256
1268
|
|
|
1257
1269
|
return new AnnotationSelectionHit(annotation, pageIndex, rect, hitPart);
|
|
@@ -1282,8 +1294,8 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1282
1294
|
annotation.put("type", "ink");
|
|
1283
1295
|
annotation.put("points", new JSONArray());
|
|
1284
1296
|
JSONObject style = new JSONObject();
|
|
1285
|
-
style.put("color",
|
|
1286
|
-
style.put("thickness",
|
|
1297
|
+
style.put("color", inkColor);
|
|
1298
|
+
style.put("thickness", inkThickness);
|
|
1287
1299
|
annotation.put("style", style);
|
|
1288
1300
|
draftAnnotations.add(annotation);
|
|
1289
1301
|
activeInkAnnotation = annotation;
|
|
@@ -1325,7 +1337,7 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1325
1337
|
JSONObject annotation = new JSONObject();
|
|
1326
1338
|
annotation.put("id", nextLocalAnnotationId());
|
|
1327
1339
|
annotation.put("page", hit.pageIndex + 1);
|
|
1328
|
-
annotation.put("type", type);
|
|
1340
|
+
annotation.put("type", normalizeAnnotationType(type));
|
|
1329
1341
|
annotation.put("bounds", new JSONObject().put("x", markupStartNormalized.x).put("y", markupStartNormalized.y).put("width", 0).put("height", 0));
|
|
1330
1342
|
annotation.put("style", new JSONObject());
|
|
1331
1343
|
draftAnnotations.add(annotation);
|
|
@@ -1590,6 +1602,19 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1590
1602
|
return style == null ? new JSONObject() : style;
|
|
1591
1603
|
}
|
|
1592
1604
|
|
|
1605
|
+
private String normalizeAnnotationType(String type) {
|
|
1606
|
+
if ("underline".equals(type) || "strikeout".equals(type)) {
|
|
1607
|
+
return "highlight";
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
return type;
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
private boolean annotationSupportsResize(JSONObject annotation) {
|
|
1614
|
+
String type = normalizeAnnotationType(annotation.optString("type", ""));
|
|
1615
|
+
return "text".equals(type) || "highlight".equals(type);
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1593
1618
|
private int annotationColor(JSONObject annotation, int fallback) {
|
|
1594
1619
|
String color = styleFor(annotation).optString("color", null);
|
|
1595
1620
|
if (TextUtils.isEmpty(color)) {
|
|
@@ -1604,15 +1629,9 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1604
1629
|
}
|
|
1605
1630
|
|
|
1606
1631
|
private int annotationFillColor(String type) {
|
|
1607
|
-
if ("highlight".equals(type)) {
|
|
1632
|
+
if ("highlight".equals(type) || "underline".equals(type) || "strikeout".equals(type)) {
|
|
1608
1633
|
return Color.argb(90, 255, 230, 60);
|
|
1609
1634
|
}
|
|
1610
|
-
if ("underline".equals(type)) {
|
|
1611
|
-
return Color.argb(120, 50, 120, 255);
|
|
1612
|
-
}
|
|
1613
|
-
if ("strikeout".equals(type)) {
|
|
1614
|
-
return Color.argb(120, 255, 50, 50);
|
|
1615
|
-
}
|
|
1616
1635
|
|
|
1617
1636
|
return Color.BLACK;
|
|
1618
1637
|
}
|
|
@@ -1700,6 +1719,18 @@ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompl
|
|
|
1700
1719
|
notifyOnChangeWithMessage("annotationSaveError|Annotation overlay unavailable");
|
|
1701
1720
|
}
|
|
1702
1721
|
|
|
1722
|
+
public void deleteSelectedAnnotation() {
|
|
1723
|
+
if (annotationOverlayView != null) {
|
|
1724
|
+
annotationOverlayView.deleteSelectedAnnotation();
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
public void deleteAllAnnotations() {
|
|
1729
|
+
if (annotationOverlayView != null) {
|
|
1730
|
+
annotationOverlayView.deleteAllAnnotations();
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1703
1734
|
private void showLog(final String str) {
|
|
1704
1735
|
Log.d("PdfView", str);
|
|
1705
1736
|
}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java
CHANGED
|
@@ -77,6 +77,12 @@ public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManag
|
|
|
77
77
|
case "annotationIdMode":
|
|
78
78
|
mViewManager.setAnnotationIdMode(view, value == null ? null : (String) value);
|
|
79
79
|
break;
|
|
80
|
+
case "annotationInkColor":
|
|
81
|
+
mViewManager.setAnnotationInkColor(view, value == null ? null : (String) value);
|
|
82
|
+
break;
|
|
83
|
+
case "annotationInkThickness":
|
|
84
|
+
mViewManager.setAnnotationInkThickness(view, value == null ? 0f : ((Double) value).floatValue());
|
|
85
|
+
break;
|
|
80
86
|
case "enableAntialiasing":
|
|
81
87
|
mViewManager.setEnableAntialiasing(view, value == null ? false : (boolean) value);
|
|
82
88
|
break;
|
|
@@ -105,6 +111,12 @@ public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManag
|
|
|
105
111
|
case "saveAnnotations":
|
|
106
112
|
mViewManager.saveAnnotations(view);
|
|
107
113
|
break;
|
|
114
|
+
case "deleteSelectedAnnotation":
|
|
115
|
+
mViewManager.deleteSelectedAnnotation(view);
|
|
116
|
+
break;
|
|
117
|
+
case "deleteAllAnnotations":
|
|
118
|
+
mViewManager.deleteAllAnnotations(view);
|
|
119
|
+
break;
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
}
|
package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java
CHANGED
|
@@ -31,6 +31,8 @@ public interface RNPDFPdfViewManagerInterface<T extends View> {
|
|
|
31
31
|
void setAnnotationTool(T view, @Nullable String value);
|
|
32
32
|
void setAnnotationEditable(T view, boolean value);
|
|
33
33
|
void setAnnotationIdMode(T view, @Nullable String value);
|
|
34
|
+
void setAnnotationInkColor(T view, @Nullable String value);
|
|
35
|
+
void setAnnotationInkThickness(T view, float value);
|
|
34
36
|
void setEnableAntialiasing(T view, boolean value);
|
|
35
37
|
void setFitPolicy(T view, int value);
|
|
36
38
|
void setSpacing(T view, int value);
|
|
@@ -38,4 +40,6 @@ public interface RNPDFPdfViewManagerInterface<T extends View> {
|
|
|
38
40
|
void setSinglePage(T view, boolean value);
|
|
39
41
|
void setNativePage(T view, int page);
|
|
40
42
|
void saveAnnotations(T view);
|
|
43
|
+
void deleteSelectedAnnotation(T view);
|
|
44
|
+
void deleteAllAnnotations(T view);
|
|
41
45
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const LEGACY_MARKUP_TYPES = new Set(['underline', 'strikeout']);
|
|
4
|
+
|
|
5
|
+
export function normalizeAnnotation(annotation) {
|
|
6
|
+
if (!annotation || typeof annotation !== 'object' || Array.isArray(annotation)) {
|
|
7
|
+
return annotation;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!LEGACY_MARKUP_TYPES.has(annotation.type)) {
|
|
11
|
+
return annotation;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
...annotation,
|
|
16
|
+
type: 'highlight',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function normalizeAnnotationPayload(payload) {
|
|
21
|
+
if (!payload || typeof payload !== 'object') {
|
|
22
|
+
return payload;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (Array.isArray(payload)) {
|
|
26
|
+
return payload.map(normalizeAnnotation);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!Array.isArray(payload.annotations)) {
|
|
30
|
+
return payload;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
...payload,
|
|
35
|
+
annotations: payload.annotations.map(normalizeAnnotation),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function joinAnnotationMessagePayload(messageParts, startIndex = 1) {
|
|
40
|
+
if (!Array.isArray(messageParts) || messageParts.length <= startIndex) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return messageParts.slice(startIndex).join('|');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function parseAnnotationMessagePayload(messageParts, startIndex = 1) {
|
|
48
|
+
const payload = joinAnnotationMessagePayload(messageParts, startIndex);
|
|
49
|
+
|
|
50
|
+
if (!payload) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
return normalizeAnnotationPayload(JSON.parse(payload));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return payload;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function stringifyAnnotationDocument(document, onError) {
|
|
62
|
+
if (!document) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
return JSON.stringify(normalizeAnnotationPayload(document));
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (onError) {
|
|
70
|
+
onError(error);
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
annotationTool: ?string,
|
|
36
36
|
annotationEditable: ?boolean,
|
|
37
37
|
annotationIdMode: ?string,
|
|
38
|
+
annotationInkColor: ?string,
|
|
39
|
+
annotationInkThickness: ?Float,
|
|
38
40
|
onChange: ?BubblingEventHandler<ChangeEvent>,
|
|
39
41
|
singlePage: ?boolean,
|
|
40
42
|
|}>;
|
|
@@ -55,10 +57,16 @@
|
|
|
55
57
|
+saveAnnotations: (
|
|
56
58
|
viewRef: React.ElementRef<ComponentType>,
|
|
57
59
|
) => void;
|
|
60
|
+
+deleteSelectedAnnotation: (
|
|
61
|
+
viewRef: React.ElementRef<ComponentType>,
|
|
62
|
+
) => void;
|
|
63
|
+
+deleteAllAnnotations: (
|
|
64
|
+
viewRef: React.ElementRef<ComponentType>,
|
|
65
|
+
) => void;
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
61
|
-
supportedCommands: ['setNativePage', 'startNativeAutoScroll', 'stopNativeAutoScroll', 'saveAnnotations'],
|
|
69
|
+
supportedCommands: ['setNativePage', 'startNativeAutoScroll', 'stopNativeAutoScroll', 'saveAnnotations', 'deleteSelectedAnnotation', 'deleteAllAnnotations'],
|
|
62
70
|
});
|
|
63
71
|
|
|
64
72
|
export default codegenNativeComponent<NativeProps>('RNPDFPdfView');
|
package/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type Source = {
|
|
|
29
29
|
|
|
30
30
|
export type AnnotationRotation = 0 | 90 | 180 | 270;
|
|
31
31
|
export type AnnotationIdMode = 'auto' | 'manual';
|
|
32
|
-
export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight'
|
|
32
|
+
export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight';
|
|
33
33
|
export type AnnotationTextAlign = 'left' | 'center' | 'right';
|
|
34
34
|
|
|
35
35
|
export type AnnotationPoint = {
|
|
@@ -76,7 +76,7 @@ export type TextAnnotation = AnnotationBase & {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
export type MarkupAnnotation = AnnotationBase & {
|
|
79
|
-
type: 'highlight'
|
|
79
|
+
type: 'highlight',
|
|
80
80
|
bounds: AnnotationBounds,
|
|
81
81
|
style?: AnnotationStyle,
|
|
82
82
|
};
|
|
@@ -120,11 +120,34 @@ export interface PdfProps {
|
|
|
120
120
|
enableRTL?: boolean,
|
|
121
121
|
enableAnnotationRendering?: boolean,
|
|
122
122
|
enableDoubleTapZoom?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Initial annotation document to render in the overlay.
|
|
125
|
+
*/
|
|
123
126
|
annotations?: AnnotationDocument,
|
|
127
|
+
/**
|
|
128
|
+
* Enable annotation editing mode.
|
|
129
|
+
*/
|
|
124
130
|
annotationMode?: boolean,
|
|
131
|
+
/**
|
|
132
|
+
* Active tool used while annotation editing is enabled.
|
|
133
|
+
*/
|
|
125
134
|
annotationTool?: AnnotationTool,
|
|
135
|
+
/**
|
|
136
|
+
* Allow in-place annotation edits.
|
|
137
|
+
*/
|
|
126
138
|
annotationEditable?: boolean,
|
|
139
|
+
/**
|
|
140
|
+
* Controls how annotation IDs are generated and preserved.
|
|
141
|
+
*/
|
|
127
142
|
annotationIdMode?: AnnotationIdMode,
|
|
143
|
+
/**
|
|
144
|
+
* Default color applied to newly created ink annotations.
|
|
145
|
+
*/
|
|
146
|
+
annotationInkColor?: string,
|
|
147
|
+
/**
|
|
148
|
+
* Default thickness applied to newly created ink annotations.
|
|
149
|
+
*/
|
|
150
|
+
annotationInkThickness?: number,
|
|
128
151
|
/**
|
|
129
152
|
* Only works on iOS. Defaults to `true`.
|
|
130
153
|
*/
|
|
@@ -151,7 +174,18 @@ export interface PdfProps {
|
|
|
151
174
|
|
|
152
175
|
export interface PdfRef {
|
|
153
176
|
setPage(pageNumber: number): void
|
|
177
|
+
/**
|
|
178
|
+
* Resolves with the current annotation document serialized by native code.
|
|
179
|
+
*/
|
|
154
180
|
saveAnnotations(): Promise<AnnotationDocument>
|
|
181
|
+
/**
|
|
182
|
+
* Deletes the currently selected custom annotation.
|
|
183
|
+
*/
|
|
184
|
+
deleteSelectedAnnotation(): void
|
|
185
|
+
/**
|
|
186
|
+
* Deletes all custom annotations in the current overlay draft.
|
|
187
|
+
*/
|
|
188
|
+
deleteAllAnnotations(): void
|
|
155
189
|
/**
|
|
156
190
|
* Start smooth automatic vertical scrolling using the display refresh rate.
|
|
157
191
|
* @param dpPerSecond - Scroll speed in density-independent pixels (dp) per second (default: 15). Produces consistent physical speed across screen densities.
|
package/index.js
CHANGED
|
@@ -23,6 +23,11 @@ import PdfViewNativeComponent, {
|
|
|
23
23
|
import ReactNativeBlobUtil from 'react-native-blob-util'
|
|
24
24
|
import {ViewPropTypes} from 'deprecated-react-native-prop-types';
|
|
25
25
|
const SHA1 = require('crypto-js/sha1');
|
|
26
|
+
import {
|
|
27
|
+
joinAnnotationMessagePayload,
|
|
28
|
+
parseAnnotationMessagePayload,
|
|
29
|
+
stringifyAnnotationDocument,
|
|
30
|
+
} from './annotationDocumentUtils';
|
|
26
31
|
import PdfView from './PdfView';
|
|
27
32
|
|
|
28
33
|
export default class Pdf extends Component {
|
|
@@ -59,9 +64,11 @@ export default class Pdf extends Component {
|
|
|
59
64
|
singlePage: PropTypes.bool,
|
|
60
65
|
annotations: PropTypes.object,
|
|
61
66
|
annotationMode: PropTypes.bool,
|
|
62
|
-
annotationTool: PropTypes.oneOf(['select', 'ink', 'text', 'highlight'
|
|
67
|
+
annotationTool: PropTypes.oneOf(['select', 'ink', 'text', 'highlight']),
|
|
63
68
|
annotationEditable: PropTypes.bool,
|
|
64
69
|
annotationIdMode: PropTypes.oneOf(['auto', 'manual']),
|
|
70
|
+
annotationInkColor: PropTypes.string,
|
|
71
|
+
annotationInkThickness: PropTypes.number,
|
|
65
72
|
onLoadComplete: PropTypes.func,
|
|
66
73
|
onPageChanged: PropTypes.func,
|
|
67
74
|
onError: PropTypes.func,
|
|
@@ -106,6 +113,8 @@ export default class Pdf extends Component {
|
|
|
106
113
|
annotationTool: 'select',
|
|
107
114
|
annotationEditable: true,
|
|
108
115
|
annotationIdMode: 'auto',
|
|
116
|
+
annotationInkColor: '#111111',
|
|
117
|
+
annotationInkThickness: 2,
|
|
109
118
|
onLoadProgress: (percent) => {
|
|
110
119
|
},
|
|
111
120
|
onLoadComplete: (numberOfPages, path) => {
|
|
@@ -423,6 +432,34 @@ export default class Pdf extends Component {
|
|
|
423
432
|
});
|
|
424
433
|
}
|
|
425
434
|
|
|
435
|
+
deleteSelectedAnnotation() {
|
|
436
|
+
this._dispatchAnnotationCommand('deleteSelectedAnnotation', PdfViewCommands.deleteSelectedAnnotation);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
deleteAllAnnotations() {
|
|
440
|
+
this._dispatchAnnotationCommand('deleteAllAnnotations', PdfViewCommands.deleteAllAnnotations);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
_dispatchAnnotationCommand(commandName, fabricCommand) {
|
|
444
|
+
if (!this._root) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (!!global?.nativeFabricUIManager) {
|
|
449
|
+
if (fabricCommand) {
|
|
450
|
+
fabricCommand(this._root);
|
|
451
|
+
}
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const ReactNative = require('react-native');
|
|
456
|
+
ReactNative.UIManager.dispatchViewManagerCommand(
|
|
457
|
+
ReactNative.findNodeHandle(this._root),
|
|
458
|
+
commandName,
|
|
459
|
+
[],
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
426
463
|
startAutoScroll( dpPerSecond = 15, resumeDelay = 3000 ) {
|
|
427
464
|
this._isAutoScrollActive = true;
|
|
428
465
|
if (!!global?.nativeFabricUIManager) {
|
|
@@ -517,24 +554,17 @@ export default class Pdf extends Component {
|
|
|
517
554
|
this._isAutoScrollActive = false;
|
|
518
555
|
this.props.onAutoScrollEnd && this.props.onAutoScrollEnd();
|
|
519
556
|
} else if (message[0] === 'annotationSaveComplete') {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
let annotationDocument;
|
|
523
|
-
try {
|
|
524
|
-
annotationDocument = message[1] ? JSON.parse(message[1]) : null;
|
|
525
|
-
} catch (e) {
|
|
526
|
-
annotationDocument = message[1];
|
|
527
|
-
}
|
|
557
|
+
const annotationDocument = parseAnnotationMessagePayload(message);
|
|
528
558
|
|
|
529
559
|
if (this._annotationSavePromise) {
|
|
530
560
|
this._annotationSavePromise.resolve(annotationDocument);
|
|
531
561
|
this._annotationSavePromise = null;
|
|
532
562
|
}
|
|
533
563
|
} else if (message[0] === 'annotationSaveError') {
|
|
534
|
-
|
|
564
|
+
const annotationError = joinAnnotationMessagePayload(message);
|
|
535
565
|
|
|
536
566
|
if (this._annotationSavePromise) {
|
|
537
|
-
this._annotationSavePromise.reject(new Error(
|
|
567
|
+
this._annotationSavePromise.reject(new Error(annotationError || 'Annotation save failed'));
|
|
538
568
|
this._annotationSavePromise = null;
|
|
539
569
|
}
|
|
540
570
|
}
|
|
@@ -549,16 +579,7 @@ export default class Pdf extends Component {
|
|
|
549
579
|
};
|
|
550
580
|
|
|
551
581
|
_getNativeAnnotations = () => {
|
|
552
|
-
|
|
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
|
-
}
|
|
582
|
+
return stringifyAnnotationDocument(this.props.annotations, this._onError);
|
|
562
583
|
};
|
|
563
584
|
|
|
564
585
|
render() {
|
package/index.js.flow
CHANGED
|
@@ -26,7 +26,7 @@ export type Source = {
|
|
|
26
26
|
|
|
27
27
|
export type AnnotationRotation = 0 | 90 | 180 | 270;
|
|
28
28
|
export type AnnotationIdMode = 'auto' | 'manual';
|
|
29
|
-
export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight'
|
|
29
|
+
export type AnnotationTool = 'select' | 'ink' | 'text' | 'highlight';
|
|
30
30
|
export type AnnotationTextAlign = 'left' | 'center' | 'right';
|
|
31
31
|
|
|
32
32
|
export type AnnotationPoint = {
|
|
@@ -73,7 +73,7 @@ export type TextAnnotation = AnnotationBase & {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
export type MarkupAnnotation = AnnotationBase & {
|
|
76
|
-
type: 'highlight'
|
|
76
|
+
type: 'highlight',
|
|
77
77
|
bounds: AnnotationBounds,
|
|
78
78
|
style?: AnnotationStyle,
|
|
79
79
|
};
|
|
@@ -100,6 +100,8 @@ export type Props = {
|
|
|
100
100
|
annotationTool?: AnnotationTool,
|
|
101
101
|
annotationEditable?: boolean,
|
|
102
102
|
annotationIdMode?: AnnotationIdMode,
|
|
103
|
+
annotationInkColor?: string,
|
|
104
|
+
annotationInkThickness?: number,
|
|
103
105
|
enableAnnotationRendering?: boolean,
|
|
104
106
|
enableAntialiasing?: boolean,
|
|
105
107
|
enablePaging?: boolean,
|
|
@@ -132,4 +134,6 @@ export type Props = {
|
|
|
132
134
|
declare export default class Pdf extends Component<Props> {
|
|
133
135
|
setPage: (pageNumber: number) => void;
|
|
134
136
|
saveAnnotations: () => Promise<AnnotationDocument>;
|
|
137
|
+
deleteSelectedAnnotation: () => void;
|
|
138
|
+
deleteAllAnnotations: () => void;
|
|
135
139
|
}
|
|
@@ -54,6 +54,8 @@ UIView
|
|
|
54
54
|
@property(nonatomic, strong) NSString *annotationTool;
|
|
55
55
|
@property(nonatomic) BOOL annotationEditable;
|
|
56
56
|
@property(nonatomic, strong) NSString *annotationIdMode;
|
|
57
|
+
@property(nonatomic, strong) NSString *annotationInkColor;
|
|
58
|
+
@property(nonatomic) float annotationInkThickness;
|
|
57
59
|
@property(nonatomic) int fitPolicy;
|
|
58
60
|
@property(nonatomic) int spacing;
|
|
59
61
|
@property(nonatomic, strong) NSString *password;
|
|
@@ -62,6 +64,8 @@ UIView
|
|
|
62
64
|
@property(nonatomic, copy) RCTBubblingEventBlock onChange;
|
|
63
65
|
|
|
64
66
|
- (void)saveAnnotations;
|
|
67
|
+
- (void)deleteSelectedAnnotation;
|
|
68
|
+
- (void)deleteAllAnnotations;
|
|
65
69
|
|
|
66
70
|
@property(nonatomic, strong) NSString *selectedText;
|
|
67
71
|
@property(nonatomic) BOOL enableTextSelection;
|
|
@@ -63,9 +63,12 @@ const float MIN_SCALE = 1.0f;
|
|
|
63
63
|
@property(nonatomic, assign) BOOL annotationEditable;
|
|
64
64
|
@property(nonatomic, copy) NSString *annotationTool;
|
|
65
65
|
@property(nonatomic, copy) NSString *annotationIdMode;
|
|
66
|
+
@property(nonatomic, copy) NSString *annotationInkColor;
|
|
67
|
+
@property(nonatomic, assign) CGFloat annotationInkThickness;
|
|
66
68
|
|
|
67
69
|
- (void)replaceAnnotationsJSONString:(NSString *)json editable:(BOOL)editable idMode:(NSString *)idMode;
|
|
68
70
|
- (void)setAnnotationMode:(BOOL)annotationMode tool:(NSString *)tool editable:(BOOL)editable idMode:(NSString *)idMode;
|
|
71
|
+
- (void)setInkDefaultsColor:(NSString *)color thickness:(CGFloat)thickness;
|
|
69
72
|
- (void)beginInkAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
|
|
70
73
|
- (void)appendInkPointAtViewPoint:(CGPoint)viewPoint page:(PDFPage *)page;
|
|
71
74
|
- (void)endInk;
|
|
@@ -77,6 +80,8 @@ const float MIN_SCALE = 1.0f;
|
|
|
77
80
|
- (void)selectAnnotation:(NSDictionary *)annotation;
|
|
78
81
|
- (void)clearSelection;
|
|
79
82
|
- (void)deleteAnnotation:(NSDictionary *)annotation;
|
|
83
|
+
- (void)deleteSelectedAnnotation;
|
|
84
|
+
- (void)deleteAllAnnotations;
|
|
80
85
|
- (void)beginSelectionInteractionAtPoint:(CGPoint)point hit:(NSDictionary *)hit;
|
|
81
86
|
- (void)updateSelectionInteractionAtPoint:(CGPoint)point;
|
|
82
87
|
- (void)endSelectionInteraction;
|
|
@@ -209,6 +214,14 @@ using namespace facebook::react;
|
|
|
209
214
|
_annotationIdMode = RCTNSStringFromStringNilIfEmpty(newProps.annotationIdMode);
|
|
210
215
|
[updatedPropNames addObject:@"annotationIdMode"];
|
|
211
216
|
}
|
|
217
|
+
if (_annotationInkColor != RCTNSStringFromStringNilIfEmpty(newProps.annotationInkColor)) {
|
|
218
|
+
_annotationInkColor = RCTNSStringFromStringNilIfEmpty(newProps.annotationInkColor);
|
|
219
|
+
[updatedPropNames addObject:@"annotationInkColor"];
|
|
220
|
+
}
|
|
221
|
+
if (_annotationInkThickness != newProps.annotationInkThickness) {
|
|
222
|
+
_annotationInkThickness = newProps.annotationInkThickness;
|
|
223
|
+
[updatedPropNames addObject:@"annotationInkThickness"];
|
|
224
|
+
}
|
|
212
225
|
if (_fitPolicy != newProps.fitPolicy) {
|
|
213
226
|
_fitPolicy = newProps.fitPolicy;
|
|
214
227
|
[updatedPropNames addObject:@"fitPolicy"];
|
|
@@ -245,6 +258,7 @@ using namespace facebook::react;
|
|
|
245
258
|
if (_annotationOverlay) {
|
|
246
259
|
[_annotationOverlay replaceAnnotationsJSONString:_annotations editable:_annotationEditable idMode:_annotationIdMode];
|
|
247
260
|
[_annotationOverlay setAnnotationMode:_annotationMode tool:_annotationTool editable:_annotationEditable idMode:_annotationIdMode];
|
|
261
|
+
[_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
|
|
248
262
|
_annotationOverlay.pdfView = _pdfView;
|
|
249
263
|
_annotationOverlay.pdfDocument = _pdfDocument;
|
|
250
264
|
}
|
|
@@ -353,6 +367,8 @@ using namespace facebook::react;
|
|
|
353
367
|
_showsHorizontalScrollIndicator = YES;
|
|
354
368
|
_showsVerticalScrollIndicator = YES;
|
|
355
369
|
_scrollEnabled = YES;
|
|
370
|
+
_annotationInkColor = @"#111111";
|
|
371
|
+
_annotationInkThickness = 2.0f;
|
|
356
372
|
_enableTextSelection = YES;
|
|
357
373
|
_selectedText = nil;
|
|
358
374
|
_currentPDFSelection = nil;
|
|
@@ -383,6 +399,7 @@ using namespace facebook::react;
|
|
|
383
399
|
_annotationOverlay.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
384
400
|
_annotationOverlay.backgroundColor = UIColor.clearColor;
|
|
385
401
|
_annotationOverlay.userInteractionEnabled = YES;
|
|
402
|
+
[_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
|
|
386
403
|
[self addSubview:_annotationOverlay];
|
|
387
404
|
[self bringSubviewToFront:_annotationOverlay];
|
|
388
405
|
|
|
@@ -672,6 +689,14 @@ using namespace facebook::react;
|
|
|
672
689
|
}
|
|
673
690
|
}
|
|
674
691
|
|
|
692
|
+
if (_annotationOverlay) {
|
|
693
|
+
[_annotationOverlay replaceAnnotationsJSONString:_annotations editable:_annotationEditable idMode:_annotationIdMode];
|
|
694
|
+
[_annotationOverlay setAnnotationMode:_annotationMode tool:_annotationTool editable:_annotationEditable idMode:_annotationIdMode];
|
|
695
|
+
[_annotationOverlay setInkDefaultsColor:_annotationInkColor thickness:_annotationInkThickness];
|
|
696
|
+
_annotationOverlay.pdfView = _pdfView;
|
|
697
|
+
_annotationOverlay.pdfDocument = _pdfDocument;
|
|
698
|
+
}
|
|
699
|
+
|
|
675
700
|
_pdfView.backgroundColor = [UIColor clearColor];
|
|
676
701
|
[_pdfView layoutDocumentView];
|
|
677
702
|
[self setNeedsDisplay];
|
|
@@ -960,12 +985,7 @@ using namespace facebook::react;
|
|
|
960
985
|
NSDictionary *hit = [_annotationOverlay annotationSelectionHitAtPoint:point includeHandles:YES];
|
|
961
986
|
if (hit) {
|
|
962
987
|
NSDictionary *annotation = hit[@"annotation"];
|
|
963
|
-
|
|
964
|
-
if ([hitPart isEqualToString:@"delete"]) {
|
|
965
|
-
[_annotationOverlay deleteAnnotation:annotation];
|
|
966
|
-
} else {
|
|
967
|
-
[_annotationOverlay selectAnnotation:annotation];
|
|
968
|
-
}
|
|
988
|
+
[_annotationOverlay selectAnnotation:annotation];
|
|
969
989
|
|
|
970
990
|
return;
|
|
971
991
|
}
|
|
@@ -1032,14 +1052,7 @@ using namespace facebook::react;
|
|
|
1032
1052
|
return;
|
|
1033
1053
|
}
|
|
1034
1054
|
|
|
1035
|
-
|
|
1036
|
-
NSString *hitPart = hit[@"hitPart"];
|
|
1037
|
-
if ([hitPart isEqualToString:@"delete"]) {
|
|
1038
|
-
[_annotationOverlay deleteAnnotation:annotation];
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
[_annotationOverlay selectAnnotation:annotation];
|
|
1055
|
+
[_annotationOverlay selectAnnotation:hit[@"annotation"]];
|
|
1043
1056
|
[_annotationOverlay beginSelectionInteractionAtPoint:point hit:hit];
|
|
1044
1057
|
} else if (sender.state == UIGestureRecognizerStateChanged) {
|
|
1045
1058
|
[_annotationOverlay updateSelectionInteractionAtPoint:point];
|
|
@@ -1052,19 +1065,19 @@ using namespace facebook::react;
|
|
|
1052
1065
|
if (sender.state == UIGestureRecognizerStateBegan) {
|
|
1053
1066
|
if ([_annotationTool isEqualToString:@"ink"]) {
|
|
1054
1067
|
[_annotationOverlay beginInkAtViewPoint:point page:pdfPage];
|
|
1055
|
-
} else if ([
|
|
1068
|
+
} else if ([_annotationTool isEqualToString:@"highlight"]) {
|
|
1056
1069
|
[_annotationOverlay beginMarkupAtViewPoint:point page:pdfPage type:_annotationTool];
|
|
1057
1070
|
}
|
|
1058
1071
|
} else if (sender.state == UIGestureRecognizerStateChanged) {
|
|
1059
1072
|
if ([_annotationTool isEqualToString:@"ink"]) {
|
|
1060
1073
|
[_annotationOverlay appendInkPointAtViewPoint:point page:pdfPage];
|
|
1061
|
-
} else if ([
|
|
1074
|
+
} else if ([_annotationTool isEqualToString:@"highlight"]) {
|
|
1062
1075
|
[_annotationOverlay updateMarkupAtViewPoint:point page:pdfPage];
|
|
1063
1076
|
}
|
|
1064
1077
|
} else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed) {
|
|
1065
1078
|
if ([_annotationTool isEqualToString:@"ink"]) {
|
|
1066
1079
|
[_annotationOverlay endInk];
|
|
1067
|
-
} else if ([
|
|
1080
|
+
} else if ([_annotationTool isEqualToString:@"highlight"]) {
|
|
1068
1081
|
[_annotationOverlay endMarkup];
|
|
1069
1082
|
}
|
|
1070
1083
|
}
|
|
@@ -1082,6 +1095,22 @@ using namespace facebook::react;
|
|
|
1082
1095
|
[self notifyOnChangeWithMessage:@"annotationSaveError|Annotation overlay unavailable"];
|
|
1083
1096
|
}
|
|
1084
1097
|
|
|
1098
|
+
- (void)deleteSelectedAnnotation
|
|
1099
|
+
{
|
|
1100
|
+
if (_annotationOverlay) {
|
|
1101
|
+
[_annotationOverlay commitTextEditingIfNeeded];
|
|
1102
|
+
[_annotationOverlay deleteSelectedAnnotation];
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
- (void)deleteAllAnnotations
|
|
1107
|
+
{
|
|
1108
|
+
if (_annotationOverlay) {
|
|
1109
|
+
[_annotationOverlay commitTextEditingIfNeeded];
|
|
1110
|
+
[_annotationOverlay deleteAllAnnotations];
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1085
1114
|
/**
|
|
1086
1115
|
* Bind tap
|
|
1087
1116
|
*
|
|
@@ -1158,7 +1187,7 @@ using namespace facebook::react;
|
|
|
1158
1187
|
return [_annotationOverlay annotationSelectionHitAtPoint:point includeHandles:YES] != nil;
|
|
1159
1188
|
}
|
|
1160
1189
|
|
|
1161
|
-
return [@[@"ink", @"highlight"
|
|
1190
|
+
return [@[@"ink", @"highlight"] containsObject:_annotationTool];
|
|
1162
1191
|
}
|
|
1163
1192
|
|
|
1164
1193
|
return !_singlePage;
|
|
@@ -1407,6 +1436,8 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1407
1436
|
_annotationEditable = YES;
|
|
1408
1437
|
_annotationTool = @"select";
|
|
1409
1438
|
_annotationIdMode = @"auto";
|
|
1439
|
+
_annotationInkColor = @"#111111";
|
|
1440
|
+
_annotationInkThickness = 2.0f;
|
|
1410
1441
|
self.backgroundColor = UIColor.clearColor;
|
|
1411
1442
|
self.opaque = NO;
|
|
1412
1443
|
}
|
|
@@ -1441,7 +1472,7 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1441
1472
|
{
|
|
1442
1473
|
_annotationMode = annotationMode;
|
|
1443
1474
|
_annotationEditable = editable;
|
|
1444
|
-
_annotationTool = tool ?: @"select";
|
|
1475
|
+
_annotationTool = [self normalizedAnnotationType:(tool ?: @"select")];
|
|
1445
1476
|
_annotationIdMode = idMode ?: @"auto";
|
|
1446
1477
|
|
|
1447
1478
|
if (!annotationMode) {
|
|
@@ -1449,6 +1480,27 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1449
1480
|
}
|
|
1450
1481
|
}
|
|
1451
1482
|
|
|
1483
|
+
- (void)setInkDefaultsColor:(NSString *)color thickness:(CGFloat)thickness
|
|
1484
|
+
{
|
|
1485
|
+
_annotationInkColor = color.length > 0 ? color : @"#111111";
|
|
1486
|
+
_annotationInkThickness = thickness > 0 ? thickness : 2.0f;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
- (NSString *)normalizedAnnotationType:(NSString *)type
|
|
1490
|
+
{
|
|
1491
|
+
if ([type isEqualToString:@"underline"] || [type isEqualToString:@"strikeout"]) {
|
|
1492
|
+
return @"highlight";
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
return type;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
- (BOOL)annotationSupportsResize:(NSDictionary *)annotation
|
|
1499
|
+
{
|
|
1500
|
+
NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
|
|
1501
|
+
return [type isEqualToString:@"text"] || [type isEqualToString:@"highlight"];
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1452
1504
|
- (NSArray *)parseAnnotationsFromJSONString:(NSString *)json
|
|
1453
1505
|
{
|
|
1454
1506
|
if (![json isKindOfClass:[NSString class]] || json.length == 0) {
|
|
@@ -1487,6 +1539,10 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1487
1539
|
}
|
|
1488
1540
|
|
|
1489
1541
|
NSMutableDictionary *annotation = [item mutableCopy];
|
|
1542
|
+
NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
|
|
1543
|
+
if (type.length > 0) {
|
|
1544
|
+
annotation[@"type"] = type;
|
|
1545
|
+
}
|
|
1490
1546
|
if (!annotation[@"id"]) {
|
|
1491
1547
|
annotation[@"id"] = RNPDFGenerateAnnotationId();
|
|
1492
1548
|
}
|
|
@@ -1727,12 +1783,6 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1727
1783
|
return nil;
|
|
1728
1784
|
}
|
|
1729
1785
|
|
|
1730
|
-
- (CGRect)deleteHandleRectForRect:(CGRect)rect
|
|
1731
|
-
{
|
|
1732
|
-
CGFloat size = MAX(16.0f, MIN(rect.size.width, rect.size.height) * 0.18f);
|
|
1733
|
-
return CGRectMake(CGRectGetMaxX(rect) - size, CGRectGetMinY(rect) - size, size, size);
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
1786
|
- (CGRect)resizeHandleRectForRect:(CGRect)rect
|
|
1737
1787
|
{
|
|
1738
1788
|
CGFloat size = MAX(16.0f, MIN(rect.size.width, rect.size.height) * 0.18f);
|
|
@@ -1768,12 +1818,8 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1768
1818
|
}
|
|
1769
1819
|
|
|
1770
1820
|
NSString *hitPart = @"body";
|
|
1771
|
-
if (includeHandles && [_selectedAnnotationId isEqualToString:annotation[@"id"]]) {
|
|
1772
|
-
|
|
1773
|
-
hitPart = @"delete";
|
|
1774
|
-
} else if (CGRectContainsPoint([self resizeHandleRectForRect:rect], point)) {
|
|
1775
|
-
hitPart = @"resize";
|
|
1776
|
-
}
|
|
1821
|
+
if (includeHandles && [_selectedAnnotationId isEqualToString:annotation[@"id"]] && [self annotationSupportsResize:annotation] && CGRectContainsPoint([self resizeHandleRectForRect:rect], point)) {
|
|
1822
|
+
hitPart = @"resize";
|
|
1777
1823
|
}
|
|
1778
1824
|
|
|
1779
1825
|
return @{@"annotation": annotation,
|
|
@@ -1832,6 +1878,23 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1832
1878
|
[self refreshDisplay];
|
|
1833
1879
|
}
|
|
1834
1880
|
|
|
1881
|
+
- (void)deleteSelectedAnnotation
|
|
1882
|
+
{
|
|
1883
|
+
NSDictionary *annotation = [self selectedAnnotation];
|
|
1884
|
+
if (annotation) {
|
|
1885
|
+
[self deleteAnnotation:annotation];
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
- (void)deleteAllAnnotations
|
|
1890
|
+
{
|
|
1891
|
+
[self commitTextEditingIfNeeded];
|
|
1892
|
+
[_draftAnnotations removeAllObjects];
|
|
1893
|
+
_selectedAnnotationId = nil;
|
|
1894
|
+
[self endSelectionInteraction];
|
|
1895
|
+
[self refreshDisplay];
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1835
1898
|
- (void)beginSelectionInteractionAtPoint:(CGPoint)point hit:(NSDictionary *)hit
|
|
1836
1899
|
{
|
|
1837
1900
|
NSDictionary *annotation = hit[@"annotation"];
|
|
@@ -1961,15 +2024,12 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1961
2024
|
[outlineColor setStroke];
|
|
1962
2025
|
[outlinePath stroke];
|
|
1963
2026
|
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
[[UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:0.95] setFill];
|
|
1971
|
-
UIBezierPath *resizePath = [UIBezierPath bezierPathWithRoundedRect:resizeHandle cornerRadius:2.0f];
|
|
1972
|
-
[resizePath fill];
|
|
2027
|
+
if ([self annotationSupportsResize:annotation]) {
|
|
2028
|
+
CGRect resizeHandle = [self resizeHandleRectForRect:rect];
|
|
2029
|
+
[[UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:0.95] setFill];
|
|
2030
|
+
UIBezierPath *resizePath = [UIBezierPath bezierPathWithRoundedRect:resizeHandle cornerRadius:2.0f];
|
|
2031
|
+
[resizePath fill];
|
|
2032
|
+
}
|
|
1973
2033
|
}
|
|
1974
2034
|
|
|
1975
2035
|
- (NSDictionary *)normalizedBoundsForViewRect:(CGRect)viewRect page:(PDFPage *)page
|
|
@@ -1999,21 +2059,16 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
1999
2059
|
|
|
2000
2060
|
- (UIColor *)colorForAnnotationType:(NSString *)type style:(NSDictionary *)style
|
|
2001
2061
|
{
|
|
2062
|
+
NSString *normalizedType = [self normalizedAnnotationType:type];
|
|
2002
2063
|
NSString *colorString = [style isKindOfClass:[NSDictionary class]] ? style[@"color"] : nil;
|
|
2003
2064
|
if (colorString) {
|
|
2004
2065
|
return RNPDFColorFromHexString(colorString, UIColor.blackColor);
|
|
2005
2066
|
}
|
|
2006
2067
|
|
|
2007
|
-
if ([
|
|
2068
|
+
if ([normalizedType isEqualToString:@"highlight"]) {
|
|
2008
2069
|
return [UIColor colorWithRed:1.0 green:0.93 blue:0.2 alpha:0.35];
|
|
2009
2070
|
}
|
|
2010
|
-
if ([
|
|
2011
|
-
return [UIColor colorWithRed:0.2 green:0.45 blue:1.0 alpha:0.5];
|
|
2012
|
-
}
|
|
2013
|
-
if ([type isEqualToString:@"strikeout"]) {
|
|
2014
|
-
return [UIColor colorWithRed:1.0 green:0.2 blue:0.2 alpha:0.45];
|
|
2015
|
-
}
|
|
2016
|
-
if ([type isEqualToString:@"text"]) {
|
|
2071
|
+
if ([normalizedType isEqualToString:@"text"]) {
|
|
2017
2072
|
return [UIColor colorWithRed:0.13 green:0.27 blue:0.67 alpha:1.0];
|
|
2018
2073
|
}
|
|
2019
2074
|
|
|
@@ -2074,7 +2129,7 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
2074
2129
|
}
|
|
2075
2130
|
|
|
2076
2131
|
PDFPage *page = [_pdfDocument pageAtIndex:pageIndex];
|
|
2077
|
-
NSString *type = annotation[@"type"];
|
|
2132
|
+
NSString *type = [self normalizedAnnotationType:annotation[@"type"]];
|
|
2078
2133
|
if ([type isEqualToString:@"ink"]) {
|
|
2079
2134
|
NSArray *points = annotation[@"points"];
|
|
2080
2135
|
if (points.count < 2) {
|
|
@@ -2127,7 +2182,7 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
2127
2182
|
NSParagraphStyleAttributeName: paragraphStyle,
|
|
2128
2183
|
};
|
|
2129
2184
|
[text drawInRect:CGRectInset(viewRect, 6.0f, 4.0f) withAttributes:attributes];
|
|
2130
|
-
} else if ([type isEqualToString:@"highlight"]
|
|
2185
|
+
} else if ([type isEqualToString:@"highlight"]) {
|
|
2131
2186
|
NSDictionary *bounds = annotation[@"bounds"];
|
|
2132
2187
|
CGRect viewRect = [self viewRectForNormalizedBounds:bounds page:page];
|
|
2133
2188
|
if (CGRectIsEmpty(viewRect)) {
|
|
@@ -2137,15 +2192,6 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
2137
2192
|
UIColor *fillColor = [self colorForAnnotationType:type style:annotation[@"style"]];
|
|
2138
2193
|
CGContextSetFillColorWithColor(context, fillColor.CGColor);
|
|
2139
2194
|
CGContextFillRect(context, viewRect);
|
|
2140
|
-
|
|
2141
|
-
if ([type isEqualToString:@"underline"] || [type isEqualToString:@"strikeout"]) {
|
|
2142
|
-
CGContextSetStrokeColorWithColor(context, fillColor.CGColor);
|
|
2143
|
-
CGContextSetLineWidth(context, MAX(1.0f, viewRect.size.height * 0.15f));
|
|
2144
|
-
CGFloat y = [type isEqualToString:@"underline"] ? CGRectGetMaxY(viewRect) - 2.0f : CGRectGetMidY(viewRect);
|
|
2145
|
-
CGContextMoveToPoint(context, CGRectGetMinX(viewRect), y);
|
|
2146
|
-
CGContextAddLineToPoint(context, CGRectGetMaxX(viewRect), y);
|
|
2147
|
-
CGContextStrokePath(context);
|
|
2148
|
-
}
|
|
2149
2195
|
}
|
|
2150
2196
|
}
|
|
2151
2197
|
|
|
@@ -2163,7 +2209,7 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
2163
2209
|
@"page": @([_pdfDocument indexForPage:page] + 1),
|
|
2164
2210
|
@"type": @"ink",
|
|
2165
2211
|
@"points": [NSMutableArray array],
|
|
2166
|
-
@"style": @{@"color": @"#111111", @"thickness": @(2.0f)}
|
|
2212
|
+
@"style": @{@"color": _annotationInkColor ?: @"#111111", @"thickness": @(_annotationInkThickness > 0 ? _annotationInkThickness : 2.0f)}
|
|
2167
2213
|
} mutableCopy];
|
|
2168
2214
|
|
|
2169
2215
|
[_draftAnnotations addObject:annotation];
|
|
@@ -2206,7 +2252,7 @@ static NSString *RNPDFGenerateAnnotationId(void)
|
|
|
2206
2252
|
NSMutableDictionary *annotation = [@{
|
|
2207
2253
|
@"id": [self nextLocalAnnotationId],
|
|
2208
2254
|
@"page": @([_pdfDocument indexForPage:page] + 1),
|
|
2209
|
-
@"type":
|
|
2255
|
+
@"type": @"highlight",
|
|
2210
2256
|
@"bounds": @{@"x": @(normalizedPoint.x), @"y": @(normalizedPoint.y), @"width": @0, @"height": @0},
|
|
2211
2257
|
@"style": @{}
|
|
2212
2258
|
} mutableCopy];
|
|
@@ -51,6 +51,8 @@ RCT_EXPORT_VIEW_PROPERTY(annotationMode, BOOL);
|
|
|
51
51
|
RCT_EXPORT_VIEW_PROPERTY(annotationTool, NSString);
|
|
52
52
|
RCT_EXPORT_VIEW_PROPERTY(annotationEditable, BOOL);
|
|
53
53
|
RCT_EXPORT_VIEW_PROPERTY(annotationIdMode, NSString);
|
|
54
|
+
RCT_EXPORT_VIEW_PROPERTY(annotationInkColor, NSString);
|
|
55
|
+
RCT_EXPORT_VIEW_PROPERTY(annotationInkThickness, float);
|
|
54
56
|
RCT_EXPORT_VIEW_PROPERTY(fitPolicy, int);
|
|
55
57
|
RCT_EXPORT_VIEW_PROPERTY(spacing, int);
|
|
56
58
|
RCT_EXPORT_VIEW_PROPERTY(password, NSString);
|
|
@@ -91,6 +93,26 @@ RCT_EXPORT_METHOD(saveAnnotations:(nonnull NSNumber *)reactTag)
|
|
|
91
93
|
}];
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
RCT_EXPORT_METHOD(deleteSelectedAnnotation:(nonnull NSNumber *)reactTag)
|
|
97
|
+
{
|
|
98
|
+
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
99
|
+
RNPDFPdfView *view = (RNPDFPdfView *)viewRegistry[reactTag];
|
|
100
|
+
if ([view isKindOfClass:[RNPDFPdfView class]]) {
|
|
101
|
+
[view deleteSelectedAnnotation];
|
|
102
|
+
}
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
RCT_EXPORT_METHOD(deleteAllAnnotations:(nonnull NSNumber *)reactTag)
|
|
107
|
+
{
|
|
108
|
+
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
109
|
+
RNPDFPdfView *view = (RNPDFPdfView *)viewRegistry[reactTag];
|
|
110
|
+
if ([view isKindOfClass:[RNPDFPdfView class]]) {
|
|
111
|
+
[view deleteAllAnnotations];
|
|
112
|
+
}
|
|
113
|
+
}];
|
|
114
|
+
}
|
|
115
|
+
|
|
94
116
|
RCT_EXPORT_METHOD(supportPDFKit:(RCTResponseSenderBlock)callback)
|
|
95
117
|
{
|
|
96
118
|
if([[[UIDevice currentDevice] systemVersion] compare:@"11.0" options:NSNumericSearch] == NSOrderedDescending
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amafil/react-native-pdf-toolkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"summary": "A react native PDF view component",
|
|
5
5
|
"description": "A react native PDF view component, support ios and android platform",
|
|
6
6
|
"main": "index.js",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"index.d.ts",
|
|
50
50
|
"index.js",
|
|
51
51
|
"index.js.flow",
|
|
52
|
+
"annotationDocumentUtils.js",
|
|
52
53
|
"PdfManager.js",
|
|
53
54
|
"PdfPageView.js",
|
|
54
55
|
"PdfView.js",
|