diff --git a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.html b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.html
index aebbbada4..969536f81 100644
--- a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.html
+++ b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.html
@@ -9,8 +9,8 @@
/
- {{ pdfViewer.totalPages }}
+ {{ reusablePdf.totalPages$ | async }}
diff --git a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts
index 469f46303..548f44168 100644
--- a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts
+++ b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts
@@ -30,7 +30,6 @@ import { AutoUnsubscribe, ConfirmationDialogInput, ErrorService, LoadingService,
import { PdfViewer } from '../../services/pdf-viewer.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { toPosition } from '../../utils/pdf-calculation.utils';
-import { ViewModeService } from '../../services/view-mode.service';
import { MultiSelectService } from '../../services/multi-select.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
@@ -84,7 +83,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private readonly _annotationManager: REDAnnotationManager,
readonly reusablePdf: ReusablePdfViewer,
readonly stateService: FilePreviewStateService,
- readonly viewModeService: ViewModeService,
readonly multiSelectService: MultiSelectService,
readonly pdfViewer: PdfViewer,
) {
@@ -143,7 +141,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.instance,
file,
() => {
- this.viewModeService.compareMode = true;
+ this.reusablePdf.openCompareMode();
},
() => {
this.pdfViewer.navigateToPage(1);
@@ -256,7 +254,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
const file = this.stateService.file;
- if (this.viewModeService.isCompare && pageNumber % 2 === 0) {
+ if (this.reusablePdf.isCompare && pageNumber % 2 === 0) {
this.instance.UI.disableElements(['textPopup']);
} else {
this.instance.UI.enableElements(['textPopup']);
@@ -285,7 +283,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private _setInitialDisplayMode() {
this.instance.UI.setFitMode('FitPage');
const instanceDisplayMode = this.documentViewer.getDisplayModeManager().getDisplayMode();
- instanceDisplayMode.mode = this.viewModeService.isCompare ? 'Facing' : 'Single';
+ instanceDisplayMode.mode = this.reusablePdf.isCompare ? 'Facing' : 'Single';
this.documentViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
}
@@ -362,7 +360,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
}
private _configureRectangleAnnotationPopup(annotation: Annotation) {
- if (!this.viewModeService.isCompare || annotation.getPageNumber() % 2 === 1) {
+ if (!this.reusablePdf.isCompare || annotation.getPageNumber() % 2 === 1) {
this.instance.UI.annotationPopup.add([
{
type: 'actionButton',
diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
index 085f8a864..9f136d435 100644
--- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
+++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts
@@ -129,7 +129,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private get _canPerformAnnotationActions$() {
const viewMode$ = this._viewModeService.viewMode$.pipe(tap(() => this.#deactivateMultiSelect()));
- return combineLatest([this.state.file$, this.state.dossier$, viewMode$, this._viewModeService.compareMode$]).pipe(
+ return combineLatest([this.state.file$, this.state.dossier$, viewMode$, this.reusablePdf.compareMode$]).pipe(
map(
([file, dossier, viewMode]) =>
this.permissionsService.canPerformAnnotationActions(file, dossier) && viewMode === 'STANDARD',
@@ -204,7 +204,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
return this._navigateToDossier();
}
- this._viewModeService.compareMode = false;
this._viewModeService.switchToStandard();
this.state.reloadBlob();
diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-draw.service.ts
index e0605da03..707fd286e 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/annotation-draw.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-draw.service.ts
@@ -12,7 +12,6 @@ import { firstValueFrom } from 'rxjs';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { PdfViewer } from './pdf-viewer.service';
import { FilePreviewStateService } from './file-preview-state.service';
-import { ViewModeService } from './view-mode.service';
import { FileDataService } from './file-data.service';
import { SuperTypes } from '@models/file/super-types';
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
@@ -32,7 +31,6 @@ export class AnnotationDrawService {
private readonly _pdf: PdfViewer,
private readonly _reusablePdf: ReusablePdfViewer,
private readonly _state: FilePreviewStateService,
- private readonly _viewModeService: ViewModeService,
private readonly _fileDataService: FileDataService,
) {}
@@ -135,7 +133,7 @@ export class AnnotationDrawService {
}
private _computeAnnotation(annotationWrapper: AnnotationWrapper) {
- const pageNumber = this._viewModeService.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
+ const pageNumber = this._reusablePdf.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
if (pageNumber > this._reusablePdf.pageCount) {
// skip imported annotations from files that have more pages than the current one
return;
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 55f710ce1..375684de0 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
@@ -1,7 +1,6 @@
import { translateQuads } from '../../../utils';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Core } from '@pdftron/webviewer';
-import { ViewModeService } from './view-mode.service';
import { File } from '@red/domain';
import { Injectable } from '@angular/core';
import { ListingService } from '@iqser/common-ui';
@@ -12,7 +11,6 @@ import { REDAnnotationManager } from '../../shared/components/reusable-pdf-viewe
@Injectable()
export class PdfViewer {
constructor(
- private readonly _viewModeService: ViewModeService,
private readonly _multiSelectService: MultiSelectService,
private readonly _reusablePdf: ReusablePdfViewer,
private readonly _annotationManager: REDAnnotationManager,
@@ -20,16 +18,11 @@ export class PdfViewer {
) {}
get paginationOffset() {
- return this._viewModeService.isCompare ? 2 : 1;
+ return this._reusablePdf.isCompare ? 2 : 1;
}
get currentPage() {
- return this._viewModeService.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
- }
-
- get totalPages() {
- const pageCount = this._reusablePdf.pageCount;
- return this._viewModeService.isCompare ? Math.ceil(pageCount / 2) : pageCount;
+ return this._reusablePdf.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
}
private get _currentInternalPage() {
diff --git a/apps/red-ui/src/app/modules/file-preview/services/view-mode.service.ts b/apps/red-ui/src/app/modules/file-preview/services/view-mode.service.ts
index 08c21b77d..9a9e50ba0 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/view-mode.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/view-mode.service.ts
@@ -7,17 +7,14 @@ import { shareDistinctLast } from '@iqser/common-ui';
@Injectable()
export class ViewModeService {
readonly viewMode$: Observable;
- readonly compareMode$: Observable;
readonly isRedacted$: Observable;
readonly isStandard$: Observable;
readonly isDelta$: Observable;
- private readonly _viewMode$ = new BehaviorSubject('STANDARD');
- private readonly _compareMode$ = new BehaviorSubject(false);
+ readonly #viewMode$ = new BehaviorSubject('STANDARD');
constructor() {
- this.viewMode$ = this._viewMode$.asObservable();
- this.compareMode$ = this._compareMode$.asObservable();
+ this.viewMode$ = this.#viewMode$.asObservable();
this.isRedacted$ = this._is('REDACTED');
this.isStandard$ = this._is('STANDARD');
this.isDelta$ = this._is('DELTA');
@@ -28,35 +25,27 @@ export class ViewModeService {
}
get viewMode() {
- return this._viewMode$.value;
+ return this.#viewMode$.value;
}
set viewMode(mode: ViewMode) {
- this._viewMode$.next(mode);
+ this.#viewMode$.next(mode);
}
get isStandard() {
- return this._viewMode$.value === 'STANDARD';
+ return this.#viewMode$.value === 'STANDARD';
}
get isDelta() {
- return this._viewMode$.value === 'DELTA';
+ return this.#viewMode$.value === 'DELTA';
}
get isRedacted() {
- return this._viewMode$.value === 'REDACTED';
+ return this.#viewMode$.value === 'REDACTED';
}
get isTextHighlights() {
- return this._viewMode$.value === 'TEXT_HIGHLIGHTS';
- }
-
- get isCompare() {
- return this._compareMode$.value;
- }
-
- set compareMode(compareMode: boolean) {
- this._compareMode$.next(compareMode);
+ return this.#viewMode$.value === 'TEXT_HIGHLIGHTS';
}
switchToStandard() {
@@ -76,7 +65,7 @@ export class ViewModeService {
}
private _switchTo(mode: ViewMode) {
- this._viewMode$.next(mode);
+ this.#viewMode$.next(mode);
}
private _is(mode: ViewMode) {
diff --git a/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts b/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts
index 1dd454726..cfb55dce0 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/viewer-header-config.service.ts
@@ -6,7 +6,6 @@ import { BASE_HREF } from '../../../tokens';
import { PdfViewer } from './pdf-viewer.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';
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
@@ -36,7 +35,6 @@ export class ViewerHeaderConfigService {
private readonly _pdfViewer: PdfViewer,
private readonly _reusablePdf: ReusablePdfViewer,
private readonly _tooltipsService: TooltipsService,
- private readonly _viewModeService: ViewModeService,
private readonly _stateService: FilePreviewStateService,
) {}
@@ -164,7 +162,7 @@ export class ViewerHeaderConfigService {
}
private async _closeCompareMode() {
- this._viewModeService.compareMode = false;
+ this._reusablePdf.closeCompareMode();
const pdfNet = this._reusablePdf.PDFNet;
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
const blob = await this._stateService.blob;
diff --git a/apps/red-ui/src/app/modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service.ts b/apps/red-ui/src/app/modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service.ts
index 66550448d..a7d15f4f6 100644
--- a/apps/red-ui/src/app/modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service.ts
+++ b/apps/red-ui/src/app/modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service.ts
@@ -3,19 +3,19 @@ import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/w
import { environment } from '@environments/environment';
import { BASE_HREF_FN, BaseHrefFn } from '../../../../tokens';
import { File } from '@red/domain';
-import { ErrorService, shareDistinctLast, shareLast } from '@iqser/common-ui';
+import { ErrorService, log, shareDistinctLast, shareLast } from '@iqser/common-ui';
import { ActivatedRoute } from '@angular/router';
import { debounceTime, map, tap } from 'rxjs/operators';
-import { fromEvent, merge, Observable, Subject } from 'rxjs';
+import { BehaviorSubject, combineLatest, fromEvent, merge, Observable } from 'rxjs';
import { ConfigService } from '@services/config.service';
import { NGXLogger } from 'ngx-logger';
import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, USELESS_ELEMENTS } from './constants';
import { Rgb } from '@shared/components/reusable-pdf-viewer/types';
-import DocumentViewer = Core.DocumentViewer;
import AnnotationManager = Core.AnnotationManager;
import TextTool = Core.Tools.TextTool;
import Annotation = Core.Annotations.Annotation;
import TextHighlightAnnotation = Core.Annotations.TextHighlightAnnotation;
+import DocumentViewer = Core.DocumentViewer;
@Injectable({
providedIn: 'root',
@@ -30,9 +30,11 @@ export class ReusablePdfViewer {
documentLoaded$: Observable;
pageComplete$: Observable;
+ compareMode$: Observable;
+ totalPages$: Observable;
#instance: WebViewerInstance;
- #documentClosed$ = new Subject();
+ readonly #compareMode$ = new BehaviorSubject(false);
constructor(
@Inject(BASE_HREF_FN) private readonly _convertPath: BaseHrefFn,
@@ -58,6 +60,10 @@ export class ReusablePdfViewer {
return this.#instance.Core.PDFNet;
}
+ get isCompare() {
+ return this.#compareMode$.value;
+ }
+
get pageCount() {
try {
return this.#instance.Core.documentViewer.getPageCount();
@@ -67,17 +73,30 @@ export class ReusablePdfViewer {
}
}
+ get #totalPages$() {
+ const layoutChanged$ = fromEvent(this.documentViewer, 'layoutChanged');
+ const pageCount$ = layoutChanged$.pipe(map(() => this.pageCount));
+ const docChanged$ = combineLatest([pageCount$, this.compareMode$]).pipe(log('total pages'));
+ return docChanged$.pipe(map(([pageCount, isCompare]) => (isCompare ? Math.ceil(pageCount / 2) : pageCount)));
+ }
+
get #pageComplete$() {
return fromEvent(this.documentViewer, 'pageComplete').pipe(debounceTime(300));
}
get #documentLoaded$() {
- const event$ = fromEvent(this.documentViewer, this.#instance.UI.Events.DOCUMENT_LOADED);
+ const event$ = fromEvent(this.documentViewer, 'documentLoaded');
const toBool$ = event$.pipe(map(() => true));
const updateCurrentPage$ = toBool$.pipe(tap(() => this.#setCurrentPage()));
- const log = tap(() => this._logger.info('[PDF] Document loaded'));
- return updateCurrentPage$.pipe(log);
+ return updateCurrentPage$.pipe(tap(() => this._logger.info('[PDF] Document loaded')));
+ }
+
+ get #documentUnloaded$() {
+ const event$ = fromEvent(this.documentViewer, 'documentUnloaded');
+ const toBool$ = event$.pipe(map(() => false));
+
+ return toBool$.pipe(tap(() => this._logger.info('[PDF] Document unloaded')));
}
async init(htmlElement: HTMLElement) {
@@ -87,8 +106,10 @@ export class ReusablePdfViewer {
this.documentViewer = this.#instance.Core.documentViewer;
this.annotationManager = this.#instance.Core.annotationManager;
- this.documentLoaded$ = merge(this.#documentClosed$, this.#documentLoaded$).pipe(shareLast());
- this.pageComplete$ = this.#pageComplete$;
+ this.documentLoaded$ = merge(this.#documentUnloaded$, this.#documentLoaded$).pipe(shareLast());
+ this.compareMode$ = this.#compareMode$.asObservable();
+ this.pageComplete$ = this.#pageComplete$.pipe(shareLast());
+ this.totalPages$ = this.#totalPages$.pipe(shareLast());
this.#setSelectionMode();
this.#configureElements();
this.#disableHotkeys();
@@ -107,10 +128,18 @@ export class ReusablePdfViewer {
closeDocument() {
this._logger.info('[PDF] Closing document');
- this.#documentClosed$.next(false);
+ this.closeCompareMode();
this.documentViewer.closeDocument();
}
+ openCompareMode() {
+ this.#compareMode$.next(true);
+ }
+
+ closeCompareMode() {
+ this.#compareMode$.next(false);
+ }
+
async lockDocument() {
const document = await this.PDFDoc;
if (!document) {