From 4a671d271eeb262eae834eb2d8e76c9ddf15d22f Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 12 May 2022 19:50:34 +0300 Subject: [PATCH] RED-3991: fix jumping to next page --- .../file-workload/file-workload.component.ts | 31 +++++++++-- .../file-preview-screen.component.html | 3 +- .../file-preview-screen.component.ts | 55 +++++-------------- .../services/pdf-viewer.service.ts | 47 +++++++--------- libs/common-ui | 2 +- 5 files changed, 62 insertions(+), 76 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index d5a978496..75203612f 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -25,7 +25,7 @@ import { shareDistinctLast, shareLast, } from '@iqser/common-ui'; -import { combineLatest, firstValueFrom, Observable } from 'rxjs'; +import { combineLatest, firstValueFrom, Observable, takeWhile } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { File } from '@red/domain'; import { ExcludedPagesService } from '../../services/excluded-pages.service'; @@ -81,6 +81,16 @@ export class FileWorkloadComponent { private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _annotationProcessingService: AnnotationProcessingService, ) { + this.pdf.currentPage$.pipe(takeWhile(() => !!this)).subscribe(pageNumber => { + this._scrollViews(); + this.scrollAnnotationsToPage(pageNumber, 'always'); + }); + this.listingService.selected$.pipe(takeWhile(() => !!this)).subscribe(annotationIds => { + if (annotationIds.length > 0) { + this.pagesPanelActive = false; + } + this.scrollToSelectedAnnotation(); + }); this.displayedAnnotations$ = this._displayedAnnotations$; this.multiSelectInactive$ = this._multiSelectInactive$; this.showExcludedPages$ = this._showExcludedPages$; @@ -114,7 +124,10 @@ export class FileWorkloadComponent { } private get _isHighlights$(): Observable { - return this.viewModeService.viewMode$.pipe(map(() => this.viewModeService.isTextHighlights)); + return this.viewModeService.viewMode$.pipe( + tap(() => this._scrollViews()), + map(() => this.viewModeService.isTextHighlights), + ); } private get _multiSelectInactive$() { @@ -283,14 +296,14 @@ export class FileWorkloadComponent { // Displayed page doesn't have annotations if ($event.key === 'ArrowDown') { const nextPage = this._nextPageWithAnnotations(); - this.pdf.selectAnnotations([this.displayedAnnotations.get(nextPage)[0]]); - return; + + return this.pdf.selectAnnotations([this.displayedAnnotations.get(nextPage)[0]]); } const prevPage = this._prevPageWithAnnotations(); const prevPageAnnotations = this.displayedAnnotations.get(prevPage); - this.pdf.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]); - return; + + return this.pdf.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]); } const page = this._firstSelectedAnnotation.pageNumber; @@ -334,6 +347,12 @@ export class FileWorkloadComponent { } } + @Debounce(0) + private _scrollViews() { + this.scrollQuickNavigation(); + this.scrollAnnotations(); + } + private _disableMultiSelectAndDocumentInfo(): void { this.multiSelectService.deactivate(); this.documentInfoService.hide(); diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.html b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.html index 4f2586b60..efe6afd23 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.html +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.html @@ -65,7 +65,7 @@
this._fileDataService.loadAnnotations(file))); ready = false; + @ViewChild(FileWorkloadComponent) readonly workloadComponent: FileWorkloadComponent; private _lastPage: string; - - @ViewChild('fileWorkloadComponent') private readonly _workloadComponent: FileWorkloadComponent; @ViewChild('annotationFilterTemplate', { read: TemplateRef, static: false, @@ -234,17 +233,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } handleAnnotationSelected(annotationIds: string[]) { - if (annotationIds.length > 0) { - this._workloadComponent.pagesPanelActive = false; - } this.listingService.setSelected(annotationIds.map(id => this._fileDataService.find(id)).filter(ann => ann !== undefined)); - this._workloadComponent?.scrollToSelectedAnnotation(); this._changeDetectorRef.markForCheck(); } selectPage(pageNumber: number) { this.pdf.navigateToPage(pageNumber); - this._workloadComponent?.scrollAnnotationsToPage(pageNumber, 'always'); this._lastPage = pageNumber.toString(); } @@ -284,10 +278,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } } - handleArrowEvent($event: KeyboardEvent): void { - this._workloadComponent.handleKeyEvent($event); - } - @HostListener('window:keyup', ['$event']) handleKeyEvent($event: KeyboardEvent) { if (this._router.url.indexOf('/file/') < 0) { @@ -314,18 +304,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } } - viewerPageChanged(page: any) { - if (typeof page !== 'number') { - return; - } - - this._scrollViews(); + viewerPageChanged(page: number) { this.multiSelectService.deactivate(); return this.#updateQueryParamsPage(page); } @Debounce(100) - viewerReady() { + async viewerReady() { this.ready = true; this._setExcludedPageStyles(); @@ -336,25 +321,20 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni // Go to initial page from query params const pageNumber: string = this._lastPage || this._activatedRoute.snapshot.queryParams.page; if (pageNumber) { - setTimeout(async () => { - const file = this.state.file; - let page = parseInt(pageNumber, 10); + const file = this.state.file; + let page = parseInt(pageNumber, 10); - if (page < 1 || Number.isNaN(page)) { - page = 1; - await this.#updateQueryParamsPage(page); - } else if (page > file.numberOfPages) { - page = file.numberOfPages; - } + if (page < 1 || Number.isNaN(page)) { + page = 1; + await this.#updateQueryParamsPage(page); + } else if (page > file.numberOfPages) { + page = file.numberOfPages; + } - this.selectPage(page); - this._scrollViews(); - this._changeDetectorRef.markForCheck(); - this._loadingService.stop(); - }); - } else { - this._loadingService.stop(); + this.selectPage(page); } + + this._loadingService.stop(); this._changeDetectorRef.markForCheck(); } @@ -367,7 +347,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni async switchView(viewMode: ViewMode) { this._viewModeService.viewMode = viewMode; await this.updateViewMode(); - this._scrollViews(); } async downloadOriginalFile({ cacheIdentifier, dossierId, fileId, filename }: File) { @@ -563,12 +542,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._errorService.set(error); } - @Debounce(0) - private _scrollViews() { - this._workloadComponent?.scrollQuickNavigation(); - this._workloadComponent?.scrollAnnotations(); - } - private async _cleanupAndRedrawAnnotations(newAnnotations: readonly AnnotationWrapper[]) { const currentFilters = this._filterService.getGroup('primaryFilters')?.filters || []; this.#rebuildFilters(); diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts index efb39eb18..2f841c6e4 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts @@ -101,17 +101,6 @@ export class PdfViewer { return true; } - async unlockDocument() { - const document = await this.documentViewer.getDocument()?.getPDFDoc(); - if (!document) { - return false; - } - - await document.unlock(); - this._logger.debug('[PDF] Unlocked'); - return true; - } - hideAnnotations(annotations: Annotation[]): void { this.annotationManager.hideAnnotations(annotations); } @@ -189,14 +178,12 @@ export class PdfViewer { } selectAnnotations(annotations?: AnnotationWrapper[]) { - if (annotations) { - const annotationsToSelect = this._multiSelectService.isActive - ? [...this._listingService.selected, ...annotations] - : annotations; - this.#selectAnnotations(annotationsToSelect); - } else { - this.deselectAllAnnotations(); + if (!annotations) { + return this.deselectAllAnnotations(); } + + const annotationsToSelect = this._multiSelectService.isActive ? [...this._listingService.selected, ...annotations] : annotations; + this.#selectAnnotations(annotationsToSelect); } deleteAnnotations(annotationsIds?: readonly string[]) { @@ -221,14 +208,10 @@ export class PdfViewer { this.annotationManager.deselectAnnotations(ann); } - #selectAnnotations(annotations?: AnnotationWrapper[]) { - if (!annotations) { - return; - } + #selectAnnotations(annotations: AnnotationWrapper[] = []) { + const filteredAnnotationsIds = annotations.filter(a => !!a).map(a => a.id); - const filteredAnnotations = annotations.filter(a => !!a); - - if (!filteredAnnotations.length) { + if (!filteredAnnotationsIds.length) { return; } @@ -236,7 +219,19 @@ export class PdfViewer { this.deselectAllAnnotations(); } - const annotationsFromViewer = this.getAnnotationsById(filteredAnnotations.map(a => a.id)); + const pageNumber = annotations[0].pageNumber; + + if (pageNumber === this.currentPage) { + return this.#jumpAndSelectAnnotations(filteredAnnotationsIds); + } + + this.navigateToPage(pageNumber); + // wait for page to be loaded and to draw annotations + setTimeout(() => this.#jumpAndSelectAnnotations(filteredAnnotationsIds), 500); + } + + #jumpAndSelectAnnotations(annotationIds: readonly string[]) { + const annotationsFromViewer = this.getAnnotationsById(annotationIds); this.annotationManager.jumpToAnnotation(annotationsFromViewer[0]); this.annotationManager.selectAnnotations(annotationsFromViewer); diff --git a/libs/common-ui b/libs/common-ui index e20ed84ca..58f7b5d8b 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit e20ed84ca2c59f7235de4d7d5e22e114b99ac51a +Subproject commit 58f7b5d8b9c88ef5c1f6ff7780e3417511523ee1