Browse Source

ReactNative - 调整示例代码, 修复安卓端弹起键盘后异常问题

liuxiaolong 3 months ago
parent
commit
8ae888e414

+ 2 - 1
android/build.gradle

@@ -85,8 +85,9 @@ repositories {
 
 
 dependencies {
-
+  implementation fileTree(include: ['*.jar'], dir: 'libs')
   implementation "com.facebook.react:react-native:+"
+
   api "com.compdf:compdfkit:2.1.1"
   api "com.compdf:compdfkit-ui:2.1.1"
   api "com.compdf:compdfkit-tools:2.1.1"

+ 0 - 0
android/settings.gradle


+ 3 - 3
android/src/main/java/com/compdfkitpdf/reactnative/CompdfkitPdfModule.java

@@ -35,7 +35,7 @@ import java.io.File;
  */
 public class CompdfkitPdfModule extends ReactContextBaseJavaModule {
 
-  private static final String TAG = "ComPDFKit-RN";
+  private static final String TAG = "ComPDFKitRN";
 
   public static final String NAME = "ComPDFKit";
 
@@ -105,7 +105,7 @@ public class CompdfkitPdfModule extends ReactContextBaseJavaModule {
   @ReactMethod
   public void init_(String license, Promise promise) {
     CPDFSdk.init(mReactContext, license, true, (code, msg) -> {
-      Log.e(TAG, "init_: code:" + code + ", msg:" + msg);
+      Log.d(TAG, "init_: code:" + code + ", msg:" + msg);
       promise.resolve(code == CPDFSdk.VERIFY_SUCCESS);
     });
   }
@@ -127,7 +127,7 @@ public class CompdfkitPdfModule extends ReactContextBaseJavaModule {
   @ReactMethod
   public void initialize(String androidOnlineLicense, String iosOnlineLicense, Promise promise) {
     CPDFSdk.init(mReactContext, androidOnlineLicense, false, (code, msg) -> {
-      Log.e(TAG, "initialize: code:" + code + ", msg:" + msg);
+      Log.d(TAG, "initialize: code:" + code + ", msg:" + msg);
       promise.resolve(code == CPDFSdk.VERIFY_SUCCESS);
     });
   }

+ 15 - 4
android/src/main/java/com/compdfkitpdf/reactnative/CompdfkitPdfPackage.java

@@ -11,6 +11,7 @@ package com.compdfkitpdf.reactnative;
 
 import androidx.annotation.NonNull;
 
+import com.compdfkitpdf.reactnative.modules.CPDFViewModule;
 import com.compdfkitpdf.reactnative.viewmanager.CPDFViewManager;
 import com.facebook.react.ReactPackage;
 import com.facebook.react.bridge.NativeModule;
@@ -22,17 +23,27 @@ import java.util.Arrays;
 import java.util.List;
 
 public class CompdfkitPdfPackage implements ReactPackage {
+
+  private CPDFViewManager mPDFViewManager;
+
   @NonNull
   @Override
   public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
-    List<NativeModule> modules = new ArrayList<>();
-    modules.add(new CompdfkitPdfModule(reactContext));
-    return modules;
+    if (null == mPDFViewManager){
+      mPDFViewManager = new CPDFViewManager(reactContext);
+    }
+    return Arrays.<NativeModule>asList(
+      new CompdfkitPdfModule(reactContext),
+      new CPDFViewModule(reactContext, mPDFViewManager)
+    );
   }
 
   @NonNull
   @Override
   public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
-    return Arrays.asList(new CPDFViewManager(reactContext));
+    if (null == mPDFViewManager){
+      mPDFViewManager = new CPDFViewManager(reactContext);
+    }
+    return Arrays.<ViewManager>asList(mPDFViewManager);
   }
 }

+ 56 - 0
android/src/main/java/com/compdfkitpdf/reactnative/modules/CPDFViewModule.java

@@ -0,0 +1,56 @@
+/**
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+package com.compdfkitpdf.reactnative.modules;
+
+import android.util.Log;
+import androidx.annotation.NonNull;
+import com.compdfkitpdf.reactnative.viewmanager.CPDFViewManager;
+import com.facebook.react.bridge.Promise;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
+import com.facebook.react.bridge.ReactMethod;
+
+
+public class CPDFViewModule extends ReactContextBaseJavaModule {
+  private static final String TAG = "ComPDFKitRN";
+
+  public static final String REACT_CLASS = "CPDFViewManager";
+
+  private CPDFViewManager mPDFViewInstance;
+
+  public CPDFViewModule(ReactApplicationContext reactApplicationContext, CPDFViewManager viewManager){
+    super(reactApplicationContext);
+    mPDFViewInstance = viewManager;
+  }
+
+  @NonNull
+  @Override
+  public String getName() {
+    return REACT_CLASS;
+  }
+
+  @ReactMethod
+  public void save(final int tag, final Promise promise){
+    Log.d(TAG, "save(tag:" + tag + ")---->");
+    getReactApplicationContext().runOnUiQueueThread(()->{
+      try{
+        mPDFViewInstance.save(tag, (s, uri) -> {
+          Log.d(TAG, "save()- save success");
+          promise.resolve(true);
+        }, e -> {
+          Log.d(TAG, "save()- save fail");
+          promise.resolve(false);
+        });
+      }catch (Exception e){
+        promise.resolve(false);
+      }
+    });
+  }
+}

+ 54 - 13
android/src/main/java/com/compdfkitpdf/reactnative/view/CPDFView.java

@@ -10,25 +10,32 @@
 package com.compdfkitpdf.reactnative.view;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.net.Uri;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentManager;
+import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.tools.common.pdf.CPDFDocumentFragment;
 import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
+import com.compdfkit.ui.reader.CPDFReaderView;
 import com.compdfkitpdf.reactnative.util.CPDFDocumentUtil;
 import com.facebook.react.uimanager.ThemedReactContext;
+import java.util.HashMap;
 
 
 public class CPDFView extends FrameLayout {
 
-  private CPDFDocumentFragment documentFragment;
+  private boolean isPasswordSet = false;
+
+  public CPDFDocumentFragment documentFragment;
 
   private FragmentManager fragmentManager;
 
@@ -42,15 +49,6 @@ public class CPDFView extends FrameLayout {
 
   private CPDFConfiguration configuration;
 
-  public CPDFView(@NonNull Context context,
-    @Nullable AttributeSet attributeSet) {
-    super(context, attributeSet);
-  }
-
-  public CPDFView(@NonNull Context context, @Nullable AttributeSet attributeSet, int i) {
-    super(context, attributeSet, i);
-  }
-
   public void setup(ThemedReactContext reactContext, FragmentManager fragmentManager) {
     this.fragmentManager = fragmentManager;
     int width = ViewGroup.LayoutParams.MATCH_PARENT;
@@ -59,8 +57,7 @@ public class CPDFView extends FrameLayout {
     setLayoutParams(params);
   }
 
-  public void setDocument(String document, String password) {
-    this.password = password;
+  public void setDocument(String document) {
     if (document.startsWith(CPDFDocumentUtil.ASSETS_SCHEME)) {
       this.document = CPDFDocumentUtil.getAssetsDocument(getContext(), document);
     } else if (document.startsWith(CPDFDocumentUtil.CONTENT_SCHEME)) {
@@ -74,13 +71,19 @@ public class CPDFView extends FrameLayout {
     initDocumentFragment();
   }
 
+  public void setPassword(String password){
+    this.password = password;
+    isPasswordSet = true;
+    initDocumentFragment();
+  }
+
   public void setConfiguration(CPDFConfiguration configuration){
     this.configuration = configuration;
     initDocumentFragment();
   }
 
   private void initDocumentFragment(){
-    if (TextUtils.isEmpty(document) || configuration == null){
+    if (TextUtils.isEmpty(document) || configuration == null || !isPasswordSet){
       return;
     }
     if (documentFragment == null) {
@@ -105,6 +108,44 @@ public class CPDFView extends FrameLayout {
     }
   }
 
+  @Override
+  protected void onAttachedToWindow() {
+    super.onAttachedToWindow();
+    getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
+  }
+
+  @Override
+  protected void onDetachedFromWindow() {
+    super.onDetachedFromWindow();
+    getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
+  }
+
+  private boolean mShouldHandleKeyboard = false;
+
+  private final ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+    @Override
+    public void onGlobalLayout() {
+      Rect r = new Rect();
+      getWindowVisibleDisplayFrame(r);
+      int screenHeight = getRootView().getHeight();
+
+      // r.bottom is the position above soft keypad or device button.
+      // if keypad is shown, the r.bottom is smaller than that before.
+      int keypadHeight = screenHeight - r.bottom;
+
+      if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
+        // keyboard is opened
+        mShouldHandleKeyboard = true;
+      } else {
+        // keyboard is closed
+        if (mShouldHandleKeyboard) {
+          mShouldHandleKeyboard = false;
+          requestLayout();
+        }
+      }
+    }
+  };
+
   private final Runnable mLayoutRunnable = () -> {
     measure(
       MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),

+ 43 - 23
android/src/main/java/com/compdfkitpdf/reactnative/viewmanager/CPDFViewManager.java

@@ -14,12 +14,16 @@ import android.app.Activity;
 
 import android.net.Uri;
 import android.util.Log;
+import android.util.SparseArray;
+import android.view.View;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
 
 import com.compdfkit.tools.common.pdf.CPDFConfigurationUtils;
 import com.compdfkit.tools.common.pdf.config.CPDFConfiguration;
+import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveCallback;
+import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveError;
 import com.compdfkitpdf.reactnative.view.CPDFView;
 import com.facebook.react.bridge.ReactApplicationContext;
 import com.facebook.react.bridge.ReadableArray;
@@ -31,8 +35,12 @@ import java.util.Map;
 
 public class CPDFViewManager extends ViewGroupManager<CPDFView> {
 
+  private static final String TAG = "ComPDFKitRN";
+
   private ReactApplicationContext reactContext;
 
+  private SparseArray<CPDFView> mDocumentViews = new SparseArray<>();
+
   public CPDFViewManager(ReactApplicationContext context) {
     this.reactContext = context;
   }
@@ -43,6 +51,21 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
     return "RCTCPDFReaderView";
   }
 
+  private View.OnAttachStateChangeListener mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
+    @Override
+    public void onViewAttachedToWindow(View v) {
+      CPDFView documentView = (CPDFView) v;
+      Log.d(TAG, "add to map: " + v.getId());
+      mDocumentViews.put(v.getId(), documentView);
+    }
+
+    @Override
+    public void onViewDetachedFromWindow(View v) {
+      Log.d(TAG, "remove from map: " + v.getId());
+      mDocumentViews.remove(v.getId());
+    }
+  };
+
   @NonNull
   @Override
   protected CPDFView createViewInstance(@NonNull ThemedReactContext themedReactContext) {
@@ -50,48 +73,45 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
     if (currentActivity instanceof FragmentActivity fragmentActivity) {
       CPDFView pdfView = new CPDFView(fragmentActivity);
       pdfView.setup(themedReactContext, fragmentActivity.getSupportFragmentManager());
-
+      pdfView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
       return pdfView;
     } else {
       throw new IllegalStateException("CPDFView can only be used in FragmentActivity subclasses");
     }
   }
 
-
   @ReactProp(name = "document")
-  public void setDocument(CPDFView pdfView, ReadableMap documentInfo) {
-    Log.e("ComPDFKitRN", "CPDFViewManager-setDocument()");
-    String document = documentInfo.getString("path");
-    String password = documentInfo.getString("password");
-    Log.e("ComPDFKitRN", "document:" + document);
-    Log.e("ComPDFKitRN", "password:" + password);
-    pdfView.setDocument(document, password);
+  public void setDocument(CPDFView pdfView, String document) {
+    Log.d(TAG, "CPDFViewManager-setDocument()");
+    Log.d(TAG, "document:" + document);
+    pdfView.setDocument(document);
+  }
+
+  @ReactProp(name = "password")
+  public void setPassword(CPDFView pdfView, String password) {
+    Log.d(TAG, "CPDFViewManager-setPassword(password: " + password + ")");
+    pdfView.setPassword(password);
   }
 
   @ReactProp(name = "configuration")
   public void setConfiguration(CPDFView pdfView, String configurationJson) {
-    Log.e("ComPDFKitRN", "CPDFViewManager-setConfiguration()");
+    Log.d(TAG, "CPDFViewManager-setConfiguration()");
     CPDFConfiguration configuration = CPDFConfigurationUtils.fromJson(configurationJson);
     pdfView.setConfiguration(configuration);
   }
 
-  @Nullable
-  @Override
-  public Map<String, Integer> getCommandsMap() {
-    Log.e("ComPDFKitRN", "CPDFViewManager-getCommandsMap()");
-    return super.getCommandsMap();
-  }
-
-  @Override
-  public void receiveCommand(@NonNull CPDFView root, String commandId,
-    @Nullable ReadableArray args) {
-    super.receiveCommand(root, commandId, args);
-    Log.e("ComPDFKitRN", "CPDFViewManager-receiveCommand()");
-
+  public void save(int tag, COnSaveCallback saveCallback, COnSaveError error) {
+    CPDFView pdfView = mDocumentViews.get(tag);
+    if (pdfView != null) {
+      pdfView.documentFragment.pdfView.savePDF(saveCallback, error);
+    } else {
+      error.error(new Exception("save() Unable to find DocumentView"));
+    }
   }
 
   @Override
   public boolean needsCustomLayoutForChildren() {
     return true;
   }
+
 }

+ 1 - 0
example/App.tsx

@@ -62,6 +62,7 @@ export default class App extends Component<Props> {
           })} />
           <Stack.Screen name='CPDFReaderViewExample' component={CPDFReaderViewExampleScreen} options={{
             headerShadowVisible: false,
+            headerTitleStyle: { fontSize: 16 },
             headerStyle: {
               backgroundColor: '#FAFCFF',
             },

+ 2 - 0
example/android/app/build.gradle

@@ -122,6 +122,8 @@ android {
 }
 
 dependencies {
+  implementation fileTree(include: ['*.jar'], dir: 'libs')
+
     // The version of react-native is set by the React Native Gradle Plugin
     implementation("com.facebook.react:react-android")
     implementation 'com.google.android.material:material:1.8.0'

+ 1 - 0
example/android/app/src/main/AndroidManifest.xml

@@ -11,6 +11,7 @@
       android:icon="@mipmap/ic_launcher"
       android:roundIcon="@mipmap/ic_launcher_round"
       android:allowBackup="false"
+      android:largeHeap="true"
       android:theme="@style/AppTheme">
 
       <activity

+ 19 - 19
example/android/build.gradle

@@ -1,24 +1,24 @@
 buildscript {
-    ext {
-        buildToolsVersion = "34.0.0"
-        minSdkVersion = 23
-        compileSdkVersion = 34
-        targetSdkVersion = 34
-        ndkVersion = "26.1.10909125"
-        kotlinVersion = "1.9.22"
-    }
-    repositories {
-        google()
-        mavenCentral()
-      maven {
-        url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
-      }
-    }
-    dependencies {
-        classpath("com.android.tools.build:gradle")
-        classpath("com.facebook.react:react-native-gradle-plugin")
-        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
+  ext {
+    buildToolsVersion = "34.0.0"
+    minSdkVersion = 23
+    compileSdkVersion = 34
+    targetSdkVersion = 34
+    ndkVersion = "26.1.10909125"
+    kotlinVersion = "1.9.22"
+  }
+  repositories {
+    google()
+    mavenCentral()
+    maven {
+      url 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
     }
+  }
+  dependencies {
+    classpath("com.android.tools.build:gradle")
+    classpath("com.facebook.react:react-native-gradle-plugin")
+    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
+  }
 }
 
 allprojects {

+ 2 - 2
example/android/config.gradle

@@ -6,7 +6,7 @@ ext {
             VERSIONCODE: 1011
     ]
     sdk = [
-            COMPDFKIT_SDK_VERSION : "2.0.1",
+            COMPDFKIT_SDK_VERSION : "2.1.1",
             COMPDFKIT_SDK_BUILD_TAG : "build_beta_2.0.1_f95eee300_202404241139"
     ]
-}
+}

+ 0 - 8
example/android/settings.gradle

@@ -3,11 +3,3 @@ apply from: file("../node_modules/@react-native-community/cli-platform-android/n
 include ':app'
 includeBuild('../node_modules/@react-native/gradle-plugin')
 
-//include ':ComPDFKit_Repo:compdfkit'
-//project(':ComPDFKit_Repo:compdfkit').projectDir = file('/Users/kdan/git_work/kdan/compdfkit_demo_android/ComPDFKit_Repo/compdfkit')
-//
-//include ':ComPDFKit_Repo:compdfkit-ui'
-//project(':ComPDFKit_Repo:compdfkit-ui').projectDir = file('/Users/kdan/git_work/kdan/compdfkit_demo_android/ComPDFKit_Repo/compdfkit-ui')
-
-//include ":ComPDFKit_Tools"
-//project(':ComPDFKit_Tools').projectDir = file('/Users/kdan/git_work/kdan/compdfkit_demo_android/ComPDFKit_Tools')

File diff suppressed because it is too large
+ 0 - 1444
example/ios/Podfile.lock


File diff suppressed because it is too large
+ 0 - 7748
example/package-lock.json


+ 2 - 2
example/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@compdfkit_pdf_sdk/react_native-example",
-  "version": "2.1.1",
-  "versionCode": "8",
+  "version": "2.1.2",
+  "versionCode": "9",
   "private": true,
   "scripts": {
     "android": "react-native run-android",

+ 65 - 21
example/src/CPDFReaderViewExample.tsx

@@ -1,26 +1,70 @@
-import React ,{ Component } from "react";
-import { CPDFReaderView, ComPDFKit } from '@compdfkit_pdf_sdk/react_native';
+/**
+ * Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+import React, { useState, useEffect, useRef } from 'react';
 import { Platform } from 'react-native';
+import { CPDFReaderView, ComPDFKit } from '@compdfkit_pdf_sdk/react_native';
+import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
+
+type RootStackParamList = {
+    CPDFReaderViewExample: { document?: string }; // 定义 `document` 参数
+};
+
+type CPDFReaderViewExampleScreenRouteProp = RouteProp<
+    RootStackParamList,
+    'CPDFReaderViewExample'
+>;
+
+const CPDFReaderViewExampleScreen = () => {
+
+    const pdfReaderRef = useRef<CPDFReaderView>(null);
+
+    const navigation = useNavigation();
+
+    const route = useRoute<CPDFReaderViewExampleScreenRouteProp>(); 
+
+    const [samplePDF] = useState(
+        route.params?.document || (Platform.OS === 'android'
+            ? 'file:///android_asset/PDF_Document.pdf'
+            : 'PDF_Document.pdf')
+    );
+
+    useEffect(() => {
+        const unsubscribe = navigation.addListener('beforeRemove', (e) => {
+            e.preventDefault();
+            // Save document changes
+            handleSave();
+            navigation.dispatch(e.data.action);
+        });
+
+        return unsubscribe;
+    }, [navigation]);
+
+
+    const handleSave = async () => {
+        if (pdfReaderRef.current) {
+            const success = await pdfReaderRef.current.save();
+            if (success) {
+                console.log('ComPDFKitRN save() : Document saved successfully');
+            } else {
+                console.log('ComPDFKitRN save() : Failed to save document');
+            }
+        }
+    };
 
-class CPDFReaderViewExampleScreen extends Component {
-
-    render() {
-        var samplePDF: string = Platform.OS == 'android' ? 'file:///android_asset/test_pdf.pdf' : 'PDF_Document.pdf'
-        // android file path example:
-        // var samplePDF = 'file:///android_asset/PDF_Document.pdf'
-        // var samplePDF = '/data/user/0/com.compdfkit.reactnative.example/cache/PDF_Document.pdf'
-        // var samplePDF = 'content://xxxx/xxx.pdf'
-        return (
-            <CPDFReaderView 
-            document={{
-                path: samplePDF,
-                password: '1234'
-            }}
-            zoomEnabled={true}
+    return (
+        <CPDFReaderView
+            ref={pdfReaderRef}
+            document={samplePDF}
             configuration={ComPDFKit.getDefaultConfig({})}
-            style={{flex : 1}}/>
-        );
-    }
-}
+        />
+    );
+};
 
 export default CPDFReaderViewExampleScreen;

+ 20 - 2
example/src/examples.tsx

@@ -25,7 +25,7 @@ const examples = [
     },
     {
         key: 'item2',
-        title: 'Select External Files',
+        title: 'Select External Files Example',
         description: `Select pdf document form system file manager`,
         action: (component: any)  => {
             // Pick a PDF file from the local storage of Android or iOS device, 
@@ -44,11 +44,29 @@ const examples = [
     },
     {
         key: 'item3',
-        title: 'Show CPDFReaderView Component',
+        title: 'CPDFReaderView Example',
         description: 'Display pdf view in react native component',
         action: (component: any)  => {
             component.props.navigation.navigate('CPDFReaderViewExample');
         }
+    },
+    {
+        key: 'item4',
+        title: 'CPDFReaderView Example 2',
+        description: 'Select a file from the system storage and display the PDF view in the React Native component',
+        action: (component: any)  => {
+            try {
+                const pickerResult = DocumentPicker.pick({
+                    type: [DocumentPicker.types.pdf]
+                });
+                pickerResult.then(res => {
+                    component.props.navigation.navigate('CPDFReaderViewExample',{
+                        document: res[0]?.uri as string
+                    });
+                })
+            } catch (err) {
+            }
+        }
     }
 ];
 export default examples;

+ 14 - 0
example/tsconfig.json

@@ -0,0 +1,14 @@
+{
+    "compilerOptions": {
+      "target": "esnext",
+      "module": "commonjs",
+      "strict": true,
+      "jsx": "react",
+      "moduleResolution": "node",
+      "esModuleInterop": true,
+      "skipLibCheck": true,
+      "forceConsistentCasingInFileNames": true
+    },
+    "exclude": ["node_modules", "build"]
+  }
+  

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@compdfkit_pdf_sdk/react_native",
-  "version": "2.1.1",
+  "version": "2.1.2",
   "description": "ComPDFKit for React Native is a comprehensive SDK that allows you to quickly add PDF functionality to Android, iOS, and React Native applications.",
   "main": "./src/index.tsx",
   "source": "src/index",

+ 2 - 2
src/index.tsx

@@ -315,8 +315,8 @@ function getDefaultConfig(overrides : Partial<CPDFConfiguration> = {}) : string
             fontColor: '#000000',
             fontColorAlpha: 255,
             fontSize: 30,
-            isBold: true,
-            isItalic: true,
+            isBold: false,
+            isItalic: false,
             typeface: CPDFTypeface.HELVETICA,
             alignment: CPDFAlignment.LEFT
           }

+ 40 - 11
src/view/CPDFReaderView.tsx

@@ -9,14 +9,28 @@
 
 import React, { PureComponent } from 'react';
 import PropTypes from 'prop-types';
-import { requireNativeComponent } from 'react-native';
+import { findNodeHandle, requireNativeComponent, NativeModules } from 'react-native';
 import { ViewPropTypes } from 'deprecated-react-native-prop-types';
+const { CPDFViewManager } = NativeModules;
 
+/**
+ * ComPDFKit PDF UI Component.
+ * 
+ * @example
+ *  <CPDFReaderView
+ *      ref={pdfReaderRef}
+ *      document={{
+ *          path: samplePDF,
+ *          password: ''
+ *      }}
+ *      configuration={ComPDFKit.getDefaultConfig({})}
+ *  />
+ */
 
 const propTypes = {
   configuration: PropTypes.string.isRequired,
-  document: PropTypes.object.isRequired,
-  zoomEnabled: PropTypes.bool,
+  document: PropTypes.string.isRequired,
+  password: PropTypes.string,
   ...ViewPropTypes,
 }
 
@@ -29,20 +43,35 @@ export class CPDFReaderView extends PureComponent<CPDFReaderViewProps, any> {
 
   static propTypes = propTypes;
 
+  static defaultProps = {
+    password: ''
+  }
+
   _setNativeRef = (ref: any) => {
     this._viewerRef = ref;
   }
 
+  /**
+   * Save the document and return whether it is saved successfully.
+   * @returns true or false
+   */
+  save = (): Promise<boolean> => {
+    const tag = findNodeHandle(this._viewerRef);
+    if (tag != null) {
+      return CPDFViewManager.save(tag);
+    }
+    return Promise.resolve(false);
+  }
+
   render() {
-      return (
-        <RCTCPDFReaderView
-          ref={this._setNativeRef}
-          style={{ flex: 1 }}
-          {...this.props}
-        />
-      )
+    return (
+      <RCTCPDFReaderView
+        ref={this._setNativeRef}
+        style={{ flex: 1 }}
+        {...this.props}
+      />
+    )
   }
 }
 
-
 const RCTCPDFReaderView = requireNativeComponent<CPDFReaderViewProps>('RCTCPDFReaderView');