import { Maybe } from '@/core'; import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, ViewChild, } from '@angular/core'; import { ButtonDirective } from 'primeng/button'; import { FileSelectEvent, FileUpload } from 'primeng/fileupload'; import { onSelectFileArgs } from './model'; @Component({ selector: 'app-shared-upload-file', templateUrl: './upload-file.component.html', imports: [FileUpload, ButtonDirective], }) export class SharedUploadFileComponent implements OnChanges, OnDestroy { @Input() loading: boolean = false; @Input() name: string = 'file'; @Input() accept: string = 'image/*'; @Input() maxSize: Maybe = 5 * 1024 * 1024; @Input() error: Maybe = null; @Input() hint: Maybe = null; @Input() initial_file_url: Maybe = null; @Output() onSelect = new EventEmitter(); @ViewChild(FileUpload) uploader?: FileUpload; filePreview: Maybe = null; private objectUrl: Maybe = null; ngOnChanges(changes: SimpleChanges) { if ('initial_file_url' in changes && !this.objectUrl) { this.filePreview = this.initial_file_url; } } ngAfterViewInit() { this.revokeObjectUrl(); if (this.initial_file_url && !this.objectUrl) { this.filePreview = this.initial_file_url; } } ngOnDestroy() { this.revokeObjectUrl(); } onSelectedFile($event: FileSelectEvent) { const file = $event.files?.[0]; if (!file) { return; } this.setPreviewFromFile(file); const payload = new FormData(); payload.append(this.name, file, file.name); this.onSelect.emit({ data: payload, file }); } onEditFile() { this.uploader?.choose(); } onDeleteFilePreview() { this.revokeObjectUrl(); this.filePreview = null; } private setPreviewFromFile(file: File) { this.revokeObjectUrl(); this.objectUrl = URL.createObjectURL(file); this.filePreview = this.objectUrl; } private revokeObjectUrl() { if (!this.objectUrl) { return; } this.filePreview = null; URL.revokeObjectURL(this.objectUrl); this.objectUrl = null; } }