|
@@ -8,15 +8,14 @@
|
|
|
*/
|
|
|
|
|
|
import React, { useState, useRef } from 'react';
|
|
|
-import { Image, Modal, Platform, ScrollView, StyleSheet, Switch, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
|
|
-import { CPDFReaderView, ComPDFKit, CPDFToolbarAction, CPDFWidgetType, CPDFTextWidget, CPDFRadiobuttonWidget, CPDFSignatureWidget, CPDFWidget } from '@compdfkit_pdf_sdk/react_native';
|
|
|
+import { Image, Modal, Platform, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
|
|
+import PDFReaderContext, { CPDFReaderView, ComPDFKit, CPDFToolbarAction, CPDFWidgetType, CPDFTextWidget, CPDFRadiobuttonWidget, CPDFSignatureWidget, CPDFWidget } from '@compdfkit_pdf_sdk/react_native';
|
|
|
import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
|
|
|
import { HeaderBackButton } from '@react-navigation/elements';
|
|
|
import { MenuProvider, Menu, MenuTrigger, MenuOptions, MenuOption } from 'react-native-popup-menu';
|
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
import DocumentPicker from 'react-native-document-picker';
|
|
|
-import { launchImageLibrary } from 'react-native-image-picker';
|
|
|
-
|
|
|
+import { CPDFWidgetListScreen } from './screens/CPDFWidgetListScreen';
|
|
|
type RootStackParamList = {
|
|
|
CPDFWidgetExample: { document?: string };
|
|
|
};
|
|
@@ -91,16 +90,6 @@ const CPDFWidgetsExampleScreen = () => {
|
|
|
const exportWidgetsPath = await pdfReaderRef.current?._pdfDocument.exportWidgets();
|
|
|
console.log('ComPDFKitRN exportWidgets:', exportWidgetsPath)
|
|
|
break;
|
|
|
-
|
|
|
- case 'Get Annotations':
|
|
|
- const pageCount = await pdfReaderRef!.current!._pdfDocument.getPageCount();
|
|
|
- for (let i = 0; i < pageCount; i++) {
|
|
|
- const page = pdfReaderRef?.current?._pdfDocument.pageAtIndex(i);
|
|
|
- const annotations = await page?.getAnnotations();
|
|
|
- console.log(`ComPDFKitRN-annotations pageIndex ${i}:`);
|
|
|
- console.log(JSON.stringify(annotations, null, 2));
|
|
|
- }
|
|
|
- break;
|
|
|
case 'Get Widgets':
|
|
|
const pageCount1 = await pdfReaderRef!.current!._pdfDocument.getPageCount();
|
|
|
let allWidgets: CPDFWidget[] = [];
|
|
@@ -146,185 +135,101 @@ const CPDFWidgetsExampleScreen = () => {
|
|
|
);
|
|
|
};
|
|
|
|
|
|
- const widgetItem = (index: number, widget: CPDFWidget) => {
|
|
|
- return (
|
|
|
- <TouchableOpacity key={index} onPress={async () => {
|
|
|
- await pdfReaderRef?.current?.setDisplayPageIndex(widget.page);
|
|
|
- setWidgetsModalVisible(false);
|
|
|
- }}>
|
|
|
- <View style={{ width: '100%' }}>
|
|
|
- <View style={{ flexDirection: 'row' }}>
|
|
|
- <Text style={styles.widgetItem}>Title: </Text>
|
|
|
- <Text style={styles.widgetBody}>{widget.title}</Text>
|
|
|
- </View>
|
|
|
- <View style={{ flexDirection: 'row' }}>
|
|
|
- <Text style={styles.widgetItem}>Type: </Text>
|
|
|
- <Text style={styles.widgetBody}>{widget.type.toUpperCase()}</Text>
|
|
|
- </View>
|
|
|
- <View style={{ flexDirection: 'row' }}>
|
|
|
- <Text style={styles.widgetItem}>PageIndex: </Text>
|
|
|
- <Text style={styles.widgetBody}>{widget.page}</Text>
|
|
|
- </View>
|
|
|
-
|
|
|
- {widget.type === CPDFWidgetType.TEXT_FIELD && (
|
|
|
- <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
- <Text style={styles.widgetBody}>{(widget as CPDFTextWidget).text}</Text>
|
|
|
- <TouchableOpacity style={{ paddingHorizontal: 16, paddingVertical:4}} onPress={async () => {
|
|
|
- setCurrentEditingWidgetIndex(index);
|
|
|
- setTextEditModalVisible(true);
|
|
|
- }}>
|
|
|
- <Text style={styles.closeButtonText}>Edit</Text>
|
|
|
- </TouchableOpacity>
|
|
|
- </View>
|
|
|
- )}
|
|
|
- {(widget.type === CPDFWidgetType.RADIO_BUTTON || widget.type == CPDFWidgetType.CHECKBOX) && (
|
|
|
- <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
- <Text style={styles.widgetItem}>isChecked:</Text>
|
|
|
- <Switch
|
|
|
- thumbColor={(widget as CPDFRadiobuttonWidget).isChecked ? '#1460F3' : 'white'}
|
|
|
- trackColor={{ false: '#E0E0E0', true: '#1460F34D' }}
|
|
|
- value={(widget as CPDFRadiobuttonWidget).isChecked} onValueChange={async () => {
|
|
|
- const updatedWidgetData = [...widgetData];
|
|
|
-
|
|
|
- if ((widget as CPDFRadiobuttonWidget).type === CPDFWidgetType.RADIO_BUTTON || (widget as CPDFRadiobuttonWidget).type === CPDFWidgetType.CHECKBOX) {
|
|
|
- const updatedWidget = widget as CPDFRadiobuttonWidget;
|
|
|
- const newChecked = !updatedWidget.isChecked;
|
|
|
- // change RadioButtonWidget or CPDFCheckboxWidget checked status;
|
|
|
- await updatedWidget.setChecked(newChecked);
|
|
|
- // update appearance
|
|
|
- await updatedWidget.updateAp();
|
|
|
-
|
|
|
- updatedWidgetData[index] = { ...widget, isChecked: newChecked };
|
|
|
- setWidgetData(updatedWidgetData);
|
|
|
- }
|
|
|
- }} />
|
|
|
- </View>
|
|
|
- )}
|
|
|
- {widget.type === CPDFWidgetType.SIGNATURES_FIELDS && (
|
|
|
- <View style={{ flexDirection: 'row', justifyContent: 'flex-end' }}>
|
|
|
- <TouchableOpacity style={{ paddingVertical:4}} onPress={async () => {
|
|
|
- const signatureWidget = widget as CPDFSignatureWidget;
|
|
|
- launchImageLibrary({
|
|
|
- mediaType:'photo'
|
|
|
- }, async res => {
|
|
|
- if( res.didCancel){
|
|
|
- return false;
|
|
|
- }
|
|
|
- const path = res.assets?.[0]?.uri;
|
|
|
- const signResult = await signatureWidget?.addImageSignature(path!);
|
|
|
- if(signResult){
|
|
|
- setWidgetsModalVisible(false);
|
|
|
- }
|
|
|
- return true;
|
|
|
- })
|
|
|
- }}>
|
|
|
- <Text style={styles.closeButtonText}>Signature</Text>
|
|
|
- </TouchableOpacity>
|
|
|
- </View>
|
|
|
- )}
|
|
|
- <View style={{ flex: 1, height: 1.5, backgroundColor: 'gray', opacity: 0.2, marginVertical: 5 }} />
|
|
|
- </View>
|
|
|
- </TouchableOpacity>
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
return (
|
|
|
- <MenuProvider>
|
|
|
- <SafeAreaView style={{ flex: 1 }}>
|
|
|
- <View style={{ flex: 1 }}>
|
|
|
- {renderToolbar()}
|
|
|
- <CPDFReaderView
|
|
|
- ref={pdfReaderRef}
|
|
|
- document={samplePDF}
|
|
|
- configuration={ComPDFKit.getDefaultConfig({
|
|
|
- toolbarConfig: {
|
|
|
- iosLeftBarAvailableActions: [
|
|
|
- CPDFToolbarAction.THUMBNAIL
|
|
|
- ]
|
|
|
- }
|
|
|
- })} />
|
|
|
- </View>
|
|
|
- <Modal visible={widgetsModalVisible} transparent={true} animationType="slide">
|
|
|
- <View style={styles.modalContainer}>
|
|
|
- <View style={styles.modalContent}>
|
|
|
- <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
- <Text style={styles.modalTitle}>Forms List</Text>
|
|
|
- <TouchableOpacity onPress={() => setWidgetsModalVisible(false)} style={styles.closeButton}>
|
|
|
- <Text style={styles.closeButtonText}>Close</Text>
|
|
|
- </TouchableOpacity>
|
|
|
- </View>
|
|
|
- <ScrollView>
|
|
|
- {widgetData.map((widget, index) => (
|
|
|
- widgetItem(index, widget)
|
|
|
- ))}
|
|
|
- </ScrollView>
|
|
|
- </View>
|
|
|
+ <PDFReaderContext.Provider value={pdfReaderRef.current}>
|
|
|
+ <MenuProvider>
|
|
|
+ <SafeAreaView style={{ flex: 1 }}>
|
|
|
+ <View style={{ flex: 1 }}>
|
|
|
+ {renderToolbar()}
|
|
|
+ <CPDFReaderView
|
|
|
+ ref={pdfReaderRef}
|
|
|
+ document={samplePDF}
|
|
|
+ configuration={ComPDFKit.getDefaultConfig({
|
|
|
+ toolbarConfig: {
|
|
|
+ iosLeftBarAvailableActions: [
|
|
|
+ CPDFToolbarAction.THUMBNAIL
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ })} />
|
|
|
</View>
|
|
|
- </Modal>
|
|
|
-
|
|
|
- <Modal visible={textEditModalVisible} transparent={true} animationType="fade">
|
|
|
- <View style={styles.editTextModalContainer}>
|
|
|
- <View style={styles.editTextModalContent}>
|
|
|
- <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
- <Text style={styles.modalTitle}>Edit Text</Text>
|
|
|
- </View>
|
|
|
-
|
|
|
- <TextInput
|
|
|
- style={styles.inputField}
|
|
|
- value={text}
|
|
|
- onChangeText={(newText) => setText(newText)}
|
|
|
- placeholder="Enter text here"
|
|
|
- multiline={true}
|
|
|
- numberOfLines={4}
|
|
|
- />
|
|
|
-
|
|
|
- <View style={styles.buttonContainer}>
|
|
|
- <TouchableOpacity onPress={() => {
|
|
|
- setTextEditModalVisible(false);
|
|
|
- }} style={styles.button}>
|
|
|
- <Text style={styles.buttonText}>Cancel</Text>
|
|
|
- </TouchableOpacity>
|
|
|
- <TouchableOpacity onPress={async () => {
|
|
|
- if (currentEditingWidgetIndex !== null && currentEditingWidgetIndex !== undefined) {
|
|
|
- const updatedWidgetData = [...widgetData];
|
|
|
- const widget = updatedWidgetData[currentEditingWidgetIndex];
|
|
|
-
|
|
|
- console.log(JSON.stringify(widget, null, 2));
|
|
|
- if(widget === undefined) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (widget.type === CPDFWidgetType.TEXT_FIELD) {
|
|
|
- const textWidget = widget as CPDFTextWidget;
|
|
|
-
|
|
|
- try {
|
|
|
- // change textFields text
|
|
|
- await textWidget.setText(text);
|
|
|
- await textWidget.updateAp();
|
|
|
-
|
|
|
- if (updatedWidgetData[currentEditingWidgetIndex]) {
|
|
|
- (updatedWidgetData[currentEditingWidgetIndex] as CPDFTextWidget).text = text;
|
|
|
+ <CPDFWidgetListScreen
|
|
|
+ visible={widgetsModalVisible}
|
|
|
+ widgets={widgetData}
|
|
|
+ onClose={() => setWidgetsModalVisible(false)}
|
|
|
+ onEditText={(index: number) => {
|
|
|
+ console.log('CPDFWidgetListScreen onEditText:', index);
|
|
|
+ setCurrentEditingWidgetIndex(index);
|
|
|
+ setTextEditModalVisible(true);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <Modal visible={textEditModalVisible} transparent={true} animationType="fade">
|
|
|
+ <View style={styles.editTextModalContainer}>
|
|
|
+ <View style={styles.editTextModalContent}>
|
|
|
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
+ <Text style={styles.modalTitle}>Edit Text</Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <TextInput
|
|
|
+ style={styles.inputField}
|
|
|
+ value={text}
|
|
|
+ onChangeText={(newText) => setText(newText)}
|
|
|
+ placeholder="Enter text here"
|
|
|
+ multiline={true}
|
|
|
+ numberOfLines={4}
|
|
|
+ returnKeyType='done'
|
|
|
+ blurOnSubmit={true}
|
|
|
+
|
|
|
+ />
|
|
|
+
|
|
|
+ <View style={styles.buttonContainer}>
|
|
|
+ <TouchableOpacity onPress={() => {
|
|
|
+ setTextEditModalVisible(false);
|
|
|
+ }} style={styles.button}>
|
|
|
+ <Text style={styles.buttonText}>Cancel</Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ <TouchableOpacity onPress={async () => {
|
|
|
+ if (currentEditingWidgetIndex !== null && currentEditingWidgetIndex !== undefined) {
|
|
|
+ const updatedWidgetData = [...widgetData];
|
|
|
+ const widget = updatedWidgetData[currentEditingWidgetIndex];
|
|
|
+
|
|
|
+ console.log(JSON.stringify(widget, null, 2));
|
|
|
+ if (widget === undefined) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (widget.type === CPDFWidgetType.TEXT_FIELD) {
|
|
|
+ const textWidget = widget as CPDFTextWidget;
|
|
|
+
|
|
|
+ try {
|
|
|
+ console.log('ComPDFKitRN setText:', text);
|
|
|
+ // -------------------->
|
|
|
+ // change textFields text
|
|
|
+ await textWidget.setText(text);
|
|
|
+ await textWidget.updateAp();
|
|
|
+ // <---------------------
|
|
|
+ if (updatedWidgetData[currentEditingWidgetIndex]) {
|
|
|
+ (updatedWidgetData[currentEditingWidgetIndex] as CPDFTextWidget).text = text;
|
|
|
+ }
|
|
|
+ setWidgetData(updatedWidgetData);
|
|
|
+ setText('');
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Failed to update text widget:", error);
|
|
|
+ }
|
|
|
}
|
|
|
- setWidgetData(updatedWidgetData);
|
|
|
- } catch (error) {
|
|
|
- console.error("Failed to update text widget:", error);
|
|
|
+ setTextEditModalVisible(false);
|
|
|
}
|
|
|
- }
|
|
|
- setTextEditModalVisible(false);
|
|
|
- }
|
|
|
- }} style={styles.button}>
|
|
|
- <Text style={styles.buttonText}>Confirm</Text>
|
|
|
+ }} style={styles.button}>
|
|
|
+ <Text style={styles.buttonText}>Confirm</Text>
|
|
|
|
|
|
- </TouchableOpacity>
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
</View>
|
|
|
</View>
|
|
|
- </View>
|
|
|
- </Modal>
|
|
|
+ </Modal>
|
|
|
|
|
|
- </SafeAreaView>
|
|
|
- </MenuProvider>
|
|
|
+ </SafeAreaView>
|
|
|
+ </MenuProvider>
|
|
|
+ </PDFReaderContext.Provider>
|
|
|
);
|
|
|
-
|
|
|
-
|
|
|
};
|
|
|
|
|
|
|