Pull request #9: Sync viewers
Merge in RED/ui from sync-viewers to master * commit 'ba72c4558b0e7276747043bc4be4b8729c29271e': Fixed typo in file name Synchronize viewers
This commit is contained in:
commit
e7e2b36fbd
@ -6,7 +6,7 @@ import { NotificationService } from '../../../notification/notification.service'
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { AppStateService } from '../../../state/app-state.service';
|
import { AppStateService } from '../../../state/app-state.service';
|
||||||
import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component';
|
import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component';
|
||||||
import { ViewerSyncService } from '../service/viwer-sync.service';
|
import { ViewerSyncService } from '../service/viewer-sync.service';
|
||||||
import { Annotations } from '@pdftron/webviewer';
|
import { Annotations } from '@pdftron/webviewer';
|
||||||
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
||||||
import { AnnotationUtils } from '../../../utils/annotation-utils';
|
import { AnnotationUtils } from '../../../utils/annotation-utils';
|
||||||
@ -95,7 +95,6 @@ export class FilePreviewScreenComponent implements OnInit {
|
|||||||
if (annotation.Id.indexOf(':') >= 0) {
|
if (annotation.Id.indexOf(':') >= 0) {
|
||||||
this.annotations.push(annotation);
|
this.annotations.push(annotation);
|
||||||
const pageNumber = annotation.getPageNumber();
|
const pageNumber = annotation.getPageNumber();
|
||||||
console.log({pageNumber})
|
|
||||||
let el = this.quickNavigation.find((page) => page.pageNumber === pageNumber);
|
let el = this.quickNavigation.find((page) => page.pageNumber === pageNumber);
|
||||||
if (!el) {
|
if (!el) {
|
||||||
el = { pageNumber, redactions: 0, hints: 0 }
|
el = { pageNumber, redactions: 0, hints: 0 }
|
||||||
|
|||||||
@ -9,13 +9,13 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {AppConfigKey, AppConfigService} from "../../../app-config/app-config.service";
|
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
||||||
import {FileStatus, FileUploadControllerService} from "@redaction/red-ui-http";
|
import { FileStatus, FileUploadControllerService } from '@redaction/red-ui-http';
|
||||||
import {Observable, of} from "rxjs";
|
import { Observable, of } from 'rxjs';
|
||||||
import {tap} from "rxjs/operators";
|
import { tap } from 'rxjs/operators';
|
||||||
import WebViewer, {Annotations, WebViewerInstance} from "@pdftron/webviewer";
|
import WebViewer, { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import {TranslateService} from "@ngx-translate/core";
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import {ViewerSyncService} from "../service/viwer-sync.service";
|
import { ViewerSyncService } from '../service/viewer-sync.service';
|
||||||
|
|
||||||
export enum FileType {
|
export enum FileType {
|
||||||
ORIGINAL = 'ORIGINAL',
|
ORIGINAL = 'ORIGINAL',
|
||||||
@ -37,12 +37,11 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
@Output() annotationsAdded = new EventEmitter<Annotations.Annotation[]>();
|
@Output() annotationsAdded = new EventEmitter<Annotations.Annotation[]>();
|
||||||
@Output() annotationSelected = new EventEmitter<Annotations.Annotation>();
|
@Output() annotationSelected = new EventEmitter<Annotations.Annotation>();
|
||||||
|
|
||||||
@ViewChild('viewer', {static: true}) viewer: ElementRef;
|
@ViewChild('viewer', { static: true }) viewer: ElementRef;
|
||||||
wvInstance: WebViewerInstance;
|
wvInstance: WebViewerInstance;
|
||||||
|
|
||||||
_fileData: Blob;
|
_fileData: Blob;
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _viewerSyncService: ViewerSyncService,
|
private readonly _viewerSyncService: ViewerSyncService,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
@ -57,7 +56,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
wvDocumentLoadedHandler(): void {
|
wvDocumentLoadedHandler(): void {
|
||||||
this.wvInstance.setFitMode('FitWidth');
|
this.wvInstance.setFitMode('FitWidth');
|
||||||
const displayMode = this.wvInstance.docViewer.getDisplayModeManager().getDisplayMode();
|
const displayMode = this.wvInstance.docViewer.getDisplayModeManager().getDisplayMode();
|
||||||
displayMode.mode = "Continuous";
|
displayMode.mode = 'Continuous';
|
||||||
this.wvInstance.docViewer.getDisplayModeManager().setDisplayMode(displayMode);
|
this.wvInstance.docViewer.getDisplayModeManager().setDisplayMode(displayMode);
|
||||||
this.fileReady.emit();
|
this.fileReady.emit();
|
||||||
}
|
}
|
||||||
@ -74,10 +73,11 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
WebViewer({
|
WebViewer({
|
||||||
licenseKey: license,
|
licenseKey: license,
|
||||||
isReadOnly: true,
|
isReadOnly: true,
|
||||||
path: '/assets/wv-resources',
|
path: '/assets/wv-resources'
|
||||||
}, this.viewer.nativeElement).then(instance => {
|
}, this.viewer.nativeElement).then(instance => {
|
||||||
this.wvInstance = instance;
|
this.wvInstance = instance;
|
||||||
this._viewerSyncService.registerViewer(this.fileType, this.wvInstance);
|
this._viewerSyncService.registerViewer(this.fileType, this.wvInstance);
|
||||||
|
this._disableElements();
|
||||||
this._configureTextPopup();
|
this._configureTextPopup();
|
||||||
this._configureHeader();
|
this._configureHeader();
|
||||||
instance.annotManager.on('annotationChanged', (annotations, action) => {
|
instance.annotManager.on('annotationChanged', (annotations, action) => {
|
||||||
@ -95,7 +95,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
instance.docViewer.on('documentLoaded', this.wvDocumentLoadedHandler);
|
instance.docViewer.on('documentLoaded', this.wvDocumentLoadedHandler);
|
||||||
instance.loadDocument(pdfBlob, {filename: this.fileStatus ? this.fileStatus.filename : 'file.pdf'});
|
instance.loadDocument(pdfBlob, { filename: this.fileStatus ? this.fileStatus.filename : 'file.pdf' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
return fileObs$;
|
return fileObs$;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _configureTextPopup() {
|
private _disableElements() {
|
||||||
this.wvInstance.disableElements([
|
this.wvInstance.disableElements([
|
||||||
'textHighlightToolButton',
|
'textHighlightToolButton',
|
||||||
'textUnderlineToolButton',
|
'textUnderlineToolButton',
|
||||||
@ -131,9 +131,14 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
'textStrikeoutToolButton',
|
'textStrikeoutToolButton',
|
||||||
'linkButton',
|
'linkButton',
|
||||||
'toggleNotesButton',
|
'toggleNotesButton',
|
||||||
'notesPanel'
|
'notesPanel',
|
||||||
|
'thumbnailControl',
|
||||||
|
'documentControl',
|
||||||
|
'ribbons'
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _configureTextPopup() {
|
||||||
this.wvInstance.textPopup.add(<any>{
|
this.wvInstance.textPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
img: '/assets/icons/general/add.svg',
|
img: '/assets/icons/general/add.svg',
|
||||||
@ -146,7 +151,6 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _configureHeader() {
|
private _configureHeader() {
|
||||||
this.wvInstance.disableElements(['ribbons']);
|
|
||||||
this.wvInstance.setToolbarGroup('toolbarGroup-View');
|
this.wvInstance.setToolbarGroup('toolbarGroup-View');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import {Injectable} from "@angular/core";
|
import { Injectable } from '@angular/core';
|
||||||
import {WebViewerInstance} from "@pdftron/webviewer";
|
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -13,24 +13,33 @@ export class ViewerSyncService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
syncViewers() {
|
syncViewers() {
|
||||||
if (this._activeViewer) {
|
if (this._activeViewer) {
|
||||||
const lastScrolledViewer = this._viewers[this._activeViewer];
|
const lastScrolledViewer = this._viewers[this._activeViewer];
|
||||||
if (lastScrolledViewer) {
|
if (lastScrolledViewer) {
|
||||||
const lastScrolledViewerScrollElement = lastScrolledViewer.docViewer.getScrollViewElement();
|
const lastScrolledViewerScrollElement = lastScrolledViewer.docViewer.getScrollViewElement();
|
||||||
const lastViewerScrollHeight = lastScrolledViewerScrollElement.scrollHeight;
|
|
||||||
const lastViewerScrollTop = lastScrolledViewerScrollElement.scrollTop;
|
const lastViewerScrollTop = lastScrolledViewerScrollElement.scrollTop;
|
||||||
|
const lastViewerScrollLeft = lastScrolledViewerScrollElement.scrollLeft;
|
||||||
|
|
||||||
|
const currentZoom = lastScrolledViewer.docViewer.getZoom();
|
||||||
|
const isLeftPanelOpen = lastScrolledViewer.isElementOpen('leftPanel');
|
||||||
|
|
||||||
for (const key of Object.keys(this._viewers)) {
|
for (const key of Object.keys(this._viewers)) {
|
||||||
if (key !== this._activeViewer) {
|
if (key !== this._activeViewer) {
|
||||||
const viewerScrollElement = this._viewers[key].docViewer.getScrollViewElement();
|
const instance = this._viewers[key];
|
||||||
const viewerScrollHeight = viewerScrollElement.scrollHeight;
|
|
||||||
if (viewerScrollHeight === lastViewerScrollHeight) {
|
// Synchronize zoom - needs to be done before scrolling
|
||||||
viewerScrollElement.scrollTo(viewerScrollElement.scrollLeft, lastViewerScrollTop);
|
instance.docViewer.zoomTo(currentZoom);
|
||||||
} else if (viewerScrollHeight > lastViewerScrollHeight) {
|
|
||||||
let delta = viewerScrollHeight / lastViewerScrollHeight;
|
// Synchronize scroll
|
||||||
delta = this._roundToTwo(delta);
|
const viewerScrollElement = instance.docViewer.getScrollViewElement();
|
||||||
viewerScrollElement.scrollTo(viewerScrollElement.scrollLeft, delta * lastViewerScrollTop);
|
viewerScrollElement.scrollTo(lastViewerScrollLeft, lastViewerScrollTop);
|
||||||
|
|
||||||
|
// Synchronize left panel
|
||||||
|
if (isLeftPanelOpen) {
|
||||||
|
instance.openElements(['leftPanel']);
|
||||||
|
} else {
|
||||||
|
instance.closeElements(['leftPanel']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +47,6 @@ export class ViewerSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
deregisterInstance(key: string) {
|
deregisterInstance(key: string) {
|
||||||
delete this._viewers[key];
|
delete this._viewers[key];
|
||||||
}
|
}
|
||||||
@ -52,12 +60,7 @@ export class ViewerSyncService {
|
|||||||
this._activeViewer = key;
|
this._activeViewer = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
get activeViewer(){
|
get activeViewer() {
|
||||||
return this._activeViewer;
|
return this._activeViewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private _roundToTwo(num) {
|
|
||||||
return +(Math.round(Number(num + "e+2")) + "e-2");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user