Skip to content

Commit de12aa0

Browse files
author
PSPDFKit
committed
Release 3.5.0
1 parent 97adc2e commit de12aa0

31 files changed

+1179
-112
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
## Newest Release
22

3+
### 3.5.0 - 17 Jan 2023
4+
- Adds Instant Synchronization support. (#37675)
5+
- Updates for PSPDFKit 8.5 for Android. (#38136)
6+
- Updates for PSPDFKit 12.0.2 for iOS. (#38136)
7+
8+
## Previous Releases
9+
310
### 3.4.1 - 18 Nov 2022
411

512
- Updates for PSPDFKit 12.0 for iOS. (#37508)
613
- Fixes missing header file issue. (#37283)
714

8-
## Previous Releases
9-
1015
### 3.4.0 - 26 Oct 2022
1116

1217
- Adds generating PDF from images, templates and HTML. (#36736)

android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ dependencies {
5858
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
5959
implementation "androidx.fragment:fragment-ktx:1.3.6"
6060
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
61+
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
6162
}

android/config.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ if (pspdfkitMavenUrl == null || pspdfkitMavenUrl == '') {
3838

3939
ext.pspdfkitVersion = localProperties.getProperty('pspdfkit.version')
4040
if (pspdfkitVersion == null || pspdfkitVersion == '') {
41-
ext.pspdfkitVersion = '8.4.1'
41+
ext.pspdfkitVersion = '8.5.0'
4242
}
4343

4444
ext.pspdfkitMavenModuleName = 'pspdfkit'
@@ -52,8 +52,8 @@ if (!pubspecFile.exists()) {
5252
def pubspecYaml = new Yaml().load(pubspecFile.newInputStream())
5353
ext.pspdfkitFlutterVersion = pubspecYaml.version
5454

55-
ext.androidCompileSdkVersion = 31
55+
ext.androidCompileSdkVersion = 33
5656
ext.androidMinSdkVersion = 21
5757
ext.androidTargetSdkVersion = 30
5858
ext.androidGradlePluginVersion = '7.1.1'
59-
ext.kotlinVersion = "1.5.31"
59+
ext.kotlinVersion = "1.7.10"

android/src/main/java/com/pspdfkit/flutter/pspdfkit/ConfigurationAdapter.java

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
*/
99
package com.pspdfkit.flutter.pspdfkit;
1010

11+
import static com.pspdfkit.flutter.pspdfkit.util.Preconditions.requireNotNullNotEmpty;
12+
import static io.flutter.util.Preconditions.checkNotNull;
13+
1114
import android.content.Context;
1215
import android.util.Log;
1316

1417
import androidx.annotation.NonNull;
1518
import androidx.annotation.Nullable;
1619
import androidx.annotation.StyleRes;
1720

21+
import com.pspdfkit.configuration.PdfConfiguration;
1822
import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
1923
import com.pspdfkit.configuration.activity.ThumbnailBarMode;
2024
import com.pspdfkit.configuration.activity.UserInterfaceViewMode;
@@ -25,13 +29,12 @@
2529
import com.pspdfkit.configuration.settings.SettingsMenuItemType;
2630
import com.pspdfkit.configuration.sharing.ShareFeatures;
2731
import com.pspdfkit.configuration.theming.ThemeMode;
32+
import com.pspdfkit.ui.special_mode.controller.AnnotationTool;
2833

2934
import java.util.ArrayList;
3035
import java.util.EnumSet;
3136
import java.util.HashMap;
32-
33-
import static com.pspdfkit.flutter.pspdfkit.util.Preconditions.requireNotNullNotEmpty;
34-
import static io.flutter.util.Preconditions.checkNotNull;
37+
import java.util.List;
3538

3639
class ConfigurationAdapter {
3740
private static final String LOG_TAG = "ConfigurationAdapter";
@@ -117,12 +120,12 @@ class ConfigurationAdapter {
117120
*/
118121
@Deprecated
119122
private static final String SHOW_DOCUMENT_LABEL = "showDocumentLabel";
120-
/**
123+
/**
121124
* @deprecated This key word was deprecated with PSPDFKit for Fluttter 3.1.
122125
* Use {@code FIRST_PAGE_ALWAYS_SINGLE} instead, which replaces it.
123126
*/
124127
private static final String IS_FIRST_PAGE_ALWAYS_SINGLE = "isFirstPageAlwaysSingle";
125-
/**
128+
/**
126129
* @deprecated This key word was deprecated with PSPDFKit for Fluttter 3.1.
127130
* Use {@code SHOW_BOOKMARKS_ACTION} instead, which replaces it.
128131
*/
@@ -134,7 +137,7 @@ class ConfigurationAdapter {
134137
private static final String PAGE_TRANSITION_SCROLL_PER_SPREAD = "scrollPerSpread";
135138
private static final String PAGE_TRANSITION_SCROLL_CONTINUOUS = "scrollContinuous";
136139
private static final String PAGE_TRANSITION_CURL = "curl";
137-
140+
138141
// Document Presentation Values
139142
private static final String PAGE_MODE_AUTOMATIC = "automatic";
140143
private static final String PAGE_MODE_SINGLE = "single";
@@ -175,8 +178,14 @@ class ConfigurationAdapter {
175178
private static final String SHOW_THUMBNAIL_BAR_SCRUBBER_BAR = "scrubberBar";
176179
private static final String SHOW_THUMBNAIL_BAR_SCROLLABLE = "scrollable";
177180

178-
@NonNull private final PdfActivityConfiguration.Builder configuration;
179-
@Nullable private String password = null;
181+
// Instant Options
182+
private static final String ENABLE_INSTANT_COMMENTS = "enableInstantComments";
183+
184+
@NonNull
185+
private final PdfActivityConfiguration.Builder configuration;
186+
@Nullable
187+
private String password = null;
188+
private boolean enableInstantComments = false;
180189

181190
ConfigurationAdapter(@NonNull Context context,
182191
@Nullable HashMap<String, Object> configurationMap) {
@@ -349,6 +358,11 @@ class ConfigurationAdapter {
349358
if (key != null) {
350359
configureAutosaveEnabled(!(Boolean) configurationMap.get(key));
351360
}
361+
362+
key = getKeyOfType(configurationMap, ENABLE_INSTANT_COMMENTS, Boolean.class);
363+
if (key != null) {
364+
enableInstantComments = (boolean) configurationMap.get(key);
365+
}
352366
}
353367
}
354368

@@ -661,27 +675,27 @@ private <T> void configureSettingsMenuItems(@NonNull ArrayList<T> settingsMenuIt
661675
case SETTINGS_MENU_ITEM_THEME:
662676
case SETTINGS_MENU_ITEM_ANDROID_THEME:
663677
settingsMenuItemTypes.add(SettingsMenuItemType.THEME);
664-
break;
678+
break;
665679
case SETTINGS_MENU_ITEM_SCREEN_AWAKE:
666680
case SETTINGS_MENU_ITEM_ANDROID_SCREEN_AWAKE:
667681
settingsMenuItemTypes.add(SettingsMenuItemType.SCREEN_AWAKE);
668-
break;
682+
break;
669683
case SETTINGS_MENU_ITEM_PAGE_LAYOUT:
670684
case SETTINGS_MENU_ITEM_ANDROID_PAGE_LAYOUT:
671685
settingsMenuItemTypes.add(SettingsMenuItemType.PAGE_LAYOUT);
672-
break;
686+
break;
673687
case SETTINGS_MENU_ITEM_PAGE_TRANSITION:
674688
settingsMenuItemTypes.add(SettingsMenuItemType.PAGE_TRANSITION);
675-
break;
689+
break;
676690
case SETTINGS_MENU_ITEM_SCROLL_DIRECTION:
677691
settingsMenuItemTypes.add(SettingsMenuItemType.SCROLL_DIRECTION);
678-
break;
692+
break;
679693
case SETTINGS_MENU_ITEM_IOS_APPEARANCE:
680694
case SETTINGS_MENU_ITEM_IOS_BRIGHTNESS:
681695
case SETTINGS_MENU_ITEM_IOS_PAGE_MODE:
682696
case SETTINGS_MENU_ITEM_IOS_SPREAD_FITTING:
683697
// NO-OP. Only supported on iOS.
684-
break;
698+
break;
685699
default:
686700
throw new IllegalArgumentException("Undefined settings menu item " + menuType);
687701
}
@@ -718,13 +732,13 @@ private static <T> void checkCast(Object object, Class<T> clazz, String key) {
718732
* When reading configuration options, we check not only for the given configuration string,
719733
* but also for a string with the `android` prefix. For instance if the user enters
720734
* `androidPageScrollDirection`, it is considered a valid string equal to `pageScrollDirection`.
721-
*
735+
* <p>
722736
* When documenting, we always prefer configuration option strings:
723-
*
737+
* <p>
724738
* - No prefix : If the key works for both iOS and Android.
725739
* - `android` prefix : If the key works only for Android.
726740
* - `iOS` prefix : If the key works only for iOS.
727-
*/
741+
*/
728742
private String addAndroidPrefix(String key) {
729743
// Capitalize the first letter.
730744
String cap = String.valueOf(key.charAt(0)).toUpperCase() + key.substring(1);
@@ -733,8 +747,8 @@ private String addAndroidPrefix(String key) {
733747

734748
@Nullable
735749
private <T> String getKeyOfType(@NonNull HashMap<String, Object> configurationMap,
736-
@NonNull String key,
737-
@NonNull Class<T> clazz) {
750+
@NonNull String key,
751+
@NonNull Class<T> clazz) {
738752
if (containsKeyOfType(configurationMap, key, clazz)) {
739753
return key;
740754
}
@@ -784,6 +798,19 @@ String getPassword() {
784798
}
785799

786800
PdfActivityConfiguration build() {
801+
// Turn on Instant comments;
802+
if (enableInstantComments) {
803+
PdfConfiguration pdfConfiguration = this.configuration.build().getConfiguration();
804+
805+
final List<AnnotationTool> annotationTools = pdfConfiguration
806+
.getEnabledAnnotationTools();
807+
// Explicitly enable Instant comment markers if your server supports this feature.
808+
annotationTools.add(AnnotationTool.INSTANT_COMMENT_MARKER);
809+
annotationTools.add(AnnotationTool.INSTANT_HIGHLIGHT_COMMENT);
810+
this.configuration
811+
.enabledAnnotationTools(annotationTools);
812+
}
813+
787814
return configuration.build();
788815
}
789816
}

android/src/main/java/com/pspdfkit/flutter/pspdfkit/EventDispatcher.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import androidx.annotation.NonNull;
1313
import androidx.annotation.Nullable;
1414

15+
import java.util.HashMap;
16+
1517
import io.flutter.plugin.common.MethodChannel;
1618

1719
/**
@@ -46,9 +48,42 @@ public void notifyActivityOnPause() {
4648
sendEvent("flutterPdfActivityOnPause");
4749
}
4850

49-
private void sendEvent(@NonNull final String method) {
51+
public void notifyInstantSyncStarted(String documentId) {
52+
sendEvent("pspdfkitInstantSyncStarted", documentId);
53+
}
54+
55+
public void notifyInstantSyncFinished(String documentId) {
56+
sendEvent("pspdfkitInstantSyncFinished", documentId);
57+
}
58+
59+
public void notifyInstantSyncFailed(String documentId, String error) {
60+
sendEvent("pspdfkitInstantSyncFailed",new HashMap<String, String>() {{
61+
put("documentId", documentId);
62+
put("error", error);
63+
}});
64+
}
65+
66+
public void notifyInstantAuthenticationFinished(String documentId,String validJWT) {
67+
sendEvent("pspdfkitInstantAuthenticationFinished", new HashMap<String, String>() {{
68+
put("documentId", documentId);
69+
put("jwt", validJWT);
70+
}});
71+
}
72+
73+
public void notifyInstantAuthenticationFailed(String documentId, String error) {
74+
sendEvent("pspdfkitInstantAuthenticationFailed", new HashMap<String, String>() {{
75+
put("documentId", documentId);
76+
put("error", error);
77+
}});
78+
}
79+
80+
private void sendEvent(String eventName) {
81+
sendEvent(eventName, null);
82+
}
83+
84+
private void sendEvent(@NonNull final String method, @Nullable final Object arguments) {
5085
if (channel != null) {
51-
channel.invokeMethod(method, null, null);
86+
channel.invokeMethod(method, arguments, null);
5287
}
5388
}
5489
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.pspdfkit.flutter.pspdfkit
2+
3+
/// Copyright © 2021-2022 PSPDFKit GmbH. All rights reserved.
4+
///
5+
/// THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
6+
/// AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE PSPDFKIT LICENSE AGREEMENT.
7+
/// UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
8+
/// This notice may not be removed from this file.
9+
///
10+
11+
import android.os.Bundle
12+
import com.pspdfkit.document.PdfDocument
13+
import com.pspdfkit.instant.document.InstantPdfDocument
14+
import com.pspdfkit.instant.exceptions.InstantException
15+
import com.pspdfkit.instant.ui.InstantPdfActivity
16+
import io.flutter.plugin.common.MethodChannel
17+
import java.util.concurrent.atomic.AtomicReference
18+
19+
/**
20+
* For communication with the PSPDFKit plugin, we keep a static reference to the current
21+
* activity.
22+
*/
23+
class FlutterInstantPdfActivity : InstantPdfActivity() {
24+
override fun onCreate(bundle: Bundle?) {
25+
super.onCreate(bundle)
26+
bindActivity()
27+
}
28+
29+
override fun onPause() {
30+
// Notify the Flutter PSPDFKit plugin that the activity is going to enter the onPause state.
31+
EventDispatcher.getInstance().notifyActivityOnPause()
32+
super.onPause()
33+
}
34+
35+
override fun onDestroy() {
36+
super.onDestroy()
37+
releaseActivity()
38+
}
39+
40+
override fun onDocumentLoaded(pdfDocument: PdfDocument) {
41+
super.onDocumentLoaded(pdfDocument)
42+
val result = loadedDocumentResult.getAndSet(null)
43+
result?.success(true)
44+
}
45+
46+
override fun onDocumentLoadFailed(throwable: Throwable) {
47+
super.onDocumentLoadFailed(throwable)
48+
val result = loadedDocumentResult.getAndSet(null)
49+
result?.success(false)
50+
}
51+
52+
override fun onSyncStarted(instantDocument: InstantPdfDocument) {
53+
super.onSyncStarted(instantDocument)
54+
EventDispatcher.getInstance()
55+
.notifyInstantSyncStarted(instantDocument.instantDocumentDescriptor.documentId)
56+
}
57+
58+
override fun onSyncFinished(instantDocument: InstantPdfDocument) {
59+
super.onSyncFinished(instantDocument)
60+
EventDispatcher.getInstance()
61+
.notifyInstantSyncFinished(instantDocument.instantDocumentDescriptor.documentId)
62+
}
63+
64+
override fun onSyncError(instantDocument: InstantPdfDocument, error: InstantException) {
65+
super.onSyncError(instantDocument, error)
66+
EventDispatcher.getInstance().notifyInstantSyncFailed(
67+
instantDocument.instantDocumentDescriptor.documentId,
68+
error.message
69+
)
70+
}
71+
72+
override fun onAuthenticationFinished(instantDocument: InstantPdfDocument, validJwt: String) {
73+
super.onAuthenticationFinished(instantDocument, validJwt)
74+
EventDispatcher.getInstance().notifyInstantAuthenticationFinished(
75+
instantDocument.instantDocumentDescriptor.documentId,
76+
validJwt
77+
)
78+
}
79+
80+
override fun onAuthenticationFailed(
81+
instantDocument: InstantPdfDocument,
82+
error: InstantException
83+
) {
84+
super.onAuthenticationFailed(instantDocument, error)
85+
EventDispatcher.getInstance().notifyInstantAuthenticationFailed(
86+
instantDocument.instantDocumentDescriptor.documentId,
87+
error.message
88+
)
89+
}
90+
91+
private fun bindActivity() {
92+
currentActivity = this
93+
}
94+
95+
private fun releaseActivity() {
96+
val result = loadedDocumentResult.getAndSet(null)
97+
result?.success(false)
98+
currentActivity = null
99+
}
100+
101+
companion object {
102+
103+
@JvmStatic
104+
var currentActivity: FlutterInstantPdfActivity? = null
105+
private set
106+
private val loadedDocumentResult = AtomicReference<MethodChannel.Result?>()
107+
108+
109+
@JvmStatic
110+
fun setLoadedDocumentResult(result: MethodChannel.Result?) {
111+
loadedDocumentResult.set(result)
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)