react-native-pdf-jsi 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -4
- package/android/src/main/java/org/wonday/pdf/PDFNativeCacheManager.java +748 -0
- package/ios/RNPDFPdf/PDFJSIManager.h +15 -0
- package/ios/RNPDFPdf/PDFJSIManager.m +581 -0
- package/ios/RNPDFPdf/PDFNativeCacheManager.h +20 -0
- package/ios/RNPDFPdf/PDFNativeCacheManager.m +743 -0
- package/package.json +32 -4
- package/src/EnhancedPdfView.js +52 -2
- package/src/PDFJSI.js +247 -3
- package/src/examples/PDFJSIExample.js +463 -195
- package/src/hooks/usePDFJSI.js +53 -0
|
@@ -1,21 +1,118 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c) 2025-present,
|
|
3
|
-
* Enhanced PDF JSI Example Usage
|
|
2
|
+
* Copyright (c) 2025-present, Enhanced PDF JSI Example
|
|
4
3
|
* All rights reserved.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Comprehensive example showing how to use the Enhanced PDF JSI functionality
|
|
6
|
+
* Demonstrates both basic usage and advanced performance features
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { useState,
|
|
10
|
-
import {
|
|
11
|
-
|
|
9
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
10
|
+
import {
|
|
11
|
+
View,
|
|
12
|
+
Text,
|
|
13
|
+
TouchableOpacity,
|
|
14
|
+
StyleSheet,
|
|
15
|
+
Alert,
|
|
16
|
+
ScrollView,
|
|
17
|
+
TextInput,
|
|
18
|
+
Platform
|
|
19
|
+
} from 'react-native';
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
// Import JSI functionality
|
|
22
|
+
import {
|
|
23
|
+
PDFJSI,
|
|
24
|
+
EnhancedPdfView,
|
|
25
|
+
usePDFJSI,
|
|
26
|
+
EnhancedPdfUtils
|
|
27
|
+
} from '../index';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Basic JSI Usage Example
|
|
31
|
+
*/
|
|
32
|
+
export const BasicJSIExample = () => {
|
|
33
|
+
const [isJSIAvailable, setIsJSIAvailable] = useState(false);
|
|
34
|
+
const [loading, setLoading] = useState(false);
|
|
35
|
+
const [result, setResult] = useState(null);
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
checkJSIAvailability();
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
const checkJSIAvailability = async () => {
|
|
42
|
+
try {
|
|
43
|
+
const available = await PDFJSI.checkJSIAvailability();
|
|
44
|
+
setIsJSIAvailable(available);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('Error checking JSI availability:', error);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const testJSI = async () => {
|
|
51
|
+
setLoading(true);
|
|
52
|
+
try {
|
|
53
|
+
const pdfId = 'test_pdf_123';
|
|
54
|
+
const pageNumber = 1;
|
|
55
|
+
const scale = 2.0;
|
|
56
|
+
const base64Data = 'dGVzdF9wZGY='; // Mock base64 data
|
|
57
|
+
|
|
58
|
+
const renderResult = await PDFJSI.renderPageDirect(pdfId, pageNumber, scale, base64Data);
|
|
59
|
+
setResult(renderResult);
|
|
60
|
+
|
|
61
|
+
Alert.alert('JSI Test', `Render result: ${renderResult.success ? 'Success' : 'Failed'}`);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
Alert.alert('JSI Test Error', error.message);
|
|
64
|
+
} finally {
|
|
65
|
+
setLoading(false);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const getStats = async () => {
|
|
70
|
+
try {
|
|
71
|
+
const stats = await PDFJSI.getJSIStats();
|
|
72
|
+
Alert.alert('JSI Stats', JSON.stringify(stats, null, 2));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
Alert.alert('Error', error.message);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
17
77
|
|
|
18
|
-
|
|
78
|
+
return (
|
|
79
|
+
<View style={styles.container}>
|
|
80
|
+
<Text style={styles.title}>Basic JSI Example</Text>
|
|
81
|
+
|
|
82
|
+
<View style={styles.statusContainer}>
|
|
83
|
+
<Text style={styles.statusText}>
|
|
84
|
+
JSI Status: {isJSIAvailable ? '✅ Available' : '❌ Not Available'}
|
|
85
|
+
</Text>
|
|
86
|
+
<Text style={styles.statusText}>
|
|
87
|
+
Platform: {Platform.OS}
|
|
88
|
+
</Text>
|
|
89
|
+
</View>
|
|
90
|
+
|
|
91
|
+
<TouchableOpacity style={styles.button} onPress={testJSI} disabled={loading}>
|
|
92
|
+
<Text style={styles.buttonText}>
|
|
93
|
+
{loading ? 'Testing...' : 'Test JSI Render'}
|
|
94
|
+
</Text>
|
|
95
|
+
</TouchableOpacity>
|
|
96
|
+
|
|
97
|
+
<TouchableOpacity style={styles.button} onPress={getStats}>
|
|
98
|
+
<Text style={styles.buttonText}>Get JSI Stats</Text>
|
|
99
|
+
</TouchableOpacity>
|
|
100
|
+
|
|
101
|
+
{result && (
|
|
102
|
+
<View style={styles.resultContainer}>
|
|
103
|
+
<Text style={styles.resultText}>
|
|
104
|
+
Result: {JSON.stringify(result, null, 2)}
|
|
105
|
+
</Text>
|
|
106
|
+
</View>
|
|
107
|
+
)}
|
|
108
|
+
</View>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Hook-based JSI Usage Example
|
|
114
|
+
*/
|
|
115
|
+
export const HookJSIExample = () => {
|
|
19
116
|
const {
|
|
20
117
|
isJSIAvailable,
|
|
21
118
|
isInitialized,
|
|
@@ -23,274 +120,445 @@ const PDFJSIExample = () => {
|
|
|
23
120
|
getPageMetrics,
|
|
24
121
|
preloadPages,
|
|
25
122
|
searchText,
|
|
26
|
-
getCacheMetrics,
|
|
27
|
-
clearCache,
|
|
28
|
-
optimizeMemory,
|
|
29
|
-
setRenderQuality,
|
|
30
|
-
updatePerformanceMetrics,
|
|
31
123
|
getPerformanceHistory,
|
|
32
|
-
|
|
124
|
+
clearPerformanceHistory,
|
|
125
|
+
createPDFInstance,
|
|
126
|
+
getPDFInstances,
|
|
127
|
+
lazyLoadPages,
|
|
128
|
+
progressiveLoadPages,
|
|
129
|
+
smartCacheFrequentPages
|
|
33
130
|
} = usePDFJSI({
|
|
34
131
|
autoInitialize: true,
|
|
35
|
-
enablePerformanceTracking: true
|
|
36
|
-
enableCaching: true
|
|
132
|
+
enablePerformanceTracking: true
|
|
37
133
|
});
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
134
|
+
|
|
135
|
+
const [pdfId, setPdfId] = useState('hook_test_pdf');
|
|
136
|
+
const [pageNumber, setPageNumber] = useState(1);
|
|
137
|
+
const [scale, setScale] = useState(2.0);
|
|
138
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
139
|
+
const [performanceData, setPerformanceData] = useState([]);
|
|
140
|
+
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
if (isInitialized && isJSIAvailable) {
|
|
143
|
+
createPDFInstance(pdfId);
|
|
46
144
|
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const handleRenderPage = async () => {
|
|
145
|
+
}, [isInitialized, isJSIAvailable, pdfId, createPDFInstance]);
|
|
146
|
+
|
|
147
|
+
const handleRenderPage = useCallback(async () => {
|
|
50
148
|
try {
|
|
51
|
-
const
|
|
52
|
-
const result = await renderPage(pdfId,
|
|
53
|
-
|
|
149
|
+
const base64Data = 'dGVzdF9wZGY='; // Mock data
|
|
150
|
+
const result = await renderPage(pdfId, pageNumber, scale, base64Data);
|
|
151
|
+
|
|
152
|
+
Alert.alert('Hook JSI', `Page rendered: ${result.success ? 'Success' : 'Failed'}`);
|
|
54
153
|
} catch (error) {
|
|
55
|
-
Alert.alert('Error',
|
|
154
|
+
Alert.alert('Error', error.message);
|
|
56
155
|
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const handleGetMetrics = async () => {
|
|
156
|
+
}, [pdfId, pageNumber, scale, renderPage]);
|
|
157
|
+
|
|
158
|
+
const handleGetMetrics = useCallback(async () => {
|
|
60
159
|
try {
|
|
61
|
-
const
|
|
62
|
-
const metrics = await getPageMetrics(pdfId, 1);
|
|
160
|
+
const metrics = await getPageMetrics(pdfId, pageNumber);
|
|
63
161
|
Alert.alert('Page Metrics', JSON.stringify(metrics, null, 2));
|
|
64
162
|
} catch (error) {
|
|
65
|
-
Alert.alert('Error',
|
|
163
|
+
Alert.alert('Error', error.message);
|
|
66
164
|
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const handlePreloadPages = async () => {
|
|
165
|
+
}, [pdfId, pageNumber, getPageMetrics]);
|
|
166
|
+
|
|
167
|
+
const handlePreloadPages = useCallback(async () => {
|
|
70
168
|
try {
|
|
71
|
-
const pdfId = 'example_pdf';
|
|
72
169
|
const success = await preloadPages(pdfId, 1, 5);
|
|
73
|
-
Alert.alert('Preload', `
|
|
170
|
+
Alert.alert('Preload', `Preloaded pages: ${success ? 'Success' : 'Failed'}`);
|
|
74
171
|
} catch (error) {
|
|
75
|
-
Alert.alert('Error',
|
|
172
|
+
Alert.alert('Error', error.message);
|
|
76
173
|
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const
|
|
174
|
+
}, [pdfId, preloadPages]);
|
|
175
|
+
|
|
176
|
+
const handleLazyLoad = useCallback(async () => {
|
|
80
177
|
try {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
Alert.alert('Search Results', `Found ${results.length} matches`);
|
|
178
|
+
const result = await lazyLoadPages(pdfId, pageNumber, 3, 100);
|
|
179
|
+
Alert.alert('Lazy Load', `Lazy loaded pages: ${result.success ? 'Success' : 'Failed'}`);
|
|
84
180
|
} catch (error) {
|
|
85
|
-
Alert.alert('Error',
|
|
181
|
+
Alert.alert('Error', error.message);
|
|
86
182
|
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const
|
|
183
|
+
}, [pdfId, pageNumber, lazyLoadPages]);
|
|
184
|
+
|
|
185
|
+
const handleProgressiveLoad = useCallback(async () => {
|
|
90
186
|
try {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
187
|
+
const result = await progressiveLoadPages(pdfId, 1, 5, (progress) => {
|
|
188
|
+
console.log(`Loading batch ${progress.batchStartPage}-${progress.batchEndPage}`);
|
|
189
|
+
});
|
|
190
|
+
Alert.alert('Progressive Load', `Loaded ${result.totalLoaded} pages`);
|
|
94
191
|
} catch (error) {
|
|
95
|
-
Alert.alert('Error',
|
|
192
|
+
Alert.alert('Error', error.message);
|
|
96
193
|
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const
|
|
194
|
+
}, [pdfId, progressiveLoadPages]);
|
|
195
|
+
|
|
196
|
+
const handleSmartCache = useCallback(async () => {
|
|
100
197
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
Alert.alert('Memory', `Optimized: ${success}`);
|
|
198
|
+
const result = await smartCacheFrequentPages(pdfId, [1, 2, 10, 50]);
|
|
199
|
+
Alert.alert('Smart Cache', `Cached ${result.successfulCaches} pages`);
|
|
104
200
|
} catch (error) {
|
|
105
|
-
Alert.alert('Error',
|
|
201
|
+
Alert.alert('Error', error.message);
|
|
106
202
|
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const
|
|
203
|
+
}, [pdfId, smartCacheFrequentPages]);
|
|
204
|
+
|
|
205
|
+
const handleSearch = useCallback(async () => {
|
|
206
|
+
if (!searchTerm.trim()) {
|
|
207
|
+
Alert.alert('Error', 'Please enter a search term');
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
110
211
|
try {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
Alert.alert('Quality', `Set to high: ${success}`);
|
|
212
|
+
const results = await searchText(pdfId, searchTerm, 1, 10);
|
|
213
|
+
Alert.alert('Search Results', `Found ${results.length} matches`);
|
|
114
214
|
} catch (error) {
|
|
115
|
-
Alert.alert('Error',
|
|
215
|
+
Alert.alert('Error', error.message);
|
|
116
216
|
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const
|
|
217
|
+
}, [pdfId, searchTerm, searchText]);
|
|
218
|
+
|
|
219
|
+
const updatePerformanceData = useCallback(() => {
|
|
120
220
|
const history = getPerformanceHistory();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
Alert.alert('
|
|
128
|
-
};
|
|
129
|
-
|
|
221
|
+
setPerformanceData(history);
|
|
222
|
+
}, [getPerformanceHistory]);
|
|
223
|
+
|
|
224
|
+
const clearPerformance = useCallback(() => {
|
|
225
|
+
clearPerformanceHistory();
|
|
226
|
+
setPerformanceData([]);
|
|
227
|
+
Alert.alert('Performance', 'Performance history cleared');
|
|
228
|
+
}, [clearPerformanceHistory]);
|
|
229
|
+
|
|
130
230
|
return (
|
|
131
231
|
<ScrollView style={styles.container}>
|
|
132
|
-
<Text style={styles.title}>
|
|
232
|
+
<Text style={styles.title}>Hook-based JSI Example</Text>
|
|
133
233
|
|
|
134
234
|
<View style={styles.statusContainer}>
|
|
135
235
|
<Text style={styles.statusText}>
|
|
136
|
-
JSI
|
|
236
|
+
JSI Status: {isJSIAvailable ? '✅ Available' : '❌ Not Available'}
|
|
137
237
|
</Text>
|
|
138
238
|
<Text style={styles.statusText}>
|
|
139
239
|
Initialized: {isInitialized ? '✅ Yes' : '⏳ No'}
|
|
140
240
|
</Text>
|
|
141
241
|
</View>
|
|
142
|
-
|
|
143
|
-
<View style={styles.
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
242
|
+
|
|
243
|
+
<View style={styles.inputContainer}>
|
|
244
|
+
<TextInput
|
|
245
|
+
style={styles.input}
|
|
246
|
+
placeholder="PDF ID"
|
|
247
|
+
value={pdfId}
|
|
248
|
+
onChangeText={setPdfId}
|
|
249
|
+
/>
|
|
250
|
+
<TextInput
|
|
251
|
+
style={styles.input}
|
|
252
|
+
placeholder="Page Number"
|
|
253
|
+
value={pageNumber.toString()}
|
|
254
|
+
onChangeText={(text) => setPageNumber(parseInt(text) || 1)}
|
|
255
|
+
keyboardType="numeric"
|
|
256
|
+
/>
|
|
257
|
+
<TextInput
|
|
258
|
+
style={styles.input}
|
|
259
|
+
placeholder="Scale"
|
|
260
|
+
value={scale.toString()}
|
|
261
|
+
onChangeText={(text) => setScale(parseFloat(text) || 1.0)}
|
|
262
|
+
keyboardType="numeric"
|
|
263
|
+
/>
|
|
154
264
|
</View>
|
|
155
|
-
|
|
156
|
-
{
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
265
|
+
|
|
266
|
+
<TouchableOpacity style={styles.button} onPress={handleRenderPage}>
|
|
267
|
+
<Text style={styles.buttonText}>Render Page</Text>
|
|
268
|
+
</TouchableOpacity>
|
|
269
|
+
|
|
270
|
+
<TouchableOpacity style={styles.button} onPress={handleGetMetrics}>
|
|
271
|
+
<Text style={styles.buttonText}>Get Page Metrics</Text>
|
|
272
|
+
</TouchableOpacity>
|
|
273
|
+
|
|
274
|
+
<TouchableOpacity style={styles.button} onPress={handlePreloadPages}>
|
|
275
|
+
<Text style={styles.buttonText}>Preload Pages 1-5</Text>
|
|
276
|
+
</TouchableOpacity>
|
|
277
|
+
|
|
278
|
+
<TouchableOpacity style={styles.button} onPress={handleLazyLoad}>
|
|
279
|
+
<Text style={styles.buttonText}>Lazy Load Pages</Text>
|
|
280
|
+
</TouchableOpacity>
|
|
281
|
+
|
|
282
|
+
<TouchableOpacity style={styles.button} onPress={handleProgressiveLoad}>
|
|
283
|
+
<Text style={styles.buttonText}>Progressive Load</Text>
|
|
284
|
+
</TouchableOpacity>
|
|
285
|
+
|
|
286
|
+
<TouchableOpacity style={styles.button} onPress={handleSmartCache}>
|
|
287
|
+
<Text style={styles.buttonText}>Smart Cache Pages</Text>
|
|
288
|
+
</TouchableOpacity>
|
|
289
|
+
|
|
290
|
+
<View style={styles.searchContainer}>
|
|
291
|
+
<TextInput
|
|
292
|
+
style={styles.input}
|
|
293
|
+
placeholder="Search term"
|
|
294
|
+
value={searchTerm}
|
|
295
|
+
onChangeText={setSearchTerm}
|
|
296
|
+
/>
|
|
297
|
+
<TouchableOpacity style={styles.button} onPress={handleSearch}>
|
|
298
|
+
<Text style={styles.buttonText}>Search</Text>
|
|
299
|
+
</TouchableOpacity>
|
|
300
|
+
</View>
|
|
301
|
+
|
|
302
|
+
<TouchableOpacity style={styles.button} onPress={updatePerformanceData}>
|
|
303
|
+
<Text style={styles.buttonText}>Update Performance Data</Text>
|
|
304
|
+
</TouchableOpacity>
|
|
305
|
+
|
|
306
|
+
<TouchableOpacity style={styles.button} onPress={clearPerformance}>
|
|
307
|
+
<Text style={styles.buttonText}>Clear Performance History</Text>
|
|
308
|
+
</TouchableOpacity>
|
|
309
|
+
|
|
310
|
+
{performanceData.length > 0 && (
|
|
311
|
+
<View style={styles.performanceContainer}>
|
|
312
|
+
<Text style={styles.performanceTitle}>Performance History:</Text>
|
|
313
|
+
{performanceData.slice(-5).map((item, index) => (
|
|
314
|
+
<Text key={index} style={styles.performanceText}>
|
|
315
|
+
{item.operation}: {item.duration.toFixed(2)}ms ({item.mode})
|
|
173
316
|
</Text>
|
|
174
317
|
))}
|
|
175
318
|
</View>
|
|
176
319
|
)}
|
|
320
|
+
</ScrollView>
|
|
321
|
+
);
|
|
322
|
+
};
|
|
177
323
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Enhanced PDF View Example
|
|
326
|
+
*/
|
|
327
|
+
export const EnhancedPdfViewExample = () => {
|
|
328
|
+
const [showPerformance, setShowPerformance] = useState(false);
|
|
329
|
+
|
|
330
|
+
const handleShowPerformance = async () => {
|
|
331
|
+
try {
|
|
332
|
+
const benchmark = await EnhancedPdfUtils.getPerformanceBenchmark();
|
|
333
|
+
Alert.alert(
|
|
334
|
+
'Performance Benchmark',
|
|
335
|
+
`JSI Available: ${benchmark.jsiAvailable}\n` +
|
|
336
|
+
`Performance Level: ${benchmark.performanceLevel}\n` +
|
|
337
|
+
`Direct Memory Access: ${benchmark.directMemoryAccess}\n` +
|
|
338
|
+
`Operations: ${benchmark.operationHistory.length}`
|
|
339
|
+
);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
Alert.alert('Error', error.message);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const handleClearCaches = async () => {
|
|
346
|
+
try {
|
|
347
|
+
const success = await EnhancedPdfUtils.clearAllCaches();
|
|
348
|
+
Alert.alert('Cache', `Caches cleared: ${success ? 'Success' : 'Failed'}`);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
Alert.alert('Error', error.message);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const handleOptimizeMemory = async () => {
|
|
355
|
+
try {
|
|
356
|
+
const success = await EnhancedPdfUtils.optimizeAllMemory();
|
|
357
|
+
Alert.alert('Memory', `Memory optimized: ${success ? 'Success' : 'Failed'}`);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
Alert.alert('Error', error.message);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
return (
|
|
364
|
+
<View style={styles.container}>
|
|
365
|
+
<Text style={styles.title}>Enhanced PDF View Example</Text>
|
|
366
|
+
|
|
367
|
+
<EnhancedPdfView
|
|
368
|
+
source={{ uri: 'https://example.com/sample.pdf' }}
|
|
369
|
+
style={styles.pdfView}
|
|
370
|
+
onLoadComplete={(numberOfPages) => {
|
|
371
|
+
console.log(`PDF loaded with ${numberOfPages} pages`);
|
|
372
|
+
}}
|
|
373
|
+
onPageChanged={(page) => {
|
|
374
|
+
console.log(`Current page: ${page}`);
|
|
375
|
+
}}
|
|
376
|
+
onError={(error) => {
|
|
377
|
+
console.error('PDF error:', error);
|
|
378
|
+
}}
|
|
379
|
+
// JSI-specific props
|
|
380
|
+
jsiEnabled={true}
|
|
381
|
+
enablePerformanceTracking={true}
|
|
382
|
+
enableSmartCaching={true}
|
|
383
|
+
/>
|
|
384
|
+
|
|
385
|
+
<View style={styles.buttonContainer}>
|
|
386
|
+
<TouchableOpacity style={styles.button} onPress={handleShowPerformance}>
|
|
387
|
+
<Text style={styles.buttonText}>Show Performance</Text>
|
|
388
|
+
</TouchableOpacity>
|
|
389
|
+
|
|
390
|
+
<TouchableOpacity style={styles.button} onPress={handleClearCaches}>
|
|
391
|
+
<Text style={styles.buttonText}>Clear Caches</Text>
|
|
392
|
+
</TouchableOpacity>
|
|
393
|
+
|
|
394
|
+
<TouchableOpacity style={styles.button} onPress={handleOptimizeMemory}>
|
|
395
|
+
<Text style={styles.buttonText}>Optimize Memory</Text>
|
|
396
|
+
</TouchableOpacity>
|
|
194
397
|
</View>
|
|
195
|
-
</
|
|
398
|
+
</View>
|
|
399
|
+
);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Main Example App
|
|
404
|
+
*/
|
|
405
|
+
export const PDFJSIExampleApp = () => {
|
|
406
|
+
const [currentExample, setCurrentExample] = useState('basic');
|
|
407
|
+
|
|
408
|
+
const renderExample = () => {
|
|
409
|
+
switch (currentExample) {
|
|
410
|
+
case 'basic':
|
|
411
|
+
return <BasicJSIExample />;
|
|
412
|
+
case 'hook':
|
|
413
|
+
return <HookJSIExample />;
|
|
414
|
+
case 'enhanced':
|
|
415
|
+
return <EnhancedPdfViewExample />;
|
|
416
|
+
default:
|
|
417
|
+
return <BasicJSIExample />;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
return (
|
|
422
|
+
<View style={styles.appContainer}>
|
|
423
|
+
<View style={styles.tabContainer}>
|
|
424
|
+
<TouchableOpacity
|
|
425
|
+
style={[styles.tab, currentExample === 'basic' && styles.activeTab]}
|
|
426
|
+
onPress={() => setCurrentExample('basic')}
|
|
427
|
+
>
|
|
428
|
+
<Text style={styles.tabText}>Basic</Text>
|
|
429
|
+
</TouchableOpacity>
|
|
430
|
+
|
|
431
|
+
<TouchableOpacity
|
|
432
|
+
style={[styles.tab, currentExample === 'hook' && styles.activeTab]}
|
|
433
|
+
onPress={() => setCurrentExample('hook')}
|
|
434
|
+
>
|
|
435
|
+
<Text style={styles.tabText}>Hook</Text>
|
|
436
|
+
</TouchableOpacity>
|
|
437
|
+
|
|
438
|
+
<TouchableOpacity
|
|
439
|
+
style={[styles.tab, currentExample === 'enhanced' && styles.activeTab]}
|
|
440
|
+
onPress={() => setCurrentExample('enhanced')}
|
|
441
|
+
>
|
|
442
|
+
<Text style={styles.tabText}>Enhanced</Text>
|
|
443
|
+
</TouchableOpacity>
|
|
444
|
+
</View>
|
|
445
|
+
|
|
446
|
+
{renderExample()}
|
|
447
|
+
</View>
|
|
196
448
|
);
|
|
197
449
|
};
|
|
198
450
|
|
|
199
451
|
const styles = StyleSheet.create({
|
|
452
|
+
appContainer: {
|
|
453
|
+
flex: 1,
|
|
454
|
+
backgroundColor: '#f5f5f5'
|
|
455
|
+
},
|
|
456
|
+
tabContainer: {
|
|
457
|
+
flexDirection: 'row',
|
|
458
|
+
backgroundColor: '#fff',
|
|
459
|
+
borderBottomWidth: 1,
|
|
460
|
+
borderBottomColor: '#ddd'
|
|
461
|
+
},
|
|
462
|
+
tab: {
|
|
463
|
+
flex: 1,
|
|
464
|
+
padding: 15,
|
|
465
|
+
alignItems: 'center',
|
|
466
|
+
borderBottomWidth: 2,
|
|
467
|
+
borderBottomColor: 'transparent'
|
|
468
|
+
},
|
|
469
|
+
activeTab: {
|
|
470
|
+
borderBottomColor: '#007AFF'
|
|
471
|
+
},
|
|
472
|
+
tabText: {
|
|
473
|
+
fontSize: 16,
|
|
474
|
+
fontWeight: '500',
|
|
475
|
+
color: '#333'
|
|
476
|
+
},
|
|
200
477
|
container: {
|
|
201
478
|
flex: 1,
|
|
202
479
|
padding: 20,
|
|
203
|
-
backgroundColor: '#
|
|
480
|
+
backgroundColor: '#fff'
|
|
204
481
|
},
|
|
205
482
|
title: {
|
|
206
483
|
fontSize: 24,
|
|
207
484
|
fontWeight: 'bold',
|
|
208
|
-
textAlign: 'center',
|
|
209
485
|
marginBottom: 20,
|
|
210
|
-
|
|
486
|
+
textAlign: 'center',
|
|
487
|
+
color: '#333'
|
|
211
488
|
},
|
|
212
489
|
statusContainer: {
|
|
213
|
-
backgroundColor: '#
|
|
490
|
+
backgroundColor: '#f8f8f8',
|
|
214
491
|
padding: 15,
|
|
215
492
|
borderRadius: 8,
|
|
216
|
-
marginBottom: 20
|
|
217
|
-
elevation: 2,
|
|
218
|
-
shadowColor: '#000',
|
|
219
|
-
shadowOffset: { width: 0, height: 2 },
|
|
220
|
-
shadowOpacity: 0.1,
|
|
221
|
-
shadowRadius: 4,
|
|
493
|
+
marginBottom: 20
|
|
222
494
|
},
|
|
223
495
|
statusText: {
|
|
224
496
|
fontSize: 16,
|
|
225
497
|
marginBottom: 5,
|
|
226
|
-
color: '#
|
|
498
|
+
color: '#333'
|
|
227
499
|
},
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
marginBottom: 20,
|
|
500
|
+
inputContainer: {
|
|
501
|
+
marginBottom: 20
|
|
231
502
|
},
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
503
|
+
input: {
|
|
504
|
+
borderWidth: 1,
|
|
505
|
+
borderColor: '#ddd',
|
|
235
506
|
borderRadius: 8,
|
|
236
|
-
|
|
237
|
-
elevation: 2,
|
|
238
|
-
shadowColor: '#000',
|
|
239
|
-
shadowOffset: { width: 0, height: 2 },
|
|
240
|
-
shadowOpacity: 0.1,
|
|
241
|
-
shadowRadius: 4,
|
|
242
|
-
},
|
|
243
|
-
statsTitle: {
|
|
244
|
-
fontSize: 18,
|
|
245
|
-
fontWeight: 'bold',
|
|
507
|
+
padding: 12,
|
|
246
508
|
marginBottom: 10,
|
|
247
|
-
|
|
509
|
+
fontSize: 16
|
|
248
510
|
},
|
|
249
|
-
|
|
250
|
-
|
|
511
|
+
searchContainer: {
|
|
512
|
+
marginBottom: 20
|
|
513
|
+
},
|
|
514
|
+
button: {
|
|
515
|
+
backgroundColor: '#007AFF',
|
|
251
516
|
padding: 15,
|
|
252
517
|
borderRadius: 8,
|
|
253
|
-
marginBottom: 20,
|
|
254
|
-
elevation: 2,
|
|
255
|
-
shadowColor: '#000',
|
|
256
|
-
shadowOffset: { width: 0, height: 2 },
|
|
257
|
-
shadowOpacity: 0.1,
|
|
258
|
-
shadowRadius: 4,
|
|
259
|
-
},
|
|
260
|
-
historyTitle: {
|
|
261
|
-
fontSize: 18,
|
|
262
|
-
fontWeight: 'bold',
|
|
263
518
|
marginBottom: 10,
|
|
264
|
-
|
|
519
|
+
alignItems: 'center'
|
|
265
520
|
},
|
|
266
|
-
|
|
521
|
+
buttonContainer: {
|
|
522
|
+
flexDirection: 'row',
|
|
523
|
+
justifyContent: 'space-around',
|
|
524
|
+
marginTop: 20
|
|
525
|
+
},
|
|
526
|
+
buttonText: {
|
|
527
|
+
color: '#fff',
|
|
528
|
+
fontSize: 16,
|
|
529
|
+
fontWeight: '600'
|
|
530
|
+
},
|
|
531
|
+
resultContainer: {
|
|
532
|
+
backgroundColor: '#f0f0f0',
|
|
533
|
+
padding: 15,
|
|
534
|
+
borderRadius: 8,
|
|
535
|
+
marginTop: 20
|
|
536
|
+
},
|
|
537
|
+
resultText: {
|
|
267
538
|
fontSize: 14,
|
|
268
|
-
|
|
269
|
-
color: '#666',
|
|
270
|
-
fontFamily: 'monospace',
|
|
539
|
+
color: '#333'
|
|
271
540
|
},
|
|
272
|
-
|
|
273
|
-
backgroundColor: '#
|
|
541
|
+
performanceContainer: {
|
|
542
|
+
backgroundColor: '#f8f8f8',
|
|
274
543
|
padding: 15,
|
|
275
544
|
borderRadius: 8,
|
|
276
|
-
|
|
277
|
-
elevation: 2,
|
|
278
|
-
shadowColor: '#000',
|
|
279
|
-
shadowOffset: { width: 0, height: 2 },
|
|
280
|
-
shadowOpacity: 0.1,
|
|
281
|
-
shadowRadius: 4,
|
|
545
|
+
marginTop: 20
|
|
282
546
|
},
|
|
283
|
-
|
|
547
|
+
performanceTitle: {
|
|
284
548
|
fontSize: 18,
|
|
285
549
|
fontWeight: 'bold',
|
|
286
550
|
marginBottom: 10,
|
|
287
|
-
color: '#333'
|
|
551
|
+
color: '#333'
|
|
288
552
|
},
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
553
|
+
performanceText: {
|
|
554
|
+
fontSize: 14,
|
|
555
|
+
marginBottom: 5,
|
|
556
|
+
color: '#666'
|
|
293
557
|
},
|
|
558
|
+
pdfView: {
|
|
559
|
+
flex: 1,
|
|
560
|
+
backgroundColor: '#f0f0f0'
|
|
561
|
+
}
|
|
294
562
|
});
|
|
295
563
|
|
|
296
|
-
export default
|
|
564
|
+
export default PDFJSIExampleApp;
|