react-native-pdf-jsi 1.0.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.
Files changed (91) hide show
  1. package/DoubleTapView.js +125 -0
  2. package/INTEGRATION_GUIDE.md +419 -0
  3. package/LICENSE +21 -0
  4. package/PdfManager.js +26 -0
  5. package/PdfPageView.js +53 -0
  6. package/PdfView.js +421 -0
  7. package/PdfViewFlatList.js +30 -0
  8. package/PinchZoomView.js +125 -0
  9. package/README.md +693 -0
  10. package/README_JSI.md +348 -0
  11. package/android/.gradle/5.6.1/fileChanges/last-build.bin +0 -0
  12. package/android/.gradle/5.6.1/fileHashes/fileHashes.lock +0 -0
  13. package/android/.gradle/5.6.1/gc.properties +0 -0
  14. package/android/.gradle/8.5/checksums/checksums.lock +0 -0
  15. package/android/.gradle/8.5/checksums/md5-checksums.bin +0 -0
  16. package/android/.gradle/8.5/checksums/sha1-checksums.bin +0 -0
  17. package/android/.gradle/8.5/dependencies-accessors/dependencies-accessors.lock +0 -0
  18. package/android/.gradle/8.5/dependencies-accessors/gc.properties +0 -0
  19. package/android/.gradle/8.5/executionHistory/executionHistory.lock +0 -0
  20. package/android/.gradle/8.5/fileChanges/last-build.bin +0 -0
  21. package/android/.gradle/8.5/fileHashes/fileHashes.lock +0 -0
  22. package/android/.gradle/8.5/gc.properties +0 -0
  23. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  24. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  25. package/android/.gradle/vcs-1/gc.properties +0 -0
  26. package/android/build.gradle +198 -0
  27. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  28. package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  29. package/android/gradle.properties +2 -0
  30. package/android/gradlew +249 -0
  31. package/android/gradlew.bat +92 -0
  32. package/android/project.properties +12 -0
  33. package/android/src/main/AndroidManifest.xml +4 -0
  34. package/android/src/main/cpp/Android.mk +50 -0
  35. package/android/src/main/cpp/CMakeLists.txt +76 -0
  36. package/android/src/main/cpp/PDFJSI.cpp +190 -0
  37. package/android/src/main/cpp/PDFJSI.h +95 -0
  38. package/android/src/main/cpp/PDFJSIBridge.cpp +32 -0
  39. package/android/src/main/cpp/PDFJSIModule.cpp +31 -0
  40. package/android/src/main/java/org/wonday/pdf/EnhancedPdfJSIBridge.java +281 -0
  41. package/android/src/main/java/org/wonday/pdf/PDFJSIManager.java +317 -0
  42. package/android/src/main/java/org/wonday/pdf/PDFJSIModule.java +189 -0
  43. package/android/src/main/java/org/wonday/pdf/PdfManager.java +180 -0
  44. package/android/src/main/java/org/wonday/pdf/PdfView.java +505 -0
  45. package/android/src/main/java/org/wonday/pdf/RNPDFPackage.java +43 -0
  46. package/android/src/main/java/org/wonday/pdf/events/TopChangeEvent.java +26 -0
  47. package/android/src/main/jniLibs/arm64-v8a/libpdfjsi.so +0 -0
  48. package/android/src/main/jniLibs/armeabi-v7a/libpdfjsi.so +0 -0
  49. package/android/src/main/jniLibs/x86/libpdfjsi.so +0 -0
  50. package/android/src/main/jniLibs/x86_64/libpdfjsi.so +0 -0
  51. package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerDelegate.java +92 -0
  52. package/android/src/paper/java/com/facebook/react/viewmanagers/RNPDFPdfViewManagerInterface.java +35 -0
  53. package/fabric/RNPDFPdfNativeComponent.js +48 -0
  54. package/index.d.ts +72 -0
  55. package/index.js +603 -0
  56. package/index.js.flow +67 -0
  57. package/ios/RNPDFPdf/PdfManager.h +23 -0
  58. package/ios/RNPDFPdf/PdfManager.mm +152 -0
  59. package/ios/RNPDFPdf/RNPDFPdfPageView.h +21 -0
  60. package/ios/RNPDFPdf/RNPDFPdfPageView.mm +185 -0
  61. package/ios/RNPDFPdf/RNPDFPdfPageViewManager.h +18 -0
  62. package/ios/RNPDFPdf/RNPDFPdfPageViewManager.mm +30 -0
  63. package/ios/RNPDFPdf/RNPDFPdfView.h +63 -0
  64. package/ios/RNPDFPdf/RNPDFPdfView.mm +1092 -0
  65. package/ios/RNPDFPdf/RNPDFPdfViewManager.h +18 -0
  66. package/ios/RNPDFPdf/RNPDFPdfViewManager.mm +68 -0
  67. package/ios/RNPDFPdf.xcodeproj/project.pbxproj +321 -0
  68. package/package.json +78 -0
  69. package/react-native-pdf.podspec +31 -0
  70. package/src/EnhancedPdfView.js +362 -0
  71. package/src/PDFJSI.js +519 -0
  72. package/src/examples/PDFJSIExample.js +296 -0
  73. package/src/hooks/usePDFJSI.js +346 -0
  74. package/src/index.js +32 -0
  75. package/windows/RCTPdf/PropertySheet.props +16 -0
  76. package/windows/RCTPdf/RCTPdf.def +3 -0
  77. package/windows/RCTPdf/RCTPdf.vcxproj +180 -0
  78. package/windows/RCTPdf/RCTPdf.vcxproj.filters +38 -0
  79. package/windows/RCTPdf/RCTPdfControl.cpp +667 -0
  80. package/windows/RCTPdf/RCTPdfControl.h +119 -0
  81. package/windows/RCTPdf/RCTPdfControl.idl +10 -0
  82. package/windows/RCTPdf/RCTPdfControl.xaml +33 -0
  83. package/windows/RCTPdf/RCTPdfViewManager.cpp +69 -0
  84. package/windows/RCTPdf/RCTPdfViewManager.h +51 -0
  85. package/windows/RCTPdf/ReactPackageProvider.cpp +15 -0
  86. package/windows/RCTPdf/ReactPackageProvider.h +16 -0
  87. package/windows/RCTPdf/ReactPackageProvider.idl +9 -0
  88. package/windows/RCTPdf/packages.config +4 -0
  89. package/windows/RCTPdf/pch.cpp +1 -0
  90. package/windows/RCTPdf/pch.h +31 -0
  91. package/windows/README.md +21 -0
@@ -0,0 +1,505 @@
1
+ /**
2
+ * Copyright (c) 2017-present, Wonday (@wonday.org)
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the MIT-style license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ package org.wonday.pdf;
10
+
11
+ import java.io.File;
12
+
13
+ import android.content.ContentResolver;
14
+ import android.content.Context;
15
+ import android.util.SizeF;
16
+ import android.view.View;
17
+ import android.view.ViewGroup;
18
+ import android.util.Log;
19
+ import android.net.Uri;
20
+ import android.util.AttributeSet;
21
+ import android.view.MotionEvent;
22
+ import android.graphics.Canvas;
23
+
24
+
25
+ import com.facebook.react.uimanager.ThemedReactContext;
26
+ import com.facebook.react.uimanager.UIManagerHelper;
27
+ import com.github.barteksc.pdfviewer.PDFView;
28
+ import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
29
+ import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
30
+ import com.github.barteksc.pdfviewer.listener.OnErrorListener;
31
+ import com.github.barteksc.pdfviewer.listener.OnTapListener;
32
+ import com.github.barteksc.pdfviewer.listener.OnDrawListener;
33
+ import com.github.barteksc.pdfviewer.listener.OnPageScrollListener;
34
+ import com.github.barteksc.pdfviewer.util.FitPolicy;
35
+ import com.github.barteksc.pdfviewer.util.Constants;
36
+ import com.github.barteksc.pdfviewer.link.LinkHandler;
37
+ import com.github.barteksc.pdfviewer.model.LinkTapEvent;
38
+
39
+ import com.facebook.react.bridge.ReactContext;
40
+ import com.facebook.react.bridge.Arguments;
41
+ import com.facebook.react.bridge.WritableMap;
42
+ import com.facebook.react.bridge.ReactContext;
43
+ import com.facebook.react.uimanager.UIManagerModule;
44
+ import com.facebook.react.uimanager.events.EventDispatcher;
45
+ import com.facebook.react.uimanager.events.Event;
46
+ import com.facebook.react.uimanager.events.RCTEventEmitter;
47
+
48
+
49
+ import static java.lang.String.format;
50
+
51
+ import java.io.FileNotFoundException;
52
+ import java.io.InputStream;
53
+
54
+ import com.google.gson.Gson;
55
+
56
+ import org.wonday.pdf.events.TopChangeEvent;
57
+
58
+ public class PdfView extends PDFView implements OnPageChangeListener,OnLoadCompleteListener,OnErrorListener,OnTapListener,OnDrawListener,OnPageScrollListener, LinkHandler {
59
+ private int page = 1; // start from 1
60
+ private boolean horizontal = false;
61
+ private float scale = 1;
62
+ private float minScale = 1;
63
+ private float maxScale = 3;
64
+ private String path;
65
+ private int spacing = 10;
66
+ private String password = "";
67
+ private boolean enableAntialiasing = true;
68
+ private boolean enableAnnotationRendering = true;
69
+ private boolean enableDoubleTapZoom = true;
70
+
71
+ private boolean enablePaging = false;
72
+ private boolean autoSpacing = false;
73
+ private boolean pageFling = false;
74
+ private boolean pageSnap = false;
75
+ private FitPolicy fitPolicy = FitPolicy.WIDTH;
76
+ private boolean singlePage = false;
77
+ private boolean scrollEnabled = true;
78
+
79
+ private float originalWidth = 0;
80
+ private float lastPageWidth = 0;
81
+ private float lastPageHeight = 0;
82
+
83
+ // used to store the parameters for `super.onSizeChanged`
84
+ private int oldW = 0;
85
+ private int oldH = 0;
86
+
87
+ public PdfView(Context context, AttributeSet set){
88
+ super(context, set);
89
+ }
90
+
91
+ @Override
92
+ public void onPageChanged(int page, int numberOfPages) {
93
+ // pdf lib page start from 0, convert it to our page (start from 1)
94
+ page = page+1;
95
+ this.page = page;
96
+ showLog(format("%s %s / %s", path, page, numberOfPages));
97
+
98
+ WritableMap event = Arguments.createMap();
99
+ event.putString("message", "pageChanged|"+page+"|"+numberOfPages);
100
+
101
+ ThemedReactContext context = (ThemedReactContext) getContext();
102
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
103
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
104
+
105
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
106
+
107
+ if (dispatcher != null) {
108
+ dispatcher.dispatchEvent(tce);
109
+ }
110
+
111
+ // ReactContext reactContext = (ReactContext)this.getContext();
112
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
113
+ // this.getId(),
114
+ // "topChange",
115
+ // event
116
+ // );
117
+ }
118
+
119
+ // In some cases Yoga (I think) will measure the view only along one axis first, resulting in
120
+ // onSizeChanged being called with either w or h set to zero. This in turn starts the rendering
121
+ // of the pdf under the hood with one dimension being set to zero and the follow-up call to
122
+ // onSizeChanged with the correct dimensions doesn't have any effect on the already started process.
123
+ // The offending class is DecodingAsyncTask, which tries to get width and height of the pdfView
124
+ // in the constructor, and is created as soon as the measurement is complete, which in some cases
125
+ // may be incomplete as described above.
126
+ // By delaying calling super.onSizeChanged until the size in both dimensions is correct we are able
127
+ // to prevent this from happening.
128
+ //
129
+ // I'm not sure whether the second condition is necessary, but without it, it would be impossible
130
+ // to set the dimensions to zero after first measurement.
131
+ @Override
132
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
133
+ if ((w > 0 && h > 0) || this.oldW > 0 || this.oldH > 0) {
134
+ super.onSizeChanged(w, h, this.oldW, this.oldH);
135
+ this.oldW = w;
136
+ this.oldH = h;
137
+ }
138
+ }
139
+
140
+ @Override
141
+ public void loadComplete(int numberOfPages) {
142
+ SizeF pageSize = getPageSize(0);
143
+ float width = pageSize.getWidth();
144
+ float height = pageSize.getHeight();
145
+
146
+ this.zoomTo(this.scale);
147
+ WritableMap event = Arguments.createMap();
148
+
149
+ //create a new json Object for the TableOfContents
150
+ Gson gson = new Gson();
151
+ event.putString("message", "loadComplete|"+numberOfPages+"|"+width+"|"+height+"|"+gson.toJson(this.getTableOfContents()));
152
+
153
+ ThemedReactContext context = (ThemedReactContext) getContext();
154
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
155
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
156
+
157
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
158
+
159
+ if (dispatcher != null) {
160
+ dispatcher.dispatchEvent(tce);
161
+ }
162
+ // ReactContext reactContext = (ReactContext)this.getContext();
163
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
164
+ // this.getId(),
165
+ // "topChange",
166
+ // event
167
+ // );
168
+
169
+ //Log.e("ReactNative", gson.toJson(this.getTableOfContents()));
170
+
171
+ }
172
+
173
+ @Override
174
+ public void onError(Throwable t){
175
+ WritableMap event = Arguments.createMap();
176
+ if (t.getMessage().contains("Password required or incorrect password")) {
177
+ event.putString("message", "error|Password required or incorrect password.");
178
+ } else {
179
+ event.putString("message", "error|"+t.getMessage());
180
+ }
181
+
182
+ ThemedReactContext context = (ThemedReactContext) getContext();
183
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
184
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
185
+
186
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
187
+
188
+ if (dispatcher != null) {
189
+ dispatcher.dispatchEvent(tce);
190
+ }
191
+
192
+ // ReactContext reactContext = (ReactContext)this.getContext();
193
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
194
+ // this.getId(),
195
+ // "topChange",
196
+ // event
197
+ // );
198
+ }
199
+
200
+ @Override
201
+ public void onPageScrolled(int page, float positionOffset){
202
+
203
+ // maybe change by other instance, restore zoom setting
204
+ Constants.Pinch.MINIMUM_ZOOM = this.minScale;
205
+ Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
206
+
207
+ }
208
+
209
+ @Override
210
+ public boolean onTap(MotionEvent e){
211
+
212
+ // maybe change by other instance, restore zoom setting
213
+ //Constants.Pinch.MINIMUM_ZOOM = this.minScale;
214
+ //Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
215
+
216
+ WritableMap event = Arguments.createMap();
217
+ event.putString("message", "pageSingleTap|"+page+"|"+e.getX()+"|"+e.getY());
218
+
219
+ ThemedReactContext context = (ThemedReactContext) getContext();
220
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
221
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
222
+
223
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
224
+
225
+ if (dispatcher != null) {
226
+ dispatcher.dispatchEvent(tce);
227
+ }
228
+ // ReactContext reactContext = (ReactContext)this.getContext();
229
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
230
+ // this.getId(),
231
+ // "topChange",
232
+ // event
233
+ // );
234
+
235
+ // process as tap
236
+ return true;
237
+
238
+ }
239
+
240
+ @Override
241
+ public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage){
242
+ if (originalWidth == 0) {
243
+ originalWidth = pageWidth;
244
+ }
245
+
246
+ if (lastPageWidth>0 && lastPageHeight>0 && (pageWidth!=lastPageWidth || pageHeight!=lastPageHeight)) {
247
+ // maybe change by other instance, restore zoom setting
248
+ Constants.Pinch.MINIMUM_ZOOM = this.minScale;
249
+ Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
250
+
251
+ WritableMap event = Arguments.createMap();
252
+ event.putString("message", "scaleChanged|"+(pageWidth/originalWidth));
253
+ ThemedReactContext context = (ThemedReactContext) getContext();
254
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
255
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
256
+
257
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
258
+
259
+ if (dispatcher != null) {
260
+ dispatcher.dispatchEvent(tce);
261
+ }
262
+ // ReactContext reactContext = (ReactContext)this.getContext();
263
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
264
+ // this.getId(),
265
+ // "topChange",
266
+ // event
267
+ // );
268
+ }
269
+
270
+ lastPageWidth = pageWidth;
271
+ lastPageHeight = pageHeight;
272
+ }
273
+
274
+ @Override
275
+ protected void onAttachedToWindow() {
276
+ super.onAttachedToWindow();
277
+ if (this.isRecycled())
278
+ this.drawPdf();
279
+ }
280
+
281
+ public void drawPdf() {
282
+ showLog(format("drawPdf path:%s %s", this.path, this.page));
283
+
284
+ if (this.path != null){
285
+
286
+ // set scale
287
+ this.setMinZoom(this.minScale);
288
+ this.setMaxZoom(this.maxScale);
289
+ this.setMidZoom((this.maxScale+this.minScale)/2);
290
+ Constants.Pinch.MINIMUM_ZOOM = this.minScale;
291
+ Constants.Pinch.MAXIMUM_ZOOM = this.maxScale;
292
+
293
+ Configurator configurator;
294
+
295
+ if (this.path.startsWith("content://")) {
296
+ ContentResolver contentResolver = getContext().getContentResolver();
297
+ InputStream inputStream = null;
298
+ Uri uri = Uri.parse(this.path);
299
+ try {
300
+ inputStream = contentResolver.openInputStream(uri);
301
+ } catch (FileNotFoundException e) {
302
+ throw new RuntimeException(e.getMessage());
303
+ }
304
+ configurator = this.fromStream(inputStream);
305
+ } else {
306
+ configurator = this.fromUri(getURI(this.path));
307
+ }
308
+
309
+ configurator.defaultPage(this.page-1)
310
+ .swipeHorizontal(this.horizontal)
311
+ .onPageChange(this)
312
+ .onLoad(this)
313
+ .onError(this)
314
+ .onDraw(this)
315
+ .onPageScroll(this)
316
+ .spacing(this.spacing)
317
+ .password(this.password)
318
+ .enableAntialiasing(this.enableAntialiasing)
319
+ .pageFitPolicy(this.fitPolicy)
320
+ .pageSnap(this.pageSnap)
321
+ .autoSpacing(this.autoSpacing)
322
+ .pageFling(this.pageFling)
323
+ .enableSwipe(!this.singlePage && this.scrollEnabled)
324
+ .enableDoubletap(!this.singlePage && this.enableDoubleTapZoom)
325
+ .enableAnnotationRendering(this.enableAnnotationRendering)
326
+ .linkHandler(this);
327
+
328
+ if (this.singlePage) {
329
+ configurator.pages(this.page-1);
330
+ setTouchesEnabled(false);
331
+ } else {
332
+ configurator.onTap(this);
333
+ }
334
+
335
+ configurator.load();
336
+ }
337
+ }
338
+
339
+ public void setEnableDoubleTapZoom(boolean enableDoubleTapZoom) {
340
+ this.enableDoubleTapZoom = enableDoubleTapZoom;
341
+ }
342
+
343
+ public void setPath(String path) {
344
+ this.path = path;
345
+ }
346
+
347
+ // page start from 1
348
+ public void setPage(int page) {
349
+ this.page = page>1?page:1;
350
+ }
351
+
352
+ public void setScale(float scale) {
353
+ this.scale = scale;
354
+ }
355
+
356
+ public void setMinScale(float minScale) {
357
+ this.minScale = minScale;
358
+ }
359
+
360
+ public void setMaxScale(float maxScale) {
361
+ this.maxScale = maxScale;
362
+ }
363
+
364
+ public void setHorizontal(boolean horizontal) {
365
+ this.horizontal = horizontal;
366
+ }
367
+
368
+ public void setScrollEnabled(boolean scrollEnabled) {
369
+ this.scrollEnabled = scrollEnabled;
370
+ }
371
+
372
+ public void setSpacing(int spacing) {
373
+ this.spacing = spacing;
374
+ }
375
+
376
+ public void setPassword(String password) {
377
+ this.password = password;
378
+ }
379
+
380
+ public void setEnableAntialiasing(boolean enableAntialiasing) {
381
+ this.enableAntialiasing = enableAntialiasing;
382
+ }
383
+
384
+ public void setEnableAnnotationRendering(boolean enableAnnotationRendering) {
385
+ this.enableAnnotationRendering = enableAnnotationRendering;
386
+ }
387
+
388
+ public void setEnablePaging(boolean enablePaging) {
389
+ this.enablePaging = enablePaging;
390
+ if (this.enablePaging) {
391
+ this.autoSpacing = true;
392
+ this.pageFling = true;
393
+ this.pageSnap = true;
394
+ } else {
395
+ this.autoSpacing = false;
396
+ this.pageFling = false;
397
+ this.pageSnap = false;
398
+ }
399
+ }
400
+
401
+ public void setFitPolicy(int fitPolicy) {
402
+ switch(fitPolicy){
403
+ case 0:
404
+ this.fitPolicy = FitPolicy.WIDTH;
405
+ break;
406
+ case 1:
407
+ this.fitPolicy = FitPolicy.HEIGHT;
408
+ break;
409
+ case 2:
410
+ default:
411
+ {
412
+ this.fitPolicy = FitPolicy.BOTH;
413
+ break;
414
+ }
415
+ }
416
+
417
+ }
418
+
419
+ public void setSinglePage(boolean singlePage) {
420
+ this.singlePage = singlePage;
421
+ }
422
+
423
+ /**
424
+ * @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
425
+ */
426
+ public void handleLinkEvent(LinkTapEvent event) {
427
+ String uri = event.getLink().getUri();
428
+ Integer page = event.getLink().getDestPageIdx();
429
+ if (uri != null && !uri.isEmpty()) {
430
+ handleUri(uri);
431
+ } else if (page != null) {
432
+ handlePage(page);
433
+ }
434
+ }
435
+
436
+ /**
437
+ * @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
438
+ */
439
+ private void handleUri(String uri) {
440
+ WritableMap event = Arguments.createMap();
441
+ event.putString("message", "linkPressed|"+uri);
442
+
443
+ ThemedReactContext context = (ThemedReactContext) getContext();
444
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
445
+ int surfaceId = UIManagerHelper.getSurfaceId(this);
446
+
447
+ TopChangeEvent tce = new TopChangeEvent(surfaceId, getId(), event);
448
+
449
+ if (dispatcher != null) {
450
+ dispatcher.dispatchEvent(tce);
451
+ }
452
+
453
+ // ReactContext reactContext = (ReactContext)this.getContext();
454
+ // reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
455
+ // this.getId(),
456
+ // "topChange",
457
+ // event
458
+ // );
459
+ }
460
+
461
+ /**
462
+ * @see https://github.com/barteksc/AndroidPdfViewer/blob/master/android-pdf-viewer/src/main/java/com/github/barteksc/pdfviewer/link/DefaultLinkHandler.java
463
+ */
464
+ private void handlePage(int page) {
465
+ this.jumpTo(page);
466
+ }
467
+
468
+ private void showLog(final String str) {
469
+ Log.d("PdfView", str);
470
+ }
471
+
472
+ private Uri getURI(final String uri) {
473
+ Uri parsed = Uri.parse(uri);
474
+
475
+ if (parsed.getScheme() == null || parsed.getScheme().isEmpty()) {
476
+ return Uri.fromFile(new File(uri));
477
+ }
478
+ return parsed;
479
+ }
480
+
481
+ private void setTouchesEnabled(final boolean enabled) {
482
+ setTouchesEnabled(this, enabled);
483
+ }
484
+
485
+ private static void setTouchesEnabled(View v, final boolean enabled) {
486
+ if (enabled) {
487
+ v.setOnTouchListener(null);
488
+ } else {
489
+ v.setOnTouchListener(new View.OnTouchListener() {
490
+ @Override
491
+ public boolean onTouch(View v, MotionEvent event) {
492
+ return true;
493
+ }
494
+ });
495
+ }
496
+
497
+ if (v instanceof ViewGroup) {
498
+ ViewGroup vg = (ViewGroup) v;
499
+ for (int i = 0; i < vg.getChildCount(); i++) {
500
+ View child = vg.getChildAt(i);
501
+ setTouchesEnabled(child, enabled);
502
+ }
503
+ }
504
+ }
505
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) 2017-present, Wonday (@wonday.org)
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the MIT-style license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ package org.wonday.pdf;
10
+
11
+ import java.util.Collections;
12
+ import java.util.List;
13
+ import java.util.ArrayList;
14
+
15
+ import com.facebook.react.ReactPackage;
16
+ import com.facebook.react.bridge.JavaScriptModule;
17
+ import com.facebook.react.bridge.NativeModule;
18
+ import com.facebook.react.bridge.ReactApplicationContext;
19
+ import com.facebook.react.uimanager.ViewManager;
20
+
21
+ public class RNPDFPackage implements ReactPackage {
22
+
23
+ @Override
24
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
25
+ List<NativeModule> modules = new ArrayList<>();
26
+ // Add JSI modules for enhanced PDF performance
27
+ modules.add(new PDFJSIManager(reactContext));
28
+ modules.add(new EnhancedPdfJSIBridge(reactContext));
29
+ return modules;
30
+ }
31
+
32
+ // Deprecated as of RN 0.47.0
33
+ public List<Class<? extends JavaScriptModule>> createJSModules() {
34
+ return Collections.emptyList();
35
+ }
36
+
37
+ @Override
38
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
39
+ List<ViewManager> modules = new ArrayList<>();
40
+ modules.add(new PdfManager(reactContext));
41
+ return modules;
42
+ }
43
+ }
@@ -0,0 +1,26 @@
1
+ package org.wonday.pdf.events;
2
+
3
+ import androidx.annotation.Nullable;
4
+
5
+ import com.facebook.react.bridge.WritableMap;
6
+ import com.facebook.react.uimanager.events.Event;
7
+
8
+ public class TopChangeEvent extends Event<TopChangeEvent> {
9
+ private WritableMap eventData;
10
+
11
+ public TopChangeEvent(int surfaceId, int viewTag, WritableMap data) {
12
+ super(surfaceId, viewTag);
13
+ eventData = data;
14
+ }
15
+
16
+ @Override
17
+ public String getEventName() {
18
+ return "topChange";
19
+ }
20
+
21
+ @Nullable
22
+ @Override
23
+ protected WritableMap getEventData() {
24
+ return eventData;
25
+ }
26
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
3
+ *
4
+ * Do not edit this file as changes may cause incorrect behavior and will be lost
5
+ * once the code is regenerated.
6
+ *
7
+ * @generated by codegen project: GeneratePropsJavaDelegate.js
8
+ */
9
+
10
+ package com.facebook.react.viewmanagers;
11
+
12
+ import android.view.View;
13
+ import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.ReadableArray;
15
+ import com.facebook.react.uimanager.BaseViewManagerDelegate;
16
+ import com.facebook.react.uimanager.BaseViewManager;
17
+ import com.facebook.react.uimanager.LayoutShadowNode;
18
+
19
+ public class RNPDFPdfViewManagerDelegate<T extends View, U extends BaseViewManager<T, ? extends LayoutShadowNode> & RNPDFPdfViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
20
+ public RNPDFPdfViewManagerDelegate(U viewManager) {
21
+ super(viewManager);
22
+ }
23
+
24
+ public void setProperty(T view, String propName, @Nullable Object value) {
25
+ switch (propName) {
26
+ case "path":
27
+ mViewManager.setPath(view, value == null ? null : (String) value);
28
+ break;
29
+ case "page":
30
+ mViewManager.setPage(view, value == null ? 0 : ((Double) value).intValue());
31
+ break;
32
+ case "scale":
33
+ mViewManager.setScale(view, value == null ? 0f : ((Double) value).floatValue());
34
+ break;
35
+ case "minScale":
36
+ mViewManager.setMinScale(view, value == null ? 0f : ((Double) value).floatValue());
37
+ break;
38
+ case "maxScale":
39
+ mViewManager.setMaxScale(view, value == null ? 0f : ((Double) value).floatValue());
40
+ break;
41
+ case "horizontal":
42
+ mViewManager.setHorizontal(view, value == null ? false : (boolean) value);
43
+ break;
44
+ case "showsHorizontalScrollIndicator":
45
+ mViewManager.setShowsHorizontalScrollIndicator(view, value == null ? false : (boolean) value);
46
+ break;
47
+ case "showsVerticalScrollIndicator":
48
+ mViewManager.setShowsVerticalScrollIndicator(view, value == null ? false : (boolean) value);
49
+ break;
50
+ case "scrollEnabled":
51
+ mViewManager.setScrollEnabled(view, value == null ? false : (boolean) value);
52
+ break;
53
+ case "enablePaging":
54
+ mViewManager.setEnablePaging(view, value == null ? false : (boolean) value);
55
+ break;
56
+ case "enableRTL":
57
+ mViewManager.setEnableRTL(view, value == null ? false : (boolean) value);
58
+ break;
59
+ case "enableAnnotationRendering":
60
+ mViewManager.setEnableAnnotationRendering(view, value == null ? false : (boolean) value);
61
+ break;
62
+ case "enableDoubleTapZoom":
63
+ mViewManager.setEnableDoubleTapZoom(view, value == null ? false : (boolean) value);
64
+ break;
65
+ case "enableAntialiasing":
66
+ mViewManager.setEnableAntialiasing(view, value == null ? false : (boolean) value);
67
+ break;
68
+ case "fitPolicy":
69
+ mViewManager.setFitPolicy(view, value == null ? 0 : ((Double) value).intValue());
70
+ break;
71
+ case "spacing":
72
+ mViewManager.setSpacing(view, value == null ? 0 : ((Double) value).intValue());
73
+ break;
74
+ case "password":
75
+ mViewManager.setPassword(view, value == null ? null : (String) value);
76
+ break;
77
+ case "singlePage":
78
+ mViewManager.setSinglePage(view, value == null ? false : (boolean) value);
79
+ break;
80
+ default:
81
+ super.setProperty(view, propName, value);
82
+ }
83
+ }
84
+
85
+ public void receiveCommand(T view, String commandName, ReadableArray args) {
86
+ switch (commandName) {
87
+ case "setNativePage":
88
+ mViewManager.setNativePage(view, args.getInt(0));
89
+ break;
90
+ }
91
+ }
92
+ }