mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
165 lines
4.1 KiB
TypeScript
165 lines
4.1 KiB
TypeScript
import { HttpClient } from '@angular/common/http'
|
|
import { Component, Input, OnDestroy, ViewChild } from '@angular/core'
|
|
import { NgbPopover, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
|
import { PdfViewerComponent, PdfViewerModule } from 'ng2-pdf-viewer'
|
|
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
|
|
import { first, Subject, takeUntil } from 'rxjs'
|
|
import { Document } from 'src/app/data/document'
|
|
import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
|
|
import { DocumentTitlePipe } from 'src/app/pipes/document-title.pipe'
|
|
import { SafeUrlPipe } from 'src/app/pipes/safeurl.pipe'
|
|
import { DocumentService } from 'src/app/services/rest/document.service'
|
|
import { SettingsService } from 'src/app/services/settings.service'
|
|
|
|
@Component({
|
|
selector: 'pngx-preview-popup',
|
|
templateUrl: './preview-popup.component.html',
|
|
styleUrls: ['./preview-popup.component.scss'],
|
|
imports: [
|
|
NgbPopoverModule,
|
|
DocumentTitlePipe,
|
|
PdfViewerModule,
|
|
SafeUrlPipe,
|
|
NgxBootstrapIconsModule,
|
|
],
|
|
})
|
|
export class PreviewPopupComponent implements OnDestroy {
|
|
private _document: Document
|
|
@Input()
|
|
set document(document: Document) {
|
|
this._document = document
|
|
this.init()
|
|
}
|
|
|
|
get document(): Document {
|
|
return this._document
|
|
}
|
|
|
|
@Input()
|
|
link: string
|
|
|
|
@Input()
|
|
linkClasses: string = 'btn btn-sm btn-outline-secondary'
|
|
|
|
@Input()
|
|
linkTarget: string = '_blank'
|
|
|
|
@Input()
|
|
linkTitle: string = $localize`Open preview`
|
|
|
|
unsubscribeNotifier: Subject<any> = new Subject()
|
|
|
|
error = false
|
|
|
|
requiresPassword: boolean = false
|
|
|
|
previewText: string
|
|
|
|
@ViewChild('popover') popover: NgbPopover
|
|
|
|
@ViewChild('pdfViewer') pdfViewer: PdfViewerComponent
|
|
|
|
mouseOnPreview: boolean = false
|
|
|
|
popoverClass: string = 'shadow popover-preview'
|
|
|
|
get renderAsObject(): boolean {
|
|
return (this.isPdf && this.useNativePdfViewer) || !this.isPdf
|
|
}
|
|
|
|
get previewURL() {
|
|
return this.documentService.getPreviewUrl(this.document.id)
|
|
}
|
|
|
|
get useNativePdfViewer(): boolean {
|
|
return this.settingsService.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)
|
|
}
|
|
|
|
get isPdf(): boolean {
|
|
return (
|
|
this.document?.archived_file_name?.length > 0 ||
|
|
this.document?.mime_type?.includes('pdf')
|
|
)
|
|
}
|
|
|
|
constructor(
|
|
private settingsService: SettingsService,
|
|
private documentService: DocumentService,
|
|
private http: HttpClient
|
|
) {}
|
|
|
|
ngOnDestroy(): void {
|
|
this.unsubscribeNotifier.next(this)
|
|
}
|
|
|
|
init() {
|
|
if (this.document.mime_type?.includes('text')) {
|
|
this.http
|
|
.get(this.previewURL, { responseType: 'text' })
|
|
.pipe(first(), takeUntil(this.unsubscribeNotifier))
|
|
.subscribe({
|
|
next: (res) => {
|
|
this.previewText = res.toString()
|
|
},
|
|
error: (err) => {
|
|
this.error = err
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
onError(event: any) {
|
|
if (event.name == 'PasswordException') {
|
|
this.requiresPassword = true
|
|
} else {
|
|
this.error = true
|
|
}
|
|
}
|
|
|
|
onPageRendered() {
|
|
// Only triggered by the pngx pdf viewer
|
|
if (this.documentService.searchQuery) {
|
|
this.pdfViewer.eventBus.dispatch('find', {
|
|
query: this.documentService.searchQuery,
|
|
caseSensitive: false,
|
|
highlightAll: true,
|
|
phraseSearch: true,
|
|
})
|
|
}
|
|
}
|
|
|
|
get previewUrl() {
|
|
return this.documentService.getPreviewUrl(this.document.id)
|
|
}
|
|
|
|
mouseEnterPreview() {
|
|
this.mouseOnPreview = true
|
|
if (!this.popover.isOpen()) {
|
|
// we're going to open but hide to pre-load content during hover delay
|
|
this.popover.open()
|
|
this.popoverClass = 'shadow popover-preview pe-none opacity-0'
|
|
setTimeout(() => {
|
|
if (this.mouseOnPreview) {
|
|
// show popover
|
|
this.popoverClass = this.popoverClass.replace('pe-none opacity-0', '')
|
|
} else {
|
|
this.popover.close(true)
|
|
}
|
|
}, 600)
|
|
}
|
|
}
|
|
|
|
mouseLeavePreview() {
|
|
this.mouseOnPreview = false
|
|
}
|
|
|
|
public close(immediate: boolean = false) {
|
|
setTimeout(
|
|
() => {
|
|
if (!this.mouseOnPreview) this.popover.close()
|
|
},
|
|
immediate ? 0 : 300
|
|
)
|
|
}
|
|
}
|