Remove viewer header config service init params

This commit is contained in:
Adina Țeudan 2022-03-25 17:21:28 +02:00
parent 285a8b8fed
commit 8cf9c46a52
4 changed files with 102 additions and 116 deletions

View File

@ -4,16 +4,16 @@
<input #compareFileInput (change)="uploadFile($event.target['files'])" accept="application/pdf" class="file-upload-input" type="file" /> <input #compareFileInput (change)="uploadFile($event.target['files'])" accept="application/pdf" class="file-upload-input" type="file" />
<div *ngIf="pdf?.totalPages && pdf?.currentPage" class="pagination noselect"> <div *ngIf="pdfViewer?.totalPages && pdfViewer?.currentPage" class="pagination noselect">
<div (click)="pdf.previousPage()"> <div (click)="pdfViewer.navigatePreviousPage()">
<mat-icon class="chevron-icon" svgIcon="red:nav-prev"></mat-icon> <mat-icon class="chevron-icon" svgIcon="red:nav-prev"></mat-icon>
</div> </div>
<div> <div>
<input <input
#pageInput #pageInput
(change)="pdf.navigateToPage(pageInput.value)" (change)="pdfViewer.navigateToPage(pageInput.value)"
[max]="pdf.totalPages" [max]="pdfViewer.totalPages"
[value]="pdf.currentPage" [value]="pdfViewer.currentPage"
class="page-number-input" class="page-number-input"
min="1" min="1"
type="number" type="number"
@ -21,9 +21,9 @@
</div> </div>
<div class="separator">/</div> <div class="separator">/</div>
<div> <div>
{{ pdf.totalPages }} {{ pdfViewer.totalPages }}
</div> </div>
<div (click)="pdf.nextPage()"> <div (click)="pdfViewer.navigateNextPage()">
<mat-icon class="chevron-icon" svgIcon="red:nav-next"></mat-icon> <mat-icon class="chevron-icon" svgIcon="red:nav-next"></mat-icon>
</div> </div>
</div> </div>

View File

@ -11,7 +11,7 @@ import {
SimpleChanges, SimpleChanges,
ViewChild, ViewChild,
} from '@angular/core'; } from '@angular/core';
import { Dossier, File, IHeaderElement, IManualRedactionEntry, RotationType } from '@red/domain'; import { Dossier, File, IHeaderElement, IManualRedactionEntry } from '@red/domain';
import { Core, WebViewerInstance } from '@pdftron/webviewer'; import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { import {
@ -36,7 +36,6 @@ import { ViewModeService } from '../../services/view-mode.service';
import { MultiSelectService } from '../../services/multi-select.service'; import { MultiSelectService } from '../../services/multi-select.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service'; import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators'; import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { PageRotationService } from '../../services/page-rotation.service'; import { PageRotationService } from '../../services/page-rotation.service';
import { ALLOWED_KEYBOARD_SHORTCUTS, HeaderElements, TextPopups } from '../../shared/constants'; import { ALLOWED_KEYBOARD_SHORTCUTS, HeaderElements, TextPopups } from '../../shared/constants';
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service'; import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
@ -81,7 +80,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private readonly _annotationActionsService: AnnotationActionsService, private readonly _annotationActionsService: AnnotationActionsService,
private readonly _configService: ConfigService, private readonly _configService: ConfigService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _fileManagementService: FileManagementService,
private readonly _pageRotationService: PageRotationService, private readonly _pageRotationService: PageRotationService,
private readonly _fileDataService: FileDataService, private readonly _fileDataService: FileDataService,
private readonly _headerConfigService: ViewerHeaderConfigService, private readonly _headerConfigService: ViewerHeaderConfigService,
@ -89,7 +87,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
readonly stateService: FilePreviewStateService, readonly stateService: FilePreviewStateService,
readonly viewModeService: ViewModeService, readonly viewModeService: ViewModeService,
readonly multiSelectService: MultiSelectService, readonly multiSelectService: MultiSelectService,
readonly pdf: PdfViewer, readonly pdfViewer: PdfViewer,
) { ) {
super(); super();
} }
@ -100,7 +98,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.addActiveScreenSubscription = this.stateService.blob$ this.addActiveScreenSubscription = this.stateService.blob$
.pipe( .pipe(
switchMap(blob => from(this.pdf.lockDocument()).pipe(map(() => blob))), switchMap(blob => from(this.pdfViewer.lockDocument()).pipe(map(() => blob))),
withLatestFrom(this.stateService.file$), withLatestFrom(this.stateService.file$),
tap(([blob, file]) => this._loadDocument(blob, file)), tap(([blob, file]) => this._loadDocument(blob, file)),
) )
@ -150,7 +148,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.viewModeService.compareMode = true; this.viewModeService.compareMode = true;
}, },
() => { () => {
this.pdf.navigateToPage(1); this.pdfViewer.navigateToPage(1);
}, },
this.instance.Core.PDFNet, this.instance.Core.PDFNet,
); );
@ -185,30 +183,14 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
fileReader.readAsArrayBuffer(fileToCompare); fileReader.readAsArrayBuffer(fileToCompare);
} }
private async _closeCompareMode() {
this.viewModeService.compareMode = false;
const pdfNet = this.instance.Core.PDFNet;
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
const blob = await this.stateService.blob;
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
const filename = (await this.stateService.file).filename ?? 'document.pdf';
this.instance.UI.loadDocument(currentDocument, { filename });
this._headerConfigService.disable([HeaderElements.CLOSE_COMPARE_BUTTON]);
this._headerConfigService.enable([HeaderElements.COMPARE_BUTTON]);
this.pdf.navigateToPage(1);
}
private async _loadViewer() { private async _loadViewer() {
this.instance = await this.pdf.loadViewer(this.viewer.nativeElement as HTMLElement); this.instance = await this.pdfViewer.loadViewer(this.viewer.nativeElement as HTMLElement);
this.documentViewer = this.pdf.documentViewer; this.documentViewer = this.pdfViewer.documentViewer;
this.annotationManager = this.pdf.annotationManager; this.annotationManager = this.pdfViewer.annotationManager;
this._setSelectionMode(); this._setSelectionMode();
this._configureElements(); this._configureElements();
this.pdf.disableHotkeys(); this.pdfViewer.disableHotkeys();
await this._configureTextPopup(); await this._configureTextPopup();
this.annotationManager.addEventListener('annotationSelected', async (annotations: Annotation[], action) => { this.annotationManager.addEventListener('annotationSelected', async (annotations: Annotation[], action) => {
@ -221,7 +203,9 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
if (!this.multiSelectService.isEnabled) { if (!this.multiSelectService.isEnabled) {
const visibleAnnotations = await this._fileDataService.visibleAnnotations; const visibleAnnotations = await this._fileDataService.visibleAnnotations;
this.pdf.deselectAnnotations(visibleAnnotations.filter(wrapper => !nextAnnotations.find(ann => ann.Id === wrapper.id))); this.pdfViewer.deselectAnnotations(
visibleAnnotations.filter(wrapper => !nextAnnotations.find(ann => ann.Id === wrapper.id)),
);
} }
await this.#configureAnnotationSpecificActions(annotations); await this.#configureAnnotationSpecificActions(annotations);
this._toggleRectangleAnnotationAction(annotations.length === 1 && annotations[0].ReadOnly); this._toggleRectangleAnnotationAction(annotations.length === 1 && annotations[0].ReadOnly);
@ -238,7 +222,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
}); });
this.documentViewer.addEventListener('pageNumberUpdated', (pageNumber: number) => { this.documentViewer.addEventListener('pageNumberUpdated', (pageNumber: number) => {
this.pdf.deselectAllAnnotations(); this.pdfViewer.deselectAllAnnotations();
this._ngZone.run(() => this.pageChanged.emit(pageNumber)); this._ngZone.run(() => this.pageChanged.emit(pageNumber));
return this._handleCustomActions(); return this._handleCustomActions();
}); });
@ -275,7 +259,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.instance.UI.enableElements(['textPopup']); this.instance.UI.enableElements(['textPopup']);
} }
if (selectedText.length > 2 && this.canPerformActions && !this.pdf.isCurrentPageExcluded(file)) { if (selectedText.length > 2 && this.canPerformActions && !this.pdfViewer.isCurrentPageExcluded(file)) {
this.instance.UI.enableElements(textActions); this.instance.UI.enableElements(textActions);
} else { } else {
this.instance.UI.disableElements(textActions); this.instance.UI.disableElements(textActions);
@ -343,20 +327,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
'annotationGroupButton', 'annotationGroupButton',
]); ]);
const closeCompareFn = async () => { this._headerConfigService.initialize(this.compareFileInput);
await this._closeCompareMode();
};
const addRotation = (type: RotationType) => {
this._pageRotationService.addRotation(type);
};
const applyRotation = async () => {
await this._pageRotationService.applyRotation();
};
const discardRotation = () => {
this._pageRotationService.discardRotation();
};
this._headerConfigService.initialize(this.compareFileInput, closeCompareFn, addRotation, applyRotation, discardRotation);
const dossierTemplateId = this.dossier.dossierTemplateId; const dossierTemplateId = this.dossier.dossierTemplateId;
@ -435,13 +406,13 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation)]; const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation)];
const manualRedaction = this._getManualRedaction({ [activePage]: quads }); const manualRedaction = this._getManualRedaction({ [activePage]: quads });
this._cleanUpSelectionAndButtonState(); this._cleanUpSelectionAndButtonState();
this.pdf.deleteAnnotations([activeAnnotation.Id]); this.pdfViewer.deleteAnnotations([activeAnnotation.Id]);
this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(quads, manualRedaction, 'REDACTION', activeAnnotation.Id)); this.manualAnnotationRequested.emit(new ManualRedactionEntryWrapper(quads, manualRedaction, 'REDACTION', activeAnnotation.Id));
} }
private _cleanUpSelectionAndButtonState() { private _cleanUpSelectionAndButtonState() {
this.pdf.deselectAllAnnotations(); this.pdfViewer.deselectAllAnnotations();
this._headerConfigService.disable([HeaderElements.SHAPE_TOOL_GROUP_BUTTON]); this._headerConfigService.disable([HeaderElements.SHAPE_TOOL_GROUP_BUTTON]);
this._headerConfigService.enable([HeaderElements.SHAPE_TOOL_GROUP_BUTTON]); this._headerConfigService.enable([HeaderElements.SHAPE_TOOL_GROUP_BUTTON]);
} }
@ -518,7 +489,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
HeaderElements.ROTATE_RIGHT_BUTTON, HeaderElements.ROTATE_RIGHT_BUTTON,
]; ];
const isCurrentPageExcluded = this.pdf.isCurrentPageExcluded(await this.stateService.file); const isCurrentPageExcluded = this.pdfViewer.isCurrentPageExcluded(await this.stateService.file);
if (this.canPerformActions && !isCurrentPageExcluded) { if (this.canPerformActions && !isCurrentPageExcluded) {
try { try {
@ -566,7 +537,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
for (const quad of quads[key]) { for (const quad of quads[key]) {
const page = parseInt(key, 10); const page = parseInt(key, 10);
const pageHeight = this.documentViewer.getPageHeight(page); const pageHeight = this.documentViewer.getPageHeight(page);
entry.positions.push(toPosition(page, pageHeight, convertQuads ? this.pdf.translateQuad(page, quad) : quad)); entry.positions.push(toPosition(page, pageHeight, convertQuads ? this.pdfViewer.translateQuad(page, quad) : quad));
} }
} }
@ -582,7 +553,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private _setReadyAndInitialState() { private _setReadyAndInitialState() {
this._ngZone.run(() => { this._ngZone.run(() => {
this.pdf.emitDocumentLoaded(); this.pdfViewer.emitDocumentLoaded();
const routePageNumber: number = this._activatedRoute.snapshot.queryParams.page; const routePageNumber: number = this._activatedRoute.snapshot.queryParams.page;
this.pageChanged.emit(routePageNumber || 1); this.pageChanged.emit(routePageNumber || 1);
this._setInitialDisplayMode(); this._setInitialDisplayMode();

View File

@ -153,13 +153,13 @@ export class PdfViewer {
this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber); this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber);
} }
previousPage() { navigatePreviousPage() {
if (this._currentInternalPage > 1) { if (this._currentInternalPage > 1) {
this._navigateToPage(Math.max(this._currentInternalPage - this.paginationOffset, 1)); this._navigateToPage(Math.max(this._currentInternalPage - this.paginationOffset, 1));
} }
} }
nextPage() { navigateNextPage() {
if (this._currentInternalPage < this._totalInternalPages) { if (this._currentInternalPage < this._totalInternalPages) {
this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, this._totalInternalPages)); this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, this._totalInternalPages));
} }

View File

@ -1,10 +1,14 @@
import { ElementRef, Inject, Injectable } from '@angular/core'; import { ElementRef, Inject, Injectable, Injector } from '@angular/core';
import { IHeaderElement, RotationType, RotationTypes } from '@red/domain'; import { IHeaderElement, RotationTypes } from '@red/domain';
import { HeaderElements, HeaderElementType } from '../shared/constants'; import { HeaderElements, HeaderElementType } from '../shared/constants';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BASE_HREF } from '../../../tokens'; import { BASE_HREF } from '../../../tokens';
import { PdfViewer } from './pdf-viewer.service'; import { PdfViewer } from './pdf-viewer.service';
import { TooltipsService } from './tooltips.service'; import { TooltipsService } from './tooltips.service';
import { environment } from '@environments/environment';
import { ViewModeService } from './view-mode.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { PageRotationService } from './page-rotation.service';
@Injectable() @Injectable()
export class ViewerHeaderConfigService { export class ViewerHeaderConfigService {
@ -22,12 +26,16 @@ export class ViewerHeaderConfigService {
[HeaderElements.APPLY_ROTATION, false], [HeaderElements.APPLY_ROTATION, false],
[HeaderElements.DISCARD_ROTATION, false], [HeaderElements.DISCARD_ROTATION, false],
]); ]);
private _rotationService: PageRotationService;
constructor( constructor(
@Inject(BASE_HREF) private readonly _baseHref: string, @Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _injector: Injector,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
private readonly _pdfViewer: PdfViewer, private readonly _pdfViewer: PdfViewer,
private readonly _tooltipsService: TooltipsService, private readonly _tooltipsService: TooltipsService,
private readonly _viewModeService: ViewModeService,
private readonly _stateService: FilePreviewStateService,
) {} ) {}
private get _rectangle(): IHeaderElement { private get _rectangle(): IHeaderElement {
@ -53,41 +61,30 @@ export class ViewerHeaderConfigService {
}; };
} }
initialize( private get _closeCompare(): IHeaderElement {
compareFileInput: ElementRef, return {
closeCompareMode: () => Promise<void>, type: 'actionButton',
addRotation: (type: RotationType) => void, element: HeaderElements.CLOSE_COMPARE_BUTTON,
applyRotation: () => Promise<void>, dataElement: HeaderElements.CLOSE_COMPARE_BUTTON,
discardRotation: () => void, img: this._convertPath('/assets/icons/general/pdftron-action-close-compare.svg'),
): void { title: 'Leave Compare Mode',
if (this._buttons) { onClick: async () => {
console.error('ERROR: ViewerHeaderConfigService can only be initialized once!'); await this._closeCompareMode();
return; },
} };
this._buttons = new Map([
[HeaderElements.SHAPE_TOOL_GROUP_BUTTON, this._rectangle],
[HeaderElements.ROTATE_LEFT_BUTTON, this._rotateLeft(addRotation)],
[HeaderElements.ROTATE_RIGHT_BUTTON, this._rotateRight(addRotation)],
[HeaderElements.APPLY_ROTATION, this._applyRotation(applyRotation)],
[HeaderElements.DISCARD_ROTATION, this._discardRotation(discardRotation)],
[HeaderElements.TOGGLE_TOOLTIPS, this._toggleTooltips],
[HeaderElements.COMPARE_BUTTON, this._compare(compareFileInput)],
[HeaderElements.CLOSE_COMPARE_BUTTON, this._closeCompare(closeCompareMode)],
]);
this._updateElements();
} }
enable(elements: HeaderElementType[]): void { private get _rotateLeft(): IHeaderElement {
this._updateState(elements, true); return {
type: 'actionButton',
element: HeaderElements.ROTATE_LEFT_BUTTON,
dataElement: HeaderElements.ROTATE_LEFT_BUTTON,
img: this._convertPath('/assets/icons/general/rotate-left.svg'),
onClick: () => this._rotationService.addRotation(RotationTypes.LEFT),
};
} }
disable(elements: HeaderElementType[]): void { private get _applyRotation(): IHeaderElement {
this._updateState(elements, false);
}
private _applyRotation(applyRotation: () => Promise<void>): IHeaderElement {
return { return {
type: 'customElement', type: 'customElement',
dataElement: HeaderElements.APPLY_ROTATION, dataElement: HeaderElements.APPLY_ROTATION,
@ -102,14 +99,14 @@ export class ViewerHeaderConfigService {
margin: 0 12px; margin: 0 12px;
`; `;
paragraph.addEventListener('click', async () => { paragraph.addEventListener('click', async () => {
await applyRotation(); await this._rotationService.applyRotation();
}); });
return paragraph; return paragraph;
}, },
}; };
} }
private _discardRotation(discardRotation: () => void): IHeaderElement { private get _discardRotation(): IHeaderElement {
return { return {
type: 'customElement', type: 'customElement',
dataElement: HeaderElements.DISCARD_ROTATION, dataElement: HeaderElements.DISCARD_ROTATION,
@ -123,43 +120,61 @@ export class ViewerHeaderConfigService {
cursor: pointer; cursor: pointer;
opacity: 0.7; opacity: 0.7;
`; `;
paragraph.addEventListener('click', () => discardRotation()); paragraph.addEventListener('click', () => this._rotationService.discardRotation());
return paragraph; return paragraph;
}, },
}; };
} }
private _rotateLeft(addRotation: (type: RotationType) => void): IHeaderElement { private get _rotateRight(): IHeaderElement {
return {
type: 'actionButton',
element: HeaderElements.ROTATE_LEFT_BUTTON,
dataElement: HeaderElements.ROTATE_LEFT_BUTTON,
img: this._convertPath('/assets/icons/general/rotate-left.svg'),
onClick: () => addRotation(RotationTypes.LEFT),
};
}
private _rotateRight(addRotation: (type: RotationType) => void): IHeaderElement {
return { return {
type: 'actionButton', type: 'actionButton',
element: HeaderElements.ROTATE_RIGHT_BUTTON, element: HeaderElements.ROTATE_RIGHT_BUTTON,
dataElement: HeaderElements.ROTATE_RIGHT_BUTTON, dataElement: HeaderElements.ROTATE_RIGHT_BUTTON,
img: this._convertPath('/assets/icons/general/rotate-right.svg'), img: this._convertPath('/assets/icons/general/rotate-right.svg'),
onClick: () => addRotation(RotationTypes.RIGHT), onClick: () => this._rotationService.addRotation(RotationTypes.RIGHT),
}; };
} }
private _closeCompare(closeCompareMode: () => Promise<void>): IHeaderElement { initialize(compareFileInput: ElementRef): void {
return { this._rotationService = this._injector.get<PageRotationService>(PageRotationService);
type: 'actionButton',
element: HeaderElements.CLOSE_COMPARE_BUTTON, this._buttons = new Map([
dataElement: HeaderElements.CLOSE_COMPARE_BUTTON, [HeaderElements.SHAPE_TOOL_GROUP_BUTTON, this._rectangle],
img: this._convertPath('/assets/icons/general/pdftron-action-close-compare.svg'), [HeaderElements.ROTATE_LEFT_BUTTON, this._rotateLeft],
title: 'Leave Compare Mode', [HeaderElements.ROTATE_RIGHT_BUTTON, this._rotateRight],
onClick: async () => { [HeaderElements.APPLY_ROTATION, this._applyRotation],
await closeCompareMode(); [HeaderElements.DISCARD_ROTATION, this._discardRotation],
}, [HeaderElements.TOGGLE_TOOLTIPS, this._toggleTooltips],
}; [HeaderElements.COMPARE_BUTTON, this._compare(compareFileInput)],
[HeaderElements.CLOSE_COMPARE_BUTTON, this._closeCompare],
]);
this._updateElements();
}
enable(elements: HeaderElementType[]): void {
this._updateState(elements, true);
}
disable(elements: HeaderElementType[]): void {
this._updateState(elements, false);
}
private async _closeCompareMode() {
this._viewModeService.compareMode = false;
const pdfNet = this._pdfViewer.instance.Core.PDFNet;
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
const blob = await this._stateService.blob;
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
const filename = (await this._stateService.file).filename ?? 'document.pdf';
this._pdfViewer.instance.UI.loadDocument(currentDocument, { filename });
this.disable([HeaderElements.CLOSE_COMPARE_BUTTON]);
this.enable([HeaderElements.COMPARE_BUTTON]);
this._pdfViewer.navigateToPage(1);
} }
private _compare(compareFileInput: ElementRef): IHeaderElement { private _compare(compareFileInput: ElementRef): IHeaderElement {