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
)
}
}