RED-3988: remove old pdf viewer stuff
This commit is contained in:
parent
fe37a78488
commit
1edab7c304
@ -1,8 +1,6 @@
|
|||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|
||||||
<redaction-reusable-pdf-viewer
|
<redaction-pdf-viewer [style.visibility]="(pdf.loaded$ | async) ? 'visible' : 'hidden'"></redaction-pdf-viewer>
|
||||||
[style.visibility]="(reusablePdfViewer.documentLoaded$ | async) ? 'visible' : 'hidden'"
|
|
||||||
></redaction-reusable-pdf-viewer>
|
|
||||||
|
|
||||||
<iqser-full-page-loading-indicator></iqser-full-page-loading-indicator>
|
<iqser-full-page-loading-indicator></iqser-full-page-loading-indicator>
|
||||||
<iqser-connection-status></iqser-connection-status>
|
<iqser-connection-status></iqser-connection-status>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Component, ViewContainerRef } from '@angular/core';
|
import { Component, ViewContainerRef } from '@angular/core';
|
||||||
import { RouterHistoryService } from '@services/router-history.service';
|
import { RouterHistoryService } from '@services/router-history.service';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { ReusablePdfViewer } from './modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '@shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-root',
|
selector: 'redaction-root',
|
||||||
@ -15,6 +15,6 @@ export class AppComponent {
|
|||||||
public viewContainerRef: ViewContainerRef,
|
public viewContainerRef: ViewContainerRef,
|
||||||
private readonly _routerHistoryService: RouterHistoryService,
|
private readonly _routerHistoryService: RouterHistoryService,
|
||||||
private readonly _userService: UserService,
|
private readonly _userService: UserService,
|
||||||
readonly reusablePdfViewer: ReusablePdfViewer,
|
readonly pdf: PdfViewer,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ import { LoggerModule, NgxLoggerLevel, TOKEN_LOGGER_CONFIG, TOKEN_LOGGER_RULES_S
|
|||||||
import { LoggerRulesService } from '@services/logger-rules.service';
|
import { LoggerRulesService } from '@services/logger-rules.service';
|
||||||
import { ILoggerConfig } from '@red/domain';
|
import { ILoggerConfig } from '@red/domain';
|
||||||
import { SystemPreferencesService } from '@services/system-preferences.service';
|
import { SystemPreferencesService } from '@services/system-preferences.service';
|
||||||
import { ReusablePdfViewerComponent } from './modules/shared/components/reusable-pdf-viewer/reusable-pdf-viewer.component';
|
import { PdfViewerComponent } from '@shared/components/reusable-pdf-viewer/pdf-viewer.component';
|
||||||
|
|
||||||
export function httpLoaderFactory(httpClient: HttpClient, configService: ConfigService): PruningTranslationLoader {
|
export function httpLoaderFactory(httpClient: HttpClient, configService: ConfigService): PruningTranslationLoader {
|
||||||
return new PruningTranslationLoader(httpClient, '/assets/i18n/', `.json?version=${configService.values.FRONTEND_APP_VERSION}`);
|
return new PruningTranslationLoader(httpClient, '/assets/i18n/', `.json?version=${configService.values.FRONTEND_APP_VERSION}`);
|
||||||
@ -72,7 +72,7 @@ const screens = [BaseScreenComponent, DownloadsListScreenComponent];
|
|||||||
|
|
||||||
const components = [
|
const components = [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
ReusablePdfViewerComponent,
|
PdfViewerComponent,
|
||||||
AuthErrorComponent,
|
AuthErrorComponent,
|
||||||
NotificationsComponent,
|
NotificationsComponent,
|
||||||
SpotlightSearchComponent,
|
SpotlightSearchComponent,
|
||||||
|
|||||||
@ -10,15 +10,15 @@ import {
|
|||||||
TemplateRef,
|
TemplateRef,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { FilterService, HasScrollbarDirective, IqserEventTarget, ListingService } from '@iqser/common-ui';
|
import { FilterService, HasScrollbarDirective, IqserEventTarget } from '@iqser/common-ui';
|
||||||
import { MultiSelectService } from '../../services/multi-select.service';
|
import { MultiSelectService } from '../../services/multi-select.service';
|
||||||
import { AnnotationReferencesService } from '../../services/annotation-references.service';
|
import { AnnotationReferencesService } from '../../services/annotation-references.service';
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
import { ViewModeService } from '../../services/view-mode.service';
|
import { ViewModeService } from '../../services/view-mode.service';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { TextHighlightsGroup } from '@red/domain';
|
import { TextHighlightsGroup } from '@red/domain';
|
||||||
import { PdfViewer } from '../../services/pdf-viewer.service';
|
|
||||||
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
|
import { AnnotationsListingService } from '../../services/annotations-listing.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-annotations-list',
|
selector: 'redaction-annotations-list',
|
||||||
@ -41,9 +41,8 @@ export class AnnotationsListComponent extends HasScrollbarDirective implements O
|
|||||||
private readonly _filterService: FilterService,
|
private readonly _filterService: FilterService,
|
||||||
private readonly _userPreferenceService: UserPreferenceService,
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
private readonly _viewModeService: ViewModeService,
|
private readonly _viewModeService: ViewModeService,
|
||||||
private readonly _pdf: PdfViewer,
|
|
||||||
private readonly _annotationManager: REDAnnotationManager,
|
private readonly _annotationManager: REDAnnotationManager,
|
||||||
private readonly _listingService: ListingService<AnnotationWrapper>,
|
private readonly _listingService: AnnotationsListingService,
|
||||||
readonly annotationReferencesService: AnnotationReferencesService,
|
readonly annotationReferencesService: AnnotationReferencesService,
|
||||||
) {
|
) {
|
||||||
super(_elementRef, _changeDetector);
|
super(_elementRef, _changeDetector);
|
||||||
@ -77,7 +76,7 @@ export class AnnotationsListComponent extends HasScrollbarDirective implements O
|
|||||||
if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) {
|
if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) {
|
||||||
this._multiSelectService.activate();
|
this._multiSelectService.activate();
|
||||||
}
|
}
|
||||||
this._pdf.selectAnnotations([annotation]);
|
this._listingService.selectAnnotations([annotation]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import {
|
|||||||
IconButtonTypes,
|
IconButtonTypes,
|
||||||
INestedFilter,
|
INestedFilter,
|
||||||
IqserEventTarget,
|
IqserEventTarget,
|
||||||
ListingService,
|
|
||||||
shareDistinctLast,
|
shareDistinctLast,
|
||||||
shareLast,
|
shareLast,
|
||||||
} from '@iqser/common-ui';
|
} from '@iqser/common-ui';
|
||||||
@ -36,9 +35,9 @@ import { FilePreviewStateService } from '../../services/file-preview-state.servi
|
|||||||
import { ViewModeService } from '../../services/view-mode.service';
|
import { ViewModeService } from '../../services/view-mode.service';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { FileDataService } from '../../services/file-data.service';
|
import { FileDataService } from '../../services/file-data.service';
|
||||||
import { PdfViewer } from '../../services/pdf-viewer.service';
|
import { PdfViewer } from '../../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import { ReusablePdfViewer } from '../../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
|
||||||
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
|
import { AnnotationsListingService } from '../../services/annotations-listing.service';
|
||||||
|
|
||||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||||
@ -73,19 +72,18 @@ export class FileWorkloadComponent {
|
|||||||
readonly filterService: FilterService,
|
readonly filterService: FilterService,
|
||||||
readonly skippedService: SkippedService,
|
readonly skippedService: SkippedService,
|
||||||
readonly state: FilePreviewStateService,
|
readonly state: FilePreviewStateService,
|
||||||
readonly multiSelectService: MultiSelectService,
|
readonly pdf: PdfViewer,
|
||||||
readonly documentInfoService: DocumentInfoService,
|
|
||||||
readonly excludedPagesService: ExcludedPagesService,
|
|
||||||
readonly fileDataService: FileDataService,
|
readonly fileDataService: FileDataService,
|
||||||
readonly viewModeService: ViewModeService,
|
readonly viewModeService: ViewModeService,
|
||||||
readonly listingService: ListingService<AnnotationWrapper>,
|
readonly multiSelectService: MultiSelectService,
|
||||||
readonly pdf: PdfViewer,
|
|
||||||
readonly reusablePdf: ReusablePdfViewer,
|
|
||||||
readonly annotationManager: REDAnnotationManager,
|
readonly annotationManager: REDAnnotationManager,
|
||||||
|
readonly documentInfoService: DocumentInfoService,
|
||||||
|
readonly listingService: AnnotationsListingService,
|
||||||
|
readonly excludedPagesService: ExcludedPagesService,
|
||||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||||
private readonly _annotationProcessingService: AnnotationProcessingService,
|
private readonly _annotationProcessingService: AnnotationProcessingService,
|
||||||
) {
|
) {
|
||||||
this.reusablePdf.currentPage$.pipe(takeWhile(() => !!this)).subscribe(pageNumber => {
|
this.pdf.currentPage$.pipe(takeWhile(() => !!this)).subscribe(pageNumber => {
|
||||||
this._scrollViews();
|
this._scrollViews();
|
||||||
this.scrollAnnotationsToPage(pageNumber, 'always');
|
this.scrollAnnotationsToPage(pageNumber, 'always');
|
||||||
});
|
});
|
||||||
@ -183,7 +181,7 @@ export class FileWorkloadComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectAllOnActivePage() {
|
selectAllOnActivePage() {
|
||||||
this.pdf.selectAnnotations(this.activeAnnotations);
|
this.listingService.selectAnnotations(this.activeAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectAllOnActivePage(): void {
|
deselectAllOnActivePage(): void {
|
||||||
@ -295,19 +293,19 @@ export class FileWorkloadComponent {
|
|||||||
if (!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) {
|
if (!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) {
|
||||||
if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) {
|
if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) {
|
||||||
// Displayed page has annotations
|
// Displayed page has annotations
|
||||||
return this.pdf.selectAnnotations(this.activeAnnotations ? [this.activeAnnotations[0]] : null);
|
return this.listingService.selectAnnotations(this.activeAnnotations ? [this.activeAnnotations[0]] : null);
|
||||||
}
|
}
|
||||||
// Displayed page doesn't have annotations
|
// Displayed page doesn't have annotations
|
||||||
if ($event.key === 'ArrowDown') {
|
if ($event.key === 'ArrowDown') {
|
||||||
const nextPage = this._nextPageWithAnnotations();
|
const nextPage = this._nextPageWithAnnotations();
|
||||||
|
|
||||||
return this.pdf.selectAnnotations([this.displayedAnnotations.get(nextPage)[0]]);
|
return this.listingService.selectAnnotations([this.displayedAnnotations.get(nextPage)[0]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevPage = this._prevPageWithAnnotations();
|
const prevPage = this._prevPageWithAnnotations();
|
||||||
const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
|
const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
|
||||||
|
|
||||||
return this.pdf.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
return this.listingService.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = this._firstSelectedAnnotation.pageNumber;
|
const page = this._firstSelectedAnnotation.pageNumber;
|
||||||
@ -320,13 +318,13 @@ export class FileWorkloadComponent {
|
|||||||
if ($event.key === 'ArrowDown') {
|
if ($event.key === 'ArrowDown') {
|
||||||
if (idx + 1 !== annotationsOnPage.length) {
|
if (idx + 1 !== annotationsOnPage.length) {
|
||||||
// If not last item in page
|
// If not last item in page
|
||||||
this.pdf.selectAnnotations([annotationsOnPage[idx + 1]]);
|
this.listingService.selectAnnotations([annotationsOnPage[idx + 1]]);
|
||||||
} else if (nextPageIdx < this.displayedPages.length) {
|
} else if (nextPageIdx < this.displayedPages.length) {
|
||||||
// If not last page
|
// If not last page
|
||||||
for (let i = nextPageIdx; i < this.displayedPages.length; i++) {
|
for (let i = nextPageIdx; i < this.displayedPages.length; i++) {
|
||||||
const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
||||||
if (nextPageAnnotations) {
|
if (nextPageAnnotations) {
|
||||||
this.pdf.selectAnnotations([nextPageAnnotations[0]]);
|
this.listingService.selectAnnotations([nextPageAnnotations[0]]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,7 +334,7 @@ export class FileWorkloadComponent {
|
|||||||
|
|
||||||
if (idx !== 0) {
|
if (idx !== 0) {
|
||||||
// If not first item in page
|
// If not first item in page
|
||||||
return this.pdf.selectAnnotations([annotationsOnPage[idx - 1]]);
|
return this.listingService.selectAnnotations([annotationsOnPage[idx - 1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageIdx) {
|
if (pageIdx) {
|
||||||
@ -344,7 +342,7 @@ export class FileWorkloadComponent {
|
|||||||
for (let i = previousPageIdx; i >= 0; i--) {
|
for (let i = previousPageIdx; i >= 0; i--) {
|
||||||
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
||||||
if (prevPageAnnotations) {
|
if (prevPageAnnotations) {
|
||||||
this.pdf.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
this.listingService.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +396,7 @@ export class FileWorkloadComponent {
|
|||||||
this.displayedPages.indexOf(this.activeViewerPage) >= 0 &&
|
this.displayedPages.indexOf(this.activeViewerPage) >= 0 &&
|
||||||
this.activeAnnotations.length > 0
|
this.activeAnnotations.length > 0
|
||||||
) {
|
) {
|
||||||
this.pdf.selectAnnotations([this.activeAnnotations[0]]);
|
this.listingService.selectAnnotations([this.activeAnnotations[0]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
<input #compareFileInput (change)="uploadFile($event.target['files'])" accept="application/pdf" class="file-upload-input" type="file" />
|
<input #compareFileInput (change)="uploadFile($event.target['files'])" accept="application/pdf" class="file-upload-input" type="file" />
|
||||||
|
|
||||||
<div *ngIf="reusablePdf.documentLoaded$ | async" class="pagination noselect">
|
<div *ngIf="pdf.loaded$ | async" class="pagination noselect">
|
||||||
<div (click)="pdfViewer.navigatePreviousPage()">
|
<div (click)="pdf.navigatePreviousPage()">
|
||||||
<mat-icon class="chevron-icon" svgIcon="red:nav-prev"></mat-icon>
|
<mat-icon class="chevron-icon" svgIcon="red:nav-prev"></mat-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
#pageInput
|
#pageInput
|
||||||
(change)="pdfViewer.navigateToPage(pageInput.value)"
|
(change)="pdf.navigateTo(pageInput.value)"
|
||||||
[max]="reusablePdf.totalPages$ | async"
|
[max]="pdf.totalPages$ | async"
|
||||||
[value]="reusablePdf.currentPage$ | async"
|
[value]="pdf.currentPage$ | async"
|
||||||
class="page-number-input"
|
class="page-number-input"
|
||||||
min="1"
|
min="1"
|
||||||
type="number"
|
type="number"
|
||||||
@ -20,10 +20,10 @@
|
|||||||
<div class="separator">/</div>
|
<div class="separator">/</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{ reusablePdf.totalPages$ | async }}
|
{{ pdf.totalPages$ | async }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div (click)="pdfViewer.navigateNextPage()">
|
<div (click)="pdf.navigateNextPage()">
|
||||||
<mat-icon class="chevron-icon" svgIcon="red:nav-next"></mat-icon>
|
<mat-icon class="chevron-icon" svgIcon="red:nav-next"></mat-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +27,6 @@ import { UserPreferenceService } from '@services/user-preference.service';
|
|||||||
import { BASE_HREF } from '../../../../tokens';
|
import { BASE_HREF } from '../../../../tokens';
|
||||||
import { ConfigService } from '@services/config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { AutoUnsubscribe, ConfirmationDialogInput, ErrorService, LoadingService, log } from '@iqser/common-ui';
|
import { AutoUnsubscribe, ConfirmationDialogInput, ErrorService, LoadingService, log } from '@iqser/common-ui';
|
||||||
import { PdfViewer } from '../../services/pdf-viewer.service';
|
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { toPosition } from '../../utils/pdf-calculation.utils';
|
import { toPosition } from '../../utils/pdf-calculation.utils';
|
||||||
import { MultiSelectService } from '../../services/multi-select.service';
|
import { MultiSelectService } from '../../services/multi-select.service';
|
||||||
@ -42,16 +41,17 @@ import { FileDataService } from '../../services/file-data.service';
|
|||||||
import { ViewerHeaderConfigService } from '../../services/viewer-header-config.service';
|
import { ViewerHeaderConfigService } from '../../services/viewer-header-config.service';
|
||||||
import { TooltipsService } from '../../services/tooltips.service';
|
import { TooltipsService } from '../../services/tooltips.service';
|
||||||
import { ManualRedactionService } from '../../services/manual-redaction.service';
|
import { ManualRedactionService } from '../../services/manual-redaction.service';
|
||||||
import { ReusablePdfViewer } from '../../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '../../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
|
import { translateQuads } from '../../../../utils';
|
||||||
import Annotation = Core.Annotations.Annotation;
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-pdf-viewer',
|
selector: 'redaction-pdf-viewer',
|
||||||
templateUrl: './pdf-viewer.component.html',
|
templateUrl: './pdf-paginator.component.html',
|
||||||
styleUrls: ['./pdf-viewer.component.scss'],
|
styleUrls: ['./pdf-paginator.component.scss'],
|
||||||
})
|
})
|
||||||
export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnChanges {
|
export class PdfPaginatorComponent extends AutoUnsubscribe implements OnInit, OnChanges {
|
||||||
@Input() dossier: Dossier;
|
@Input() dossier: Dossier;
|
||||||
@Input() canPerformActions = false;
|
@Input() canPerformActions = false;
|
||||||
@Output() readonly annotationSelected = new EventEmitter<string[]>();
|
@Output() readonly annotationSelected = new EventEmitter<string[]>();
|
||||||
@ -81,10 +81,9 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
private readonly _tooltipsService: TooltipsService,
|
private readonly _tooltipsService: TooltipsService,
|
||||||
private readonly _errorService: ErrorService,
|
private readonly _errorService: ErrorService,
|
||||||
private readonly _annotationManager: REDAnnotationManager,
|
private readonly _annotationManager: REDAnnotationManager,
|
||||||
readonly reusablePdf: ReusablePdfViewer,
|
readonly pdf: PdfViewer,
|
||||||
readonly stateService: FilePreviewStateService,
|
readonly stateService: FilePreviewStateService,
|
||||||
readonly multiSelectService: MultiSelectService,
|
readonly multiSelectService: MultiSelectService,
|
||||||
readonly pdfViewer: PdfViewer,
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -96,10 +95,10 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
this.addActiveScreenSubscription = this.stateService.blob$
|
this.addActiveScreenSubscription = this.stateService.blob$
|
||||||
.pipe(
|
.pipe(
|
||||||
log('Reload blob'),
|
log('Reload blob'),
|
||||||
switchMap(blob => from(this.reusablePdf.lockDocument()).pipe(map(() => blob))),
|
switchMap(blob => from(this.pdf.lockDocument()).pipe(map(() => blob))),
|
||||||
withLatestFrom(this.stateService.file$),
|
withLatestFrom(this.stateService.file$),
|
||||||
tap(() => this._errorService.clear()),
|
tap(() => this._errorService.clear()),
|
||||||
tap(([blob, file]) => this.reusablePdf.loadDocument(blob, file)),
|
tap(([blob, file]) => this.pdf.loadDocument(blob, file)),
|
||||||
tap(() => this._pageRotationService.clearRotationsHideActions()),
|
tap(() => this._pageRotationService.clearRotationsHideActions()),
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
@ -141,10 +140,10 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
this.instance,
|
this.instance,
|
||||||
file,
|
file,
|
||||||
() => {
|
() => {
|
||||||
this.reusablePdf.openCompareMode();
|
this.pdf.openCompareMode();
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.pdfViewer.navigateToPage(1);
|
this.pdf.navigateTo(1);
|
||||||
},
|
},
|
||||||
this.instance.Core.PDFNet,
|
this.instance.Core.PDFNet,
|
||||||
);
|
);
|
||||||
@ -180,9 +179,9 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _loadViewer() {
|
private _loadViewer() {
|
||||||
this.instance = this.reusablePdf.instance;
|
this.instance = this.pdf.instance;
|
||||||
this.documentViewer = this.reusablePdf.documentViewer;
|
this.documentViewer = this.pdf.documentViewer;
|
||||||
this.annotationManager = this.reusablePdf.annotationManager;
|
this.annotationManager = this.pdf.annotationManager;
|
||||||
|
|
||||||
this._configureElements();
|
this._configureElements();
|
||||||
this._configureTextPopup();
|
this._configureTextPopup();
|
||||||
@ -254,13 +253,14 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
|
|
||||||
const file = this.stateService.file;
|
const file = this.stateService.file;
|
||||||
|
|
||||||
if (this.reusablePdf.isCompare && pageNumber % 2 === 0) {
|
if (this.pdf.isCompare && pageNumber % 2 === 0) {
|
||||||
this.instance.UI.disableElements(['textPopup']);
|
this.instance.UI.disableElements(['textPopup']);
|
||||||
} else {
|
} else {
|
||||||
this.instance.UI.enableElements(['textPopup']);
|
this.instance.UI.enableElements(['textPopup']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedText.length > 2 && this.canPerformActions && !this.pdfViewer.isCurrentPageExcluded(file)) {
|
const isCurrentPageExcluded = file.isPageExcluded(this.pdf.currentPage);
|
||||||
|
if (selectedText.length > 2 && this.canPerformActions && !isCurrentPageExcluded) {
|
||||||
this.instance.UI.enableElements(textActions);
|
this.instance.UI.enableElements(textActions);
|
||||||
} else {
|
} else {
|
||||||
this.instance.UI.disableElements(textActions);
|
this.instance.UI.disableElements(textActions);
|
||||||
@ -283,7 +283,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
private _setInitialDisplayMode() {
|
private _setInitialDisplayMode() {
|
||||||
this.instance.UI.setFitMode('FitPage');
|
this.instance.UI.setFitMode('FitPage');
|
||||||
const instanceDisplayMode = this.documentViewer.getDisplayModeManager().getDisplayMode();
|
const instanceDisplayMode = this.documentViewer.getDisplayModeManager().getDisplayMode();
|
||||||
instanceDisplayMode.mode = this.reusablePdf.isCompare ? 'Facing' : 'Single';
|
instanceDisplayMode.mode = this.pdf.isCompare ? 'Facing' : 'Single';
|
||||||
this.documentViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
|
this.documentViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _configureRectangleAnnotationPopup(annotation: Annotation) {
|
private _configureRectangleAnnotationPopup(annotation: Annotation) {
|
||||||
if (!this.reusablePdf.isCompare || annotation.getPageNumber() % 2 === 1) {
|
if (!this.pdf.isCompare || annotation.getPageNumber() % 2 === 1) {
|
||||||
this.instance.UI.annotationPopup.add([
|
this.instance.UI.annotationPopup.add([
|
||||||
{
|
{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
@ -459,7 +459,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
HeaderElements.ROTATE_RIGHT_BUTTON,
|
HeaderElements.ROTATE_RIGHT_BUTTON,
|
||||||
];
|
];
|
||||||
|
|
||||||
const isCurrentPageExcluded = this.pdfViewer.isCurrentPageExcluded(this.stateService.file);
|
const isCurrentPageExcluded = this.stateService.file.isPageExcluded(this.pdf.currentPage);
|
||||||
|
|
||||||
if (this.canPerformActions && !isCurrentPageExcluded) {
|
if (this.canPerformActions && !isCurrentPageExcluded) {
|
||||||
try {
|
try {
|
||||||
@ -507,7 +507,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
for (const quad of quads[key]) {
|
for (const quad of quads[key]) {
|
||||||
const page = parseInt(key, 10);
|
const page = parseInt(key, 10);
|
||||||
const pageHeight = this.documentViewer.getPageHeight(page);
|
const pageHeight = this.documentViewer.getPageHeight(page);
|
||||||
entry.positions.push(toPosition(page, pageHeight, convertQuads ? this.pdfViewer.translateQuad(page, quad) : quad));
|
entry.positions.push(toPosition(page, pageHeight, convertQuads ? this.#translateQuad(page, quad) : quad));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,6 +516,11 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#translateQuad(page: number, quad: Core.Math.Quad) {
|
||||||
|
const rotation = this.pdf.documentViewer.getCompleteRotation(page);
|
||||||
|
return translateQuads(page, rotation, quad);
|
||||||
|
}
|
||||||
|
|
||||||
private _setReadyAndInitialState() {
|
private _setReadyAndInitialState() {
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
this._setInitialDisplayMode();
|
this._setInitialDisplayMode();
|
||||||
@ -12,7 +12,6 @@ import { EntitiesService, FilterService, ListingService, SearchService } from '@
|
|||||||
import { AnnotationProcessingService } from './services/annotation-processing.service';
|
import { AnnotationProcessingService } from './services/annotation-processing.service';
|
||||||
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
||||||
import { PageRotationService } from './services/page-rotation.service';
|
import { PageRotationService } from './services/page-rotation.service';
|
||||||
import { PdfViewer } from './services/pdf-viewer.service';
|
|
||||||
import { FileDataService } from './services/file-data.service';
|
import { FileDataService } from './services/file-data.service';
|
||||||
import { ViewerHeaderConfigService } from './services/viewer-header-config.service';
|
import { ViewerHeaderConfigService } from './services/viewer-header-config.service';
|
||||||
import { TooltipsService } from './services/tooltips.service';
|
import { TooltipsService } from './services/tooltips.service';
|
||||||
@ -32,14 +31,14 @@ export const filePreviewScreenProviders = [
|
|||||||
FilePreviewStateService,
|
FilePreviewStateService,
|
||||||
AnnotationReferencesService,
|
AnnotationReferencesService,
|
||||||
PageRotationService,
|
PageRotationService,
|
||||||
PdfViewer,
|
|
||||||
AnnotationProcessingService,
|
AnnotationProcessingService,
|
||||||
FileDataService,
|
FileDataService,
|
||||||
{ provide: EntitiesService, useExisting: FileDataService },
|
{ provide: EntitiesService, useExisting: FileDataService },
|
||||||
dossiersServiceProvider,
|
dossiersServiceProvider,
|
||||||
ViewerHeaderConfigService,
|
ViewerHeaderConfigService,
|
||||||
TooltipsService,
|
TooltipsService,
|
||||||
{ provide: ListingService, useClass: AnnotationsListingService },
|
AnnotationsListingService,
|
||||||
|
{ provide: ListingService, useExisting: AnnotationsListingService },
|
||||||
SearchService,
|
SearchService,
|
||||||
StampService,
|
StampService,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -86,7 +86,7 @@
|
|||||||
<redaction-file-workload
|
<redaction-file-workload
|
||||||
(selectPage)="selectPage($event)"
|
(selectPage)="selectPage($event)"
|
||||||
*ngIf="!file.excluded"
|
*ngIf="!file.excluded"
|
||||||
[activeViewerPage]="reusablePdf.currentPage$ | async"
|
[activeViewerPage]="pdf.currentPage$ | async"
|
||||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||||
[dialogRef]="dialogRef"
|
[dialogRef]="dialogRef"
|
||||||
[file]="file"
|
[file]="file"
|
||||||
|
|||||||
@ -45,13 +45,12 @@ import { ManualRedactionService } from './services/manual-redaction.service';
|
|||||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||||
import { PageRotationService } from './services/page-rotation.service';
|
import { PageRotationService } from './services/page-rotation.service';
|
||||||
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
|
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
|
||||||
import { PdfViewer } from './services/pdf-viewer.service';
|
|
||||||
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
|
import { FilePreviewDialogService } from './services/file-preview-dialog.service';
|
||||||
import { FileDataService } from './services/file-data.service';
|
import { FileDataService } from './services/file-data.service';
|
||||||
import { ActionsHelpModeKeys, ALL_HOTKEYS } from './utils/constants';
|
import { ActionsHelpModeKeys, ALL_HOTKEYS } from './utils/constants';
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
import { StampService } from './services/stamp.service';
|
import { StampService } from './services/stamp.service';
|
||||||
import { ReusablePdfViewer } from '../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import { REDAnnotationManager } from '../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
import Annotation = Core.Annotations.Annotation;
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@ -79,7 +78,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly pdf: PdfViewer,
|
readonly pdf: PdfViewer,
|
||||||
readonly reusablePdf: ReusablePdfViewer,
|
|
||||||
readonly documentInfoService: DocumentInfoService,
|
readonly documentInfoService: DocumentInfoService,
|
||||||
readonly state: FilePreviewStateService,
|
readonly state: FilePreviewStateService,
|
||||||
readonly listingService: ListingService<AnnotationWrapper>,
|
readonly listingService: ListingService<AnnotationWrapper>,
|
||||||
@ -129,7 +127,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
private get _canPerformAnnotationActions$() {
|
private get _canPerformAnnotationActions$() {
|
||||||
const viewMode$ = this._viewModeService.viewMode$.pipe(tap(() => this.#deactivateMultiSelect()));
|
const viewMode$ = this._viewModeService.viewMode$.pipe(tap(() => this.#deactivateMultiSelect()));
|
||||||
|
|
||||||
return combineLatest([this.state.file$, this.state.dossier$, viewMode$, this.reusablePdf.compareMode$]).pipe(
|
return combineLatest([this.state.file$, this.state.dossier$, viewMode$, this.pdf.compareMode$]).pipe(
|
||||||
map(
|
map(
|
||||||
([file, dossier, viewMode]) =>
|
([file, dossier, viewMode]) =>
|
||||||
this.permissionsService.canPerformAnnotationActions(file, dossier) && viewMode === 'STANDARD',
|
this.permissionsService.canPerformAnnotationActions(file, dossier) && viewMode === 'STANDARD',
|
||||||
@ -194,7 +192,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
ngOnDetach(): void {
|
ngOnDetach(): void {
|
||||||
this._pageRotationService.clearRotations();
|
this._pageRotationService.clearRotations();
|
||||||
this.reusablePdf.closeDocument();
|
this.pdf.closeDocument();
|
||||||
super.ngOnDetach();
|
super.ngOnDetach();
|
||||||
this._changeDetectorRef.markForCheck();
|
this._changeDetectorRef.markForCheck();
|
||||||
}
|
}
|
||||||
@ -237,7 +235,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectPage(pageNumber: number) {
|
selectPage(pageNumber: number) {
|
||||||
this.pdf.navigateToPage(pageNumber);
|
this.pdf.navigateTo(pageNumber);
|
||||||
this._lastPage = pageNumber.toString();
|
this._lastPage = pageNumber.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,11 +346,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadAnnotations() {
|
loadAnnotations() {
|
||||||
const documentLoaded$ = this.reusablePdf.documentLoaded$.pipe(
|
const documentLoaded$ = this.pdf.loaded$.pipe(
|
||||||
filter(s => s),
|
filter(s => s),
|
||||||
tap(() => this.viewerReady()),
|
tap(() => this.viewerReady()),
|
||||||
);
|
);
|
||||||
const currentPageAnnotations$ = combineLatest([this.reusablePdf.currentPage$, this._fileDataService.annotations$]).pipe(
|
const currentPageAnnotations$ = combineLatest([this.pdf.currentPage$, this._fileDataService.annotations$]).pipe(
|
||||||
map(([page, annotations]) => annotations.filter(annotation => annotation.pageNumber === page)),
|
map(([page, annotations]) => annotations.filter(annotation => annotation.pageNumber === page)),
|
||||||
);
|
);
|
||||||
let start;
|
let start;
|
||||||
@ -480,10 +478,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
private _setExcludedPageStyles() {
|
private _setExcludedPageStyles() {
|
||||||
const file = this._filesMapService.get(this.dossierId, this.fileId);
|
const file = this._filesMapService.get(this.dossierId, this.fileId);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const iframeDoc = this.reusablePdf.instance.UI.iframeWindow.document;
|
const iframeDoc = this.pdf.instance.UI.iframeWindow.document;
|
||||||
const pageContainer = iframeDoc.getElementById(`pageWidgetContainer${this.pdf.currentPage}`);
|
const currentPage = this.pdf.currentPage;
|
||||||
|
const elementId = `pageWidgetContainer${currentPage}`;
|
||||||
|
const pageContainer = iframeDoc.getElementById(elementId);
|
||||||
if (pageContainer) {
|
if (pageContainer) {
|
||||||
if (file.excludedPages.includes(this.pdf.currentPage)) {
|
if (file.excludedPages.includes(currentPage)) {
|
||||||
pageContainer.classList.add('excluded-page');
|
pageContainer.classList.add('excluded-page');
|
||||||
} else {
|
} else {
|
||||||
pageContainer.classList.remove('excluded-page');
|
pageContainer.classList.remove('excluded-page');
|
||||||
@ -515,7 +515,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
|
|
||||||
this.addActiveScreenSubscription = this.reusablePdf.pageComplete$.subscribe(() => {
|
this.addActiveScreenSubscription = this.pdf.pageComplete$.subscribe(() => {
|
||||||
this._setExcludedPageStyles();
|
this._setExcludedPageStyles();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { AnnotationDetailsComponent } from './components/annotation-details/anno
|
|||||||
import { AnnotationsListComponent } from './components/annotations-list/annotations-list.component';
|
import { AnnotationsListComponent } from './components/annotations-list/annotations-list.component';
|
||||||
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
|
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
|
||||||
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
|
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
|
||||||
import { PdfViewerComponent } from './components/pdf-viewer/pdf-viewer.component';
|
import { PdfPaginatorComponent } from './components/pdf-paginator/pdf-paginator.component';
|
||||||
import { AnnotationActionsComponent } from './components/annotation-actions/annotation-actions.component';
|
import { AnnotationActionsComponent } from './components/annotation-actions/annotation-actions.component';
|
||||||
import { CommentsComponent } from './components/comments/comments.component';
|
import { CommentsComponent } from './components/comments/comments.component';
|
||||||
import { DocumentInfoComponent } from './components/document-info/document-info.component';
|
import { DocumentInfoComponent } from './components/document-info/document-info.component';
|
||||||
@ -70,7 +70,7 @@ const components = [
|
|||||||
AnnotationsListComponent,
|
AnnotationsListComponent,
|
||||||
PageIndicatorComponent,
|
PageIndicatorComponent,
|
||||||
PageExclusionComponent,
|
PageExclusionComponent,
|
||||||
PdfViewerComponent,
|
PdfPaginatorComponent,
|
||||||
AnnotationActionsComponent,
|
AnnotationActionsComponent,
|
||||||
CommentsComponent,
|
CommentsComponent,
|
||||||
DocumentInfoComponent,
|
DocumentInfoComponent,
|
||||||
|
|||||||
@ -31,11 +31,10 @@ import { defaultDialogConfig, List, ListingService } from '@iqser/common-ui';
|
|||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { PdfViewer } from './pdf-viewer.service';
|
|
||||||
import { FilePreviewDialogService } from './file-preview-dialog.service';
|
import { FilePreviewDialogService } from './file-preview-dialog.service';
|
||||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||||
import { FileDataService } from './file-data.service';
|
import { FileDataService } from './file-data.service';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import { REDAnnotationManager } from '../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
import Quad = Core.Math.Quad;
|
import Quad = Core.Math.Quad;
|
||||||
|
|
||||||
@ -51,7 +50,6 @@ export class AnnotationActionsService {
|
|||||||
private readonly _dialogService: FilePreviewDialogService,
|
private readonly _dialogService: FilePreviewDialogService,
|
||||||
private readonly _dialog: MatDialog,
|
private readonly _dialog: MatDialog,
|
||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _annotationManager: REDAnnotationManager,
|
private readonly _annotationManager: REDAnnotationManager,
|
||||||
private readonly _annotationDrawService: AnnotationDrawService,
|
private readonly _annotationDrawService: AnnotationDrawService,
|
||||||
private readonly _activeDossiersService: ActiveDossiersService,
|
private readonly _activeDossiersService: ActiveDossiersService,
|
||||||
@ -403,17 +401,17 @@ export class AnnotationActionsService {
|
|||||||
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
||||||
this._annotationManager.deleteAnnotation(annotationWrapper);
|
this._annotationManager.deleteAnnotation(annotationWrapper);
|
||||||
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
||||||
this._reusablePdf.annotationManager.addAnnotation(rectangleAnnotation, { imported: true });
|
this._pdf.annotationManager.addAnnotation(rectangleAnnotation, { imported: true });
|
||||||
await this._reusablePdf.annotationManager.drawAnnotationsFromList([rectangleAnnotation]);
|
await this._pdf.annotationManager.drawAnnotationsFromList([rectangleAnnotation]);
|
||||||
this._reusablePdf.annotationManager.selectAnnotation(rectangleAnnotation);
|
this._pdf.annotationManager.selectAnnotation(rectangleAnnotation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewerAnnotation.ReadOnly = false;
|
viewerAnnotation.ReadOnly = false;
|
||||||
viewerAnnotation.Hidden = false;
|
viewerAnnotation.Hidden = false;
|
||||||
viewerAnnotation.disableRotationControl();
|
viewerAnnotation.disableRotationControl();
|
||||||
this._reusablePdf.annotationManager.redrawAnnotation(viewerAnnotation);
|
this._pdf.annotationManager.redrawAnnotation(viewerAnnotation);
|
||||||
this._reusablePdf.annotationManager.selectAnnotation(viewerAnnotation);
|
this._pdf.annotationManager.selectAnnotation(viewerAnnotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
async acceptResize($event: MouseEvent, annotation: AnnotationWrapper): Promise<void> {
|
async acceptResize($event: MouseEvent, annotation: AnnotationWrapper): Promise<void> {
|
||||||
@ -465,8 +463,8 @@ export class AnnotationActionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#generateRectangle(annotationWrapper: AnnotationWrapper) {
|
#generateRectangle(annotationWrapper: AnnotationWrapper) {
|
||||||
const annotation = this._reusablePdf.rectangle();
|
const annotation = this._pdf.rectangle();
|
||||||
const pageHeight = this._reusablePdf.documentViewer.getPageHeight(annotationWrapper.pageNumber);
|
const pageHeight = this._pdf.documentViewer.getPageHeight(annotationWrapper.pageNumber);
|
||||||
const rectangle: IRectangle = annotationWrapper.positions[0];
|
const rectangle: IRectangle = annotationWrapper.positions[0];
|
||||||
annotation.PageNumber = annotationWrapper.pageNumber;
|
annotation.PageNumber = annotationWrapper.pageNumber;
|
||||||
annotation.X = rectangle.topLeft.x;
|
annotation.X = rectangle.topLeft.x;
|
||||||
@ -533,15 +531,15 @@ export class AnnotationActionsService {
|
|||||||
private async _extractTextAndPositions(annotationId: string) {
|
private async _extractTextAndPositions(annotationId: string) {
|
||||||
const viewerAnnotation = this._annotationManager.getAnnotation(annotationId);
|
const viewerAnnotation = this._annotationManager.getAnnotation(annotationId);
|
||||||
|
|
||||||
const document = await this._reusablePdf.PDFDoc;
|
const document = await this._pdf.PDFDoc;
|
||||||
const page = await document.getPage(viewerAnnotation.getPageNumber());
|
const page = await document.getPage(viewerAnnotation.getPageNumber());
|
||||||
if (this._reusablePdf.isTextHighlight(viewerAnnotation)) {
|
if (this._pdf.isTextHighlight(viewerAnnotation)) {
|
||||||
const words = [];
|
const words = [];
|
||||||
const rectangles: IRectangle[] = [];
|
const rectangles: IRectangle[] = [];
|
||||||
for (const quad of viewerAnnotation.Quads) {
|
for (const quad of viewerAnnotation.Quads) {
|
||||||
const rect = toPosition(
|
const rect = toPosition(
|
||||||
viewerAnnotation.getPageNumber(),
|
viewerAnnotation.getPageNumber(),
|
||||||
this._reusablePdf.getPageHeight(viewerAnnotation.getPageNumber()),
|
this._pdf.getPageHeight(viewerAnnotation.getPageNumber()),
|
||||||
this._translateQuads(viewerAnnotation.getPageNumber(), quad),
|
this._translateQuads(viewerAnnotation.getPageNumber(), quad),
|
||||||
);
|
);
|
||||||
rectangles.push(rect);
|
rectangles.push(rect);
|
||||||
@ -552,7 +550,7 @@ export class AnnotationActionsService {
|
|||||||
*/
|
*/
|
||||||
const percentHeightOffset = rect.height / 10;
|
const percentHeightOffset = rect.height / 10;
|
||||||
|
|
||||||
const pdfNetRect = new this._reusablePdf.PDFNet.Rect(
|
const pdfNetRect = new this._pdf.PDFNet.Rect(
|
||||||
rect.topLeft.x,
|
rect.topLeft.x,
|
||||||
rect.topLeft.y + percentHeightOffset,
|
rect.topLeft.y + percentHeightOffset,
|
||||||
rect.topLeft.x + rect.width,
|
rect.topLeft.x + rect.width,
|
||||||
@ -569,7 +567,7 @@ export class AnnotationActionsService {
|
|||||||
} else {
|
} else {
|
||||||
const rect = toPosition(
|
const rect = toPosition(
|
||||||
viewerAnnotation.getPageNumber(),
|
viewerAnnotation.getPageNumber(),
|
||||||
this._reusablePdf.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
|
this._pdf.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
|
||||||
this._annotationDrawService.annotationToQuads(viewerAnnotation),
|
this._annotationDrawService.annotationToQuads(viewerAnnotation),
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
@ -580,12 +578,12 @@ export class AnnotationActionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _translateQuads(page: number, quad: Quad): Quad {
|
private _translateQuads(page: number, quad: Quad): Quad {
|
||||||
const rotation = this._reusablePdf.documentViewer.getCompleteRotation(page);
|
const rotation = this._pdf.documentViewer.getCompleteRotation(page);
|
||||||
return translateQuads(page, rotation, quad);
|
return translateQuads(page, rotation, quad);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _extractTextFromRect(page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
|
private async _extractTextFromRect(page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
|
||||||
const txt = await this._reusablePdf.PDFNet.TextExtractor.create();
|
const txt = await this._pdf.PDFNet.TextExtractor.create();
|
||||||
await txt.begin(page, rect); // Read the page.
|
await txt.begin(page, rect); // Read the page.
|
||||||
|
|
||||||
const words: string[] = [];
|
const words: string[] = [];
|
||||||
|
|||||||
@ -10,11 +10,10 @@ import { IRectangle, ISectionGrid, ISectionRectangle } from '@red/domain';
|
|||||||
import { SkippedService } from './skipped.service';
|
import { SkippedService } from './skipped.service';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||||
import { PdfViewer } from './pdf-viewer.service';
|
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { FileDataService } from './file-data.service';
|
import { FileDataService } from './file-data.service';
|
||||||
import { SuperTypes } from '@models/file/super-types';
|
import { SuperTypes } from '@models/file/super-types';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import Annotation = Core.Annotations.Annotation;
|
import Annotation = Core.Annotations.Annotation;
|
||||||
import Quad = Core.Math.Quad;
|
import Quad = Core.Math.Quad;
|
||||||
|
|
||||||
@ -29,14 +28,13 @@ export class AnnotationDrawService {
|
|||||||
private readonly _userPreferenceService: UserPreferenceService,
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
private readonly _skippedService: SkippedService,
|
private readonly _skippedService: SkippedService,
|
||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _state: FilePreviewStateService,
|
private readonly _state: FilePreviewStateService,
|
||||||
private readonly _fileDataService: FileDataService,
|
private readonly _fileDataService: FileDataService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
draw(annotations: readonly AnnotationWrapper[]) {
|
draw(annotations: readonly AnnotationWrapper[]) {
|
||||||
const licenseKey = environment.licenseKey ? atob(environment.licenseKey) : null;
|
const licenseKey = environment.licenseKey ? atob(environment.licenseKey) : null;
|
||||||
return this._reusablePdf.PDFNet.runWithCleanup(() => this._draw(annotations), licenseKey);
|
return this._pdf.PDFNet.runWithCleanup(() => this._draw(annotations), licenseKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
getColor(superType: string, dictionary?: string) {
|
getColor(superType: string, dictionary?: string) {
|
||||||
@ -64,7 +62,7 @@ export class AnnotationDrawService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
convertColor(hexColor: string) {
|
convertColor(hexColor: string) {
|
||||||
return this._reusablePdf.color(hexToRgb(hexColor));
|
return this._pdf.color(hexToRgb(hexColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationToQuads(annotation: Annotation) {
|
annotationToQuads(annotation: Annotation) {
|
||||||
@ -80,13 +78,13 @@ export class AnnotationDrawService {
|
|||||||
const x4 = annotation.getRect().x1;
|
const x4 = annotation.getRect().x1;
|
||||||
const y4 = annotation.getRect().y1;
|
const y4 = annotation.getRect().y1;
|
||||||
|
|
||||||
return this._reusablePdf.quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
return this._pdf.quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _draw(annotationWrappers: readonly AnnotationWrapper[]) {
|
private async _draw(annotationWrappers: readonly AnnotationWrapper[]) {
|
||||||
const annotations = annotationWrappers.map(annotation => this._computeAnnotation(annotation)).filter(a => !!a);
|
const annotations = annotationWrappers.map(annotation => this._computeAnnotation(annotation)).filter(a => !!a);
|
||||||
this._reusablePdf.annotationManager.addAnnotations(annotations, { imported: true });
|
this._pdf.annotationManager.addAnnotations(annotations, { imported: true });
|
||||||
await this._reusablePdf.annotationManager.drawAnnotationsFromList(annotations);
|
await this._pdf.annotationManager.drawAnnotationsFromList(annotations);
|
||||||
|
|
||||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||||
const { dossierId, fileId } = this._state;
|
const { dossierId, fileId } = this._state;
|
||||||
@ -107,13 +105,13 @@ export class AnnotationDrawService {
|
|||||||
// })
|
// })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this._reusablePdf.annotationManager.addAnnotations(sections, { imported: true });
|
this._pdf.annotationManager.addAnnotations(sections, { imported: true });
|
||||||
await this._reusablePdf.annotationManager.drawAnnotationsFromList(sections);
|
await this._pdf.annotationManager.drawAnnotationsFromList(sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeSection(pageNumber: number, sectionRectangle: ISectionRectangle) {
|
private _computeSection(pageNumber: number, sectionRectangle: ISectionRectangle) {
|
||||||
const rectangleAnnot = this._reusablePdf.rectangle();
|
const rectangleAnnot = this._pdf.rectangle();
|
||||||
const pageHeight = this._reusablePdf.getPageHeight(pageNumber);
|
const pageHeight = this._pdf.getPageHeight(pageNumber);
|
||||||
const rectangle: IRectangle = {
|
const rectangle: IRectangle = {
|
||||||
topLeft: sectionRectangle.topLeft,
|
topLeft: sectionRectangle.topLeft,
|
||||||
page: pageNumber,
|
page: pageNumber,
|
||||||
@ -133,15 +131,15 @@ export class AnnotationDrawService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _computeAnnotation(annotationWrapper: AnnotationWrapper) {
|
private _computeAnnotation(annotationWrapper: AnnotationWrapper) {
|
||||||
const pageNumber = this._reusablePdf.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
|
const pageNumber = this._pdf.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
|
||||||
if (pageNumber > this._reusablePdf.pageCount) {
|
if (pageNumber > this._pdf.pageCount) {
|
||||||
// skip imported annotations from files that have more pages than the current one
|
// skip imported annotations from files that have more pages than the current one
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (annotationWrapper.superType === SuperTypes.TextHighlight) {
|
if (annotationWrapper.superType === SuperTypes.TextHighlight) {
|
||||||
const rectangleAnnot = this._reusablePdf.rectangle();
|
const rectangleAnnot = this._pdf.rectangle();
|
||||||
const pageHeight = this._reusablePdf.getPageHeight(pageNumber);
|
const pageHeight = this._pdf.getPageHeight(pageNumber);
|
||||||
const rectangle: IRectangle = annotationWrapper.positions[0];
|
const rectangle: IRectangle = annotationWrapper.positions[0];
|
||||||
rectangleAnnot.PageNumber = pageNumber;
|
rectangleAnnot.PageNumber = pageNumber;
|
||||||
rectangleAnnot.X = rectangle.topLeft.x;
|
rectangleAnnot.X = rectangle.topLeft.x;
|
||||||
@ -156,7 +154,7 @@ export class AnnotationDrawService {
|
|||||||
return rectangleAnnot;
|
return rectangleAnnot;
|
||||||
}
|
}
|
||||||
|
|
||||||
const annotation = this._reusablePdf.textHighlight();
|
const annotation = this._pdf.textHighlight();
|
||||||
annotation.Quads = this._rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
annotation.Quads = this._rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
||||||
annotation.Opacity = annotationWrapper.isChangeLogRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
annotation.Opacity = annotationWrapper.isChangeLogRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
||||||
annotation.setContents(annotationWrapper.content);
|
annotation.setContents(annotationWrapper.content);
|
||||||
@ -183,7 +181,7 @@ export class AnnotationDrawService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _rectanglesToQuads(positions: IRectangle[], pageNumber: number): Quad[] {
|
private _rectanglesToQuads(positions: IRectangle[], pageNumber: number): Quad[] {
|
||||||
const pageHeight = this._reusablePdf.getPageHeight(pageNumber);
|
const pageHeight = this._pdf.getPageHeight(pageNumber);
|
||||||
return positions.map(p => this._rectangleToQuad(p, pageHeight));
|
return positions.map(p => this._rectangleToQuad(p, pageHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +198,6 @@ export class AnnotationDrawService {
|
|||||||
const x4 = rectangle.topLeft.x;
|
const x4 = rectangle.topLeft.x;
|
||||||
const y4 = pageHeight - rectangle.topLeft.y;
|
const y4 = pageHeight - rectangle.topLeft.y;
|
||||||
|
|
||||||
return this._reusablePdf.quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
return this._pdf.quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import { Injectable } from '@angular/core';
|
|||||||
import { EntitiesService, FilterService, ListingService, SearchService } from '@iqser/common-ui';
|
import { EntitiesService, FilterService, ListingService, SearchService } from '@iqser/common-ui';
|
||||||
import { filter, tap } from 'rxjs/operators';
|
import { filter, tap } from 'rxjs/operators';
|
||||||
import { MultiSelectService } from './multi-select.service';
|
import { MultiSelectService } from './multi-select.service';
|
||||||
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
|
import { REDAnnotationManager } from '../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AnnotationsListingService extends ListingService<AnnotationWrapper> {
|
export class AnnotationsListingService extends ListingService<AnnotationWrapper> {
|
||||||
@ -11,6 +13,8 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
|
|||||||
protected readonly _searchService: SearchService<AnnotationWrapper>,
|
protected readonly _searchService: SearchService<AnnotationWrapper>,
|
||||||
protected readonly _entitiesService: EntitiesService<AnnotationWrapper>,
|
protected readonly _entitiesService: EntitiesService<AnnotationWrapper>,
|
||||||
private readonly _multiSelectService: MultiSelectService,
|
private readonly _multiSelectService: MultiSelectService,
|
||||||
|
private readonly _pdf: PdfViewer,
|
||||||
|
private readonly _annotationManager: REDAnnotationManager,
|
||||||
) {
|
) {
|
||||||
super(_filterService, _searchService, _entitiesService);
|
super(_filterService, _searchService, _entitiesService);
|
||||||
|
|
||||||
@ -21,4 +25,42 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
|
|||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectAnnotations(annotations?: AnnotationWrapper[]) {
|
||||||
|
if (!annotations) {
|
||||||
|
return this._annotationManager.deselectAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations;
|
||||||
|
this.#selectAnnotations(annotationsToSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
#selectAnnotations(annotations: AnnotationWrapper[] = []) {
|
||||||
|
const filteredAnnotationsIds = annotations.filter(a => !!a).map(a => a.id);
|
||||||
|
|
||||||
|
if (!filteredAnnotationsIds.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._multiSelectService.isActive) {
|
||||||
|
this._annotationManager.deselectAnnotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageNumber = annotations[0].pageNumber;
|
||||||
|
|
||||||
|
if (pageNumber === this._pdf.currentPage) {
|
||||||
|
return this.#jumpAndSelectAnnotations(filteredAnnotationsIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pdf.navigateTo(pageNumber);
|
||||||
|
// wait for page to be loaded and to draw annotations
|
||||||
|
setTimeout(() => this.#jumpAndSelectAnnotations(filteredAnnotationsIds), 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
#jumpAndSelectAnnotations(annotationIds: readonly string[]) {
|
||||||
|
const annotationsFromViewer = this._annotationManager.getAnnotations(annotationIds);
|
||||||
|
|
||||||
|
this._pdf.annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
|
||||||
|
this._pdf.annotationManager.selectAnnotations(annotationsFromViewer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { RotationType, RotationTypes } from '@red/domain';
|
|||||||
import { FileManagementService } from '@services/files/file-management.service';
|
import { FileManagementService } from '@services/files/file-management.service';
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { distinctUntilChanged, map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
import { distinctUntilChanged, map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||||
import { PdfViewer } from './pdf-viewer.service';
|
|
||||||
import { HeaderElements } from '../utils/constants';
|
import { HeaderElements } from '../utils/constants';
|
||||||
import {
|
import {
|
||||||
ConfirmationDialogComponent,
|
ConfirmationDialogComponent,
|
||||||
@ -17,7 +16,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ViewerHeaderConfigService } from './viewer-header-config.service';
|
import { ViewerHeaderConfigService } from './viewer-header-config.service';
|
||||||
import { FilesService } from '@services/files/files.service';
|
import { FilesService } from '@services/files/files.service';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
|
|
||||||
const ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION];
|
const ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION];
|
||||||
const ONE_ROTATION_DEGREE = 90;
|
const ONE_ROTATION_DEGREE = 90;
|
||||||
@ -28,7 +27,6 @@ export class PageRotationService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _dialog: MatDialog,
|
private readonly _dialog: MatDialog,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _screenState: FilePreviewStateService,
|
private readonly _screenState: FilePreviewStateService,
|
||||||
@ -70,7 +68,7 @@ export class PageRotationService {
|
|||||||
for (const page of Object.keys(rotations)) {
|
for (const page of Object.keys(rotations)) {
|
||||||
const times = rotations[page] / ONE_ROTATION_DEGREE;
|
const times = rotations[page] / ONE_ROTATION_DEGREE;
|
||||||
for (let i = 1; i <= times; i++) {
|
for (let i = 1; i <= times; i++) {
|
||||||
this._reusablePdf.documentViewer.rotateCounterClockwise(Number(page));
|
this._pdf.documentViewer.rotateCounterClockwise(Number(page));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,9 +83,9 @@ export class PageRotationService {
|
|||||||
this.#rotations$.next({ ...this.#rotations$.value, [pageNumber]: rotationValue });
|
this.#rotations$.next({ ...this.#rotations$.value, [pageNumber]: rotationValue });
|
||||||
|
|
||||||
if (rotation === RotationTypes.LEFT) {
|
if (rotation === RotationTypes.LEFT) {
|
||||||
this._reusablePdf.documentViewer.rotateCounterClockwise(pageNumber);
|
this._pdf.documentViewer.rotateCounterClockwise(pageNumber);
|
||||||
} else {
|
} else {
|
||||||
this._reusablePdf.documentViewer.rotateClockwise(pageNumber);
|
this._pdf.documentViewer.rotateClockwise(pageNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasRotations()) {
|
if (this.hasRotations()) {
|
||||||
|
|||||||
@ -1,103 +0,0 @@
|
|||||||
import { translateQuads } from '../../../utils';
|
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
|
||||||
import { Core } from '@pdftron/webviewer';
|
|
||||||
import { File } from '@red/domain';
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { ListingService } from '@iqser/common-ui';
|
|
||||||
import { MultiSelectService } from './multi-select.service';
|
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
|
||||||
import { REDAnnotationManager } from '../../shared/components/reusable-pdf-viewer/annotation-manager.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PdfViewer {
|
|
||||||
constructor(
|
|
||||||
private readonly _multiSelectService: MultiSelectService,
|
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _annotationManager: REDAnnotationManager,
|
|
||||||
private readonly _listingService: ListingService<AnnotationWrapper>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
get paginationOffset() {
|
|
||||||
return this._reusablePdf.isCompare ? 2 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
get currentPage() {
|
|
||||||
return this._reusablePdf.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _currentInternalPage() {
|
|
||||||
return this._reusablePdf.documentViewer?.getCurrentPage() ?? 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
isCurrentPageExcluded(file: File) {
|
|
||||||
const currentPage = this.currentPage;
|
|
||||||
return !!file?.excludedPages?.includes(currentPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToPage(pageNumber: string | number) {
|
|
||||||
const parsedNumber = typeof pageNumber === 'string' ? parseInt(pageNumber, 10) : pageNumber;
|
|
||||||
this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
navigatePreviousPage() {
|
|
||||||
if (this._currentInternalPage > 1) {
|
|
||||||
this._navigateToPage(Math.max(this._currentInternalPage - this.paginationOffset, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateNextPage() {
|
|
||||||
const pageCount = this._reusablePdf.pageCount;
|
|
||||||
if (this._currentInternalPage < pageCount) {
|
|
||||||
this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, pageCount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
translateQuad(page: number, quad: Core.Math.Quad) {
|
|
||||||
const rotation = this._reusablePdf.documentViewer.getCompleteRotation(page);
|
|
||||||
return translateQuads(page, rotation, quad);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectAnnotations(annotations?: AnnotationWrapper[]) {
|
|
||||||
if (!annotations) {
|
|
||||||
return this._annotationManager.deselectAnnotations();
|
|
||||||
}
|
|
||||||
|
|
||||||
const annotationsToSelect = this._multiSelectService.isActive ? [...this._listingService.selected, ...annotations] : annotations;
|
|
||||||
this.#selectAnnotations(annotationsToSelect);
|
|
||||||
}
|
|
||||||
|
|
||||||
#selectAnnotations(annotations: AnnotationWrapper[] = []) {
|
|
||||||
const filteredAnnotationsIds = annotations.filter(a => !!a).map(a => a.id);
|
|
||||||
|
|
||||||
if (!filteredAnnotationsIds.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._multiSelectService.isActive) {
|
|
||||||
this._annotationManager.deselectAnnotations();
|
|
||||||
}
|
|
||||||
|
|
||||||
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), 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
#jumpAndSelectAnnotations(annotationIds: readonly string[]) {
|
|
||||||
const annotationsFromViewer = this._annotationManager.getAnnotations(annotationIds);
|
|
||||||
|
|
||||||
this._reusablePdf.annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
|
|
||||||
this._reusablePdf.annotationManager.selectAnnotations(annotationsFromViewer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _navigateToPage(pageNumber: number) {
|
|
||||||
if (this._currentInternalPage !== pageNumber) {
|
|
||||||
this._reusablePdf.documentViewer.displayPageLocation(pageNumber, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { clearStamps, stampPDFPage } from '../../../utils';
|
import { clearStamps, stampPDFPage } from '../../../utils';
|
||||||
import { PdfViewer } from './pdf-viewer.service';
|
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
import { ViewModeService } from './view-mode.service';
|
import { ViewModeService } from './view-mode.service';
|
||||||
@ -8,14 +7,13 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { Core } from '@pdftron/webviewer';
|
import { Core } from '@pdftron/webviewer';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
import PDFNet = Core.PDFNet;
|
import PDFNet = Core.PDFNet;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StampService {
|
export class StampService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _state: FilePreviewStateService,
|
private readonly _state: FilePreviewStateService,
|
||||||
private readonly _logger: NGXLogger,
|
private readonly _logger: NGXLogger,
|
||||||
private readonly _viewModeService: ViewModeService,
|
private readonly _viewModeService: ViewModeService,
|
||||||
@ -24,7 +22,7 @@ export class StampService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async stampPDF(): Promise<void> {
|
async stampPDF(): Promise<void> {
|
||||||
const pdfDoc = await this._reusablePdf.PDFDoc;
|
const pdfDoc = await this._pdf.PDFDoc;
|
||||||
if (!pdfDoc) {
|
if (!pdfDoc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,7 +31,7 @@ export class StampService {
|
|||||||
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
|
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await clearStamps(pdfDoc, this._reusablePdf.PDFNet, allPages);
|
await clearStamps(pdfDoc, this._pdf.PDFNet, allPages);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error clearing stamps: ', e);
|
console.error('Error clearing stamps: ', e);
|
||||||
return;
|
return;
|
||||||
@ -48,15 +46,16 @@ export class StampService {
|
|||||||
await this._stampExcludedPages(pdfDoc, file.excludedPages);
|
await this._stampExcludedPages(pdfDoc, file.excludedPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._reusablePdf.documentViewer.refreshAll();
|
this._pdf.documentViewer.refreshAll();
|
||||||
this._reusablePdf.documentViewer.updateView([this._pdf.currentPage], this._pdf.currentPage);
|
const currentPage = this._pdf.currentPage;
|
||||||
|
this._pdf.documentViewer.updateView([currentPage], currentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _stampExcludedPages(document: PDFNet.PDFDoc, excludedPages: number[]): Promise<void> {
|
private async _stampExcludedPages(document: PDFNet.PDFDoc, excludedPages: number[]): Promise<void> {
|
||||||
if (excludedPages && excludedPages.length > 0) {
|
if (excludedPages && excludedPages.length > 0) {
|
||||||
await stampPDFPage(
|
await stampPDFPage(
|
||||||
document,
|
document,
|
||||||
this._reusablePdf.PDFNet,
|
this._pdf.PDFNet,
|
||||||
this._translateService.instant('file-preview.excluded-from-redaction') as string,
|
this._translateService.instant('file-preview.excluded-from-redaction') as string,
|
||||||
17,
|
17,
|
||||||
'courier',
|
'courier',
|
||||||
@ -72,7 +71,7 @@ export class StampService {
|
|||||||
const watermark = await firstValueFrom(this._watermarkService.getWatermark(dossierTemplateId));
|
const watermark = await firstValueFrom(this._watermarkService.getWatermark(dossierTemplateId));
|
||||||
await stampPDFPage(
|
await stampPDFPage(
|
||||||
document,
|
document,
|
||||||
this._reusablePdf.PDFNet,
|
this._pdf.PDFNet,
|
||||||
watermark.text,
|
watermark.text,
|
||||||
watermark.fontSize,
|
watermark.fontSize,
|
||||||
watermark.fontType,
|
watermark.fontType,
|
||||||
|
|||||||
@ -4,13 +4,13 @@ import { HeaderElements } from '../utils/constants';
|
|||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { BASE_HREF } from '../../../tokens';
|
import { BASE_HREF } from '../../../tokens';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TooltipsService {
|
export class TooltipsService {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||||
private readonly _pdfViewer: ReusablePdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _userPreferenceService: UserPreferenceService,
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
) {}
|
) {}
|
||||||
@ -31,13 +31,13 @@ export class TooltipsService {
|
|||||||
|
|
||||||
updateTooltipsVisibility(): void {
|
updateTooltipsVisibility(): void {
|
||||||
const current = this._userPreferenceService.getFilePreviewTooltipsPreference();
|
const current = this._userPreferenceService.getFilePreviewTooltipsPreference();
|
||||||
this._pdfViewer.instance.UI.setAnnotationContentOverlayHandler(() => (current ? undefined : false));
|
this._pdf.instance.UI.setAnnotationContentOverlayHandler(() => (current ? undefined : false));
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleTooltips(): Promise<void> {
|
async toggleTooltips(): Promise<void> {
|
||||||
await this._userPreferenceService.toggleFilePreviewTooltipsPreference();
|
await this._userPreferenceService.toggleFilePreviewTooltipsPreference();
|
||||||
this.updateTooltipsVisibility();
|
this.updateTooltipsVisibility();
|
||||||
this._pdfViewer.instance.UI.updateElement(HeaderElements.TOGGLE_TOOLTIPS, {
|
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_TOOLTIPS, {
|
||||||
title: this.toggleTooltipsBtnTitle,
|
title: this.toggleTooltipsBtnTitle,
|
||||||
img: this.toggleTooltipsBtnIcon,
|
img: this.toggleTooltipsBtnIcon,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,12 +3,11 @@ import { IHeaderElement, RotationTypes } from '@red/domain';
|
|||||||
import { HeaderElements, HeaderElementType } from '../utils/constants';
|
import { HeaderElements, HeaderElementType } from '../utils/constants';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { BASE_HREF } from '../../../tokens';
|
import { BASE_HREF } from '../../../tokens';
|
||||||
import { PdfViewer } from './pdf-viewer.service';
|
|
||||||
import { TooltipsService } from './tooltips.service';
|
import { TooltipsService } from './tooltips.service';
|
||||||
import { environment } from '@environments/environment';
|
import { environment } from '@environments/environment';
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { PageRotationService } from './page-rotation.service';
|
import { PageRotationService } from './page-rotation.service';
|
||||||
import { ReusablePdfViewer } from '../../shared/components/reusable-pdf-viewer/reusable-pdf-viewer.service';
|
import { PdfViewer } from '../../shared/components/reusable-pdf-viewer/pdf-viewer.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ViewerHeaderConfigService {
|
export class ViewerHeaderConfigService {
|
||||||
@ -32,8 +31,7 @@ export class ViewerHeaderConfigService {
|
|||||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||||
private readonly _injector: Injector,
|
private readonly _injector: Injector,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
private readonly _pdfViewer: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _reusablePdf: ReusablePdfViewer,
|
|
||||||
private readonly _tooltipsService: TooltipsService,
|
private readonly _tooltipsService: TooltipsService,
|
||||||
private readonly _stateService: FilePreviewStateService,
|
private readonly _stateService: FilePreviewStateService,
|
||||||
) {}
|
) {}
|
||||||
@ -162,19 +160,19 @@ export class ViewerHeaderConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _closeCompareMode() {
|
private async _closeCompareMode() {
|
||||||
this._reusablePdf.closeCompareMode();
|
this._pdf.closeCompareMode();
|
||||||
const pdfNet = this._reusablePdf.PDFNet;
|
const pdfNet = this._pdf.PDFNet;
|
||||||
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||||
const blob = await this._stateService.blob;
|
const blob = await this._stateService.blob;
|
||||||
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
|
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
|
||||||
|
|
||||||
const filename = this._stateService.file.filename ?? 'document.pdf';
|
const filename = this._stateService.file.filename ?? 'document.pdf';
|
||||||
this._reusablePdf.instance.UI.loadDocument(currentDocument, { filename });
|
this._pdf.instance.UI.loadDocument(currentDocument, { filename });
|
||||||
|
|
||||||
this.disable([HeaderElements.CLOSE_COMPARE_BUTTON]);
|
this.disable([HeaderElements.CLOSE_COMPARE_BUTTON]);
|
||||||
this.enable([HeaderElements.COMPARE_BUTTON]);
|
this.enable([HeaderElements.COMPARE_BUTTON]);
|
||||||
|
|
||||||
this._pdfViewer.navigateToPage(1);
|
this._pdf.navigateTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compare(compareFileInput: ElementRef): IHeaderElement {
|
private _compare(compareFileInput: ElementRef): IHeaderElement {
|
||||||
@ -197,7 +195,7 @@ export class ViewerHeaderConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _updateElements(): void {
|
private _updateElements(): void {
|
||||||
this._reusablePdf.instance.UI.setHeaderItems(header => {
|
this._pdf.instance.UI.setHeaderItems(header => {
|
||||||
const enabledItems: IHeaderElement[] = [];
|
const enabledItems: IHeaderElement[] = [];
|
||||||
const groups: HeaderElementType[][] = [
|
const groups: HeaderElementType[][] = [
|
||||||
[HeaderElements.COMPARE_BUTTON, HeaderElements.CLOSE_COMPARE_BUTTON],
|
[HeaderElements.COMPARE_BUTTON, HeaderElements.CLOSE_COMPARE_BUTTON],
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { Component, ElementRef, ViewChild } from '@angular/core';
|
import { Component, ElementRef, ViewChild } from '@angular/core';
|
||||||
import { ReusablePdfViewer } from './reusable-pdf-viewer.service';
|
import { PdfViewer } from './pdf-viewer.service';
|
||||||
import { REDAnnotationManager } from '@shared/components/reusable-pdf-viewer/annotation-manager.service';
|
import { REDAnnotationManager } from '@shared/components/reusable-pdf-viewer/annotation-manager.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-reusable-pdf-viewer',
|
selector: 'redaction-pdf-viewer',
|
||||||
template: ' <div #viewer></div>',
|
template: ' <div #viewer></div>',
|
||||||
styles: [
|
styles: [
|
||||||
`
|
`
|
||||||
@ -17,10 +17,10 @@ import { REDAnnotationManager } from '@shared/components/reusable-pdf-viewer/ann
|
|||||||
`,
|
`,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ReusablePdfViewerComponent {
|
export class PdfViewerComponent {
|
||||||
#viewer: ElementRef;
|
#viewer: ElementRef;
|
||||||
|
|
||||||
constructor(readonly reusablePdfViewer: ReusablePdfViewer, private readonly _annotationManager: REDAnnotationManager) {}
|
constructor(private readonly _pdf: PdfViewer, private readonly _annotationManager: REDAnnotationManager) {}
|
||||||
|
|
||||||
@ViewChild('viewer', { static: true })
|
@ViewChild('viewer', { static: true })
|
||||||
set viewer(value: ElementRef) {
|
set viewer(value: ElementRef) {
|
||||||
@ -29,7 +29,7 @@ export class ReusablePdfViewerComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.#viewer = value;
|
this.#viewer = value;
|
||||||
const pdfInit = this.reusablePdfViewer.init(value.nativeElement as HTMLElement);
|
const pdfInit = this._pdf.init(value.nativeElement as HTMLElement);
|
||||||
pdfInit.then(instance => this._annotationManager.init(instance.Core.annotationManager));
|
pdfInit.then(instance => this._annotationManager.init(instance.Core.annotationManager));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import { Inject, Injectable, Injector } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||||
import { environment } from '@environments/environment';
|
import { environment } from '@environments/environment';
|
||||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../../tokens';
|
import { BASE_HREF_FN } from '../../../../tokens';
|
||||||
import { File } from '@red/domain';
|
import { File } from '@red/domain';
|
||||||
import { ErrorService, log, shareDistinctLast, shareLast } from '@iqser/common-ui';
|
import { ErrorService, shareDistinctLast, shareLast } from '@iqser/common-ui';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { debounceTime, map, tap } from 'rxjs/operators';
|
import { debounceTime, distinctUntilChanged, map, tap } from 'rxjs/operators';
|
||||||
import { BehaviorSubject, combineLatest, fromEvent, merge, Observable } from 'rxjs';
|
import { BehaviorSubject, combineLatest, fromEvent, merge, Observable } from 'rxjs';
|
||||||
import { ConfigService } from '@services/config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
@ -20,15 +20,18 @@ import DocumentViewer = Core.DocumentViewer;
|
|||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class ReusablePdfViewer {
|
export class PdfViewer {
|
||||||
readonly currentPage$ = this._activatedRoute.queryParamMap.pipe(
|
readonly currentPage$ = this._activatedRoute.queryParamMap.pipe(
|
||||||
map(params => Number(params.get('page') ?? '1')),
|
map(params => Number(params.get('page') ?? '1')),
|
||||||
shareDistinctLast(),
|
shareDistinctLast(),
|
||||||
);
|
);
|
||||||
documentViewer: DocumentViewer;
|
documentViewer: DocumentViewer;
|
||||||
|
/**
|
||||||
|
* @deprecated Use REDAnnotationManager service instead
|
||||||
|
*/
|
||||||
annotationManager: AnnotationManager;
|
annotationManager: AnnotationManager;
|
||||||
|
|
||||||
documentLoaded$: Observable<boolean>;
|
loaded$: Observable<boolean>;
|
||||||
pageComplete$: Observable<unknown>;
|
pageComplete$: Observable<unknown>;
|
||||||
compareMode$: Observable<boolean>;
|
compareMode$: Observable<boolean>;
|
||||||
totalPages$: Observable<number>;
|
totalPages$: Observable<number>;
|
||||||
@ -37,8 +40,6 @@ export class ReusablePdfViewer {
|
|||||||
readonly #compareMode$ = new BehaviorSubject(false);
|
readonly #compareMode$ = new BehaviorSubject(false);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(BASE_HREF_FN) private readonly _convertPath: BaseHrefFn,
|
|
||||||
private readonly _errorService: ErrorService,
|
|
||||||
private readonly _logger: NGXLogger,
|
private readonly _logger: NGXLogger,
|
||||||
private readonly _activatedRoute: ActivatedRoute,
|
private readonly _activatedRoute: ActivatedRoute,
|
||||||
private readonly _injector: Injector,
|
private readonly _injector: Injector,
|
||||||
@ -73,10 +74,19 @@ export class ReusablePdfViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentPage() {
|
||||||
|
const currentInternalPage = this.#currentInternalPage;
|
||||||
|
return this.isCompare ? Math.ceil(currentInternalPage / 2) : currentInternalPage;
|
||||||
|
}
|
||||||
|
|
||||||
get #totalPages$() {
|
get #totalPages$() {
|
||||||
const layoutChanged$ = fromEvent(this.documentViewer, 'layoutChanged');
|
const layoutChanged$ = fromEvent(this.documentViewer, 'layoutChanged');
|
||||||
const pageCount$ = layoutChanged$.pipe(map(() => this.pageCount));
|
const pageCount$ = layoutChanged$.pipe(
|
||||||
const docChanged$ = combineLatest([pageCount$, this.compareMode$]).pipe(log('total pages'));
|
map(() => this.pageCount),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
);
|
||||||
|
const docChanged$ = combineLatest([pageCount$, this.compareMode$]);
|
||||||
|
|
||||||
return docChanged$.pipe(map(([pageCount, isCompare]) => (isCompare ? Math.ceil(pageCount / 2) : pageCount)));
|
return docChanged$.pipe(map(([pageCount, isCompare]) => (isCompare ? Math.ceil(pageCount / 2) : pageCount)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +94,10 @@ export class ReusablePdfViewer {
|
|||||||
return fromEvent(this.documentViewer, 'pageComplete').pipe(debounceTime(300));
|
return fromEvent(this.documentViewer, 'pageComplete').pipe(debounceTime(300));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get #paginationOffset() {
|
||||||
|
return this.isCompare ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
get #documentLoaded$() {
|
get #documentLoaded$() {
|
||||||
const event$ = fromEvent(this.documentViewer, 'documentLoaded');
|
const event$ = fromEvent(this.documentViewer, 'documentLoaded');
|
||||||
const toBool$ = event$.pipe(map(() => true));
|
const toBool$ = event$.pipe(map(() => true));
|
||||||
@ -99,6 +113,29 @@ export class ReusablePdfViewer {
|
|||||||
return toBool$.pipe(tap(() => this._logger.info('[PDF] Document unloaded')));
|
return toBool$.pipe(tap(() => this._logger.info('[PDF] Document unloaded')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get #currentInternalPage() {
|
||||||
|
return this.documentViewer.getCurrentPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateTo(page: string | number) {
|
||||||
|
const parsedNumber = typeof page === 'string' ? parseInt(page, 10) : page;
|
||||||
|
const paginationOffset = this.#paginationOffset;
|
||||||
|
this.#navigateTo(paginationOffset === 2 ? parsedNumber * paginationOffset - 1 : parsedNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigatePreviousPage() {
|
||||||
|
if (this.#currentInternalPage > 1) {
|
||||||
|
this.#navigateTo(Math.max(this.#currentInternalPage - this.#paginationOffset, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateNextPage() {
|
||||||
|
const pageCount = this.pageCount;
|
||||||
|
if (this.#currentInternalPage < pageCount) {
|
||||||
|
this.#navigateTo(Math.min(this.#currentInternalPage + this.#paginationOffset, pageCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async init(htmlElement: HTMLElement) {
|
async init(htmlElement: HTMLElement) {
|
||||||
this.#instance = await this.#getInstance(htmlElement);
|
this.#instance = await this.#getInstance(htmlElement);
|
||||||
this._logger.info('[PDF] Initialized');
|
this._logger.info('[PDF] Initialized');
|
||||||
@ -106,10 +143,10 @@ export class ReusablePdfViewer {
|
|||||||
this.documentViewer = this.#instance.Core.documentViewer;
|
this.documentViewer = this.#instance.Core.documentViewer;
|
||||||
this.annotationManager = this.#instance.Core.annotationManager;
|
this.annotationManager = this.#instance.Core.annotationManager;
|
||||||
|
|
||||||
this.documentLoaded$ = merge(this.#documentUnloaded$, this.#documentLoaded$).pipe(shareLast());
|
this.loaded$ = merge(this.#documentUnloaded$, this.#documentLoaded$).pipe(shareLast());
|
||||||
this.compareMode$ = this.#compareMode$.asObservable();
|
this.compareMode$ = this.#compareMode$.asObservable();
|
||||||
this.pageComplete$ = this.#pageComplete$.pipe(shareLast());
|
this.pageComplete$ = this.#pageComplete$.pipe(shareLast());
|
||||||
this.totalPages$ = this.#totalPages$.pipe(shareLast());
|
this.totalPages$ = this.#totalPages$.pipe(shareDistinctLast());
|
||||||
this.#setSelectionMode();
|
this.#setSelectionMode();
|
||||||
this.#configureElements();
|
this.#configureElements();
|
||||||
this.#disableHotkeys();
|
this.#disableHotkeys();
|
||||||
@ -154,13 +191,13 @@ export class ReusablePdfViewer {
|
|||||||
async loadDocument(blob: Blob, file: File) {
|
async loadDocument(blob: Blob, file: File) {
|
||||||
this._logger.info('[PDF] Loading document', blob, file);
|
this._logger.info('[PDF] Loading document', blob, file);
|
||||||
const onError = () => {
|
const onError = () => {
|
||||||
this._errorService.set(DOCUMENT_LOADING_ERROR);
|
this._injector.get(ErrorService).set(DOCUMENT_LOADING_ERROR);
|
||||||
this._logger.error('[PDF] Error while loading document');
|
this._logger.error('[PDF] Error while loading document');
|
||||||
// this.stateService.reloadBlob();
|
// this.stateService.reloadBlob();
|
||||||
};
|
};
|
||||||
|
|
||||||
const pdfNet = this.#instance.Core.PDFNet;
|
const pdfNet = this.#instance.Core.PDFNet;
|
||||||
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
await pdfNet.initialize(environment.licenseKey ? window.atob(environment.licenseKey) : null);
|
||||||
const document = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
|
const document = await pdfNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
|
||||||
await document.flattenAnnotations(false);
|
await document.flattenAnnotations(false);
|
||||||
|
|
||||||
@ -187,6 +224,12 @@ export class ReusablePdfViewer {
|
|||||||
return annotation instanceof this.#instance.Core.Annotations.TextHighlightAnnotation;
|
return annotation instanceof this.#instance.Core.Annotations.TextHighlightAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#navigateTo(pageNumber: number) {
|
||||||
|
if (this.#currentInternalPage !== pageNumber) {
|
||||||
|
this.documentViewer.displayPageLocation(pageNumber, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#disableHotkeys(): void {
|
#disableHotkeys(): void {
|
||||||
DISABLED_HOTKEYS.forEach(key => this.#instance.UI.hotkeys.off(key));
|
DISABLED_HOTKEYS.forEach(key => this.#instance.UI.hotkeys.off(key));
|
||||||
}
|
}
|
||||||
@ -202,11 +245,12 @@ export class ReusablePdfViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#getInstance(htmlElement: HTMLElement) {
|
#getInstance(htmlElement: HTMLElement) {
|
||||||
|
const convertPath = this._injector.get(BASE_HREF_FN);
|
||||||
const options: WebViewerOptions = {
|
const options: WebViewerOptions = {
|
||||||
licenseKey: environment.licenseKey ? atob(environment.licenseKey) : null,
|
licenseKey: environment.licenseKey ? window.atob(environment.licenseKey) : null,
|
||||||
fullAPI: true,
|
fullAPI: true,
|
||||||
path: this._convertPath('/assets/wv-resources'),
|
path: convertPath('/assets/wv-resources'),
|
||||||
css: this._convertPath('/assets/pdftron/stylesheet.css'),
|
css: convertPath('/assets/pdftron/stylesheet.css'),
|
||||||
backendType: 'ems',
|
backendType: 'ems',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -154,4 +154,8 @@ export class File extends Entity<IFile> implements IFile {
|
|||||||
const routerPath = this.dossierArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE;
|
const routerPath = this.dossierArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE;
|
||||||
return this.canBeOpened ? `/main/${this.dossierTemplateId}/${routerPath}/${this.dossierId}/file/${this.fileId}` : undefined;
|
return this.canBeOpened ? `/main/${this.dossierTemplateId}/${routerPath}/${this.dossierId}/file/${this.fileId}` : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPageExcluded(page: number): boolean {
|
||||||
|
return this.excludedPages.includes(page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user