Add preview for local files
continuous-integration/drone/push Build is passing Details

master
Alix JEUDI--LEMOINE 2 days ago
parent 6fa89932c5
commit 508cc0166e

@ -50,9 +50,9 @@
class="mt-2 text-sm text-gray-500 dark:text-gray-400" class="mt-2 text-sm text-gray-500 dark:text-gray-400"
> >
<ul> <ul>
<li *ngFor="let fileObj of fileNames" class="relative"> <li *ngFor="let fileObj of fileNames; let index = index; trackBy: trackByFile" class="relative" (mouseleave)="onFileNameMouseLeave()">
<span <span
(mouseenter)="onFileNameMouseEnter(fileObj.name)" (mouseenter)="onFileNameMouseEnter(fileObj)"
class="cursor-pointer underline decoration-dotted max-w-[160px] truncate inline-block align-middle z-50" class="cursor-pointer underline decoration-dotted max-w-[160px] truncate inline-block align-middle z-50"
[title]="fileObj.name" [title]="fileObj.name"
> >
@ -87,7 +87,7 @@
<span class="sr-only">Delete</span> <span class="sr-only">Delete</span>
</button> </button>
<div <div
*ngIf="hoveredFileName === fileObj.name && previewUrl" *ngIf="hoveredFile?.name === fileObj.name && previewUrl"
class="absolute top-8 left-20 z-20 border-2 border-gray-300 rounded shadow-lg" class="absolute top-8 left-20 z-20 border-2 border-gray-300 rounded shadow-lg"
> >
<img <img

@ -19,15 +19,16 @@ import { ImageService } from '../../services/image/image.service';
export class DragDropComponent implements OnChanges, OnDestroy { export class DragDropComponent implements OnChanges, OnDestroy {
@Input() initialFiles: { name: string; id?: string }[] = []; @Input() initialFiles: { name: string; id?: string }[] = [];
@Input() errorMessage: string = ''; @Input() errorMessage: string = '';
fileNames: { name: string; id?: string }[] = [];
@Output() filesSelected = new EventEmitter<FileList>(); @Output() filesSelected = new EventEmitter<FileList>();
@Output() fileRemoved = new EventEmitter<string>(); @Output() fileRemoved = new EventEmitter<string>();
hoveredFileName: string | null = null; fileNames: { name: string; id?: string }[] = [];
hoveredFile: { name: string; id?: string } | null = null;
previewUrl: string | null = null; previewUrl: string | null = null;
private objectUrl: string | null = null;
private imageUrlCache: { [id: string]: string } = {}; private imageUrlCache: { [id: string]: string } = {};
private lastHoveredId: string | null = null; private imageLocalUrlCache: { [name: string]: string } = {};
private inputFiles: Array<File> = [];
constructor(private imageService: ImageService) {} constructor(private imageService: ImageService) {}
@ -47,6 +48,7 @@ export class DragDropComponent implements OnChanges, OnDestroy {
const input = event.target as HTMLInputElement; const input = event.target as HTMLInputElement;
if (input.files) { if (input.files) {
this.updateFileNames(input.files); this.updateFileNames(input.files);
this.inputFiles = Array.from(input.files);
this.filesSelected.emit(input.files); this.filesSelected.emit(input.files);
} }
} }
@ -56,6 +58,7 @@ export class DragDropComponent implements OnChanges, OnDestroy {
event.stopPropagation(); event.stopPropagation();
if (event.dataTransfer && event.dataTransfer.files) { if (event.dataTransfer && event.dataTransfer.files) {
this.updateFileNames(event.dataTransfer.files); this.updateFileNames(event.dataTransfer.files);
this.inputFiles = Array.from(event.dataTransfer.files);
this.filesSelected.emit(event.dataTransfer.files); this.filesSelected.emit(event.dataTransfer.files);
} }
} }
@ -86,21 +89,23 @@ export class DragDropComponent implements OnChanges, OnDestroy {
} }
} }
async onFileNameMouseEnter(fileName: string): Promise<void> { async onFileNameMouseEnter(fileObj: { name: string; id?: string }): Promise<void> {
const fileObj = this.getFileByName(fileName); const localFile = this.inputFiles.find((f) => f.name === fileObj.name);
if (!fileObj) {
this.hoveredFileName = null; if (!fileObj && !localFile) {
this.hoveredFile = null;
this.previewUrl = null; this.previewUrl = null;
this.lastHoveredId = null;
return; return;
} }
// Ne rien faire si on survole le même fichier // Ne rien faire si on survole le même fichier
if (fileObj.id && this.lastHoveredId === fileObj.id) { if(this.hoveredFile === fileObj) {
return; return;
} }
this.hoveredFileName = fileName;
this.lastHoveredId = fileObj.id || null; if(fileObj && fileObj.id) { // Si le fichier est dans le backend
if (fileObj.id) { this.hoveredFile = fileObj;
if (this.imageUrlCache[fileObj.id]) { if (this.imageUrlCache[fileObj.id]) {
this.previewUrl = this.imageUrlCache[fileObj.id]; this.previewUrl = this.imageUrlCache[fileObj.id];
} else { } else {
@ -110,15 +115,22 @@ export class DragDropComponent implements OnChanges, OnDestroy {
this.previewUrl = objectUrl; this.previewUrl = objectUrl;
}); });
} }
} else { } else if (localFile) { // Si le fichier est dans l'input
this.previewUrl = null; this.hoveredFile = fileObj;
if (!this.imageLocalUrlCache[fileObj.name]) {
this.imageLocalUrlCache[fileObj.name] = URL.createObjectURL(localFile);
}
this.previewUrl = this.imageLocalUrlCache[fileObj.name];
} }
} }
@HostListener('mouseleave') onFileNameMouseLeave(): void { onFileNameMouseLeave(): void {
this.hoveredFileName = null; this.hoveredFile = null;
this.previewUrl = null; this.previewUrl = null;
this.lastHoveredId = null; }
trackByFile(index: number, file: { name: string; id?: string }): string {
return file.id || file.name;
} }
getFileByName(fileName: string): { name: string; id?: string } | undefined { getFileByName(fileName: string): { name: string; id?: string } | undefined {

Loading…
Cancel
Save