feat: ajout de la fonctionnalité de conversion de fichiers CBR en CBZ, intégration d'un nouveau store pour gérer l'état de conversion, création de composants Vue pour l'upload de fichiers et le suivi de la progression, ainsi que la mise à jour de l'API pour gérer les conversions. Amélioration de la documentation API pour inclure les nouveaux endpoints et formats de fichiers supportés.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-07-16 11:33:28 +02:00
parent 7a05934116
commit d9e78b5229
9 changed files with 1599 additions and 4 deletions

View File

@@ -0,0 +1,240 @@
import { defineStore } from 'pinia';
import { ApiConversionRepository } from '../../infrastructure/api/apiConversionRepository';
const conversionRepository = new ApiConversionRepository();
export const useConversionStore = defineStore('conversion', {
state: () => ({
// État de conversion
isConverting: false,
conversionProgress: 0,
conversionError: null,
conversionSuccess: false,
// Fichier en cours de traitement
currentFile: null,
convertedFile: null,
// Historique des conversions (optionnel)
conversionHistory: [],
// État de l'interface
isDragOver: false,
showSuccessMessage: false,
}),
getters: {
/**
* Indique si une conversion est en cours
*/
isProcessing: (state) => state.isConverting,
/**
* Indique si un fichier est sélectionné
*/
hasSelectedFile: (state) => state.currentFile !== null,
/**
* Indique si une conversion a réussi
*/
hasSucceeded: (state) => state.conversionSuccess && state.convertedFile !== null,
/**
* Indique si une erreur est présente
*/
hasError: (state) => state.conversionError !== null,
/**
* Obtient le nom du fichier actuel
*/
currentFileName: (state) => state.currentFile?.name || '',
/**
* Obtient la taille formatée du fichier actuel
*/
currentFileSize: (state) => {
if (!state.currentFile) return '';
const bytes = state.currentFile.size;
const sizes = ['octets', 'Ko', 'Mo', 'Go'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`;
},
/**
* Obtient le nombre de conversions réussies
*/
conversionCount: (state) => state.conversionHistory.length,
},
actions: {
/**
* Sélectionne un fichier pour la conversion
* @param {File} file - Le fichier sélectionné
*/
selectFile(file) {
// Validation du fichier
const validation = conversionRepository.validateFile(file);
if (!validation.isValid) {
this.setError(validation.error);
return false;
}
// Réinitialisation de l'état
this.clearError();
this.conversionSuccess = false;
this.convertedFile = null;
this.showSuccessMessage = false;
// Stockage du fichier
this.currentFile = file;
return true;
},
/**
* Lance la conversion du fichier sélectionné
*/
async convertCurrentFile() {
if (!this.currentFile) {
this.setError('Aucun fichier sélectionné');
return false;
}
try {
this.isConverting = true;
this.conversionProgress = 0;
this.clearError();
// Simulation du progrès (l'API ne fournit pas de progrès en temps réel)
const progressInterval = setInterval(() => {
if (this.conversionProgress < 90) {
this.conversionProgress += Math.random() * 10;
}
}, 100);
// Appel à l'API de conversion
const convertedFileBlob = await conversionRepository.convertFile(this.currentFile);
// Nettoyage de l'interval de progrès
clearInterval(progressInterval);
this.conversionProgress = 100;
// Stockage du fichier converti
this.convertedFile = convertedFileBlob;
this.conversionSuccess = true;
this.showSuccessMessage = true;
// Ajout à l'historique
this.addToHistory({
originalName: this.currentFile.name,
originalSize: this.currentFile.size,
convertedSize: convertedFileBlob.size,
timestamp: new Date().toISOString(),
});
return true;
} catch (error) {
this.setError(error.message || 'Erreur lors de la conversion');
return false;
} finally {
this.isConverting = false;
this.conversionProgress = 0;
}
},
/**
* Télécharge le fichier converti
*/
downloadConvertedFile() {
if (!this.convertedFile || !this.currentFile) {
this.setError('Aucun fichier converti disponible');
return;
}
try {
conversionRepository.downloadConvertedFile(
this.convertedFile,
this.currentFile.name
);
} catch (error) {
this.setError(error.message || 'Erreur lors du téléchargement');
}
},
/**
* Réinitialise l'état de conversion
*/
resetConversion() {
this.currentFile = null;
this.convertedFile = null;
this.conversionSuccess = false;
this.showSuccessMessage = false;
this.conversionProgress = 0;
this.clearError();
},
/**
* Définit une erreur
* @param {string} message - Message d'erreur
*/
setError(message) {
this.conversionError = message;
this.conversionSuccess = false;
this.showSuccessMessage = false;
},
/**
* Efface l'erreur actuelle
*/
clearError() {
this.conversionError = null;
},
/**
* Cache le message de succès
*/
hideSuccessMessage() {
this.showSuccessMessage = false;
},
/**
* Gère l'état du drag and drop
* @param {boolean} isDragOver - Indique si un fichier est survolé
*/
setDragOver(isDragOver) {
this.isDragOver = isDragOver;
},
/**
* Ajoute une conversion à l'historique
* @param {Object} conversionData - Données de la conversion
*/
addToHistory(conversionData) {
this.conversionHistory.unshift(conversionData);
// Limiter l'historique à 10 éléments
if (this.conversionHistory.length > 10) {
this.conversionHistory = this.conversionHistory.slice(0, 10);
}
},
/**
* Efface l'historique des conversions
*/
clearHistory() {
this.conversionHistory = [];
},
/**
* Valide un fichier sans le sélectionner
* @param {File} file - Le fichier à valider
* @returns {Object} - Résultat de la validation
*/
validateFile(file) {
return conversionRepository.validateFile(file);
}
}
});