mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-09 23:49:29 -06:00
Enhancement: pngx pdf viewer (#12043)
This commit is contained in:
@@ -456,17 +456,15 @@
|
||||
@case (ContentRenderType.PDF) {
|
||||
@if (!useNativePdfViewer) {
|
||||
<div class="preview-sticky pdf-viewer-container">
|
||||
<pdf-viewer
|
||||
<pngx-pdf-viewer
|
||||
[src]="{ url: previewUrl, password: password }"
|
||||
[original-size]="false"
|
||||
[show-borders]="true"
|
||||
[show-all]="true"
|
||||
[renderMode]="PdfRenderMode.All"
|
||||
[(page)]="previewCurrentPage"
|
||||
[zoom-scale]="previewZoomScale"
|
||||
[zoomScale]="previewZoomScale"
|
||||
[zoom]="previewZoomSetting"
|
||||
(error)="onError($event)"
|
||||
(after-load-complete)="pdfPreviewLoaded($event)">
|
||||
</pdf-viewer>
|
||||
(loadError)="onError($event)"
|
||||
(afterLoadComplete)="pdfPreviewLoaded($event)">
|
||||
</pngx-pdf-viewer>
|
||||
</div>
|
||||
} @else {
|
||||
<object [data]="previewUrl | safeUrl" class="preview-sticky" width="100%"></object>
|
||||
|
||||
@@ -5,20 +5,15 @@
|
||||
}
|
||||
|
||||
.pdf-viewer-container {
|
||||
padding-top: 10px;
|
||||
padding: 8px;
|
||||
background-color: gray;
|
||||
|
||||
pdf-viewer {
|
||||
pngx-pdf-viewer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .ng2-pdf-viewer-container .page {
|
||||
--page-margin: 0 auto 10px;
|
||||
--page-border: 0;
|
||||
}
|
||||
|
||||
.btn-group .dropdown-toggle-split {
|
||||
border-top-right-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
|
||||
@@ -69,8 +69,11 @@ import { environment } from 'src/environments/environment'
|
||||
import { ConfirmDialogComponent } from '../common/confirm-dialog/confirm-dialog.component'
|
||||
import { PasswordRemovalConfirmDialogComponent } from '../common/confirm-dialog/password-removal-confirm-dialog/password-removal-confirm-dialog.component'
|
||||
import { CustomFieldsDropdownComponent } from '../common/custom-fields-dropdown/custom-fields-dropdown.component'
|
||||
import {
|
||||
PdfZoomLevel,
|
||||
PdfZoomScale,
|
||||
} from '../common/pdf-viewer/pdf-viewer.types'
|
||||
import { DocumentDetailComponent } from './document-detail.component'
|
||||
import { ZoomSetting } from './zoom-setting'
|
||||
|
||||
const doc: Document = {
|
||||
id: 3,
|
||||
@@ -860,7 +863,7 @@ describe('DocumentDetailComponent', () => {
|
||||
|
||||
it('should support zoom controls', () => {
|
||||
initNormally()
|
||||
component.setZoom(ZoomSetting.One) // from select
|
||||
component.setZoom(PdfZoomLevel.One) // from select
|
||||
expect(component.previewZoomSetting).toEqual('1')
|
||||
component.increaseZoom()
|
||||
expect(component.previewZoomSetting).toEqual('1.5')
|
||||
@@ -868,18 +871,18 @@ describe('DocumentDetailComponent', () => {
|
||||
expect(component.previewZoomSetting).toEqual('2')
|
||||
component.decreaseZoom()
|
||||
expect(component.previewZoomSetting).toEqual('1.5')
|
||||
component.setZoom(ZoomSetting.One) // from select
|
||||
component.setZoom(PdfZoomLevel.One) // from select
|
||||
component.decreaseZoom()
|
||||
expect(component.previewZoomSetting).toEqual('.75')
|
||||
|
||||
component.setZoom(ZoomSetting.PageFit) // from select
|
||||
component.setZoom(PdfZoomScale.PageFit) // from select
|
||||
expect(component.previewZoomScale).toEqual('page-fit')
|
||||
expect(component.previewZoomSetting).toEqual('1')
|
||||
component.increaseZoom()
|
||||
expect(component.previewZoomSetting).toEqual('1.5')
|
||||
expect(component.previewZoomScale).toEqual('page-width')
|
||||
|
||||
component.setZoom(ZoomSetting.PageFit) // from select
|
||||
component.setZoom(PdfZoomScale.PageFit) // from select
|
||||
expect(component.previewZoomScale).toEqual('page-fit')
|
||||
expect(component.previewZoomSetting).toEqual('1')
|
||||
component.decreaseZoom()
|
||||
@@ -889,10 +892,10 @@ describe('DocumentDetailComponent', () => {
|
||||
|
||||
it('should select correct zoom setting in dropdown', () => {
|
||||
initNormally()
|
||||
component.setZoom(ZoomSetting.PageFit)
|
||||
expect(component.currentZoom).toEqual(ZoomSetting.PageFit)
|
||||
component.setZoom(ZoomSetting.Quarter)
|
||||
expect(component.currentZoom).toEqual(ZoomSetting.Quarter)
|
||||
component.setZoom(PdfZoomScale.PageFit)
|
||||
expect(component.currentZoom).toEqual(PdfZoomScale.PageFit)
|
||||
component.setZoom(PdfZoomLevel.Quarter)
|
||||
expect(component.currentZoom).toEqual(PdfZoomLevel.Quarter)
|
||||
})
|
||||
|
||||
it('should support updating notes dynamically', () => {
|
||||
@@ -1017,7 +1020,7 @@ describe('DocumentDetailComponent', () => {
|
||||
settingsService.set(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, false)
|
||||
expect(component.useNativePdfViewer).toBeFalsy()
|
||||
fixture.detectChanges()
|
||||
expect(fixture.debugElement.query(By.css('pdf-viewer'))).not.toBeNull()
|
||||
expect(fixture.debugElement.query(By.css('pngx-pdf-viewer'))).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should display native pdf viewer if enabled', () => {
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
NgbNavModule,
|
||||
} from '@ng-bootstrap/ng-bootstrap'
|
||||
import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms'
|
||||
import { PDFDocumentProxy, PdfViewerModule } from 'ng2-pdf-viewer'
|
||||
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
||||
import { DeviceDetectorService } from 'ngx-device-detector'
|
||||
import { BehaviorSubject, Observable, of, Subject, timer } from 'rxjs'
|
||||
@@ -108,13 +107,19 @@ import { UrlComponent } from '../common/input/url/url.component'
|
||||
import { PageHeaderComponent } from '../common/page-header/page-header.component'
|
||||
import { PdfEditorEditMode } from '../common/pdf-editor/pdf-editor-edit-mode'
|
||||
import { PDFEditorComponent } from '../common/pdf-editor/pdf-editor.component'
|
||||
import { PngxPdfViewerComponent } from '../common/pdf-viewer/pdf-viewer.component'
|
||||
import {
|
||||
PdfRenderMode,
|
||||
PdfZoomLevel,
|
||||
PdfZoomScale,
|
||||
PngxPdfDocumentProxy,
|
||||
} from '../common/pdf-viewer/pdf-viewer.types'
|
||||
import { ShareLinksDialogComponent } from '../common/share-links-dialog/share-links-dialog.component'
|
||||
import { SuggestionsDropdownComponent } from '../common/suggestions-dropdown/suggestions-dropdown.component'
|
||||
import { DocumentHistoryComponent } from '../document-history/document-history.component'
|
||||
import { DocumentNotesComponent } from '../document-notes/document-notes.component'
|
||||
import { ComponentWithPermissions } from '../with-permissions/with-permissions.component'
|
||||
import { MetadataCollapseComponent } from './metadata-collapse/metadata-collapse.component'
|
||||
import { ZoomSetting } from './zoom-setting'
|
||||
|
||||
enum DocumentDetailNavIDs {
|
||||
Details = 1,
|
||||
@@ -168,16 +173,17 @@ enum ContentRenderType {
|
||||
NgbNavModule,
|
||||
NgbDropdownModule,
|
||||
NgxBootstrapIconsModule,
|
||||
PdfViewerModule,
|
||||
TextAreaComponent,
|
||||
RouterModule,
|
||||
PngxPdfViewerComponent,
|
||||
],
|
||||
})
|
||||
export class DocumentDetailComponent
|
||||
extends ComponentWithPermissions
|
||||
implements OnInit, OnDestroy, DirtyComponent
|
||||
{
|
||||
private documentsService = inject(DocumentService)
|
||||
PdfRenderMode = PdfRenderMode
|
||||
documentsService = inject(DocumentService)
|
||||
private route = inject(ActivatedRoute)
|
||||
private tagService = inject(TagService)
|
||||
private correspondentService = inject(CorrespondentService)
|
||||
@@ -246,8 +252,8 @@ export class DocumentDetailComponent
|
||||
|
||||
previewCurrentPage: number = 1
|
||||
previewNumPages: number
|
||||
previewZoomSetting: ZoomSetting = ZoomSetting.One
|
||||
previewZoomScale: ZoomSetting = ZoomSetting.PageWidth
|
||||
previewZoomSetting: PdfZoomLevel = PdfZoomLevel.One
|
||||
previewZoomScale: PdfZoomScale = PdfZoomScale.PageWidth
|
||||
|
||||
store: BehaviorSubject<any>
|
||||
isDirty$: Observable<boolean>
|
||||
@@ -503,7 +509,9 @@ export class DocumentDetailComponent
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.setZoom(this.settings.get(SETTINGS_KEYS.PDF_VIEWER_ZOOM_SETTING))
|
||||
this.setZoom(
|
||||
this.settings.get(SETTINGS_KEYS.PDF_VIEWER_ZOOM_SETTING) as PdfZoomScale
|
||||
)
|
||||
this.documentForm.valueChanges
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe((values) => {
|
||||
@@ -1204,7 +1212,7 @@ export class DocumentDetailComponent
|
||||
})
|
||||
}
|
||||
|
||||
pdfPreviewLoaded(pdf: PDFDocumentProxy) {
|
||||
pdfPreviewLoaded(pdf: PngxPdfDocumentProxy) {
|
||||
this.previewNumPages = pdf.numPages
|
||||
if (this.password) this.requiresPassword = false
|
||||
setTimeout(() => {
|
||||
@@ -1225,31 +1233,33 @@ export class DocumentDetailComponent
|
||||
}
|
||||
}
|
||||
|
||||
setZoom(setting: ZoomSetting) {
|
||||
if (ZoomSetting.PageFit === setting || ZoomSetting.PageWidth === setting) {
|
||||
setZoom(setting: PdfZoomScale | PdfZoomLevel) {
|
||||
if (
|
||||
setting === PdfZoomScale.PageFit ||
|
||||
setting === PdfZoomScale.PageWidth
|
||||
) {
|
||||
this.previewZoomScale = setting
|
||||
this.previewZoomSetting = ZoomSetting.One
|
||||
} else {
|
||||
this.previewZoomSetting = setting
|
||||
this.previewZoomScale = ZoomSetting.PageWidth
|
||||
this.previewZoomSetting = PdfZoomLevel.One
|
||||
return
|
||||
}
|
||||
this.previewZoomSetting = setting
|
||||
this.previewZoomScale = PdfZoomScale.PageWidth
|
||||
}
|
||||
|
||||
get zoomSettings() {
|
||||
return Object.values(ZoomSetting).filter(
|
||||
(setting) => setting !== ZoomSetting.PageWidth
|
||||
)
|
||||
return [PdfZoomScale.PageFit, ...Object.values(PdfZoomLevel)]
|
||||
}
|
||||
|
||||
get currentZoom() {
|
||||
if (this.previewZoomScale === ZoomSetting.PageFit) {
|
||||
return ZoomSetting.PageFit
|
||||
} else return this.previewZoomSetting
|
||||
if (this.previewZoomScale === PdfZoomScale.PageFit) {
|
||||
return PdfZoomScale.PageFit
|
||||
}
|
||||
return this.previewZoomSetting
|
||||
}
|
||||
|
||||
getZoomSettingTitle(setting: ZoomSetting): string {
|
||||
getZoomSettingTitle(setting: PdfZoomScale | PdfZoomLevel): string {
|
||||
switch (setting) {
|
||||
case ZoomSetting.PageFit:
|
||||
case PdfZoomScale.PageFit:
|
||||
return $localize`Page Fit`
|
||||
default:
|
||||
return `${parseFloat(setting) * 100}%`
|
||||
@@ -1257,25 +1267,24 @@ export class DocumentDetailComponent
|
||||
}
|
||||
|
||||
increaseZoom(): void {
|
||||
let currentIndex = Object.values(ZoomSetting).indexOf(
|
||||
this.previewZoomSetting
|
||||
)
|
||||
if (this.previewZoomScale === ZoomSetting.PageFit) currentIndex = 5
|
||||
this.previewZoomScale = ZoomSetting.PageWidth
|
||||
const zoomLevels = Object.values(PdfZoomLevel)
|
||||
let currentIndex = zoomLevels.indexOf(this.previewZoomSetting)
|
||||
if (this.previewZoomScale === PdfZoomScale.PageFit) {
|
||||
currentIndex = zoomLevels.indexOf(PdfZoomLevel.One)
|
||||
}
|
||||
this.previewZoomScale = PdfZoomScale.PageWidth
|
||||
this.previewZoomSetting =
|
||||
Object.values(ZoomSetting)[
|
||||
Math.min(Object.values(ZoomSetting).length - 1, currentIndex + 1)
|
||||
]
|
||||
zoomLevels[Math.min(zoomLevels.length - 1, currentIndex + 1)]
|
||||
}
|
||||
|
||||
decreaseZoom(): void {
|
||||
let currentIndex = Object.values(ZoomSetting).indexOf(
|
||||
this.previewZoomSetting
|
||||
)
|
||||
if (this.previewZoomScale === ZoomSetting.PageFit) currentIndex = 4
|
||||
this.previewZoomScale = ZoomSetting.PageWidth
|
||||
this.previewZoomSetting =
|
||||
Object.values(ZoomSetting)[Math.max(2, currentIndex - 1)]
|
||||
const zoomLevels = Object.values(PdfZoomLevel)
|
||||
let currentIndex = zoomLevels.indexOf(this.previewZoomSetting)
|
||||
if (this.previewZoomScale === PdfZoomScale.PageFit) {
|
||||
currentIndex = zoomLevels.indexOf(PdfZoomLevel.ThreeQuarters)
|
||||
}
|
||||
this.previewZoomScale = PdfZoomScale.PageWidth
|
||||
this.previewZoomSetting = zoomLevels[Math.max(0, currentIndex - 1)]
|
||||
}
|
||||
|
||||
get showPermissions(): boolean {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
export enum ZoomSetting {
|
||||
PageFit = 'page-fit',
|
||||
PageWidth = 'page-width',
|
||||
Quarter = '.25',
|
||||
Half = '.5',
|
||||
ThreeQuarters = '.75',
|
||||
One = '1',
|
||||
OneAndHalf = '1.5',
|
||||
Two = '2',
|
||||
Three = '3',
|
||||
}
|
||||
Reference in New Issue
Block a user