|
|
|
@ -5,6 +5,7 @@ import {
|
|
|
|
|
Input,
|
|
|
|
|
OnDestroy,
|
|
|
|
|
OnInit,
|
|
|
|
|
ViewChild,
|
|
|
|
|
} from '@angular/core';
|
|
|
|
|
import {
|
|
|
|
|
FormBuilder,
|
|
|
|
@ -41,12 +42,14 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
|
|
@Input() isHomePage: boolean = false;
|
|
|
|
|
@Input() pin!: Pin;
|
|
|
|
|
|
|
|
|
|
@ViewChild(DragDropComponent) dragDropComponent!: DragDropComponent;
|
|
|
|
|
form!: FormGroup;
|
|
|
|
|
suggestions: any[] = [];
|
|
|
|
|
inputFocused: boolean = false;
|
|
|
|
|
files: any[] = [];
|
|
|
|
|
files: File[] = [];
|
|
|
|
|
isPinModalOpen: boolean = false;
|
|
|
|
|
@Input() modalId!: string;
|
|
|
|
|
uploadError: string = '';
|
|
|
|
|
|
|
|
|
|
private modalOpenSubscription!: Subscription;
|
|
|
|
|
private routerSubscription!: Subscription;
|
|
|
|
@ -98,8 +101,11 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
|
|
: '',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Initialiser les fichiers existants
|
|
|
|
|
this.files = this.pin?.files || [];
|
|
|
|
|
this.pin.files.forEach((file) => {
|
|
|
|
|
this.imageService.getImageMetadata(file).subscribe((metadata) => {
|
|
|
|
|
this.files.push(new File([], metadata.metadata.original_filename + "|" + file.toString(), { type: metadata.metadata.content_type }));
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// S'abonner aux changements d'état du modal
|
|
|
|
|
this.modalOpenSubscription = this.modalService
|
|
|
|
@ -191,106 +197,92 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
|
|
|
|
|
|
|
async onFilesReceived(files: FileList): Promise<void> {
|
|
|
|
|
// Ajouter les nouveaux fichiers à la liste existante
|
|
|
|
|
this.files = [...this.files, ...Array.from(files)];
|
|
|
|
|
this.files = [...this.files, ...Array.from(files).map((file) => file)];
|
|
|
|
|
this.uploadError = ''; // Réinitialiser l'erreur
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < files.length; i++) {
|
|
|
|
|
if (this.dragDropComponent) {
|
|
|
|
|
this.dragDropComponent.updateFileNamesFromFileList(files);
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('EditPinPopupComponent - dragDropComponent not available');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ne traiter que la première photo pour les métadonnées EXIF
|
|
|
|
|
if (files.length > 0) {
|
|
|
|
|
try {
|
|
|
|
|
const data = await this.exifService.getLocation(files[i]);
|
|
|
|
|
const data = await this.exifService.getLocation(files[0]);
|
|
|
|
|
if (data.latitude !== undefined && data.longitude !== undefined) {
|
|
|
|
|
try {
|
|
|
|
|
const address = await this.autocompleteService
|
|
|
|
|
.getAddressFromCoordinates(data.latitude, data.longitude)
|
|
|
|
|
.pipe(take(1))
|
|
|
|
|
.toPromise();
|
|
|
|
|
|
|
|
|
|
this.autocompleteService.getAddressFromCoordinates(data.latitude, data.longitude).subscribe((address) => {
|
|
|
|
|
if (address) {
|
|
|
|
|
this.form.get('location')?.setValue(address.display_name);
|
|
|
|
|
this.form.get('complete_address')?.setValue(address.display_name);
|
|
|
|
|
this.form.get('coordinates')?.setValue([data.latitude, data.longitude]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} catch (addressError) {
|
|
|
|
|
console.error("Erreur lors de la récupération de l'adresse:", addressError);
|
|
|
|
|
// Utiliser les coordonnées brutes en cas d'échec
|
|
|
|
|
this.form.get('location')?.setValue(`${data.latitude}, ${data.longitude}`);
|
|
|
|
|
this.form.get('complete_address')?.setValue(`${data.latitude}, ${data.longitude}`);
|
|
|
|
|
this.form.get('coordinates')?.setValue([data.latitude, data.longitude]);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Erreur :', error);
|
|
|
|
|
console.error(
|
|
|
|
|
'EditPinPopupComponent - Error processing EXIF data:',
|
|
|
|
|
error
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
submitForm(): void {
|
|
|
|
|
// Marquer tous les champs comme touched pour afficher les erreurs
|
|
|
|
|
Object.keys(this.form.controls).forEach(key => {
|
|
|
|
|
const control = this.form.get(key);
|
|
|
|
|
control?.markAsTouched();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (this.form.valid) {
|
|
|
|
|
const uploadObservables = this.files.map((file) => {
|
|
|
|
|
if(file.size === 0) {
|
|
|
|
|
if(file.name.includes("|")) {
|
|
|
|
|
return of({id: file.name.split("|")[1]});
|
|
|
|
|
} else {
|
|
|
|
|
this.uploadError = file.name + ' : ' + 'Image vide';
|
|
|
|
|
return of(null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return this.imageService.postImage(file).pipe(
|
|
|
|
|
catchError(error => {
|
|
|
|
|
this.uploadError = file.name + ' : ' + error.error.detail || 'Erreur lors de l\'upload de l\'image';
|
|
|
|
|
if (this.dragDropComponent) {
|
|
|
|
|
this.dragDropComponent.errorMessage = this.uploadError;
|
|
|
|
|
}
|
|
|
|
|
return of(null);
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
forkJoin(uploadObservables).subscribe((responses) => {
|
|
|
|
|
console.log(responses);
|
|
|
|
|
// Vérifier si toutes les réponses sont valides
|
|
|
|
|
if (responses.some(response => response === null)) {
|
|
|
|
|
return; // Ne pas continuer si une erreur s'est produite
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.files = responses.map((res: any) => res.id);
|
|
|
|
|
|
|
|
|
|
const coordinates = this.form.get('coordinates')?.value;
|
|
|
|
|
const pinData = {
|
|
|
|
|
...this.form.value,
|
|
|
|
|
files: this.files,
|
|
|
|
|
date: this.form.get('date')?.value || null,
|
|
|
|
|
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location
|
|
|
|
|
location: coordinates || [0, 0],
|
|
|
|
|
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Supprimer le champ coordinates qui n'est pas dans le modèle Pin
|
|
|
|
|
delete pinData.coordinates;
|
|
|
|
|
// Filtrer les fichiers qui sont déjà des IDs (images existantes)
|
|
|
|
|
const existingFiles = this.files.filter(
|
|
|
|
|
(file) => typeof file === 'string'
|
|
|
|
|
);
|
|
|
|
|
const newFiles = this.files.filter((file) => file instanceof File);
|
|
|
|
|
|
|
|
|
|
// Récupérer la date et la formater correctement
|
|
|
|
|
const dateValue = this.form.get('date')?.value;
|
|
|
|
|
const formattedDate = dateValue
|
|
|
|
|
? new Date(dateValue).toISOString()
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
if (newFiles.length > 0) {
|
|
|
|
|
// Upload des nouveaux fichiers
|
|
|
|
|
const uploadObservables = newFiles.map((file) =>
|
|
|
|
|
this.imageService.postImage(file)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
forkJoin(uploadObservables).subscribe((responses) => {
|
|
|
|
|
// Combiner les IDs des nouvelles images avec les IDs existants
|
|
|
|
|
const allFileIds = [
|
|
|
|
|
...existingFiles,
|
|
|
|
|
...responses.map((res: any) => res.id),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const pinData = {
|
|
|
|
|
...this.form.getRawValue(),
|
|
|
|
|
files: allFileIds,
|
|
|
|
|
user_id: this.pin.user_id,
|
|
|
|
|
date: formattedDate,
|
|
|
|
|
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location
|
|
|
|
|
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.pinService.updatePin(this.pin.id, pinData).subscribe(() => {
|
|
|
|
|
this.pinService.updatePin(this.pin.id, pinData)?.subscribe(() => {
|
|
|
|
|
this.mapReloadService.requestReload();
|
|
|
|
|
this.closePinModal();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// Si pas de nouveaux fichiers, mettre à jour directement avec les fichiers existants
|
|
|
|
|
const pinData = {
|
|
|
|
|
...this.form.getRawValue(),
|
|
|
|
|
files: existingFiles,
|
|
|
|
|
user_id: this.pin.user_id,
|
|
|
|
|
date: formattedDate,
|
|
|
|
|
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location
|
|
|
|
|
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.pinService.updatePin(this.pin.id, pinData).subscribe(() => {
|
|
|
|
|
this.mapReloadService.requestReload();
|
|
|
|
|
this.closePinModal();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
console.error('Le formulaire est invalide');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -300,19 +292,34 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
|
|
|
|
|
|
|
closePinModal() {
|
|
|
|
|
this.modalService.closeModal(this.modalId);
|
|
|
|
|
this.form.reset();
|
|
|
|
|
this.files = [];
|
|
|
|
|
this.uploadError = '';
|
|
|
|
|
if (this.dragDropComponent) {
|
|
|
|
|
this.dragDropComponent.updateFileNamesFromFileList(new DataTransfer().files);
|
|
|
|
|
this.dragDropComponent.errorMessage = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeFile(fileName: string): void {
|
|
|
|
|
const index = this.files.findIndex((file) => {
|
|
|
|
|
if (typeof file === 'string') {
|
|
|
|
|
return file === fileName;
|
|
|
|
|
}
|
|
|
|
|
return file.name === fileName;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
removeFile(fileName: string): void {
|
|
|
|
|
const index = this.files.findIndex((file) => file.name === fileName);
|
|
|
|
|
if (index > -1) {
|
|
|
|
|
this.files.splice(index, 1);
|
|
|
|
|
this.form.patchValue({ files: this.files });
|
|
|
|
|
this.uploadError = ''; // Réinitialiser l'erreur lors de la suppression d'un fichier
|
|
|
|
|
if (this.dragDropComponent) {
|
|
|
|
|
this.dragDropComponent.errorMessage = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mettre à jour le form control
|
|
|
|
|
const dataTransfer = new DataTransfer();
|
|
|
|
|
this.files.forEach((file) => dataTransfer.items.add(file as File));
|
|
|
|
|
this.form.patchValue({ files: dataTransfer.files });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getFileNames(): string[] {
|
|
|
|
|
return this.files.map(file => {
|
|
|
|
|
return file.name.split("|")[0];
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|