Skip to content

Commit

Permalink
Release 2.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
PSPDFKit committed Oct 25, 2022
1 parent 75869d1 commit b20a3c8
Show file tree
Hide file tree
Showing 94 changed files with 13,397 additions and 5,393 deletions.
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
./android
./ios
./assets
./node_modules/**/*.js
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
root: true,
extends: '@react-native-community',
rules: {
'react/no-string-refs': 'off',
'no-alert': 'off',
},
};
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ PSPDFKit/PSPDFKitUI.xcframework

# UWP license file
samples/Catalog/windows/Catalog/License.xaml

.fake
10 changes: 10 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
bracketSpacing: true,
bracketSameLine: false,
singleQuote: true,
trailingComma: 'all',
arrowParens: 'avoid',
"endOfLine": "auto",
"printWidth": 80,
"tabWidth": 2,
};
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
## Newest Release

### 2.3.1 - 22 Jul 2022
### 2.4.0 - 25 Oct 2022

- Updates for PSPDFKit 8.2.1 for Android. (#34430)
- Adds PDF generation from HTML, images and template. (#36736)
- Updates for PSPDFKit 8.4.1 for Android
- Updates for PSPDFKit 12.0 for iOS

## Previous Releases

### 2.3.1 - 22 Jul 2022

- Updates for PSPDFKit 8.2.1 for Android. (#34430)

### 2.3.0 - 19 Jul 2022

- Adds Android Toolbar menu customization from `PSPDFKitView` properties. (#33417)
Expand Down
4 changes: 2 additions & 2 deletions android/.project
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
</natures>
<filteredResources>
<filter>
<id>0</id>
<id>1666692500644</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* Contains gradle configuration constants
*/
ext {
PSPDFKIT_VERSION = '8.2.1'
PSPDFKIT_VERSION = '8.4.1'
}

buildscript {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public List<NativeModule> createNativeModules(ReactApplicationContext reactConte
List<NativeModule> modules = new ArrayList<>();
modules.add(new PSPDFKitModule(reactContext));
modules.add(new TestingModule(reactContext));
modules.add(new RNProcessor(reactContext));
return modules;
}

Expand Down
243 changes: 243 additions & 0 deletions android/src/main/java/com/pspdfkit/react/RNProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
/*
* PSPDFKitPackage.java
*
* PSPDFKit
*
* Copyright © 2017-2022 PSPDFKit GmbH. 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 PSPDFKIT LICENSE AGREEMENT.
* UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
* This notice may not be removed from this file.
*/

package com.pspdfkit.react;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.webkit.URLUtil;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.pspdfkit.document.html.HtmlToPdfConverter;
import com.pspdfkit.document.processor.NewPage;
import com.pspdfkit.document.processor.PagePattern;
import com.pspdfkit.document.processor.PdfProcessor;
import com.pspdfkit.document.processor.PdfProcessorTask;
import com.pspdfkit.react.helper.RNConfigurationHelper;
import com.pspdfkit.react.helper.RNFileHelper;
import com.pspdfkit.utils.Size;

import java.io.File;
import java.util.Objects;

public class RNProcessor extends ReactContextBaseJavaModule {
public RNProcessor(ReactApplicationContext reactContext) {
super(reactContext);
}

@NonNull
@Override
public String getName() {
return "RNProcessor";
}

@ReactMethod
public void getTemporaryDirectory(Promise callback) {
try {
Context context = Objects.requireNonNull(getCurrentActivity()).getApplication().getApplicationContext();
WritableMap result = Arguments.createMap();
result.putString("tempDir", context.getCacheDir().getAbsolutePath());
callback.resolve(result);
} catch (Exception e) {
callback.reject(e);
}
}

@ReactMethod
public void generateBlankPDF(@NonNull ReadableMap configuration, Promise callback) {
try {
File outputFile = RNFileHelper.getFilePath(getContext(), configuration, callback);

if (outputFile == null) {
callback.reject("E_MISSING_FOLDER", "Cannot create documents folder");
return;
}

double width = configuration.getDouble("width");
double height = configuration.getDouble("height");


WritableMap result = Arguments.createMap();
result.putString("fileURL", outputFile.getAbsolutePath());

final PdfProcessorTask task = PdfProcessorTask.newPage(NewPage.patternPage(new Size((float) width, (float) height), PagePattern.BLANK).build());

PdfProcessor.processDocumentAsync(task, outputFile)
.doFinally(() -> callback.resolve(result))
.doOnError(callback::reject)
.subscribe();
} catch (Exception e) {
callback.reject(e);
}
}

@SuppressLint("CheckResult")
@ReactMethod
public void generatePDFFromHtmlString(@NonNull ReadableMap configuration, String htmlString, Promise callback) {
try {
File outputFile = RNFileHelper.getFilePath(getContext(), configuration, callback);

WritableMap result = Arguments.createMap();
assert outputFile != null;
result.putString("fileURL", outputFile.toURI().toString());

HtmlToPdfConverter.fromHTMLString(getContext(), htmlString)
.title("Converted document")
.convertToPdfAsync(outputFile)
.doFinally(() -> callback.resolve(result))
.doOnError((error) -> callback.reject(error))
.subscribe();

} catch (Exception e) {
callback.reject(e);
}
}

@SuppressLint({"CheckResult", "SetJavaScriptEnabled"})
@ReactMethod
public void generatePDFFromHtmlURL(@NonNull ReadableMap configuration, String originUri, Promise callback) {
try {
if (!URLUtil.isValidUrl(originUri)) {
callback.reject("E_NEW_INVALID_URL", "Please provide valid URL.");
return;
}

Uri originURL = Uri.parse(originUri);
File outputFile = RNFileHelper.getFilePath(getContext(), configuration, callback);

if (outputFile == null) {
callback.reject("E_NEW_INVALID_FILE_PATH", "Please provide valid file path.");
return;
}

RNFileHelper.deleteExistingFileIfNeeded(outputFile, configuration, callback);

WritableMap result = Arguments.createMap();
result.putString("fileURL", outputFile.getAbsolutePath());

Context context = Objects.requireNonNull(getCurrentActivity()).getApplication().getApplicationContext();

final HtmlToPdfConverter converter = HtmlToPdfConverter.fromUri(context, originURL);
boolean isJavascriptEnabled = !configuration.hasKey("enableJavascript") || configuration.getBoolean("enableJavaScript");
converter.setJavaScriptEnabled(isJavascriptEnabled);

converter.convertToPdfAsync(outputFile)
.doFinally(() -> callback.resolve(result))
.doOnError((error) -> callback.reject(error))
.subscribe(() -> {
callback.resolve(result);
}, throwable -> {
callback.reject(throwable);
});

} catch (
Exception e) {
callback.reject(e);
}

}

@SuppressLint("CheckResult")
@ReactMethod
public void generatePDFFromTemplate(@NonNull ReadableMap configuration, Promise callback) {
try {
File outputFile = RNFileHelper.getFilePath(getContext(), configuration, callback);

if (outputFile == null) {
callback.reject("ERROR_NEW_INVALID_FILE_PATH", "Please provide valid file path.");
return;
}

WritableMap result = Arguments.createMap();
result.putString("fileURL", outputFile.toURI().toString());
RNFileHelper.deleteExistingFileIfNeeded(outputFile, configuration, callback);
Context context = Objects.requireNonNull(getCurrentActivity()).getApplication().getApplicationContext();

RNConfigurationHelper configHelper = new RNConfigurationHelper(configuration, context);

ReadableArray templates = configuration.getArray("templates");

if (templates != null) {
PdfProcessorTask pdfProcessorTask = PdfProcessorTask.empty();

for (int i = 0; i < templates.size(); i++) {
configHelper.configuration = templates.getMap(i);
pdfProcessorTask.addNewPage(configHelper.parseConfiguration(), i);
}
PdfProcessor.processDocumentAsync(pdfProcessorTask, outputFile)
.doFinally(() -> callback.resolve(result))
.doOnError((error) -> callback.reject(error))
.subscribe();
return;
}

callback.reject("ERROR_NEW_INVALID_CONFIGURATION", "Please provide valid configuration object.");
} catch (Exception e) {
callback.reject(e);
}
}

@ReactMethod
public void generatePDFFromImages(@NonNull ReadableMap configuration, Promise callback) {
try {
File outputFile = RNFileHelper.getFilePath(getContext(), configuration, callback);
Context context = Objects.requireNonNull(getCurrentActivity()).getApplication().getApplicationContext();

WritableMap result = Arguments.createMap();
assert outputFile != null;

result.putString("fileURL", outputFile.toURI().toString());
RNFileHelper.deleteExistingFileIfNeeded(outputFile, configuration, callback);

final PdfProcessorTask pdfProcessorTask = PdfProcessorTask.empty();

@Nullable ReadableArray images = configuration.getArray("images");

if (images == null) {
callback.reject("ERROR_MISSING_IMAGES", "Please provide array of image objects.");
return;
}

for (int i = 0; i < images.size(); i++) {
RNConfigurationHelper configHelper = new RNConfigurationHelper(configuration, context);
NewPage newPage = configHelper.parseConfiguration("image", configuration.getArray("images").getMap(i));
if (newPage != null) {
pdfProcessorTask.addNewPage(newPage, i);
}
}

PdfProcessor.processDocumentAsync(pdfProcessorTask, outputFile)
.doOnError((error) -> callback.reject(error))
.doFinally(() -> callback.resolve(result))
.subscribe();

} catch (Exception e) {
callback.reject(e);
}
}

private Context getContext() {
return Objects.requireNonNull(getCurrentActivity()).getApplication().getApplicationContext();
}
}
39 changes: 39 additions & 0 deletions android/src/main/java/com/pspdfkit/react/helper/ColorHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.pspdfkit.react.helper;

/*
* PSPDFKitPackage.java
*
* PSPDFKit
*
* Copyright © 2017-2022 PSPDFKit GmbH. 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 PSPDFKIT LICENSE AGREEMENT.
* UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
* This notice may not be removed from this file.
*/

import android.graphics.Color;

public class ColorHelper {
public static int rgb(String color) {
try{
String splitStr = color.substring(color.indexOf('(') + 1, color.indexOf(')'));
String[] components = splitStr.split(",");

int[] colorValues = new int[components.length];
for (int i = 0; i < components.length; i++) {
double channelColor = Double.parseDouble(components[i].trim());
if(channelColor > 1) {
colorValues[i] = Integer.parseInt(components[i].trim());
continue;
}
colorValues[i] = (int)(channelColor * 255);
}

return Color.rgb(colorValues[0], colorValues[1], colorValues[2]);
} catch(Exception ex) {
return Color.parseColor("#FFFFFF");
}
}
}
Loading

0 comments on commit b20a3c8

Please sign in to comment.