diff --git a/apps/red-ui/src/app/models/file/annotation.wrapper.ts b/apps/red-ui/src/app/models/file/annotation.wrapper.ts index 8714d1fe9..a576bfbfe 100644 --- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts +++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts @@ -67,7 +67,6 @@ export class AnnotationWrapper implements IListable { isRemoved = false; isRemovedLocally = false; lastManualChange: ManualRedactionType; - oldState: EntryState; get isRuleBased() { return this.engines.includes(LogEntryEngines.RULE); @@ -287,9 +286,13 @@ export class AnnotationWrapper implements IListable { annotationWrapper.typeLabel = dictionary?.virtual ? undefined : dictionary?.label; - const colorKey = annotationEntityColorConfig[annotationWrapper.superType]; - const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType]; - annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string); + if (annotationWrapper.pending) { + annotationWrapper.color = defaultColors[annotationDefaultColorConfig.analysis] as string; + } else { + const colorKey = annotationEntityColorConfig[annotationWrapper.superType]; + const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType]; + annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string); + } annotationWrapper['entry'] = logEntry; return annotationWrapper; diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts index 5c3a677b6..1498b9ed4 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { List } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Core } from '@pdftron/webviewer'; -import { IRectangle, ISectionRectangle, SuperTypes } from '@red/domain'; +import { IRectangle, ISectionRectangle, IPoint, SuperTypes } from '@red/domain'; import { DefaultColorsService } from '@services/entity-services/default-colors.service'; import { hexToRgb } from '@utils/functions'; import { BoundingBox, Table } from '../../file-preview/services/tables.service'; @@ -11,6 +11,7 @@ import { REDDocumentViewer } from './document-viewer.service'; import { PdfViewer } from './pdf-viewer.service'; import Annotation = Core.Annotations.Annotation; import Quad = Core.Math.Quad; +import PolylineAnnotation = Core.Annotations.PolylineAnnotation; const DEFAULT_TEXT_ANNOTATION_OPACITY = 1; const DEFAULT_REMOVED_ANNOTATION_OPACITY = 0.2; @@ -128,6 +129,24 @@ export class AnnotationDrawService { return; } + if (annotationWrapper.pending) { + const polylineAnnot = this._pdf.polyline(); + polylineAnnot.ReadOnly = true; + polylineAnnot.StrokeColor = this.convertColor(annotationWrapper.color); + polylineAnnot.StrokeThickness = 4; + polylineAnnot.Id = annotationWrapper.id; + polylineAnnot.PageNumber = pageNumber; + polylineAnnot.Opacity = 0.5; + + const points = this.#computePolylinePoints(annotationWrapper.positions, annotationWrapper.pageNumber); + for (let i = 0; i < points.length; i++) { + const y = i % 2 === 1 ? points[i - 1].y : points[i].y; + polylineAnnot.addPathPoint(points[i].x, y); + } + + return polylineAnnot; + } + if (annotationWrapper.superType === SuperTypes.TextHighlight) { const rectangleAnnot = this._pdf.rectangle(); const pageHeight = this._documentViewer.getHeight(pageNumber); @@ -184,18 +203,53 @@ export class AnnotationDrawService { } #rectangleToQuad(rectangle: IRectangle, pageHeight: number): Quad { - const x1 = rectangle.topLeft.x; - const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height); - - const x2 = rectangle.topLeft.x + rectangle.width; - const y2 = pageHeight - (rectangle.topLeft.y + rectangle.height); - - const x3 = rectangle.topLeft.x + rectangle.width; - const y3 = pageHeight - rectangle.topLeft.y; - - const x4 = rectangle.topLeft.x; - const y4 = pageHeight - rectangle.topLeft.y; + const { x: x1, y: y1 } = this.#topLeft(rectangle, pageHeight); + const { x: x2, y: y2 } = this.#topRight(rectangle, pageHeight); + const { x: x3, y: y3 } = this.#bottomRight(rectangle, pageHeight); + const { x: x4, y: y4 } = this.#bottomLeft(rectangle, pageHeight); return this._pdf.quad(x1, y1, x2, y2, x3, y3, x4, y4); } + + #computePolylinePoints(positions: IRectangle[], pageNumber: number): IPoint[] { + const pageHeight = this._documentViewer.getHeight(pageNumber); + const points = [this.#topLeft(positions[0], pageHeight)]; + + for (let i = 0; i < positions.length; i++) { + points.push(this.#topRight(positions[i], pageHeight)); + points.push(this.#bottomRight(positions[i], pageHeight)); + } + + for (let i = positions.length - 1; i >= 0; i--) { + points.push(this.#bottomLeft(positions[i], pageHeight)); + points.push(this.#topLeft(positions[i], pageHeight)); + } + + points.push(this.#topRight(positions[0], pageHeight)); + return points; + } + + #topLeft(rectangle: IRectangle, pageHeight: number): IPoint { + const x = rectangle.topLeft.x; + const y = pageHeight - (rectangle.topLeft.y + rectangle.height); + return { x, y }; + } + + #topRight(rectangle: IRectangle, pageHeight: number): IPoint { + const x = rectangle.topLeft.x + rectangle.width; + const y = pageHeight - (rectangle.topLeft.y + rectangle.height); + return { x, y }; + } + + #bottomRight(rectangle: IRectangle, pageHeight: number): IPoint { + const x = rectangle.topLeft.x + rectangle.width; + const y = pageHeight - rectangle.topLeft.y; + return { x, y }; + } + + #bottomLeft(rectangle: IRectangle, pageHeight: number): IPoint { + const x = rectangle.topLeft.x; + const y = pageHeight - rectangle.topLeft.y; + return { x, y }; + } } diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts index 90da413ac..09fc4f9a7 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts @@ -243,6 +243,10 @@ export class PdfViewer { return new this.#instance.Core.Annotations.TextHighlightAnnotation(); } + polyline() { + return new this.#instance.Core.Annotations.PolylineAnnotation(); + } + isTextHighlight(annotation: Annotation): annotation is TextHighlightAnnotation { return annotation instanceof this.#instance.Core.Annotations.TextHighlightAnnotation; }