From a80f54cdbbba3299a98bff6d39437f42b48e09c5 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Fri, 4 Mar 2022 20:16:27 +0200 Subject: [PATCH] make page rotate --- .../page-indicator.component.html | 9 +++--- .../page-indicator.component.scss | 15 ++------- .../page-indicator.component.ts | 24 ++++++++++---- .../pdf-viewer/pdf-viewer.component.ts | 22 ++++++------- .../services/file-preview-state.service.ts | 11 ++++--- .../services/page-rotation.service.ts | 31 ++++++++++++------- libs/red-cache/src/lib/caches/cache-utils.ts | 4 +++ 7 files changed, 67 insertions(+), 49 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.html index 0881cf43d..b323ebfd2 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.html @@ -7,11 +7,12 @@ class="page-wrapper" > -
- {{ number }} -
+ +
{{ number }}
+
-
+ +
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.scss b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.scss index 190cce31c..a6cc77d4e 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.scss @@ -57,22 +57,13 @@ top: 8px; display: flex; justify-content: center; - background-color: var(--iqser-white); - color: var(--iqser-accent); + background-color: var(--iqser-primary); + color: var(--iqser-white); mat-icon { width: 12px; height: 10px; - opacity: 50%; - } - - &.not-applied { - background-color: var(--iqser-primary); - color: var(--iqser-white); - - mat-icon { - opacity: 100%; - } + opacity: 100%; } } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.ts index 60ac5e23c..65c30d7e0 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/page-indicator/page-indicator.component.ts @@ -1,11 +1,21 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, +} from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { ConfigService } from '@services/config.service'; import { ViewedPagesService } from '@services/entity-services/viewed-pages.service'; import { IViewedPage } from '@red/domain'; import { AutoUnsubscribe } from '@iqser/common-ui'; import { FilePreviewStateService } from '../../services/file-preview-state.service'; -import { BehaviorSubject, firstValueFrom } from 'rxjs'; +import { firstValueFrom, Observable } from 'rxjs'; import { PageRotationService } from '../../services/page-rotation.service'; @Component({ @@ -14,7 +24,7 @@ import { PageRotationService } from '../../services/page-rotation.service'; styleUrls: ['./page-indicator.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy, OnChanges { +export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy, OnChanges, OnInit { @Input() active = false; @Input() showDottedIcon = false; @Input() number: number; @@ -25,9 +35,7 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy pageReadTimeout: number = null; read = false; - - rotation$ = new BehaviorSubject(true); - notAppliedRotation$ = new BehaviorSubject(true); + isRotated$: Observable; constructor( private readonly _viewedPagesService: ViewedPagesService, @@ -52,6 +60,10 @@ export class PageIndicatorComponent extends AutoUnsubscribe implements OnDestroy return this._stateService.fileId; } + ngOnInit() { + this.isRotated$ = this._pageRotationService.isRotated(this.number); + } + ngOnChanges() { this._setReadState(); return this.handlePageRead(); diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/pdf-viewer/pdf-viewer.component.ts index 6ec2139d2..ba4ee0ed4 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/pdf-viewer/pdf-viewer.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/pdf-viewer/pdf-viewer.component.ts @@ -27,7 +27,7 @@ import { AnnotationActionsService } from '../../services/annotation-actions.serv import { UserPreferenceService } from '@services/user-preference.service'; import { BASE_HREF } from '../../../../../../tokens'; import { ConfigService } from '@services/config.service'; -import { AutoUnsubscribe, ConfirmationDialogInput, LoadingService } from '@iqser/common-ui'; +import { AutoUnsubscribe, ConfirmationDialogInput, LoadingService, log } from '@iqser/common-ui'; import { DossiersDialogService } from '../../../../services/dossiers-dialog.service'; import { loadCompareDocumentWrapper } from '../../../../utils/compare-mode.utils'; import { PdfViewerUtils } from '../../../../utils/pdf-viewer.utils'; @@ -393,7 +393,10 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha cursor: pointer; margin: 0 12px; `; - paragraph.addEventListener('click', () => this._pageRotationService.applyRotation()); + paragraph.addEventListener('click', () => { + this._pageRotationService.applyRotation(); + this._showRotationConfirmationButtons(); + }); return paragraph; }, }; @@ -411,7 +414,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha opacity: 0.7; `; paragraph.addEventListener('click', () => { - this._pageRotationService.rotations.clear(); + this._pageRotationService.clearRotations(); this._showRotationConfirmationButtons(); }); return paragraph; @@ -452,6 +455,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha img: this._convertPath('/assets/icons/general/rotate-left.svg'), onClick: () => { this._pageRotationService.addRotation(this.utils.currentPage, RotationTypes.LEFT); + this.documentViewer.rotateCounterClockwise(this.utils.currentPage); this._showRotationConfirmationButtons(); }, }, @@ -462,6 +466,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha img: this._convertPath('/assets/icons/general/rotate-right.svg'), onClick: () => { this._pageRotationService.addRotation(this.utils.currentPage, RotationTypes.RIGHT); + this.documentViewer.rotateClockwise(this.utils.currentPage); this._showRotationConfirmationButtons(); }, }, @@ -514,17 +519,12 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha } private _showRotationConfirmationButtons() { - const rotationValues = Array.from(this._pageRotationService.rotations.values()); - const rotationElements = [elements.APPLY_ROTATION, elements.DISCARD_ROTATION]; - if (rotationValues.length > 0 && rotationValues.find(v => v !== 0)) { - if (!this._pageRotationService.isRotated) { - this.instance.UI.enableElements(rotationElements); - this._pageRotationService.setRotation(true); - } + + if (this._pageRotationService.hasRotations()) { + this.instance.UI.enableElements(rotationElements); } else { this.instance.UI.disableElements(rotationElements); - this._pageRotationService.setRotation(false); } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts index 961597d46..5c43e1fc6 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/file-preview-state.service.ts @@ -1,15 +1,16 @@ import { Injectable } from '@angular/core'; -import { BehaviorSubject, firstValueFrom, Observable, pairwise, switchMap } from 'rxjs'; +import { BehaviorSubject, firstValueFrom, from, Observable, pairwise, switchMap } from 'rxjs'; import { FileDataModel } from '@models/file/file-data.model'; import { Dossier, File } from '@red/domain'; import { DossiersService } from '@services/entity-services/dossiers.service'; import { ActivatedRoute } from '@angular/router'; import { FilesMapService } from '@services/entity-services/files-map.service'; import { PermissionsService } from '../../../../../services/permissions.service'; -import { boolFactory, shareLast } from '@iqser/common-ui'; +import { boolFactory } from '@iqser/common-ui'; import { filter, startWith } from 'rxjs/operators'; import { FileManagementService } from '@services/entity-services/file-management.service'; import { DOSSIER_ID, FILE_ID } from '@utils/constants'; +import { wipeFilesCache } from '../../../../../../../../../libs/red-cache/src'; @Injectable() export class FilePreviewStateService { @@ -71,11 +72,11 @@ export class FilePreviewStateService { pairwise(), filter(([oldFile, newFile]) => oldFile?.cacheIdentifier !== newFile.cacheIdentifier), switchMap(([, newFile]) => this.#downloadOriginalFile(newFile.cacheIdentifier)), - shareLast(), ); } - #downloadOriginalFile(cacheIdentifier: string): Observable { - return this._fileManagementService.downloadOriginalFile(this.dossierId, this.fileId, 'body', cacheIdentifier); + #downloadOriginalFile(cacheIdentifier?: string): Observable { + const downloadFile = this._fileManagementService.downloadOriginalFile(this.dossierId, this.fileId, 'body', cacheIdentifier); + return from(wipeFilesCache()).pipe(switchMap(() => downloadFile)); } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/page-rotation.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/page-rotation.service.ts index 77d44ad56..57c745236 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/page-rotation.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/page-rotation.service.ts @@ -4,11 +4,12 @@ import { PermissionsService } from '@services/permissions.service'; import { RotationType } from '@red/domain'; import { FileManagementService } from '@services/entity-services/file-management.service'; import { FilePreviewStateService } from './file-preview-state.service'; +import { distinctUntilChanged, map } from 'rxjs/operators'; +import { log } from '@iqser/common-ui'; @Injectable() export class PageRotationService { - readonly rotations = new Map(); - private readonly _isRotated$ = new BehaviorSubject(false); + readonly rotations$ = new BehaviorSubject>({}); constructor( private readonly _permissionsService: PermissionsService, @@ -16,30 +17,38 @@ export class PageRotationService { private readonly _screenState: FilePreviewStateService, ) {} - get isRotated(): boolean { - return this._isRotated$.value; - } - get canRotate() { return this._screenState.file.then(file => this._permissionsService.isFileAssignee(file)); } - setRotation(value: boolean): void { - this._isRotated$.next(value); + isRotated(page: number) { + return this.rotations$.pipe( + map(rotations => !!rotations[page]), + distinctUntilChanged(), + ); + } + + hasRotations() { + return Object.values(this.rotations$.value).filter(v => !!v).length > 0; } applyRotation() { - const pages = Object.fromEntries(this.rotations); + const pages = this.rotations$.value; const { dossierId, fileId } = this._screenState; const request = this._fileManagementService.rotatePage({ pages }, dossierId, fileId); + this.clearRotations(); return firstValueFrom(request); } addRotation(pageNumber: number, rotation: RotationType): void { - const pageRotation = this.rotations.get(pageNumber); + const pageRotation = this.rotations$.value[pageNumber]; const rotationValue = pageRotation ? (pageRotation + Number(rotation)) % 360 : rotation; - this.rotations.set(pageNumber, rotationValue); + this.rotations$.next({ ...this.rotations$.value, [pageNumber]: rotationValue }); + } + + clearRotations() { + this.rotations$.next({}); } } diff --git a/libs/red-cache/src/lib/caches/cache-utils.ts b/libs/red-cache/src/lib/caches/cache-utils.ts index 9539093c2..35422e063 100644 --- a/libs/red-cache/src/lib/caches/cache-utils.ts +++ b/libs/red-cache/src/lib/caches/cache-utils.ts @@ -31,6 +31,10 @@ export async function wipeCaches(logoutDependant: boolean = false) { } } +export function wipeFilesCache() { + return caches.delete('files'); +} + export async function wipeCacheEntry(cacheName: string, entry: string) { caches.open(cacheName).then(cache => { cache.delete(entry, { ignoreSearch: false });