@papyrus-sdk/engine-native 0.1.1 → 0.1.2

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 (26) hide show
  1. package/LICENSE +21 -0
  2. package/android/build.gradle +40 -40
  3. package/android/src/main/AndroidManifest.xml +3 -3
  4. package/android/src/main/java/com/papyrus/engine/PapyrusEngineStore.java +71 -71
  5. package/android/src/main/java/com/papyrus/engine/PapyrusNativeEngineModule.java +529 -529
  6. package/android/src/main/java/com/papyrus/engine/PapyrusNativeEngineModule.kt +540 -0
  7. package/android/src/main/java/com/papyrus/engine/PapyrusOutline.java +20 -20
  8. package/android/src/main/java/com/papyrus/engine/PapyrusOutlineItem.java +13 -13
  9. package/android/src/main/java/com/papyrus/engine/PapyrusPackage.java +24 -24
  10. package/android/src/main/java/com/papyrus/engine/PapyrusPageView.java +86 -86
  11. package/android/src/main/java/com/papyrus/engine/PapyrusPageViewManager.java +16 -16
  12. package/android/src/main/java/com/papyrus/engine/PapyrusPageViewModule.kt +12 -0
  13. package/android/src/main/java/com/papyrus/engine/PapyrusTextHit.java +15 -15
  14. package/android/src/main/java/com/papyrus/engine/PapyrusTextSearch.java +20 -20
  15. package/android/src/main/java/com/papyrus/engine/PapyrusTextSelect.java +20 -20
  16. package/android/src/main/java/com/papyrus/engine/PapyrusTextSelection.java +11 -11
  17. package/dist/index.d.mts +8 -7
  18. package/dist/index.d.ts +8 -7
  19. package/dist/index.js +200 -8
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +201 -9
  22. package/dist/index.mjs.map +1 -1
  23. package/ios/PapyrusNativeEngine.podspec +1 -1
  24. package/ios/PapyrusPageViewManager.m +19 -19
  25. package/package.json +30 -30
  26. package/react-native.config.js +10 -10
@@ -0,0 +1,540 @@
1
+ package com.papyrus.engine
2
+
3
+ import android.content.ContentResolver
4
+ import android.content.Context
5
+ import android.net.Uri
6
+ import android.os.ParcelFileDescriptor
7
+ import android.view.View
8
+ import com.facebook.react.bridge.UiThreadUtil
9
+ import com.shockwave.pdfium.PdfDocument
10
+ import expo.modules.kotlin.Promise
11
+ import expo.modules.kotlin.modules.Module
12
+ import expo.modules.kotlin.modules.ModuleDefinition
13
+ import expo.modules.kotlin.typedarray.Uint8Array
14
+ import java.io.File
15
+ import java.io.FileOutputStream
16
+ import java.io.IOException
17
+ import java.io.InputStream
18
+ import java.lang.reflect.Method
19
+ import java.net.HttpURLConnection
20
+ import java.net.URL
21
+ import java.util.concurrent.ExecutorService
22
+ import java.util.concurrent.Executors
23
+
24
+ class PapyrusNativeEngineModule : Module() {
25
+ private val executor: ExecutorService = Executors.newSingleThreadExecutor()
26
+
27
+ override fun definition() = ModuleDefinition {
28
+ Name("PapyrusNativeEngine")
29
+
30
+ Function("createEngine") {
31
+ val context = appContext.reactContext ?: return@Function "default"
32
+ PapyrusEngineStore.createEngine(context)
33
+ }
34
+
35
+ Function("destroyEngine") { engineId: String ->
36
+ PapyrusEngineStore.destroyEngine(engineId)
37
+ }
38
+
39
+ AsyncFunction("load") { engineId: String, source: Map<String, Any?>, promise: Promise ->
40
+ executor.execute {
41
+ try {
42
+ val state = PapyrusEngineStore.getEngine(engineId)
43
+ if (state == null) {
44
+ promise.reject("papyrus_no_engine", "Engine not found", null)
45
+ return@execute
46
+ }
47
+
48
+ val context = appContext.reactContext ?: throw IllegalStateException("React context missing")
49
+ val file = materializeSource(source, context)
50
+ if (file == null) {
51
+ promise.reject("papyrus_invalid_source", "Unsupported PDF source", null)
52
+ return@execute
53
+ }
54
+
55
+ val fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
56
+ val document = state.pdfium.newDocument(fd)
57
+ PapyrusEngineStore.setDocument(state, document, fd, file.absolutePath)
58
+
59
+ val pageCount = state.pdfium.getPageCount(document)
60
+ promise.resolve(mapOf("pageCount" to pageCount))
61
+ } catch (error: Throwable) {
62
+ promise.reject("papyrus_load_failed", error.message, error)
63
+ }
64
+ }
65
+ }
66
+
67
+ Function("getPageCount") { engineId: String ->
68
+ val state = PapyrusEngineStore.getEngine(engineId)
69
+ if (state == null || state.document == null) return@Function 0
70
+ state.pdfium.getPageCount(state.document)
71
+ }
72
+
73
+ AsyncFunction("renderPage") { engineId: String, pageIndex: Int, target: Int, scale: Double, zoom: Double, rotation: Int ->
74
+ val state = PapyrusEngineStore.getEngine(engineId) ?: return@AsyncFunction
75
+ UiThreadUtil.runOnUiThread {
76
+ val view = appContext.findView<View>(target)
77
+ if (view is PapyrusPageView) {
78
+ view.render(state, pageIndex, scale.toFloat(), zoom.toFloat(), rotation)
79
+ }
80
+ }
81
+ }
82
+
83
+ AsyncFunction("renderTextLayer") { engineId: String, pageIndex: Int, target: Int, scale: Double, zoom: Double, rotation: Int ->
84
+ // no-op
85
+ Unit
86
+ }
87
+
88
+ AsyncFunction("getTextContent") { engineId: String, pageIndex: Int, promise: Promise ->
89
+ executor.execute {
90
+ val state = PapyrusEngineStore.getEngine(engineId)
91
+ if (state == null || state.document == null) {
92
+ promise.resolve(emptyList<Any>())
93
+ return@execute
94
+ }
95
+ val text = synchronized(state.pdfiumLock) { extractPageText(state, pageIndex) }
96
+ val items = mutableListOf<Map<String, Any>>()
97
+ if (!text.isNullOrEmpty()) {
98
+ items.add(
99
+ mapOf(
100
+ "str" to text,
101
+ "dir" to "ltr",
102
+ "width" to 0,
103
+ "height" to 0,
104
+ "transform" to listOf(1, 0, 0, 1, 0, 0),
105
+ "fontName" to ""
106
+ )
107
+ )
108
+ }
109
+ promise.resolve(items)
110
+ }
111
+ }
112
+
113
+ AsyncFunction("getPageDimensions") { engineId: String, pageIndex: Int, promise: Promise ->
114
+ executor.execute {
115
+ val state = PapyrusEngineStore.getEngine(engineId)
116
+ if (state == null || state.document == null) {
117
+ promise.resolve(mapOf("width" to 0, "height" to 0))
118
+ return@execute
119
+ }
120
+ val (width, height) = synchronized(state.pdfiumLock) {
121
+ val w = state.pdfium.getPageWidthPoint(state.document, pageIndex)
122
+ val h = state.pdfium.getPageHeightPoint(state.document, pageIndex)
123
+ Pair(w, h)
124
+ }
125
+ promise.resolve(mapOf("width" to width, "height" to height))
126
+ }
127
+ }
128
+
129
+ AsyncFunction("getOutline") { engineId: String, promise: Promise ->
130
+ executor.execute {
131
+ val state = PapyrusEngineStore.getEngine(engineId)
132
+ if (state == null || state.document == null) {
133
+ promise.resolve(emptyList<Any>())
134
+ return@execute
135
+ }
136
+
137
+ var items: Array<PapyrusOutlineItem>? = null
138
+ try {
139
+ if (PapyrusOutline.AVAILABLE) {
140
+ if (!state.sourcePath.isNullOrEmpty()) {
141
+ synchronized(state.pdfiumLock) {
142
+ items = PapyrusOutline.nativeGetOutlineFile(state.sourcePath)
143
+ }
144
+ } else {
145
+ val docPtr = synchronized(state.pdfiumLock) { extractNativeDocPointer(state.document) }
146
+ if (docPtr != 0L) {
147
+ synchronized(state.pdfiumLock) {
148
+ items = PapyrusOutline.nativeGetOutline(docPtr)
149
+ }
150
+ }
151
+ }
152
+ }
153
+ } catch (_: Throwable) {
154
+ items = null
155
+ }
156
+
157
+ val result = mutableListOf<Map<String, Any?>>()
158
+ items?.forEach { item ->
159
+ result.add(serializeOutlineItem(item))
160
+ }
161
+ promise.resolve(result)
162
+ }
163
+ }
164
+
165
+ AsyncFunction("getPageIndex") { engineId: String, dest: Map<String, Any?>, promise: Promise ->
166
+ val kind = dest["kind"] as? String
167
+ val value = dest["value"]
168
+
169
+ if (kind == "pageIndex" && value is Number) {
170
+ promise.resolve(value.toInt())
171
+ return@AsyncFunction
172
+ }
173
+
174
+ if (kind == "pageNumber" && value is Number) {
175
+ promise.resolve(maxOf(0, value.toInt() - 1))
176
+ return@AsyncFunction
177
+ }
178
+
179
+ promise.resolve(null)
180
+ }
181
+
182
+ AsyncFunction("searchText") { engineId: String, query: String, promise: Promise ->
183
+ executor.execute {
184
+ val state = PapyrusEngineStore.getEngine(engineId)
185
+ if (state == null || state.document == null || query.length < 2) {
186
+ promise.resolve(emptyList<Any>())
187
+ return@execute
188
+ }
189
+
190
+ val pageCount = state.pdfium.getPageCount(state.document)
191
+ state.isSearching = true
192
+ try {
193
+ try {
194
+ if (PapyrusTextSearch.AVAILABLE) {
195
+ var hits: Array<PapyrusTextHit>? = null
196
+ if (!state.sourcePath.isNullOrEmpty()) {
197
+ synchronized(state.pdfiumLock) {
198
+ hits = PapyrusTextSearch.nativeSearchFile(state.sourcePath, query)
199
+ }
200
+ } else {
201
+ val docPtr = synchronized(state.pdfiumLock) { extractNativeDocPointer(state.document) }
202
+ if (docPtr != 0L) {
203
+ synchronized(state.pdfiumLock) {
204
+ hits = PapyrusTextSearch.nativeSearch(docPtr, pageCount, query)
205
+ }
206
+ }
207
+ }
208
+
209
+ if (!hits.isNullOrEmpty()) {
210
+ val results = mutableListOf<Map<String, Any?>>()
211
+ hits?.forEach { hit ->
212
+ val result = mutableMapOf<String, Any?>(
213
+ "pageIndex" to hit.pageIndex,
214
+ "text" to (hit.text ?: query),
215
+ "matchIndex" to hit.matchIndex
216
+ )
217
+ val rects = hit.rects
218
+ if (rects != null && rects.size >= 4) {
219
+ val rectList = mutableListOf<Map<String, Any>>()
220
+ var i = 0
221
+ while (i + 3 < rects.size) {
222
+ rectList.add(
223
+ mapOf(
224
+ "x" to rects[i],
225
+ "y" to rects[i + 1],
226
+ "width" to rects[i + 2],
227
+ "height" to rects[i + 3]
228
+ )
229
+ )
230
+ i += 4
231
+ }
232
+ result["rects"] = rectList
233
+ }
234
+ results.add(result)
235
+ }
236
+ promise.resolve(results)
237
+ return@execute
238
+ }
239
+ }
240
+ } catch (_: Throwable) {
241
+ }
242
+
243
+ val normalizedQuery = query.lowercase()
244
+ val results = mutableListOf<Map<String, Any?>>()
245
+
246
+ for (pageIndex in 0 until pageCount) {
247
+ val text = synchronized(state.pdfiumLock) { extractPageText(state, pageIndex) } ?: ""
248
+ if (text.isEmpty()) continue
249
+
250
+ val lower = text.lowercase()
251
+ var pos = lower.indexOf(normalizedQuery)
252
+ var matchIndex = 0
253
+ while (pos != -1) {
254
+ val start = maxOf(0, pos - 20)
255
+ val end = minOf(text.length, pos + normalizedQuery.length + 20)
256
+ val preview = text.substring(start, end)
257
+
258
+ results.add(
259
+ mapOf(
260
+ "pageIndex" to pageIndex,
261
+ "text" to preview,
262
+ "matchIndex" to matchIndex++
263
+ )
264
+ )
265
+
266
+ pos = lower.indexOf(normalizedQuery, pos + 1)
267
+ }
268
+ }
269
+
270
+ promise.resolve(results)
271
+ } finally {
272
+ state.isSearching = false
273
+ }
274
+ }
275
+ }
276
+
277
+ AsyncFunction("selectText") { engineId: String, pageIndex: Int, x: Double, y: Double, width: Double, height: Double, promise: Promise ->
278
+ executor.execute {
279
+ val state = PapyrusEngineStore.getEngine(engineId)
280
+ if (state == null || state.document == null || pageIndex < 0) {
281
+ promise.resolve(null)
282
+ return@execute
283
+ }
284
+
285
+ if (!PapyrusTextSelect.AVAILABLE) {
286
+ promise.resolve(null)
287
+ return@execute
288
+ }
289
+
290
+ var selection: PapyrusTextSelection? = null
291
+ try {
292
+ if (!state.sourcePath.isNullOrEmpty()) {
293
+ synchronized(state.pdfiumLock) {
294
+ selection = PapyrusTextSelect.nativeSelectTextFile(
295
+ state.sourcePath,
296
+ pageIndex,
297
+ x.toFloat(),
298
+ y.toFloat(),
299
+ width.toFloat(),
300
+ height.toFloat()
301
+ )
302
+ }
303
+ } else {
304
+ val docPtr = synchronized(state.pdfiumLock) { extractNativeDocPointer(state.document) }
305
+ if (docPtr != 0L) {
306
+ synchronized(state.pdfiumLock) {
307
+ selection = PapyrusTextSelect.nativeSelectText(
308
+ docPtr,
309
+ pageIndex,
310
+ x.toFloat(),
311
+ y.toFloat(),
312
+ width.toFloat(),
313
+ height.toFloat()
314
+ )
315
+ }
316
+ }
317
+ }
318
+ } catch (_: Throwable) {
319
+ selection = null
320
+ }
321
+
322
+ val rects = selection?.rects
323
+ if (selection == null || rects == null || rects.isEmpty()) {
324
+ promise.resolve(null)
325
+ return@execute
326
+ }
327
+
328
+ val rectList = mutableListOf<Map<String, Any>>()
329
+ var i = 0
330
+ while (i + 3 < rects.size) {
331
+ rectList.add(
332
+ mapOf(
333
+ "x" to rects[i],
334
+ "y" to rects[i + 1],
335
+ "width" to rects[i + 2],
336
+ "height" to rects[i + 3]
337
+ )
338
+ )
339
+ i += 4
340
+ }
341
+
342
+ promise.resolve(
343
+ mapOf(
344
+ "text" to (selection?.text ?: ""),
345
+ "rects" to rectList
346
+ )
347
+ )
348
+ }
349
+ }
350
+ }
351
+
352
+ private fun extractPageText(state: PapyrusEngineStore.EngineState, pageIndex: Int): String? {
353
+ try {
354
+ state.pdfium.openPage(state.document, pageIndex)
355
+ } catch (_: Throwable) {
356
+ }
357
+
358
+ try {
359
+ var method: Method? = null
360
+ method = try {
361
+ state.pdfium.javaClass.getDeclaredMethod("getPageText", PdfDocument::class.java, Int::class.javaPrimitiveType)
362
+ } catch (_: NoSuchMethodException) {
363
+ null
364
+ }
365
+
366
+ if (method == null) {
367
+ method = try {
368
+ state.pdfium.javaClass.getDeclaredMethod("nativeGetPageText", Long::class.javaPrimitiveType, Int::class.javaPrimitiveType)
369
+ } catch (_: NoSuchMethodException) {
370
+ null
371
+ }
372
+ }
373
+
374
+ if (method != null) {
375
+ method.isAccessible = true
376
+ val result = if (method.parameterTypes.size == 2 && method.parameterTypes[0] == PdfDocument::class.java) {
377
+ method.invoke(state.pdfium, state.document, pageIndex)
378
+ } else if (method.parameterTypes.size == 2 && method.parameterTypes[0] == Long::class.javaPrimitiveType) {
379
+ val docPtr = extractNativeDocPointer(state.document)
380
+ method.invoke(state.pdfium, docPtr, pageIndex)
381
+ } else {
382
+ null
383
+ }
384
+ return result?.toString() ?: ""
385
+ }
386
+ } catch (_: Throwable) {
387
+ }
388
+
389
+ return ""
390
+ }
391
+
392
+ private fun extractNativeDocPointer(document: PdfDocument?): Long {
393
+ if (document == null) return 0L
394
+ return try {
395
+ val field = PdfDocument::class.java.getDeclaredField("mNativeDocPtr")
396
+ field.isAccessible = true
397
+ val value = field.get(document)
398
+ if (value is Long) value else 0L
399
+ } catch (_: Throwable) {
400
+ 0L
401
+ }
402
+ }
403
+
404
+ private fun serializeOutlineItem(item: PapyrusOutlineItem): Map<String, Any?> {
405
+ val map = mutableMapOf<String, Any?>(
406
+ "title" to (item.title ?: ""),
407
+ "pageIndex" to item.pageIndex
408
+ )
409
+ val children = item.children
410
+ if (children != null && children.isNotEmpty()) {
411
+ val childMaps = mutableListOf<Map<String, Any?>>()
412
+ children.forEach { child ->
413
+ childMaps.add(serializeOutlineItem(child))
414
+ }
415
+ map["children"] = childMaps
416
+ }
417
+ return map
418
+ }
419
+
420
+ @Throws(IOException::class)
421
+ private fun materializeSource(source: Map<String, Any?>, context: Context): File? {
422
+ val uriValue = source["uri"]
423
+ if (uriValue is String) {
424
+ if (uriValue.startsWith("http://") || uriValue.startsWith("https://")) {
425
+ return downloadToCache(uriValue, context)
426
+ }
427
+
428
+ if (uriValue.startsWith("asset:/")) {
429
+ return copyFromAsset(uriValue.substring("asset:/".length), context)
430
+ }
431
+
432
+ if (uriValue.startsWith("file:///android_asset/")) {
433
+ return copyFromAsset(uriValue.substring("file:///android_asset/".length), context)
434
+ }
435
+
436
+ if (uriValue.startsWith("content://")) {
437
+ return copyFromContentUri(Uri.parse(uriValue), context)
438
+ }
439
+
440
+ if (uriValue.startsWith("file://")) {
441
+ return File(Uri.parse(uriValue).path ?: return null)
442
+ }
443
+
444
+ return File(uriValue)
445
+ }
446
+
447
+ val dataValue = source["data"]
448
+ if (dataValue != null) {
449
+ val bytes = toByteArray(dataValue)
450
+ if (bytes != null) {
451
+ return writeBytesToCache(bytes, context)
452
+ }
453
+ }
454
+
455
+ return null
456
+ }
457
+
458
+ private fun toByteArray(value: Any): ByteArray? {
459
+ return when (value) {
460
+ is ByteArray -> value
461
+ is Uint8Array -> {
462
+ val bytes = ByteArray(value.byteLength)
463
+ value.read(bytes, 0, value.byteLength)
464
+ bytes
465
+ }
466
+ is List<*> -> {
467
+ val bytes = ByteArray(value.size)
468
+ value.forEachIndexed { index, item ->
469
+ val number = item as? Number ?: return null
470
+ bytes[index] = number.toInt().toByte()
471
+ }
472
+ bytes
473
+ }
474
+ else -> null
475
+ }
476
+ }
477
+
478
+ @Throws(IOException::class)
479
+ private fun downloadToCache(uri: String, context: Context): File {
480
+ val url = URL(uri)
481
+ val connection = url.openConnection() as HttpURLConnection
482
+ connection.connect()
483
+ if (connection.responseCode >= 400) {
484
+ throw IOException("Failed to download PDF")
485
+ }
486
+ val inputStream = connection.inputStream
487
+ val out = createTempFile(context)
488
+ writeStreamToFile(inputStream, out)
489
+ connection.disconnect()
490
+ return out
491
+ }
492
+
493
+ @Throws(IOException::class)
494
+ private fun copyFromContentUri(uri: Uri, context: Context): File {
495
+ val resolver: ContentResolver = context.contentResolver
496
+ val inputStream = resolver.openInputStream(uri) ?: throw IOException("Unable to read content URI")
497
+ val out = createTempFile(context)
498
+ writeStreamToFile(inputStream, out)
499
+ return out
500
+ }
501
+
502
+ @Throws(IOException::class)
503
+ private fun copyFromAsset(assetPath: String, context: Context): File {
504
+ val inputStream = context.assets.open(assetPath)
505
+ val out = createTempFile(context)
506
+ writeStreamToFile(inputStream, out)
507
+ return out
508
+ }
509
+
510
+ @Throws(IOException::class)
511
+ private fun writeBytesToCache(bytes: ByteArray, context: Context): File {
512
+ val out = createTempFile(context)
513
+ FileOutputStream(out).use { fos ->
514
+ fos.write(bytes)
515
+ fos.flush()
516
+ }
517
+ return out
518
+ }
519
+
520
+ @Throws(IOException::class)
521
+ private fun createTempFile(context: Context): File {
522
+ val cacheDir = context.cacheDir
523
+ return File.createTempFile("papyrus", ".pdf", cacheDir)
524
+ }
525
+
526
+ @Throws(IOException::class)
527
+ private fun writeStreamToFile(inputStream: InputStream, out: File) {
528
+ FileOutputStream(out).use { fos ->
529
+ val buffer = ByteArray(8192)
530
+ var read: Int
531
+ while (true) {
532
+ read = inputStream.read(buffer)
533
+ if (read == -1) break
534
+ fos.write(buffer, 0, read)
535
+ }
536
+ fos.flush()
537
+ }
538
+ inputStream.close()
539
+ }
540
+ }
@@ -1,20 +1,20 @@
1
- package com.papyrus.engine;
2
-
3
- final class PapyrusOutline {
4
- static final boolean AVAILABLE;
5
-
6
- static {
7
- boolean available = false;
8
- try {
9
- System.loadLibrary("papyrus_text");
10
- available = true;
11
- } catch (Throwable ignored) {
12
- available = false;
13
- }
14
- AVAILABLE = available;
15
- }
16
-
17
- static native PapyrusOutlineItem[] nativeGetOutline(long docPtr);
18
-
19
- static native PapyrusOutlineItem[] nativeGetOutlineFile(String filePath);
20
- }
1
+ package com.papyrus.engine;
2
+
3
+ final class PapyrusOutline {
4
+ static final boolean AVAILABLE;
5
+
6
+ static {
7
+ boolean available = false;
8
+ try {
9
+ System.loadLibrary("papyrus_text");
10
+ available = true;
11
+ } catch (Throwable ignored) {
12
+ available = false;
13
+ }
14
+ AVAILABLE = available;
15
+ }
16
+
17
+ static native PapyrusOutlineItem[] nativeGetOutline(long docPtr);
18
+
19
+ static native PapyrusOutlineItem[] nativeGetOutlineFile(String filePath);
20
+ }
@@ -1,13 +1,13 @@
1
- package com.papyrus.engine;
2
-
3
- final class PapyrusOutlineItem {
4
- final String title;
5
- final int pageIndex;
6
- final PapyrusOutlineItem[] children;
7
-
8
- PapyrusOutlineItem(String title, int pageIndex, PapyrusOutlineItem[] children) {
9
- this.title = title != null ? title : "";
10
- this.pageIndex = pageIndex;
11
- this.children = children;
12
- }
13
- }
1
+ package com.papyrus.engine;
2
+
3
+ final class PapyrusOutlineItem {
4
+ final String title;
5
+ final int pageIndex;
6
+ final PapyrusOutlineItem[] children;
7
+
8
+ PapyrusOutlineItem(String title, int pageIndex, PapyrusOutlineItem[] children) {
9
+ this.title = title != null ? title : "";
10
+ this.pageIndex = pageIndex;
11
+ this.children = children;
12
+ }
13
+ }
@@ -1,24 +1,24 @@
1
- package com.papyrus.engine;
2
-
3
- import com.facebook.react.ReactPackage;
4
- import com.facebook.react.bridge.NativeModule;
5
- import com.facebook.react.bridge.ReactApplicationContext;
6
- import com.facebook.react.uimanager.ViewManager;
7
-
8
- import java.util.ArrayList;
9
- import java.util.Collections;
10
- import java.util.List;
11
-
12
- public class PapyrusPackage implements ReactPackage {
13
- @Override
14
- public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
15
- List<NativeModule> modules = new ArrayList<>();
16
- modules.add(new PapyrusNativeEngineModule(reactContext));
17
- return modules;
18
- }
19
-
20
- @Override
21
- public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
22
- return Collections.singletonList(new PapyrusPageViewManager());
23
- }
24
- }
1
+ package com.papyrus.engine;
2
+
3
+ import com.facebook.react.ReactPackage;
4
+ import com.facebook.react.bridge.NativeModule;
5
+ import com.facebook.react.bridge.ReactApplicationContext;
6
+ import com.facebook.react.uimanager.ViewManager;
7
+
8
+ import java.util.ArrayList;
9
+ import java.util.Collections;
10
+ import java.util.List;
11
+
12
+ public class PapyrusPackage implements ReactPackage {
13
+ @Override
14
+ public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
15
+ List<NativeModule> modules = new ArrayList<>();
16
+ modules.add(new PapyrusNativeEngineModule(reactContext));
17
+ return modules;
18
+ }
19
+
20
+ @Override
21
+ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
22
+ return Collections.singletonList(new PapyrusPageViewManager());
23
+ }
24
+ }