refactor: use Server Actions for read progress updates
- Create src/app/actions/read-progress.ts with updateReadProgress and deleteReadProgress - Update mark-as-read-button and mark-as-unread-button to use Server Actions - Update usePageNavigation hook to use Server Action - Use revalidateTag with 'min' profile for cache invalidation
This commit is contained in:
53
src/app/actions/read-progress.ts
Normal file
53
src/app/actions/read-progress.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { revalidateTag } from "next/cache";
|
||||||
|
import { BookService } from "@/lib/services/book.service";
|
||||||
|
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||||
|
import { AppError } from "@/utils/errors";
|
||||||
|
|
||||||
|
const HOME_CACHE_TAG = "home-data";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour la progression de lecture d'un livre
|
||||||
|
* Note: ne pas utiliser "use server" avec redirect - on gère manuellement
|
||||||
|
*/
|
||||||
|
export async function updateReadProgress(
|
||||||
|
bookId: string,
|
||||||
|
page: number,
|
||||||
|
completed: boolean = false
|
||||||
|
): Promise<{ success: boolean; message: string }> {
|
||||||
|
try {
|
||||||
|
await BookService.updateReadProgress(bookId, page, completed);
|
||||||
|
|
||||||
|
// Invalider le cache de la home (sans refresh auto)
|
||||||
|
revalidateTag(HOME_CACHE_TAG, "min");
|
||||||
|
|
||||||
|
return { success: true, message: "Progression mise à jour" };
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof AppError) {
|
||||||
|
return { success: false, message: error.message };
|
||||||
|
}
|
||||||
|
return { success: false, message: "Erreur lors de la mise à jour" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supprime la progression de lecture d'un livre
|
||||||
|
*/
|
||||||
|
export async function deleteReadProgress(
|
||||||
|
bookId: string
|
||||||
|
): Promise<{ success: boolean; message: string }> {
|
||||||
|
try {
|
||||||
|
await BookService.deleteReadProgress(bookId);
|
||||||
|
|
||||||
|
// Invalider le cache de la home (sans refresh auto)
|
||||||
|
revalidateTag(HOME_CACHE_TAG, "min");
|
||||||
|
|
||||||
|
return { success: true, message: "Progression supprimée" };
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof AppError) {
|
||||||
|
return { success: false, message: error.message };
|
||||||
|
}
|
||||||
|
return { success: false, message: "Erreur lors de la suppression" };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import { useRouter } from "next/navigation";
|
|||||||
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
|
import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service";
|
||||||
import type { KomgaBook } from "@/types/komga";
|
import type { KomgaBook } from "@/types/komga";
|
||||||
import logger from "@/lib/logger";
|
import logger from "@/lib/logger";
|
||||||
|
import { updateReadProgress } from "@/app/actions/read-progress";
|
||||||
|
|
||||||
interface UsePageNavigationProps {
|
interface UsePageNavigationProps {
|
||||||
book: KomgaBook;
|
book: KomgaBook;
|
||||||
@@ -48,11 +49,7 @@ export function usePageNavigation({
|
|||||||
try {
|
try {
|
||||||
ClientOfflineBookService.setCurrentPage(bookRef.current, page);
|
ClientOfflineBookService.setCurrentPage(bookRef.current, page);
|
||||||
const completed = page === pagesLengthRef.current;
|
const completed = page === pagesLengthRef.current;
|
||||||
await fetch(`/api/komga/books/${bookRef.current.id}/read-progress`, {
|
await updateReadProgress(bookRef.current.id, page, completed);
|
||||||
method: "PATCH",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ page, completed }),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ err: error }, "Sync error:");
|
logger.error({ err: error }, "Sync error:");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.serv
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import logger from "@/lib/logger";
|
import logger from "@/lib/logger";
|
||||||
|
import { updateReadProgress } from "@/app/actions/read-progress";
|
||||||
|
|
||||||
interface MarkAsReadButtonProps {
|
interface MarkAsReadButtonProps {
|
||||||
bookId: string;
|
bookId: string;
|
||||||
@@ -32,16 +33,11 @@ export function MarkAsReadButton({
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
ClientOfflineBookService.removeCurrentPageById(bookId);
|
ClientOfflineBookService.removeCurrentPageById(bookId);
|
||||||
const response = await fetch(`/api/komga/books/${bookId}/read-progress`, {
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ page: pagesCount, completed: true }),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
const result = await updateReadProgress(bookId, pagesCount, true);
|
||||||
throw new Error(t("books.actions.markAsRead.error.update"));
|
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error(result.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.serv
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import logger from "@/lib/logger";
|
import logger from "@/lib/logger";
|
||||||
|
import { deleteReadProgress } from "@/app/actions/read-progress";
|
||||||
|
|
||||||
interface MarkAsUnreadButtonProps {
|
interface MarkAsUnreadButtonProps {
|
||||||
bookId: string;
|
bookId: string;
|
||||||
@@ -23,12 +24,10 @@ export function MarkAsUnreadButton({ bookId, onSuccess, className }: MarkAsUnrea
|
|||||||
e.stopPropagation(); // Empêcher la propagation au parent
|
e.stopPropagation(); // Empêcher la propagation au parent
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/komga/books/${bookId}/read-progress`, {
|
const result = await deleteReadProgress(bookId);
|
||||||
method: "DELETE",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!result.success) {
|
||||||
throw new Error(t("books.actions.markAsUnread.error.update"));
|
throw new Error(result.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On supprime la page courante du localStorage seulement après que l'API a répondu
|
// On supprime la page courante du localStorage seulement après que l'API a répondu
|
||||||
|
|||||||
Reference in New Issue
Block a user