@thatkid02/react-native-pdf-viewer 0.0.1 → 0.0.3
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 +40 -10
- package/android/src/main/java/com/margelo/nitro/pdfviewer/HybridPdfViewer.kt +24 -0
- package/android/src/main/java/com/margelo/nitro/pdfviewer/PdfViewer.kt +187 -14
- package/ios/PdfViewer.swift +107 -18
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/PdfViewer.nitro.d.ts +19 -0
- package/lib/typescript/src/PdfViewer.nitro.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridPdfViewerSpec.cpp +36 -0
- package/nitrogen/generated/android/c++/JHybridPdfViewerSpec.hpp +8 -0
- package/nitrogen/generated/android/c++/views/JHybridPdfViewerStateUpdater.cpp +16 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/pdfviewer/HybridPdfViewerSpec.kt +24 -0
- package/nitrogen/generated/ios/c++/HybridPdfViewerSpecSwift.hpp +28 -0
- package/nitrogen/generated/ios/c++/views/HybridPdfViewerComponent.mm +20 -0
- package/nitrogen/generated/ios/swift/HybridPdfViewerSpec.swift +4 -0
- package/nitrogen/generated/ios/swift/HybridPdfViewerSpec_cxx.swift +68 -0
- package/nitrogen/generated/shared/c++/HybridPdfViewerSpec.cpp +8 -0
- package/nitrogen/generated/shared/c++/HybridPdfViewerSpec.hpp +8 -0
- package/nitrogen/generated/shared/c++/views/HybridPdfViewerComponent.cpp +48 -0
- package/nitrogen/generated/shared/c++/views/HybridPdfViewerComponent.hpp +4 -0
- package/nitrogen/generated/shared/json/PdfViewerConfig.json +4 -0
- package/package.json +1 -1
- package/src/PdfViewer.nitro.ts +21 -0
- package/src/index.tsx +2 -1
package/README.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# react-native-pdf-viewer
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@thatkid02/react-native-pdf-viewer)
|
|
4
|
+
[](https://www.npmjs.com/package/@thatkid02/react-native-pdf-viewer)
|
|
5
|
+
|
|
3
6
|
High-performance PDF viewer for React Native, built with [Nitro Modules](https://nitro.margelo.com/) for native rendering performance.
|
|
4
7
|
|
|
8
|
+
<video src="docs/pdf.mp4" controls></video>
|
|
9
|
+
|
|
5
10
|
## Features
|
|
6
11
|
|
|
7
12
|
✅ **High-performance PDF rendering** with native APIs (PDFKit on iOS, PdfRenderer on Android)
|
|
@@ -28,7 +33,7 @@ High-performance PDF viewer for React Native, built with [Nitro Modules](https:/
|
|
|
28
33
|
## Installation
|
|
29
34
|
|
|
30
35
|
```sh
|
|
31
|
-
npm install react-native-pdf-viewer react-native-nitro-modules
|
|
36
|
+
npm install @thatkid02/react-native-pdf-viewer react-native-nitro-modules
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
> `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
|
|
@@ -38,7 +43,7 @@ npm install react-native-pdf-viewer react-native-nitro-modules
|
|
|
38
43
|
### Basic Example
|
|
39
44
|
|
|
40
45
|
```tsx
|
|
41
|
-
import { PdfViewerView } from 'react-native-pdf-viewer';
|
|
46
|
+
import { PdfViewerView } from '@thatkid02/react-native-pdf-viewer';
|
|
42
47
|
|
|
43
48
|
export default function App() {
|
|
44
49
|
return (
|
|
@@ -58,10 +63,12 @@ export default function App() {
|
|
|
58
63
|
|
|
59
64
|
### Advanced Example with All Features
|
|
60
65
|
|
|
66
|
+
- callback is exposed by nitro modules to avoid re-renders [here](https://nitro.margelo.com/docs/view-components#callbacks-have-to-be-wrapped)
|
|
67
|
+
|
|
61
68
|
```tsx
|
|
62
69
|
import React, { useRef } from 'react';
|
|
63
70
|
import { View, Button, StyleSheet } from 'react-native';
|
|
64
|
-
import { PdfViewerView, type PdfViewer } from 'react-native-pdf-viewer';
|
|
71
|
+
import { PdfViewerView, type PdfViewer } from '@thatkid02/react-native-pdf-viewer';
|
|
65
72
|
|
|
66
73
|
export default function AdvancedPdfViewer() {
|
|
67
74
|
const pdfRef = useRef<PdfViewer>(null);
|
|
@@ -94,10 +101,11 @@ export default function AdvancedPdfViewer() {
|
|
|
94
101
|
pdfRef.current?.setScale(2.0);
|
|
95
102
|
};
|
|
96
103
|
|
|
104
|
+
|
|
97
105
|
return (
|
|
98
106
|
<View style={styles.container}>
|
|
99
107
|
<PdfViewerView
|
|
100
|
-
|
|
108
|
+
hybridRef={callback((ref: PdfViewerRef | null) => {
|
|
101
109
|
source="https://example.com/document.pdf"
|
|
102
110
|
style={styles.pdf}
|
|
103
111
|
// Layout options
|
|
@@ -111,12 +119,12 @@ export default function AdvancedPdfViewer() {
|
|
|
111
119
|
// Loading indicator
|
|
112
120
|
showsActivityIndicator={true}
|
|
113
121
|
// Event handlers
|
|
114
|
-
onLoadComplete={handleLoadComplete}
|
|
115
|
-
onPageChange={handlePageChange}
|
|
116
|
-
onScaleChange={handleScaleChange}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
onLoadingChange={(
|
|
122
|
+
onLoadComplete={callback(handleLoadComplete)}
|
|
123
|
+
onPageChange={callback(handlePageChange)}
|
|
124
|
+
onScaleChange={callback(handleScaleChange)}
|
|
125
|
+
onError={callback(handleError)}
|
|
126
|
+
onThumbnailGenerated={callback(handleThumbnailGenerated)}
|
|
127
|
+
onLoadingChange={callback(handleLoadingChange)}
|
|
120
128
|
/>
|
|
121
129
|
|
|
122
130
|
<View style={styles.controls}>
|
|
@@ -183,6 +191,10 @@ const styles = StyleSheet.create({
|
|
|
183
191
|
| `showsActivityIndicator` | `boolean` | `true` | Show loading indicator |
|
|
184
192
|
| `horizontal` | `boolean` | `false` | Horizontal scroll (iOS only) |
|
|
185
193
|
| `enablePaging` | `boolean` | `false` | Enable paging mode (iOS only) |
|
|
194
|
+
| `contentInsetTop` | `number` | `0` | Top content inset (for glass topbars) |
|
|
195
|
+
| `contentInsetBottom` | `number` | `0` | Bottom content inset (for glass toolbars) |
|
|
196
|
+
| `contentInsetLeft` | `number` | `0` | Left content inset |
|
|
197
|
+
| `contentInsetRight` | `number` | `0` | Right content inset |
|
|
186
198
|
| `onLoadComplete` | `(event) => void` | - | Called when PDF loads |
|
|
187
199
|
| `onPageChange` | `(event) => void` | - | Called when page changes |
|
|
188
200
|
| `onScaleChange` | `(event) => void` | - | Called when zoom changes |
|
|
@@ -190,6 +202,24 @@ const styles = StyleSheet.create({
|
|
|
190
202
|
| `onThumbnailGenerated` | `(event) => void` | - | Called when thumbnail is ready |
|
|
191
203
|
| `onLoadingChange` | `(event) => void` | - | Called when loading state changes |
|
|
192
204
|
|
|
205
|
+
#### Glass UI / Transparent Bars
|
|
206
|
+
|
|
207
|
+
Use `contentInset` props to make the PDF scroll behind transparent headers and toolbars:
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
<PdfViewerView
|
|
211
|
+
source="https://example.com/document.pdf"
|
|
212
|
+
contentInsetTop={80} // Height of your transparent top bar
|
|
213
|
+
contentInsetBottom={60} // Height of your transparent bottom toolbar
|
|
214
|
+
style={{ flex: 1 }}
|
|
215
|
+
/>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This creates a modern "glass" effect where:
|
|
219
|
+
- PDF content starts below the top bar
|
|
220
|
+
- Content scrolls behind transparent bars
|
|
221
|
+
- Content ends above the bottom toolbar
|
|
222
|
+
|
|
193
223
|
### Methods
|
|
194
224
|
|
|
195
225
|
Access methods via ref:
|
|
@@ -138,6 +138,30 @@ class HybridPdfViewer(private val reactContext: ThemedReactContext) : HybridPdfV
|
|
|
138
138
|
value?.let { documentViewer.showsActivityIndicator = it }
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
override var contentInsetTop: Double? = null
|
|
142
|
+
set(value) {
|
|
143
|
+
field = value
|
|
144
|
+
value?.let { documentViewer.contentInsetTop = it.toFloat() }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
override var contentInsetBottom: Double? = null
|
|
148
|
+
set(value) {
|
|
149
|
+
field = value
|
|
150
|
+
value?.let { documentViewer.contentInsetBottom = it.toFloat() }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
override var contentInsetLeft: Double? = null
|
|
154
|
+
set(value) {
|
|
155
|
+
field = value
|
|
156
|
+
value?.let { documentViewer.contentInsetLeft = it.toFloat() }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
override var contentInsetRight: Double? = null
|
|
160
|
+
set(value) {
|
|
161
|
+
field = value
|
|
162
|
+
value?.let { documentViewer.contentInsetRight = it.toFloat() }
|
|
163
|
+
}
|
|
164
|
+
|
|
141
165
|
// Event callbacks - these are set by Nitro
|
|
142
166
|
override var onLoadComplete: ((event: LoadCompleteEvent) -> Unit)? = null
|
|
143
167
|
override var onPageChange: ((event: PageChangeEvent) -> Unit)? = null
|
|
@@ -102,6 +102,28 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
102
102
|
var minScale: Float = 0.5f
|
|
103
103
|
var maxScale: Float = 4.0f
|
|
104
104
|
|
|
105
|
+
// Content insets for glass UI / transparent bars
|
|
106
|
+
var contentInsetTop: Float = 0f
|
|
107
|
+
set(value) {
|
|
108
|
+
field = value
|
|
109
|
+
updateContentInsets()
|
|
110
|
+
}
|
|
111
|
+
var contentInsetBottom: Float = 0f
|
|
112
|
+
set(value) {
|
|
113
|
+
field = value
|
|
114
|
+
updateContentInsets()
|
|
115
|
+
}
|
|
116
|
+
var contentInsetLeft: Float = 0f
|
|
117
|
+
set(value) {
|
|
118
|
+
field = value
|
|
119
|
+
updateContentInsets()
|
|
120
|
+
}
|
|
121
|
+
var contentInsetRight: Float = 0f
|
|
122
|
+
set(value) {
|
|
123
|
+
field = value
|
|
124
|
+
updateContentInsets()
|
|
125
|
+
}
|
|
126
|
+
|
|
105
127
|
// Callbacks for HybridPdfViewer integration
|
|
106
128
|
var onLoadCompleteCallback: ((pageCount: Int, pageWidth: Int, pageHeight: Int) -> Unit)? = null
|
|
107
129
|
var onPageChangeCallback: ((page: Int, pageCount: Int) -> Unit)? = null
|
|
@@ -125,6 +147,9 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
125
147
|
|
|
126
148
|
// Allow parent to intercept touch events for pinch-to-zoom
|
|
127
149
|
requestDisallowInterceptTouchEvent(false)
|
|
150
|
+
|
|
151
|
+
// Enable drawing content under padding (for glass UI effect)
|
|
152
|
+
clipToPadding = false
|
|
128
153
|
}
|
|
129
154
|
|
|
130
155
|
loadingIndicator = ProgressBar(context).apply {
|
|
@@ -191,6 +216,17 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
191
216
|
})
|
|
192
217
|
}
|
|
193
218
|
|
|
219
|
+
private fun updateContentInsets() {
|
|
220
|
+
// Apply content insets as padding
|
|
221
|
+
// clipToPadding=false allows content to draw under padding (glass UI effect)
|
|
222
|
+
recyclerView.setPadding(
|
|
223
|
+
contentInsetLeft.toInt(),
|
|
224
|
+
contentInsetTop.toInt(),
|
|
225
|
+
contentInsetRight.toInt(),
|
|
226
|
+
contentInsetBottom.toInt()
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
|
|
194
230
|
private fun setupRecyclerView() {
|
|
195
231
|
// Android always uses vertical scroll (horizontal is iOS-only)
|
|
196
232
|
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
|
@@ -329,12 +365,7 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
329
365
|
pendingThumbnails.clear()
|
|
330
366
|
lastReportedPage = -1
|
|
331
367
|
|
|
332
|
-
//
|
|
333
|
-
componentScope.launch(Dispatchers.IO) {
|
|
334
|
-
preloadPageDimensions(renderer)
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Get first page dimensions immediately
|
|
368
|
+
// Get first page dimensions immediately for initial render
|
|
338
369
|
val firstDim = try {
|
|
339
370
|
renderMutex.withLock {
|
|
340
371
|
renderer.openPage(0).use { page ->
|
|
@@ -348,6 +379,12 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
348
379
|
Pair(612, 792)
|
|
349
380
|
}
|
|
350
381
|
|
|
382
|
+
// Preload a few more page dimensions in background (non-blocking)
|
|
383
|
+
// This helps with initial scrolling but doesn't delay the initial render
|
|
384
|
+
componentScope.launch(Dispatchers.IO) {
|
|
385
|
+
preloadInitialPageDimensions(renderer)
|
|
386
|
+
}
|
|
387
|
+
|
|
351
388
|
adapter = PdfPageAdapter()
|
|
352
389
|
recyclerView.adapter = adapter
|
|
353
390
|
|
|
@@ -359,6 +396,13 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
359
396
|
}
|
|
360
397
|
emitLoadComplete(renderer.pageCount, firstDim.first, firstDim.second)
|
|
361
398
|
|
|
399
|
+
// Force initial layout and render by scrolling slightly
|
|
400
|
+
// This ensures content appears without requiring user interaction
|
|
401
|
+
post {
|
|
402
|
+
recyclerView.scrollBy(0, 2)
|
|
403
|
+
recyclerView.scrollBy(0, -2)
|
|
404
|
+
}
|
|
405
|
+
|
|
362
406
|
schedulePreload()
|
|
363
407
|
}
|
|
364
408
|
} catch (e: SecurityException) {
|
|
@@ -386,18 +430,67 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
386
430
|
}
|
|
387
431
|
}
|
|
388
432
|
|
|
389
|
-
|
|
390
|
-
|
|
433
|
+
// Preload only first few pages (non-blocking) for better initial experience
|
|
434
|
+
private suspend fun preloadInitialPageDimensions(renderer: PdfRenderer) {
|
|
435
|
+
// Preload first 5-10 pages to improve initial scrolling
|
|
436
|
+
val pagesToPreload = minOf(10, renderer.pageCount)
|
|
437
|
+
for (i in 1 until pagesToPreload) { // Start from 1 since 0 is already loaded
|
|
391
438
|
try {
|
|
439
|
+
kotlinx.coroutines.delay(50) // Small delay to not block other operations
|
|
392
440
|
renderMutex.withLock {
|
|
393
|
-
|
|
394
|
-
|
|
441
|
+
if (pageDimensions[i] == null) { // Only if not already loaded
|
|
442
|
+
renderer.openPage(i).use { page ->
|
|
443
|
+
pageDimensions[i] = Pair(page.width, page.height)
|
|
444
|
+
}
|
|
395
445
|
}
|
|
396
446
|
}
|
|
397
447
|
} catch (e: Exception) {
|
|
398
448
|
Log.e(TAG, "Error preloading page $i dimensions", e)
|
|
399
449
|
}
|
|
400
450
|
}
|
|
451
|
+
|
|
452
|
+
// Lazily load remaining pages with lower priority
|
|
453
|
+
if (renderer.pageCount > pagesToPreload) {
|
|
454
|
+
for (i in pagesToPreload until renderer.pageCount) {
|
|
455
|
+
try {
|
|
456
|
+
kotlinx.coroutines.delay(100) // Longer delay for non-critical pages
|
|
457
|
+
renderMutex.withLock {
|
|
458
|
+
if (pageDimensions[i] == null) {
|
|
459
|
+
renderer.openPage(i).use { page ->
|
|
460
|
+
pageDimensions[i] = Pair(page.width, page.height)
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
} catch (e: Exception) {
|
|
465
|
+
Log.e(TAG, "Error preloading page $i dimensions", e)
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Get page dimensions on-demand if not already cached
|
|
472
|
+
private suspend fun getPageDimensions(pageIndex: Int): Pair<Int, Int> {
|
|
473
|
+
// Return cached if available
|
|
474
|
+
pageDimensions[pageIndex]?.let { return it }
|
|
475
|
+
|
|
476
|
+
// Load on-demand
|
|
477
|
+
val renderer = pdfRenderer ?: return Pair(612, 792) // Standard page size fallback
|
|
478
|
+
|
|
479
|
+
return try {
|
|
480
|
+
renderMutex.withLock {
|
|
481
|
+
// Check again inside lock in case another thread loaded it
|
|
482
|
+
pageDimensions[pageIndex] ?: run {
|
|
483
|
+
renderer.openPage(pageIndex).use { page ->
|
|
484
|
+
Pair(page.width, page.height).also {
|
|
485
|
+
pageDimensions[pageIndex] = it
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
} catch (e: Exception) {
|
|
491
|
+
Log.e(TAG, "Error loading page $pageIndex dimensions", e)
|
|
492
|
+
Pair(612, 792) // Fallback
|
|
493
|
+
}
|
|
401
494
|
}
|
|
402
495
|
|
|
403
496
|
private fun closePdfRenderer() {
|
|
@@ -445,18 +538,81 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
445
538
|
uri.startsWith("http://") || uri.startsWith("https://") -> {
|
|
446
539
|
val hash = uri.hashCode().toString()
|
|
447
540
|
val file = File(context.cacheDir, "pdf_$hash.pdf")
|
|
541
|
+
val tempFile = File(context.cacheDir, "pdf_${hash}_temp.pdf")
|
|
542
|
+
|
|
543
|
+
// Check if cached file exists and is reasonably fresh (< 1 hour)
|
|
544
|
+
if (file.exists() && (System.currentTimeMillis() - file.lastModified() < 3600_000)) {
|
|
545
|
+
if (BuildConfig.DEBUG) {
|
|
546
|
+
Log.d(TAG, "Using cached PDF file: ${file.absolutePath}")
|
|
547
|
+
}
|
|
548
|
+
return@withContext file
|
|
549
|
+
}
|
|
448
550
|
|
|
449
|
-
|
|
450
|
-
|
|
551
|
+
// Download with better error handling and progress
|
|
552
|
+
try {
|
|
553
|
+
val url = URL(uri)
|
|
554
|
+
val connection = url.openConnection().apply {
|
|
451
555
|
connectTimeout = 30_000 // 30 seconds
|
|
452
556
|
readTimeout = 60_000 // 60 seconds
|
|
557
|
+
setRequestProperty("Accept", "application/pdf")
|
|
558
|
+
|
|
559
|
+
// Add cache headers for better HTTP caching
|
|
560
|
+
if (file.exists()) {
|
|
561
|
+
setRequestProperty("If-Modified-Since",
|
|
562
|
+
java.text.SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", java.util.Locale.US)
|
|
563
|
+
.apply { timeZone = java.util.TimeZone.getTimeZone("GMT") }
|
|
564
|
+
.format(java.util.Date(file.lastModified())))
|
|
565
|
+
}
|
|
453
566
|
}
|
|
567
|
+
|
|
568
|
+
val contentLength = connection.contentLength
|
|
569
|
+
if (BuildConfig.DEBUG) {
|
|
570
|
+
Log.d(TAG, "Downloading PDF: $uri, size: $contentLength bytes")
|
|
571
|
+
}
|
|
572
|
+
|
|
454
573
|
connection.getInputStream().use { input ->
|
|
455
|
-
FileOutputStream(
|
|
456
|
-
|
|
574
|
+
FileOutputStream(tempFile).use { output ->
|
|
575
|
+
val buffer = ByteArray(8192)
|
|
576
|
+
var bytesRead: Int
|
|
577
|
+
var totalRead = 0
|
|
578
|
+
|
|
579
|
+
while (input.read(buffer).also { bytesRead = it } != -1) {
|
|
580
|
+
output.write(buffer, 0, bytesRead)
|
|
581
|
+
totalRead += bytesRead
|
|
582
|
+
|
|
583
|
+
// Log progress for large files
|
|
584
|
+
if (BuildConfig.DEBUG && contentLength > 0 && totalRead % (contentLength / 10 + 1) == 0) {
|
|
585
|
+
val progress = (totalRead * 100) / contentLength
|
|
586
|
+
Log.d(TAG, "Download progress: $progress%")
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
output.flush()
|
|
457
591
|
}
|
|
458
592
|
}
|
|
593
|
+
|
|
594
|
+
// Move temp file to final location
|
|
595
|
+
if (tempFile.exists()) {
|
|
596
|
+
file.delete() // Remove old cached file
|
|
597
|
+
tempFile.renameTo(file)
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (BuildConfig.DEBUG) {
|
|
601
|
+
Log.d(TAG, "Download completed: ${file.absolutePath}")
|
|
602
|
+
}
|
|
603
|
+
} catch (e: Exception) {
|
|
604
|
+
// Clean up temp file on error
|
|
605
|
+
tempFile.delete()
|
|
606
|
+
|
|
607
|
+
// If download failed but we have an old cached version, use it
|
|
608
|
+
if (file.exists()) {
|
|
609
|
+
Log.w(TAG, "Download failed, using cached version: ${e.message}")
|
|
610
|
+
return@withContext file
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
throw e
|
|
459
614
|
}
|
|
615
|
+
|
|
460
616
|
file
|
|
461
617
|
}
|
|
462
618
|
else -> File(uri)
|
|
@@ -850,6 +1006,23 @@ class PdfViewer(context: Context) : FrameLayout(context) {
|
|
|
850
1006
|
val scale = (viewWidth.toFloat() / dimensions.first) * currentScale
|
|
851
1007
|
val targetHeight = (dimensions.second * scale).toInt().coerceAtLeast(100)
|
|
852
1008
|
holder.imageView.layoutParams.height = targetHeight
|
|
1009
|
+
} else {
|
|
1010
|
+
// Dimensions not loaded yet, use default height and trigger lazy load
|
|
1011
|
+
holder.imageView.layoutParams.height = (viewWidth * 1.414f).toInt().coerceAtLeast(100)
|
|
1012
|
+
|
|
1013
|
+
// Trigger lazy loading of dimensions in background
|
|
1014
|
+
componentScope.launch(Dispatchers.IO) {
|
|
1015
|
+
val dims = getPageDimensions(position)
|
|
1016
|
+
withContext(Dispatchers.Main) {
|
|
1017
|
+
// Update the view if it's still showing this position
|
|
1018
|
+
if (holder.bindingAdapterPosition == position) {
|
|
1019
|
+
val scale = (viewWidth.toFloat() / dims.first) * currentScale
|
|
1020
|
+
val targetHeight = (dims.second * scale).toInt().coerceAtLeast(100)
|
|
1021
|
+
holder.imageView.layoutParams.height = targetHeight
|
|
1022
|
+
holder.imageView.requestLayout()
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
853
1026
|
}
|
|
854
1027
|
|
|
855
1028
|
// Check cache for valid bitmap at current scale
|
package/ios/PdfViewer.swift
CHANGED
|
@@ -127,6 +127,8 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
127
127
|
ensureMainThread {
|
|
128
128
|
self.pdfView.displayMode = enablePaging ? .singlePage : .singlePageContinuous
|
|
129
129
|
self.pdfView.usePageViewController(enablePaging, withViewOptions: nil)
|
|
130
|
+
// Ensure autoScales is enabled for proper width fitting in both modes
|
|
131
|
+
self.pdfView.autoScales = true
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
}
|
|
@@ -145,6 +147,61 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
// Content insets for glass UI / transparent bars
|
|
151
|
+
var contentInsetTop: Double? {
|
|
152
|
+
didSet {
|
|
153
|
+
updateContentInsets()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
var contentInsetBottom: Double? {
|
|
158
|
+
didSet {
|
|
159
|
+
updateContentInsets()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var contentInsetLeft: Double? {
|
|
164
|
+
didSet {
|
|
165
|
+
updateContentInsets()
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
var contentInsetRight: Double? {
|
|
170
|
+
didSet {
|
|
171
|
+
updateContentInsets()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private func updateContentInsets() {
|
|
176
|
+
ensureMainThread {
|
|
177
|
+
// Get scroll view from PDFView's view hierarchy
|
|
178
|
+
// PDFView uses PDFDocumentView which contains a scroll view
|
|
179
|
+
if let scrollView = self.findScrollView(in: self.pdfView) {
|
|
180
|
+
let insets = UIEdgeInsets(
|
|
181
|
+
top: CGFloat(self.contentInsetTop ?? 0),
|
|
182
|
+
left: CGFloat(self.contentInsetLeft ?? 0),
|
|
183
|
+
bottom: CGFloat(self.contentInsetBottom ?? 0),
|
|
184
|
+
right: CGFloat(self.contentInsetRight ?? 0)
|
|
185
|
+
)
|
|
186
|
+
scrollView.contentInset = insets
|
|
187
|
+
// Adjust scroll indicator insets to match
|
|
188
|
+
scrollView.scrollIndicatorInsets = insets
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private func findScrollView(in view: UIView) -> UIScrollView? {
|
|
194
|
+
if let scrollView = view as? UIScrollView {
|
|
195
|
+
return scrollView
|
|
196
|
+
}
|
|
197
|
+
for subview in view.subviews {
|
|
198
|
+
if let scrollView = findScrollView(in: subview) {
|
|
199
|
+
return scrollView
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return nil
|
|
203
|
+
}
|
|
204
|
+
|
|
148
205
|
var enableZoom: Bool? {
|
|
149
206
|
didSet {
|
|
150
207
|
guard let enableZoom = enableZoom else { return }
|
|
@@ -228,7 +285,7 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
228
285
|
// Create PDF view
|
|
229
286
|
pdfView = PDFView()
|
|
230
287
|
pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
231
|
-
pdfView.autoScales =
|
|
288
|
+
pdfView.autoScales = true // Enable autoScales to fit width by default
|
|
232
289
|
pdfView.displayDirection = .vertical
|
|
233
290
|
pdfView.displayMode = .singlePageContinuous
|
|
234
291
|
pdfView.usePageViewController(false, withViewOptions: nil)
|
|
@@ -257,8 +314,11 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
257
314
|
activityIndicator.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
|
|
258
315
|
])
|
|
259
316
|
|
|
260
|
-
|
|
317
|
+
// Use default configuration with caching enabled for better performance
|
|
318
|
+
let config = URLSessionConfiguration.default
|
|
261
319
|
config.timeoutIntervalForRequest = 30.0
|
|
320
|
+
config.requestCachePolicy = .returnCacheDataElseLoad
|
|
321
|
+
config.urlCache = URLCache.shared
|
|
262
322
|
urlSession = URLSession(configuration: config)
|
|
263
323
|
|
|
264
324
|
super.init()
|
|
@@ -287,7 +347,13 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
287
347
|
|
|
288
348
|
// Observe bounds changes to update scale factor when view is resized
|
|
289
349
|
boundsObservation = pdfView.observe(\.bounds, options: [.new]) { [weak self] _, _ in
|
|
290
|
-
self
|
|
350
|
+
guard let self = self else { return }
|
|
351
|
+
// Only re-enable autoScales during bounds change if we're at default scale
|
|
352
|
+
// This allows manual zoom to persist through view lifecycle changes
|
|
353
|
+
if self.pdfView.displayMode == .singlePageContinuous && self.pdfView.scaleFactor == 1.0 {
|
|
354
|
+
self.pdfView.autoScales = true
|
|
355
|
+
}
|
|
356
|
+
self.updateScaleToFitWidthIfNeeded()
|
|
291
357
|
}
|
|
292
358
|
}
|
|
293
359
|
|
|
@@ -434,9 +500,19 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
434
500
|
pdfView.document = document
|
|
435
501
|
thumbnailCache.removeAllObjects()
|
|
436
502
|
|
|
503
|
+
// Ensure autoScales is enabled for proper width fitting
|
|
504
|
+
pdfView.autoScales = true
|
|
505
|
+
|
|
437
506
|
// Update scale after document is loaded
|
|
438
507
|
updateScaleToFitWidthIfNeeded()
|
|
439
508
|
|
|
509
|
+
// If bounds were zero, schedule a delayed update
|
|
510
|
+
if pdfView.bounds.width == 0 {
|
|
511
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
|
512
|
+
self?.updateScaleToFitWidthIfNeeded()
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
440
516
|
if let firstPage = document.page(at: 0) {
|
|
441
517
|
let pageRect = firstPage.bounds(for: .mediaBox)
|
|
442
518
|
onLoadComplete?(LoadCompleteEvent(
|
|
@@ -454,16 +530,31 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
454
530
|
let pageRect = firstPage.bounds(for: .mediaBox)
|
|
455
531
|
let viewWidth = pdfView.bounds.width
|
|
456
532
|
|
|
457
|
-
// Only update scale if view has been laid out (width > 0)
|
|
533
|
+
// Only update scale if view has been laid out (width > 0)
|
|
458
534
|
guard viewWidth > 0 && pageRect.width > 0 else { return }
|
|
459
535
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
536
|
+
// In continuous scroll mode, check if we should enable autoScales
|
|
537
|
+
if pdfView.displayMode == .singlePageContinuous {
|
|
538
|
+
// Only enable autoScales if at default scale (hasn't been manually zoomed)
|
|
539
|
+
// This preserves user's manual zoom level through view lifecycle
|
|
540
|
+
let currentScale = pdfView.scaleFactor
|
|
541
|
+
let isDefaultScale = abs(currentScale - 1.0) < 0.01
|
|
542
|
+
|
|
543
|
+
if isDefaultScale {
|
|
544
|
+
pdfView.autoScales = true
|
|
545
|
+
// Force PDFView to recalculate scale if needed
|
|
546
|
+
pdfView.layoutDocumentView()
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
// For paging mode, calculate and set the scale to fit width
|
|
550
|
+
let scale = viewWidth / pageRect.width
|
|
551
|
+
let minScale = CGFloat(self.minScale ?? 0.5)
|
|
552
|
+
let maxScale = CGFloat(self.maxScale ?? 4.0)
|
|
553
|
+
|
|
554
|
+
// Clamp the scale between min and max
|
|
555
|
+
let clampedScale = max(minScale, min(maxScale, scale))
|
|
556
|
+
pdfView.scaleFactor = clampedScale
|
|
557
|
+
}
|
|
467
558
|
}
|
|
468
559
|
|
|
469
560
|
private func resolveURL(from source: String) -> URL? {
|
|
@@ -532,13 +623,11 @@ class HybridPdfViewer: HybridPdfViewerSpec {
|
|
|
532
623
|
let maxScale = CGFloat(self.maxScale ?? 4.0)
|
|
533
624
|
let clampedScale = max(minScale, min(maxScale, CGFloat(scale)))
|
|
534
625
|
|
|
535
|
-
//
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
self?.pdfView.scaleFactor = clampedScale
|
|
541
|
-
}
|
|
626
|
+
// Disable autoScales when manually setting scale
|
|
627
|
+
// This allows programmatic zoom control to work
|
|
628
|
+
ensureMainThread {
|
|
629
|
+
self.pdfView.autoScales = false
|
|
630
|
+
self.pdfView.scaleFactor = clampedScale
|
|
542
631
|
}
|
|
543
632
|
}
|
|
544
633
|
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getHostComponent","callback","PdfViewerConfig","require","PdfViewerView"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,4BAA4B;
|
|
1
|
+
{"version":3,"names":["getHostComponent","callback","PdfViewerConfig","require","PdfViewerView"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,4BAA4B;AAIvE,MAAMC,eAAe,GAAGC,OAAO,CAAC,wDAAwD,CAAC;AAEzF,OAAO,MAAMC,aAAa,GAAGJ,gBAAgB,CAC3C,WAAW,EACX,MAAME,eACR,CAAC;;AAED;;AAGA;;AAYA;AACA,SAASD,QAAQ","ignoreList":[]}
|
|
@@ -46,6 +46,25 @@ export interface PdfViewerProps extends HybridViewProps {
|
|
|
46
46
|
*/
|
|
47
47
|
enablePaging?: boolean;
|
|
48
48
|
spacing?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Top content inset in pixels
|
|
51
|
+
* Useful for transparent/glass top bars - content starts below but scrolls behind
|
|
52
|
+
* @example 80 // Start content below 80px top bar
|
|
53
|
+
*/
|
|
54
|
+
contentInsetTop?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Bottom content inset in pixels
|
|
57
|
+
* Useful for transparent/glass bottom bars - content ends above but scrolls behind
|
|
58
|
+
*/
|
|
59
|
+
contentInsetBottom?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Left content inset in pixels
|
|
62
|
+
*/
|
|
63
|
+
contentInsetLeft?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Right content inset in pixels
|
|
66
|
+
*/
|
|
67
|
+
contentInsetRight?: number;
|
|
49
68
|
enableZoom?: boolean;
|
|
50
69
|
minScale?: number;
|
|
51
70
|
maxScale?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PdfViewer.nitro.d.ts","sourceRoot":"","sources":["../../../src/PdfViewer.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,iBAAiB;IAEhC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAChE,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IAEzD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAG7B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtC,qBAAqB,IAAI,IAAI,CAAC;CAC/B;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"PdfViewer.nitro.d.ts","sourceRoot":"","sources":["../../../src/PdfViewer.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,iBAAiB;IAEhC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAChE,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IAEzD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAG7B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAG9B,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAGtC,qBAAqB,IAAI,IAAI,CAAC;CAC/B;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAI1E,eAAO,MAAM,aAAa,wFAGzB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAGvE,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -101,6 +101,42 @@ namespace margelo::nitro::pdfviewer {
|
|
|
101
101
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* spacing */)>("setSpacing");
|
|
102
102
|
method(_javaPart, spacing.has_value() ? jni::JDouble::valueOf(spacing.value()) : nullptr);
|
|
103
103
|
}
|
|
104
|
+
std::optional<double> JHybridPdfViewerSpec::getContentInsetTop() {
|
|
105
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getContentInsetTop");
|
|
106
|
+
auto __result = method(_javaPart);
|
|
107
|
+
return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
|
|
108
|
+
}
|
|
109
|
+
void JHybridPdfViewerSpec::setContentInsetTop(std::optional<double> contentInsetTop) {
|
|
110
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* contentInsetTop */)>("setContentInsetTop");
|
|
111
|
+
method(_javaPart, contentInsetTop.has_value() ? jni::JDouble::valueOf(contentInsetTop.value()) : nullptr);
|
|
112
|
+
}
|
|
113
|
+
std::optional<double> JHybridPdfViewerSpec::getContentInsetBottom() {
|
|
114
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getContentInsetBottom");
|
|
115
|
+
auto __result = method(_javaPart);
|
|
116
|
+
return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
|
|
117
|
+
}
|
|
118
|
+
void JHybridPdfViewerSpec::setContentInsetBottom(std::optional<double> contentInsetBottom) {
|
|
119
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* contentInsetBottom */)>("setContentInsetBottom");
|
|
120
|
+
method(_javaPart, contentInsetBottom.has_value() ? jni::JDouble::valueOf(contentInsetBottom.value()) : nullptr);
|
|
121
|
+
}
|
|
122
|
+
std::optional<double> JHybridPdfViewerSpec::getContentInsetLeft() {
|
|
123
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getContentInsetLeft");
|
|
124
|
+
auto __result = method(_javaPart);
|
|
125
|
+
return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
|
|
126
|
+
}
|
|
127
|
+
void JHybridPdfViewerSpec::setContentInsetLeft(std::optional<double> contentInsetLeft) {
|
|
128
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* contentInsetLeft */)>("setContentInsetLeft");
|
|
129
|
+
method(_javaPart, contentInsetLeft.has_value() ? jni::JDouble::valueOf(contentInsetLeft.value()) : nullptr);
|
|
130
|
+
}
|
|
131
|
+
std::optional<double> JHybridPdfViewerSpec::getContentInsetRight() {
|
|
132
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JDouble>()>("getContentInsetRight");
|
|
133
|
+
auto __result = method(_javaPart);
|
|
134
|
+
return __result != nullptr ? std::make_optional(__result->value()) : std::nullopt;
|
|
135
|
+
}
|
|
136
|
+
void JHybridPdfViewerSpec::setContentInsetRight(std::optional<double> contentInsetRight) {
|
|
137
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JDouble> /* contentInsetRight */)>("setContentInsetRight");
|
|
138
|
+
method(_javaPart, contentInsetRight.has_value() ? jni::JDouble::valueOf(contentInsetRight.value()) : nullptr);
|
|
139
|
+
}
|
|
104
140
|
std::optional<bool> JHybridPdfViewerSpec::getEnableZoom() {
|
|
105
141
|
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JBoolean>()>("getEnableZoom");
|
|
106
142
|
auto __result = method(_javaPart);
|
|
@@ -57,6 +57,14 @@ namespace margelo::nitro::pdfviewer {
|
|
|
57
57
|
void setEnablePaging(std::optional<bool> enablePaging) override;
|
|
58
58
|
std::optional<double> getSpacing() override;
|
|
59
59
|
void setSpacing(std::optional<double> spacing) override;
|
|
60
|
+
std::optional<double> getContentInsetTop() override;
|
|
61
|
+
void setContentInsetTop(std::optional<double> contentInsetTop) override;
|
|
62
|
+
std::optional<double> getContentInsetBottom() override;
|
|
63
|
+
void setContentInsetBottom(std::optional<double> contentInsetBottom) override;
|
|
64
|
+
std::optional<double> getContentInsetLeft() override;
|
|
65
|
+
void setContentInsetLeft(std::optional<double> contentInsetLeft) override;
|
|
66
|
+
std::optional<double> getContentInsetRight() override;
|
|
67
|
+
void setContentInsetRight(std::optional<double> contentInsetRight) override;
|
|
60
68
|
std::optional<bool> getEnableZoom() override;
|
|
61
69
|
void setEnableZoom(std::optional<bool> enableZoom) override;
|
|
62
70
|
std::optional<double> getMinScale() override;
|
|
@@ -52,6 +52,22 @@ void JHybridPdfViewerStateUpdater::updateViewProps(jni::alias_ref<jni::JClass> /
|
|
|
52
52
|
view->setSpacing(props.spacing.value);
|
|
53
53
|
// TODO: Set isDirty = false
|
|
54
54
|
}
|
|
55
|
+
if (props.contentInsetTop.isDirty) {
|
|
56
|
+
view->setContentInsetTop(props.contentInsetTop.value);
|
|
57
|
+
// TODO: Set isDirty = false
|
|
58
|
+
}
|
|
59
|
+
if (props.contentInsetBottom.isDirty) {
|
|
60
|
+
view->setContentInsetBottom(props.contentInsetBottom.value);
|
|
61
|
+
// TODO: Set isDirty = false
|
|
62
|
+
}
|
|
63
|
+
if (props.contentInsetLeft.isDirty) {
|
|
64
|
+
view->setContentInsetLeft(props.contentInsetLeft.value);
|
|
65
|
+
// TODO: Set isDirty = false
|
|
66
|
+
}
|
|
67
|
+
if (props.contentInsetRight.isDirty) {
|
|
68
|
+
view->setContentInsetRight(props.contentInsetRight.value);
|
|
69
|
+
// TODO: Set isDirty = false
|
|
70
|
+
}
|
|
55
71
|
if (props.enableZoom.isDirty) {
|
|
56
72
|
view->setEnableZoom(props.enableZoom.value);
|
|
57
73
|
// TODO: Set isDirty = false
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/pdfviewer/HybridPdfViewerSpec.kt
CHANGED
|
@@ -62,6 +62,30 @@ abstract class HybridPdfViewerSpec: HybridView() {
|
|
|
62
62
|
@set:Keep
|
|
63
63
|
abstract var spacing: Double?
|
|
64
64
|
|
|
65
|
+
@get:DoNotStrip
|
|
66
|
+
@get:Keep
|
|
67
|
+
@set:DoNotStrip
|
|
68
|
+
@set:Keep
|
|
69
|
+
abstract var contentInsetTop: Double?
|
|
70
|
+
|
|
71
|
+
@get:DoNotStrip
|
|
72
|
+
@get:Keep
|
|
73
|
+
@set:DoNotStrip
|
|
74
|
+
@set:Keep
|
|
75
|
+
abstract var contentInsetBottom: Double?
|
|
76
|
+
|
|
77
|
+
@get:DoNotStrip
|
|
78
|
+
@get:Keep
|
|
79
|
+
@set:DoNotStrip
|
|
80
|
+
@set:Keep
|
|
81
|
+
abstract var contentInsetLeft: Double?
|
|
82
|
+
|
|
83
|
+
@get:DoNotStrip
|
|
84
|
+
@get:Keep
|
|
85
|
+
@set:DoNotStrip
|
|
86
|
+
@set:Keep
|
|
87
|
+
abstract var contentInsetRight: Double?
|
|
88
|
+
|
|
65
89
|
@get:DoNotStrip
|
|
66
90
|
@get:Keep
|
|
67
91
|
@set:DoNotStrip
|
|
@@ -100,6 +100,34 @@ namespace margelo::nitro::pdfviewer {
|
|
|
100
100
|
inline void setSpacing(std::optional<double> spacing) noexcept override {
|
|
101
101
|
_swiftPart.setSpacing(spacing);
|
|
102
102
|
}
|
|
103
|
+
inline std::optional<double> getContentInsetTop() noexcept override {
|
|
104
|
+
auto __result = _swiftPart.getContentInsetTop();
|
|
105
|
+
return __result;
|
|
106
|
+
}
|
|
107
|
+
inline void setContentInsetTop(std::optional<double> contentInsetTop) noexcept override {
|
|
108
|
+
_swiftPart.setContentInsetTop(contentInsetTop);
|
|
109
|
+
}
|
|
110
|
+
inline std::optional<double> getContentInsetBottom() noexcept override {
|
|
111
|
+
auto __result = _swiftPart.getContentInsetBottom();
|
|
112
|
+
return __result;
|
|
113
|
+
}
|
|
114
|
+
inline void setContentInsetBottom(std::optional<double> contentInsetBottom) noexcept override {
|
|
115
|
+
_swiftPart.setContentInsetBottom(contentInsetBottom);
|
|
116
|
+
}
|
|
117
|
+
inline std::optional<double> getContentInsetLeft() noexcept override {
|
|
118
|
+
auto __result = _swiftPart.getContentInsetLeft();
|
|
119
|
+
return __result;
|
|
120
|
+
}
|
|
121
|
+
inline void setContentInsetLeft(std::optional<double> contentInsetLeft) noexcept override {
|
|
122
|
+
_swiftPart.setContentInsetLeft(contentInsetLeft);
|
|
123
|
+
}
|
|
124
|
+
inline std::optional<double> getContentInsetRight() noexcept override {
|
|
125
|
+
auto __result = _swiftPart.getContentInsetRight();
|
|
126
|
+
return __result;
|
|
127
|
+
}
|
|
128
|
+
inline void setContentInsetRight(std::optional<double> contentInsetRight) noexcept override {
|
|
129
|
+
_swiftPart.setContentInsetRight(contentInsetRight);
|
|
130
|
+
}
|
|
103
131
|
inline std::optional<bool> getEnableZoom() noexcept override {
|
|
104
132
|
auto __result = _swiftPart.getEnableZoom();
|
|
105
133
|
return __result;
|
|
@@ -91,6 +91,26 @@ using namespace margelo::nitro::pdfviewer::views;
|
|
|
91
91
|
swiftPart.setSpacing(newViewProps.spacing.value);
|
|
92
92
|
newViewProps.spacing.isDirty = false;
|
|
93
93
|
}
|
|
94
|
+
// contentInsetTop: optional
|
|
95
|
+
if (newViewProps.contentInsetTop.isDirty) {
|
|
96
|
+
swiftPart.setContentInsetTop(newViewProps.contentInsetTop.value);
|
|
97
|
+
newViewProps.contentInsetTop.isDirty = false;
|
|
98
|
+
}
|
|
99
|
+
// contentInsetBottom: optional
|
|
100
|
+
if (newViewProps.contentInsetBottom.isDirty) {
|
|
101
|
+
swiftPart.setContentInsetBottom(newViewProps.contentInsetBottom.value);
|
|
102
|
+
newViewProps.contentInsetBottom.isDirty = false;
|
|
103
|
+
}
|
|
104
|
+
// contentInsetLeft: optional
|
|
105
|
+
if (newViewProps.contentInsetLeft.isDirty) {
|
|
106
|
+
swiftPart.setContentInsetLeft(newViewProps.contentInsetLeft.value);
|
|
107
|
+
newViewProps.contentInsetLeft.isDirty = false;
|
|
108
|
+
}
|
|
109
|
+
// contentInsetRight: optional
|
|
110
|
+
if (newViewProps.contentInsetRight.isDirty) {
|
|
111
|
+
swiftPart.setContentInsetRight(newViewProps.contentInsetRight.value);
|
|
112
|
+
newViewProps.contentInsetRight.isDirty = false;
|
|
113
|
+
}
|
|
94
114
|
// enableZoom: optional
|
|
95
115
|
if (newViewProps.enableZoom.isDirty) {
|
|
96
116
|
swiftPart.setEnableZoom(newViewProps.enableZoom.value);
|
|
@@ -15,6 +15,10 @@ public protocol HybridPdfViewerSpec_protocol: HybridObject, HybridView {
|
|
|
15
15
|
var horizontal: Bool? { get set }
|
|
16
16
|
var enablePaging: Bool? { get set }
|
|
17
17
|
var spacing: Double? { get set }
|
|
18
|
+
var contentInsetTop: Double? { get set }
|
|
19
|
+
var contentInsetBottom: Double? { get set }
|
|
20
|
+
var contentInsetLeft: Double? { get set }
|
|
21
|
+
var contentInsetRight: Double? { get set }
|
|
18
22
|
var enableZoom: Bool? { get set }
|
|
19
23
|
var minScale: Double? { get set }
|
|
20
24
|
var maxScale: Double? { get set }
|
|
@@ -181,6 +181,74 @@ open class HybridPdfViewerSpec_cxx {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
public final var contentInsetTop: bridge.std__optional_double_ {
|
|
185
|
+
@inline(__always)
|
|
186
|
+
get {
|
|
187
|
+
return { () -> bridge.std__optional_double_ in
|
|
188
|
+
if let __unwrappedValue = self.__implementation.contentInsetTop {
|
|
189
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
190
|
+
} else {
|
|
191
|
+
return .init()
|
|
192
|
+
}
|
|
193
|
+
}()
|
|
194
|
+
}
|
|
195
|
+
@inline(__always)
|
|
196
|
+
set {
|
|
197
|
+
self.__implementation.contentInsetTop = newValue.value
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public final var contentInsetBottom: bridge.std__optional_double_ {
|
|
202
|
+
@inline(__always)
|
|
203
|
+
get {
|
|
204
|
+
return { () -> bridge.std__optional_double_ in
|
|
205
|
+
if let __unwrappedValue = self.__implementation.contentInsetBottom {
|
|
206
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
207
|
+
} else {
|
|
208
|
+
return .init()
|
|
209
|
+
}
|
|
210
|
+
}()
|
|
211
|
+
}
|
|
212
|
+
@inline(__always)
|
|
213
|
+
set {
|
|
214
|
+
self.__implementation.contentInsetBottom = newValue.value
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public final var contentInsetLeft: bridge.std__optional_double_ {
|
|
219
|
+
@inline(__always)
|
|
220
|
+
get {
|
|
221
|
+
return { () -> bridge.std__optional_double_ in
|
|
222
|
+
if let __unwrappedValue = self.__implementation.contentInsetLeft {
|
|
223
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
224
|
+
} else {
|
|
225
|
+
return .init()
|
|
226
|
+
}
|
|
227
|
+
}()
|
|
228
|
+
}
|
|
229
|
+
@inline(__always)
|
|
230
|
+
set {
|
|
231
|
+
self.__implementation.contentInsetLeft = newValue.value
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public final var contentInsetRight: bridge.std__optional_double_ {
|
|
236
|
+
@inline(__always)
|
|
237
|
+
get {
|
|
238
|
+
return { () -> bridge.std__optional_double_ in
|
|
239
|
+
if let __unwrappedValue = self.__implementation.contentInsetRight {
|
|
240
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
241
|
+
} else {
|
|
242
|
+
return .init()
|
|
243
|
+
}
|
|
244
|
+
}()
|
|
245
|
+
}
|
|
246
|
+
@inline(__always)
|
|
247
|
+
set {
|
|
248
|
+
self.__implementation.contentInsetRight = newValue.value
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
184
252
|
public final var enableZoom: bridge.std__optional_bool_ {
|
|
185
253
|
@inline(__always)
|
|
186
254
|
get {
|
|
@@ -22,6 +22,14 @@ namespace margelo::nitro::pdfviewer {
|
|
|
22
22
|
prototype.registerHybridSetter("enablePaging", &HybridPdfViewerSpec::setEnablePaging);
|
|
23
23
|
prototype.registerHybridGetter("spacing", &HybridPdfViewerSpec::getSpacing);
|
|
24
24
|
prototype.registerHybridSetter("spacing", &HybridPdfViewerSpec::setSpacing);
|
|
25
|
+
prototype.registerHybridGetter("contentInsetTop", &HybridPdfViewerSpec::getContentInsetTop);
|
|
26
|
+
prototype.registerHybridSetter("contentInsetTop", &HybridPdfViewerSpec::setContentInsetTop);
|
|
27
|
+
prototype.registerHybridGetter("contentInsetBottom", &HybridPdfViewerSpec::getContentInsetBottom);
|
|
28
|
+
prototype.registerHybridSetter("contentInsetBottom", &HybridPdfViewerSpec::setContentInsetBottom);
|
|
29
|
+
prototype.registerHybridGetter("contentInsetLeft", &HybridPdfViewerSpec::getContentInsetLeft);
|
|
30
|
+
prototype.registerHybridSetter("contentInsetLeft", &HybridPdfViewerSpec::setContentInsetLeft);
|
|
31
|
+
prototype.registerHybridGetter("contentInsetRight", &HybridPdfViewerSpec::getContentInsetRight);
|
|
32
|
+
prototype.registerHybridSetter("contentInsetRight", &HybridPdfViewerSpec::setContentInsetRight);
|
|
25
33
|
prototype.registerHybridGetter("enableZoom", &HybridPdfViewerSpec::getEnableZoom);
|
|
26
34
|
prototype.registerHybridSetter("enableZoom", &HybridPdfViewerSpec::setEnableZoom);
|
|
27
35
|
prototype.registerHybridGetter("minScale", &HybridPdfViewerSpec::getMinScale);
|
|
@@ -71,6 +71,14 @@ namespace margelo::nitro::pdfviewer {
|
|
|
71
71
|
virtual void setEnablePaging(std::optional<bool> enablePaging) = 0;
|
|
72
72
|
virtual std::optional<double> getSpacing() = 0;
|
|
73
73
|
virtual void setSpacing(std::optional<double> spacing) = 0;
|
|
74
|
+
virtual std::optional<double> getContentInsetTop() = 0;
|
|
75
|
+
virtual void setContentInsetTop(std::optional<double> contentInsetTop) = 0;
|
|
76
|
+
virtual std::optional<double> getContentInsetBottom() = 0;
|
|
77
|
+
virtual void setContentInsetBottom(std::optional<double> contentInsetBottom) = 0;
|
|
78
|
+
virtual std::optional<double> getContentInsetLeft() = 0;
|
|
79
|
+
virtual void setContentInsetLeft(std::optional<double> contentInsetLeft) = 0;
|
|
80
|
+
virtual std::optional<double> getContentInsetRight() = 0;
|
|
81
|
+
virtual void setContentInsetRight(std::optional<double> contentInsetRight) = 0;
|
|
74
82
|
virtual std::optional<bool> getEnableZoom() = 0;
|
|
75
83
|
virtual void setEnableZoom(std::optional<bool> enableZoom) = 0;
|
|
76
84
|
virtual std::optional<double> getMinScale() = 0;
|
|
@@ -65,6 +65,46 @@ namespace margelo::nitro::pdfviewer::views {
|
|
|
65
65
|
throw std::runtime_error(std::string("PdfViewer.spacing: ") + exc.what());
|
|
66
66
|
}
|
|
67
67
|
}()),
|
|
68
|
+
contentInsetTop([&]() -> CachedProp<std::optional<double>> {
|
|
69
|
+
try {
|
|
70
|
+
const react::RawValue* rawValue = rawProps.at("contentInsetTop", nullptr, nullptr);
|
|
71
|
+
if (rawValue == nullptr) return sourceProps.contentInsetTop;
|
|
72
|
+
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
73
|
+
return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.contentInsetTop);
|
|
74
|
+
} catch (const std::exception& exc) {
|
|
75
|
+
throw std::runtime_error(std::string("PdfViewer.contentInsetTop: ") + exc.what());
|
|
76
|
+
}
|
|
77
|
+
}()),
|
|
78
|
+
contentInsetBottom([&]() -> CachedProp<std::optional<double>> {
|
|
79
|
+
try {
|
|
80
|
+
const react::RawValue* rawValue = rawProps.at("contentInsetBottom", nullptr, nullptr);
|
|
81
|
+
if (rawValue == nullptr) return sourceProps.contentInsetBottom;
|
|
82
|
+
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
83
|
+
return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.contentInsetBottom);
|
|
84
|
+
} catch (const std::exception& exc) {
|
|
85
|
+
throw std::runtime_error(std::string("PdfViewer.contentInsetBottom: ") + exc.what());
|
|
86
|
+
}
|
|
87
|
+
}()),
|
|
88
|
+
contentInsetLeft([&]() -> CachedProp<std::optional<double>> {
|
|
89
|
+
try {
|
|
90
|
+
const react::RawValue* rawValue = rawProps.at("contentInsetLeft", nullptr, nullptr);
|
|
91
|
+
if (rawValue == nullptr) return sourceProps.contentInsetLeft;
|
|
92
|
+
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
93
|
+
return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.contentInsetLeft);
|
|
94
|
+
} catch (const std::exception& exc) {
|
|
95
|
+
throw std::runtime_error(std::string("PdfViewer.contentInsetLeft: ") + exc.what());
|
|
96
|
+
}
|
|
97
|
+
}()),
|
|
98
|
+
contentInsetRight([&]() -> CachedProp<std::optional<double>> {
|
|
99
|
+
try {
|
|
100
|
+
const react::RawValue* rawValue = rawProps.at("contentInsetRight", nullptr, nullptr);
|
|
101
|
+
if (rawValue == nullptr) return sourceProps.contentInsetRight;
|
|
102
|
+
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
103
|
+
return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.contentInsetRight);
|
|
104
|
+
} catch (const std::exception& exc) {
|
|
105
|
+
throw std::runtime_error(std::string("PdfViewer.contentInsetRight: ") + exc.what());
|
|
106
|
+
}
|
|
107
|
+
}()),
|
|
68
108
|
enableZoom([&]() -> CachedProp<std::optional<bool>> {
|
|
69
109
|
try {
|
|
70
110
|
const react::RawValue* rawValue = rawProps.at("enableZoom", nullptr, nullptr);
|
|
@@ -182,6 +222,10 @@ namespace margelo::nitro::pdfviewer::views {
|
|
|
182
222
|
horizontal(other.horizontal),
|
|
183
223
|
enablePaging(other.enablePaging),
|
|
184
224
|
spacing(other.spacing),
|
|
225
|
+
contentInsetTop(other.contentInsetTop),
|
|
226
|
+
contentInsetBottom(other.contentInsetBottom),
|
|
227
|
+
contentInsetLeft(other.contentInsetLeft),
|
|
228
|
+
contentInsetRight(other.contentInsetRight),
|
|
185
229
|
enableZoom(other.enableZoom),
|
|
186
230
|
minScale(other.minScale),
|
|
187
231
|
maxScale(other.maxScale),
|
|
@@ -200,6 +244,10 @@ namespace margelo::nitro::pdfviewer::views {
|
|
|
200
244
|
case hashString("horizontal"): return true;
|
|
201
245
|
case hashString("enablePaging"): return true;
|
|
202
246
|
case hashString("spacing"): return true;
|
|
247
|
+
case hashString("contentInsetTop"): return true;
|
|
248
|
+
case hashString("contentInsetBottom"): return true;
|
|
249
|
+
case hashString("contentInsetLeft"): return true;
|
|
250
|
+
case hashString("contentInsetRight"): return true;
|
|
203
251
|
case hashString("enableZoom"): return true;
|
|
204
252
|
case hashString("minScale"): return true;
|
|
205
253
|
case hashString("maxScale"): return true;
|
|
@@ -53,6 +53,10 @@ namespace margelo::nitro::pdfviewer::views {
|
|
|
53
53
|
CachedProp<std::optional<bool>> horizontal;
|
|
54
54
|
CachedProp<std::optional<bool>> enablePaging;
|
|
55
55
|
CachedProp<std::optional<double>> spacing;
|
|
56
|
+
CachedProp<std::optional<double>> contentInsetTop;
|
|
57
|
+
CachedProp<std::optional<double>> contentInsetBottom;
|
|
58
|
+
CachedProp<std::optional<double>> contentInsetLeft;
|
|
59
|
+
CachedProp<std::optional<double>> contentInsetRight;
|
|
56
60
|
CachedProp<std::optional<bool>> enableZoom;
|
|
57
61
|
CachedProp<std::optional<double>> minScale;
|
|
58
62
|
CachedProp<std::optional<double>> maxScale;
|
package/package.json
CHANGED
package/src/PdfViewer.nitro.ts
CHANGED
|
@@ -63,6 +63,27 @@ export interface PdfViewerProps extends HybridViewProps {
|
|
|
63
63
|
enablePaging?: boolean;
|
|
64
64
|
spacing?: number;
|
|
65
65
|
|
|
66
|
+
// Content insets - allows content to start below transparent headers/toolbars
|
|
67
|
+
/**
|
|
68
|
+
* Top content inset in pixels
|
|
69
|
+
* Useful for transparent/glass top bars - content starts below but scrolls behind
|
|
70
|
+
* @example 80 // Start content below 80px top bar
|
|
71
|
+
*/
|
|
72
|
+
contentInsetTop?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Bottom content inset in pixels
|
|
75
|
+
* Useful for transparent/glass bottom bars - content ends above but scrolls behind
|
|
76
|
+
*/
|
|
77
|
+
contentInsetBottom?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Left content inset in pixels
|
|
80
|
+
*/
|
|
81
|
+
contentInsetLeft?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Right content inset in pixels
|
|
84
|
+
*/
|
|
85
|
+
contentInsetRight?: number;
|
|
86
|
+
|
|
66
87
|
// Zoom controls
|
|
67
88
|
enableZoom?: boolean;
|
|
68
89
|
minScale?: number;
|
package/src/index.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getHostComponent, callback } from 'react-native-nitro-modules';
|
|
2
2
|
import type { HybridRef } from 'react-native-nitro-modules';
|
|
3
|
-
const PdfViewerConfig = require('../nitrogen/generated/shared/json/PdfViewerConfig.json');
|
|
4
3
|
import type { PdfViewerMethods, PdfViewerProps } from './PdfViewer.nitro';
|
|
5
4
|
|
|
5
|
+
const PdfViewerConfig = require('../nitrogen/generated/shared/json/PdfViewerConfig.json');
|
|
6
|
+
|
|
6
7
|
export const PdfViewerView = getHostComponent<PdfViewerProps, PdfViewerMethods>(
|
|
7
8
|
'PdfViewer',
|
|
8
9
|
() => PdfViewerConfig
|