Skip to content

Commit 77dd26d

Browse files
author
Reinhard Hafenscher
authored
Merge pull request #259 from PSPDFKit/reinhard/configuration-prop
Android improvements
2 parents 3c473ce + 414937d commit 77dd26d

File tree

8 files changed

+209
-109
lines changed

8 files changed

+209
-109
lines changed

android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,15 @@ public void accept(List<Annotation> annotations) {
186186
}
187187
break;
188188
case COMMAND_ADD_ANNOTATION:
189-
if (args != null) {
190-
annotationDisposables.add(root.addAnnotation(args.getMap(0)));
189+
if (args != null && args.size() == 2) {
190+
final int requestId = args.getInt(0);
191+
annotationDisposables.add(root.addAnnotation(requestId, args.getMap(1)));
191192
}
192193
break;
193194
case COMMAND_REMOVE_ANNOTATION:
194-
if (args != null) {
195-
annotationDisposables.add(root.removeAnnotation(args.getMap(0)));
195+
if (args != null && args.size() == 2) {
196+
final int requestId = args.getInt(0);
197+
annotationDisposables.add(root.removeAnnotation(requestId, args.getMap(1)));
196198
}
197199
break;
198200
case COMMAND_GET_ALL_UNSAVED_ANNOTATIONS:
@@ -211,8 +213,9 @@ public void accept(JSONObject jsonObject) {
211213
}
212214
break;
213215
case COMMAND_ADD_ANNOTATIONS:
214-
if (args != null && args.size() == 1) {
215-
annotationDisposables.add(root.addAnnotations(args.getMap(0)));
216+
if (args != null && args.size() == 2) {
217+
final int requestId = args.getInt(0);
218+
annotationDisposables.add(root.addAnnotations(requestId, args.getMap(1)));
216219
}
217220
break;
218221
case COMMAND_GET_FORM_FIELD_VALUE:

android/src/main/java/com/pspdfkit/react/events/PdfViewDataReturnedEvent.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull List<
4747
payload = Arguments.makeNativeMap(map);
4848
}
4949

50+
public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, boolean result) {
51+
super(viewId);
52+
this.requestId = requestId;
53+
Map<String, Object> map = new HashMap<>();
54+
map.put("requestId", requestId);
55+
map.put("result", result);
56+
57+
payload = Arguments.makeNativeMap(map);
58+
}
59+
5060
public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull JSONObject jsonObject) {
5161
super(viewId);
5262
this.requestId = requestId;

android/src/main/java/com/pspdfkit/views/PdfView.java

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@
5454
import java.util.ArrayList;
5555
import java.util.EnumSet;
5656
import java.util.List;
57+
import java.util.NoSuchElementException;
5758
import java.util.concurrent.Callable;
5859

60+
import io.reactivex.Completable;
5961
import io.reactivex.Observable;
6062
import io.reactivex.ObservableSource;
6163
import io.reactivex.Single;
@@ -171,47 +173,46 @@ public void setFragmentTag(String fragmentTag) {
171173
}
172174

173175
public void setConfiguration(PdfActivityConfiguration configuration) {
176+
if (configuration != null && !configuration.equals(this.configuration)) {
177+
// The configuration changed, recreate the fragment.
178+
// We set the current page index so the fragment is created at this location.
179+
this.pageIndex = fragment != null ? fragment.getPageIndex() : this.pageIndex;
180+
removeFragment(false);
181+
}
174182
this.configuration = configuration;
175183
setupFragment();
176184
}
177185

178-
public void setDocument(@Nullable String document) {
179-
if (document == null) {
186+
public void setDocument(@Nullable String documentPath) {
187+
if (documentPath == null) {
188+
this.document = null;
180189
removeFragment(false);
181190
return;
182191
}
183192

184-
if (Uri.parse(document).getScheme() == null) {
193+
if (Uri.parse(documentPath).getScheme() == null) {
185194
// If there is no scheme it might be a raw path.
186195
try {
187-
File file = new File(document);
188-
document = Uri.fromFile(file).toString();
196+
File file = new File(documentPath);
197+
documentPath = Uri.fromFile(file).toString();
189198
} catch (Exception e) {
190-
document = FILE_SCHEME + document;
199+
documentPath = FILE_SCHEME + document;
191200
}
192201
}
193202
if (documentOpeningDisposable != null) {
194203
documentOpeningDisposable.dispose();
195204
}
196205
updateState();
197-
documentOpeningDisposable = PdfDocumentLoader.openDocumentAsync(getContext(), Uri.parse(document))
206+
documentOpeningDisposable = PdfDocumentLoader.openDocumentAsync(getContext(), Uri.parse(documentPath))
198207
.subscribeOn(Schedulers.io())
199208
.observeOn(AndroidSchedulers.mainThread())
200-
.subscribe(new Consumer<PdfDocument>() {
201-
202-
@Override
203-
public void accept(PdfDocument pdfDocument) throws Exception {
204-
PdfView.this.document = pdfDocument;
205-
setupFragment();
206-
}
207-
208-
}, new Consumer<Throwable>() {
209-
@Override
210-
public void accept(Throwable throwable) throws Exception {
211-
PdfView.this.document = null;
212-
setupFragment();
213-
eventDispatcher.dispatchEvent(new PdfViewDocumentLoadFailedEvent(getId(), throwable.getMessage()));
214-
}
209+
.subscribe(pdfDocument -> {
210+
PdfView.this.document = pdfDocument;
211+
setupFragment();
212+
}, throwable -> {
213+
PdfView.this.document = null;
214+
setupFragment();
215+
eventDispatcher.dispatchEvent(new PdfViewDocumentLoadFailedEvent(getId(), throwable.getMessage()));
215216
});
216217
}
217218

@@ -329,15 +330,17 @@ public void removeFragment(boolean makeInactive) {
329330
PdfFragment pdfFragment = (PdfFragment) fragmentManager.findFragmentByTag(fragmentTag);
330331
if (pdfFragment != null) {
331332
fragmentManager.beginTransaction()
332-
.remove(pdfFragment)
333-
.commitAllowingStateLoss();
333+
.remove(pdfFragment)
334+
.commitNowAllowingStateLoss();
334335
}
335336
if (makeInactive) {
337+
// Clear everything.
336338
isActive = false;
339+
document = null;
337340
}
338341

339342
fragment = null;
340-
document = null;
343+
341344
fragmentGetter.onComplete();
342345
fragmentGetter = BehaviorSubject.create();
343346
pendingFragmentActions.dispose();
@@ -492,17 +495,19 @@ private EnumSet<AnnotationType> getTypeFromString(@Nullable String type) {
492495
return EnumSet.noneOf(AnnotationType.class);
493496
}
494497

495-
public Disposable addAnnotation(ReadableMap annotation) {
498+
public Disposable addAnnotation(final int requestId, ReadableMap annotation) {
496499
return fragmentGetter.take(1).map(PdfFragment::getDocument).subscribeOn(Schedulers.io())
497-
.observeOn(AndroidSchedulers.mainThread())
498-
.subscribe(pdfDocument -> {
499-
JSONObject json = new JSONObject(annotation.toHashMap());
500-
pdfDocument.getAnnotationProvider().createAnnotationFromInstantJson(json.toString());
501-
});
502-
500+
.map(pdfDocument -> {
501+
JSONObject json = new JSONObject(annotation.toHashMap());
502+
return pdfDocument.getAnnotationProvider().createAnnotationFromInstantJson(json.toString());
503+
})
504+
.map(Annotation::toInstantJson)
505+
.observeOn(AndroidSchedulers.mainThread())
506+
.subscribe((instantJson) -> eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, true)),
507+
(throwable) -> eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, throwable)));
503508
}
504509

505-
public Disposable removeAnnotation(ReadableMap annotation) {
510+
public Disposable removeAnnotation(final int requestId, ReadableMap annotation) {
506511
return fragmentGetter.take(1).map(PdfFragment::getDocument).subscribeOn(Schedulers.io())
507512
.observeOn(AndroidSchedulers.mainThread())
508513
.flatMap(pdfDocument -> {
@@ -515,10 +520,23 @@ public Disposable removeAnnotation(ReadableMap annotation) {
515520
if (pageIndex == -1 || type == null || name == null) {
516521
return Observable.empty();
517522
}
523+
518524
return pdfDocument.getAnnotationProvider().getAllAnnotationsOfType(getTypeFromString(type), pageIndex, 1)
519525
.filter(annotationToFilter -> name.equals(annotationToFilter.getName()))
520526
.map(filteredAnnotation -> new Pair<>(filteredAnnotation, pdfDocument));
521-
}).subscribe(pair -> pair.second.getAnnotationProvider().removeAnnotationFromPage(pair.first));
527+
})
528+
.firstOrError()
529+
.flatMapCompletable(pair -> Completable.fromAction(() -> {
530+
pair.second.getAnnotationProvider().removeAnnotationFromPage(pair.first);
531+
}))
532+
.subscribe(() -> eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, true)), (throwable -> {
533+
if (throwable instanceof NoSuchElementException) {
534+
// We didn't find an annotation so return false.
535+
eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, false));
536+
} else {
537+
eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, throwable));
538+
}
539+
}));
522540
}
523541

524542
public Single<JSONObject> getAllUnsavedAnnotations() {
@@ -535,14 +553,16 @@ public JSONObject call() throws Exception {
535553
});
536554
}
537555

538-
public Disposable addAnnotations(ReadableMap annotation) {
556+
public Disposable addAnnotations(final int requestId, ReadableMap annotation) {
539557
return fragmentGetter.take(1).map(PdfFragment::getDocument).subscribeOn(Schedulers.io())
540-
.observeOn(AndroidSchedulers.mainThread())
541-
.subscribe(pdfDocument -> {
542-
JSONObject json = new JSONObject(annotation.toHashMap());
543-
final DataProvider dataProvider = new DocumentJsonDataProvider(json);
544-
DocumentJsonFormatter.importDocumentJson(pdfDocument, dataProvider);
545-
});
558+
.flatMapCompletable(currentDocument -> Completable.fromAction(() -> {
559+
JSONObject json = new JSONObject(annotation.toHashMap());
560+
final DataProvider dataProvider = new DocumentJsonDataProvider(json);
561+
DocumentJsonFormatter.importDocumentJson(currentDocument, dataProvider);
562+
}))
563+
.observeOn(AndroidSchedulers.mainThread())
564+
.subscribe(() -> eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, true)),
565+
(throwable) -> eventDispatcher.dispatchEvent(new PdfViewDataReturnedEvent(getId(), requestId, throwable)));
546566
}
547567

548568
public Disposable getFormFieldValue(final int requestId, @NonNull String formElementName) {

index.js

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,26 @@ class PSPDFKitView extends React.Component {
186186
* Adds a new annotation to the current document.
187187
*
188188
* @param annotation InstantJson of the annotation to add.
189+
*
190+
* Returns a promise resolving to true if the annotation was added. Otherwise, returns false if an error has occurred.
189191
*/
190192
addAnnotation = function(annotation) {
191193
if (Platform.OS === "android") {
194+
let requestId = this._nextRequestId++;
195+
let requestMap = this._requestMap;
196+
197+
// We create a promise here that will be resolved once onDataReturned is called.
198+
let promise = new Promise(function(resolve, reject) {
199+
requestMap[requestId] = { resolve: resolve, reject: reject };
200+
});
201+
192202
UIManager.dispatchViewManagerCommand(
193203
findNodeHandle(this.refs.pdfView),
194204
this._getViewManagerConfig("RCTPSPDFKitView").Commands.addAnnotation,
195-
[annotation]
205+
[requestId, annotation]
196206
);
207+
208+
return promise;
197209
} else if (Platform.OS === "ios") {
198210
return NativeModules.PSPDFKitViewManager.addAnnotation(
199211
annotation,
@@ -206,14 +218,26 @@ class PSPDFKitView extends React.Component {
206218
* Removes an existing annotation from the current document.
207219
*
208220
* @param annotation InstantJson of the annotation to remove.
221+
*
222+
* Returns a promise resolving to true if the annotation was removed. Otherwise, returns false if the annotation couldn't be found.
209223
*/
210224
removeAnnotation = function(annotation) {
211225
if (Platform.OS === "android") {
226+
let requestId = this._nextRequestId++;
227+
let requestMap = this._requestMap;
228+
229+
// We create a promise here that will be resolved once onDataReturned is called.
230+
let promise = new Promise(function(resolve, reject) {
231+
requestMap[requestId] = { resolve: resolve, reject: reject };
232+
});
233+
212234
UIManager.dispatchViewManagerCommand(
213235
findNodeHandle(this.refs.pdfView),
214236
this._getViewManagerConfig("RCTPSPDFKitView").Commands.removeAnnotation,
215-
[annotation]
237+
[requestId, annotation]
216238
);
239+
240+
return promise;
217241
} else if (Platform.OS === "ios") {
218242
return NativeModules.PSPDFKitViewManager.removeAnnotation(
219243
annotation,
@@ -256,14 +280,26 @@ class PSPDFKitView extends React.Component {
256280
* Applies the passed in document instant json.
257281
*
258282
* @param annotations The document instant json to apply.
283+
*
284+
* Returns a promise resolving to true if the annotation was added.
259285
*/
260286
addAnnotations = function(annotations) {
261287
if (Platform.OS === "android") {
288+
let requestId = this._nextRequestId++;
289+
let requestMap = this._requestMap;
290+
291+
// We create a promise here that will be resolved once onDataReturned is called.
292+
let promise = new Promise(function(resolve, reject) {
293+
requestMap[requestId] = { resolve: resolve, reject: reject };
294+
});
295+
262296
UIManager.dispatchViewManagerCommand(
263297
findNodeHandle(this.refs.pdfView),
264298
this._getViewManagerConfig("RCTPSPDFKitView").Commands.addAnnotations,
265-
[annotations]
299+
[requestId, annotations]
266300
);
301+
302+
return promise;
267303
} else if (Platform.OS === "ios") {
268304
return NativeModules.PSPDFKitViewManager.addAnnotations(
269305
annotations,

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-pspdfkit",
3-
"version": "1.24.8",
3+
"version": "1.24.9",
44
"description": "A React Native module for the PSPDFKit library.",
55
"keywords": [
66
"react native",

0 commit comments

Comments
 (0)