import { BaseApiService } from "./base-api.service"; import { KomgaBook } from "@/types/komga"; import { ImageService } from "./image.service"; import { PreferencesService } from "./preferences.service"; export class BookService extends BaseApiService { static async getBook(bookId: string): Promise<{ book: KomgaBook; pages: number[] }> { try { return this.fetchWithCache<{ book: KomgaBook; pages: number[] }>( `book-${bookId}`, async () => { // Récupération des détails du tome const book = await this.fetchFromApi({ path: `books/${bookId}` }); // Récupération des pages du tome const pages = await this.fetchFromApi<{ number: number }[]>({ path: `books/${bookId}/pages`, }); return { book, pages: pages.map((page: any) => page.number), }; }, "BOOKS" ); } catch (error) { return this.handleError(error, "Impossible de récupérer le tome"); } } static async updateReadProgress( bookId: string, page: number, completed: boolean = false ): Promise { try { const config = await this.getKomgaConfig(); const url = this.buildUrl(config, `books/${bookId}/read-progress`); const headers = this.getAuthHeaders(config); headers.set("Content-Type", "application/json"); const response = await fetch(url, { method: "PATCH", headers, body: JSON.stringify({ page, completed }), }); if (!response.ok) { throw new Error("Erreur lors de la mise à jour de la progression"); } } catch (error) { return this.handleError(error, "Impossible de mettre à jour la progression"); } } static async deleteReadProgress(bookId: string): Promise { try { const config = await this.getKomgaConfig(); const url = this.buildUrl(config, `books/${bookId}/read-progress`); const headers = this.getAuthHeaders(config); headers.set("Content-Type", "application/json"); const response = await fetch(url, { method: "DELETE", headers, }); if (!response.ok) { throw new Error("Erreur lors de la suppression de la progression"); } } catch (error) { return this.handleError(error, "Impossible de supprimer la progression"); } } static async getPage(bookId: string, pageNumber: number): Promise { try { // Ajuster le numéro de page pour l'API Komga (zero-based) const adjustedPageNumber = pageNumber - 1; const response = await ImageService.getImage( `books/${bookId}/pages/${adjustedPageNumber}?zero_based=true` ); return new Response(response.buffer, { headers: { "Content-Type": response.contentType || "image/jpeg", "Cache-Control": "public, max-age=31536000, immutable", }, }); } catch (error) { throw this.handleError(error, "Impossible de récupérer la page"); } } static async getCover(bookId: string): Promise { try { // Récupérer les préférences de l'utilisateur const preferences = await PreferencesService.getPreferences(); // Si l'utilisateur préfère les vignettes, utiliser la miniature if (preferences.showThumbnails) { const response = await ImageService.getImage(`books/${bookId}/thumbnail`); return new Response(response.buffer, { headers: { "Content-Type": response.contentType || "image/jpeg", "Cache-Control": "public, max-age=31536000, immutable", }, }); } // Sinon, récupérer la première page return this.getPage(bookId, 1); } catch (error) { throw this.handleError(error, "Impossible de récupérer la couverture"); } } static getPageUrl(bookId: string, pageNumber: number): string { return `/api/komga/images/books/${bookId}/pages/${pageNumber}`; } static getPageThumbnailUrl(bookId: string, pageNumber: number): string { return `/api/komga/images/books/${bookId}/pages/${pageNumber}/thumbnail`; } static async getPageThumbnail(bookId: string, pageNumber: number): Promise { try { const response = await ImageService.getImage( `books/${bookId}/pages/${pageNumber}/thumbnail?zero_based=true` ); return new Response(response.buffer, { headers: { "Content-Type": response.contentType || "image/jpeg", "Cache-Control": "public, max-age=31536000, immutable", }, }); } catch (error) { throw this.handleError(error, "Impossible de récupérer la miniature de la page"); } } static getCoverUrl(bookId: string): string { return `/api/komga/images/books/${bookId}/thumbnail`; } }