react-native-optimized-pdf 1.1.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- const { View, Platform, requireNativeComponent } = require('react-native');
2
+ import { View, Platform, requireNativeComponent } from 'react-native';
3
3
  import { PdfCacheService } from './services/pdfCache';
4
4
  import { PdfNavigationControls } from './components/PdfNavigationControls';
5
5
  import { PdfLoadingOverlay, PdfErrorOverlay } from './components/PdfOverlays';
@@ -9,11 +9,16 @@ import {
9
9
  DEFAULT_SHOW_NAVIGATION_CONTROLS,
10
10
  ERROR_MESSAGES,
11
11
  } from './constants';
12
- import type { OptimizedPdfViewProps, NativeLoadCompleteEvent, NativePageCountEvent } from './types';
12
+ import type {
13
+ OptimizedPdfViewProps,
14
+ NativeLoadCompleteEvent,
15
+ NativePageCountEvent,
16
+ NativeOptimizedPdfViewProps,
17
+ } from './types';
13
18
 
14
19
  const NativeOptimizedPdfView =
15
20
  Platform.OS === 'ios' || Platform.OS === 'android'
16
- ? requireNativeComponent('OptimizedPdfView')
21
+ ? requireNativeComponent<NativeOptimizedPdfViewProps>('OptimizedPdfView')
17
22
  : () => null;
18
23
 
19
24
  /**
@@ -37,6 +42,7 @@ const NativeOptimizedPdfView =
37
42
  */
38
43
  export default function OptimizedPdfView({
39
44
  source,
45
+ page,
40
46
  password,
41
47
  maximumZoom = DEFAULT_MAXIMUM_ZOOM,
42
48
  enableAntialiasing = DEFAULT_ENABLE_ANTIALIASING,
@@ -52,7 +58,7 @@ export default function OptimizedPdfView({
52
58
  const [loading, setLoading] = useState(true);
53
59
  const [progress, setProgress] = useState(0);
54
60
  const [error, setError] = useState<string | null>(null);
55
- const [page, setPage] = useState(0);
61
+ const [internalPage, setInternalPage] = useState(0);
56
62
  const [totalPages, setTotalPages] = useState(1);
57
63
  const lastSource = useRef<string | null>(null);
58
64
 
@@ -64,7 +70,7 @@ export default function OptimizedPdfView({
64
70
  setProgress(0);
65
71
  setError(null);
66
72
  setLocalPath(null);
67
- setPage(0);
73
+ setInternalPage(0);
68
74
  setTotalPages(1);
69
75
  lastSource.current = source.uri;
70
76
 
@@ -96,23 +102,23 @@ export default function OptimizedPdfView({
96
102
  }, [source.uri, source.cache, source.cacheFileName, source.expiration, onError, source]);
97
103
 
98
104
  const handleNextPage = () => {
99
- if (page < totalPages - 1) {
100
- const newPage = page + 1;
101
- setPage(newPage);
105
+ if (internalPage < totalPages - 1) {
106
+ const newPage = internalPage + 1;
107
+ setInternalPage(newPage);
102
108
  onPageChange?.(newPage);
103
109
  }
104
110
  };
105
111
 
106
112
  const handlePrevPage = () => {
107
- if (page > 0) {
108
- const newPage = page - 1;
109
- setPage(newPage);
113
+ if (internalPage > 0) {
114
+ const newPage = internalPage - 1;
115
+ setInternalPage(newPage);
110
116
  onPageChange?.(newPage);
111
117
  }
112
118
  };
113
119
 
114
120
  const handlePageChange = (newPage: number) => {
115
- setPage(newPage);
121
+ setInternalPage(newPage);
116
122
  onPageChange?.(newPage);
117
123
  };
118
124
 
@@ -135,15 +141,11 @@ export default function OptimizedPdfView({
135
141
  return <PdfErrorOverlay error={error} style={style} />;
136
142
  }
137
143
 
138
- if (!localPath) {
139
- return null;
140
- }
141
-
142
144
  return (
143
145
  <View style={[{ flex: 1 }, style]}>
144
146
  <NativeOptimizedPdfView
145
- source={localPath}
146
- page={page}
147
+ source={localPath as string}
148
+ page={showNavigationControls ? internalPage : page || 0}
147
149
  enableAntialiasing={enableAntialiasing}
148
150
  maximumZoom={maximumZoom}
149
151
  password={password || ''}
@@ -155,7 +157,7 @@ export default function OptimizedPdfView({
155
157
  />
156
158
  {showNavigationControls && (
157
159
  <PdfNavigationControls
158
- currentPage={page}
160
+ currentPage={internalPage}
159
161
  totalPages={totalPages}
160
162
  onNextPage={handleNextPage}
161
163
  onPrevPage={handlePrevPage}
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- const { View, Text, TouchableOpacity, TextInput, StyleSheet } = require('react-native');
2
+ import { View, Text, TouchableOpacity, TextInput, StyleSheet } from 'react-native';
3
3
  import type { PdfNavigationControlsProps } from '../types';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- const { View, Text, ActivityIndicator, StyleSheet } = require('react-native');
2
+ import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
3
3
  import type { PdfLoadingOverlayProps, PdfErrorOverlayProps } from '../types';
4
4
 
5
5
  /**
@@ -8,7 +8,7 @@ import type { PdfLoadingOverlayProps, PdfErrorOverlayProps } from '../types';
8
8
  export const PdfLoadingOverlay: React.FC<PdfLoadingOverlayProps> = ({ progress, style }) => {
9
9
  return (
10
10
  <View style={[styles.container, style]}>
11
- <ActivityIndicator size="large" color="#fff" />
11
+ <ActivityIndicator size="large" color="#000000" />
12
12
  <Text style={styles.progressText}>{progress}%</Text>
13
13
  </View>
14
14
  );
@@ -33,7 +33,7 @@ const styles = StyleSheet.create({
33
33
  padding: 20,
34
34
  },
35
35
  progressText: {
36
- color: '#fff',
36
+ color: '#000000',
37
37
  marginTop: 10,
38
38
  fontSize: 16,
39
39
  fontWeight: '600',
package/src/constants.ts CHANGED
@@ -8,6 +8,4 @@ export const DEFAULT_SHOW_NAVIGATION_CONTROLS = true;
8
8
 
9
9
  export const ERROR_MESSAGES = {
10
10
  DOWNLOAD_FAILED: 'Failed to download PDF',
11
- LOAD_FAILED: 'Failed to load PDF',
12
- INVALID_SOURCE: 'Invalid PDF source',
13
11
  } as const;
@@ -1,4 +1,4 @@
1
- import RNFS from 'react-native-fs';
1
+ import * as RNFS from '@dr.pogodin/react-native-fs';
2
2
  import md5 from 'crypto-js/md5';
3
3
  import type { PdfSource } from '../types';
4
4
 
@@ -33,11 +33,12 @@ export class PdfCacheService {
33
33
  // Check if cache has expired
34
34
  const stat = await RNFS.stat(localPath);
35
35
  const now = Date.now() / 1000;
36
- return now - stat.mtime < source.expiration;
36
+ const modifiedAt = stat.mtime.getTime() / 1000;
37
+ return now - modifiedAt < source.expiration;
37
38
  }
38
39
 
39
40
  /**
40
- * Download a PDF file and cache it locally
41
+ * Download a PDF file and cache it locally, or return a local file directly
41
42
  * @param source PDF source configuration
42
43
  * @param onProgress Optional callback for download progress
43
44
  * @returns Local file path
@@ -46,6 +47,11 @@ export class PdfCacheService {
46
47
  source: PdfSource,
47
48
  onProgress?: (percent: number) => void,
48
49
  ): Promise<string> {
50
+ // Local files are already readable by the native viewer.
51
+ if (source.uri.startsWith('file://') || source.uri.startsWith('/')) {
52
+ return source.uri;
53
+ }
54
+
49
55
  const localPath = this.getCacheFilePath(source);
50
56
 
51
57
  // Check if we can use cached version
@@ -12,8 +12,6 @@ export interface PdfSource {
12
12
  cacheFileName?: string;
13
13
  /** Cache expiration time in seconds. If not set, cache never expires */
14
14
  expiration?: number;
15
- /** HTTP method for download. Default: 'GET' */
16
- method?: string;
17
15
  /** HTTP headers for download request */
18
16
  headers?: Record<string, string>;
19
17
  }
@@ -41,6 +39,8 @@ export interface PdfErrorEvent {
41
39
  export interface OptimizedPdfViewProps {
42
40
  /** PDF source configuration */
43
41
  source: PdfSource;
42
+ /** Current page index (0-based) */
43
+ page?: number;
44
44
  /** Password for encrypted PDF files */
45
45
  password?: string;
46
46
  /** Maximum zoom level. Default: 3 */
@@ -110,3 +110,26 @@ export interface PdfErrorOverlayProps {
110
110
  error: string;
111
111
  style?: ViewStyle;
112
112
  }
113
+
114
+ export interface NativeOptimizedPdfViewProps {
115
+ /** PDF source configuration */
116
+ source: string;
117
+ /** Current page index (0-based) */
118
+ page: number;
119
+ /** Password for encrypted PDF files */
120
+ password?: string;
121
+ /** Maximum zoom level. Default: 3 */
122
+ maximumZoom?: number;
123
+ /** Enable antialiasing for better rendering quality. Default: true */
124
+ enableAntialiasing?: boolean;
125
+ /** Callback when PDF is loaded successfully */
126
+ onLoadComplete?: (event: NativeLoadCompleteEvent) => void;
127
+ /** Callback when an error occurs */
128
+ onError?: (error: PdfErrorEvent) => void;
129
+ /** Callback when page count is available */
130
+ onPageCount?: (event: NativePageCountEvent) => void;
131
+ /** Callback when page changes */
132
+ onPasswordRequired?: () => void;
133
+ /** Custom style for the container */
134
+ style?: ViewStyle;
135
+ }
package/tsconfig.json CHANGED
@@ -1,17 +1,24 @@
1
1
  {
2
+ // "extends": "@react-native/typescript-config/tsconfig.json",
2
3
  "compilerOptions": {
3
- "target": "es2017",
4
- "module": "commonjs",
5
- "lib": ["es6"],
6
- "allowJs": true,
7
- "jsx": "react-native",
8
- "noEmit": true,
9
- "isolatedModules": true,
10
- "strict": true,
11
- "moduleResolution": "node",
4
+ "target": "ESNext",
5
+ "module": "ESNext",
12
6
  "esModuleInterop": true,
7
+ "moduleResolution": "bundler",
8
+ "jsx": "react-native",
13
9
  "skipLibCheck": true,
14
- "forceConsistentCasingInFileNames": true
10
+ "strict": true,
11
+ "noUnusedLocals": true,
12
+ "noUnusedParameters": true,
13
+ "noEmit": false,
14
+ "checkJs": false,
15
+ "allowJs": false,
16
+ "noImplicitAny": false,
17
+ "declaration": true,
18
+ "paths": {
19
+ "react-native-calendars": ["./src/index.ts"]
20
+ },
15
21
  },
22
+ "include": ["src/**/*", "example/App.tsx"],
16
23
  "exclude": ["node_modules", "**/__tests__/**"]
17
24
  }