From 9dec57a7eea6b6a2049f8881e76888a52f8a162f Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 22 Jun 2022 16:29:20 +0300 Subject: [PATCH] RED-3837: fix annotations redraw --- apps/red-ui/src/app/app.module.ts | 11 +++- .../file-preview-screen.component.ts | 60 ++++++++++--------- .../services/annotation-manager.service.ts | 3 + apps/red-ui/src/app/utils/functions.ts | 4 ++ 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index f40766fdc..c1ef70792 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -65,9 +65,8 @@ function cleanupBaseUrl(baseUrl: string) { return ''; } else if (baseUrl[baseUrl.length - 1] === '/') { return baseUrl.substring(0, baseUrl.length - 1); - } else { - return baseUrl; } + return baseUrl; } const screens = [BaseScreenComponent, DownloadsListScreenComponent]; @@ -128,7 +127,13 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp enabled: false, }, PDF: { - enabled: true, + enabled: false, + }, + FILE: { + enabled: false, + }, + CHANGES: { + enabled: false, }, STATS: { enabled: false, 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 95655f218..5d9c1dee1 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 @@ -9,6 +9,7 @@ import { Debounce, ErrorService, FilterService, + List, LoadingService, NestedFilter, OnAttach, @@ -26,7 +27,7 @@ import { File, ViewMode, ViewModes } from '@red/domain'; import { PermissionsService } from '@services/permissions.service'; import { combineLatest, firstValueFrom, from, of, pairwise } from 'rxjs'; import { UserPreferenceService } from '@services/user-preference.service'; -import { byId, byPage, download, handleFilterDelta } from '../../utils'; +import { byId, byPage, download, handleFilterDelta, hasChanges } from '../../utils'; import { FilesService } from '@services/files/files.service'; import { FileManagementService } from '@services/files/file-management.service'; import { catchError, filter, map, startWith, switchMap, tap } from 'rxjs/operators'; @@ -368,11 +369,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni tap(annotations => this.deleteAnnotations(...annotations)), ); const currentPageAnnotations$ = combineLatest([this.pdf.currentPage$, annotations$]).pipe( - map(([, annotations]) => annotations), - map(([oldAnnotations, newAnnotations]) => { - const page = this.pdf.currentPage; - return [oldAnnotations.filter(byPage(page)), newAnnotations.filter(byPage(page))] as const; - }), + map( + ([page, [oldAnnotations, newAnnotations]]) => + [oldAnnotations.filter(byPage(page)), newAnnotations.filter(byPage(page))] as const, + ), ); let start; @@ -390,16 +390,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni deleteAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { const annotationsToDelete = oldAnnotations.filter(oldAnnotation => { const newAnnotation = newAnnotations.find(byId(oldAnnotation.id)); - if (!newAnnotation) { - return true; - } - return JSON.stringify(oldAnnotation) !== JSON.stringify(newAnnotation); + return newAnnotation ? hasChanges(oldAnnotation, newAnnotation) : true; }); - if (annotationsToDelete.length === 0) { - return; - } - this._logger.info('[ANNOTATIONS] To delete: ', annotationsToDelete); this._annotationManager.delete(annotationsToDelete); } @@ -407,11 +400,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni async drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { const annotationsToDraw = this.#getAnnotationsToDraw(oldAnnotations, newAnnotations); this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw); - - if (annotationsToDraw.length === 0) { - return [oldAnnotations, newAnnotations]; - } - this._annotationManager.delete(annotationsToDraw); await this._cleanupAndRedrawAnnotations(annotationsToDraw); return [oldAnnotations, newAnnotations]; @@ -427,12 +415,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } #getAnnotationsToDraw(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { - const annotations = this._annotationManager.annotations; - const ann = annotations.map(a => oldAnnotations.some(byId(a.Id))); - const hasAnnotations = ann.filter(a => !!a).length > 0; + const currentPage = this.pdf.currentPage; + const currentPageAnnotations = this._annotationManager.get(a => a.getPageNumber() === currentPage); + const existingAnnotations = currentPageAnnotations.map(a => oldAnnotations.find(byId(a.Id))).filter(a => !!a); - if (hasAnnotations) { - return this.#findAnnotationsToDraw(newAnnotations, oldAnnotations); + if (existingAnnotations.length > 0) { + return this.#findAnnotationsToDraw(newAnnotations, oldAnnotations, existingAnnotations); } return newAnnotations; } @@ -471,19 +459,30 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._changeDetectorRef.markForCheck(); } - #findAnnotationsToDraw(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) { + #findAnnotationsToDraw( + newAnnotations: AnnotationWrapper[], + oldAnnotations: AnnotationWrapper[], + existingAnnotations: AnnotationWrapper[], + ) { + function selectToDrawIfDoesNotExist(newAnnotation: AnnotationWrapper) { + return !existingAnnotations.some(byId(newAnnotation.id)); + } + return newAnnotations.filter(newAnnotation => { const oldAnnotation = oldAnnotations.find(byId(newAnnotation.id)); if (!oldAnnotation) { return true; } - const changed = JSON.stringify(oldAnnotation) !== JSON.stringify(newAnnotation); - if (changed && this.userPreferenceService.areDevFeaturesEnabled) { + if (!hasChanges(oldAnnotation, newAnnotation)) { + return selectToDrawIfDoesNotExist(newAnnotation); + } + + if (this.userPreferenceService.areDevFeaturesEnabled) { this.#logDiff(oldAnnotation, newAnnotation); } - return changed; + return true; }); } @@ -586,7 +585,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._errorService.set(error); } - private async _cleanupAndRedrawAnnotations(newAnnotations: readonly AnnotationWrapper[]) { + private async _cleanupAndRedrawAnnotations(newAnnotations: List) { + if (!newAnnotations.length) { + return; + } const currentFilters = this._filterService.getGroup('primaryFilters')?.filters || []; this.#rebuildFilters(); diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts index 2934f5f4c..7cd273b14 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts @@ -42,6 +42,9 @@ export class REDAnnotationManager { delete(annotations?: List | List | string | AnnotationWrapper) { const items = isStringOrWrapper(annotations) ? [this.get(annotations)] : this.get(annotations); + if (!items.length) { + return; + } const options: DeleteAnnotationsOptions = { force: true }; this.#manager.deleteAnnotations(items, options); } diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index e7b7f1651..918227208 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -96,3 +96,7 @@ export function getLast(list: List) { } export const dateWithoutTime = (date: Dayjs) => date.set('h', 0).set('m', 0).set('s', 0).set('ms', 0); + +export function hasChanges(left: T, right: T) { + return JSON.stringify(left) !== JSON.stringify(right); +}