feat: Reader working, some work still need to be done

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-02-17 12:02:56 +01:00
parent 33f5a5568a
commit 668702b1fb
20 changed files with 994 additions and 127 deletions

View File

@@ -0,0 +1,129 @@
import React, { createContext, useContext, useReducer, useCallback } from 'react';
import { ApiReaderRepository } from '../../infrastructure/api/apiReaderRepository';
import { GetChapterContext } from '../../application/useCases/getChapterContext';
import { GetPage } from '../../application/useCases/getPage';
import { GetPages } from '../../application/useCases/getPages';
const readerRepository = new ApiReaderRepository();
const getChapterContext = new GetChapterContext(readerRepository);
const getPage = new GetPage(readerRepository);
const getPages = new GetPages(readerRepository);
const ReaderContext = createContext(null);
const initialState = {
context: null,
currentPage: 1,
pages: [],
loading: false,
error: null,
mode: 'classic', // 'classic' ou 'scrolling'
};
function readerReducer(state, action) {
switch (action.type) {
case 'SET_LOADING':
return { ...state, loading: action.payload };
case 'SET_ERROR':
return { ...state, error: action.payload, loading: false };
case 'SET_CONTEXT':
return { ...state, context: action.payload, loading: false };
case 'SET_PAGES':
return { ...state, pages: action.payload, loading: false };
case 'SET_CURRENT_PAGE':
return { ...state, currentPage: action.payload };
case 'SET_MODE':
return { ...state, mode: action.payload };
case 'RESET_STATE':
return initialState;
default:
return state;
}
}
export function ReaderProvider({ children }) {
const [state, dispatch] = useReducer(readerReducer, initialState);
const loadChapterContext = useCallback(async (chapterId) => {
dispatch({ type: 'RESET_STATE' });
dispatch({ type: 'SET_LOADING', payload: true });
try {
const context = await getChapterContext.execute(chapterId);
dispatch({ type: 'SET_CONTEXT', payload: context });
return true;
} catch (error) {
dispatch({ type: 'SET_ERROR', payload: error.response?.status === 404 ? 'Chapitre introuvable' : 'Erreur lors du chargement du chapitre' });
console.error(error);
return false;
}
}, []);
const loadPage = useCallback(async (chapterId, pageNumber) => {
dispatch({ type: 'SET_LOADING', payload: true });
try {
const page = await getPage.execute(chapterId, pageNumber);
dispatch({ type: 'SET_LOADING', payload: false });
return page;
} catch (error) {
const errorMessage = error.response?.status === 404
? 'Page introuvable'
: 'Erreur lors du chargement de la page';
dispatch({ type: 'SET_ERROR', payload: errorMessage });
dispatch({ type: 'SET_LOADING', payload: false });
return null;
}
}, []);
const loadPages = useCallback(async (chapterId) => {
dispatch({ type: 'SET_LOADING', payload: true });
try {
const { pages } = await getPages.execute(chapterId);
if (!pages || pages.length === 0) {
dispatch({ type: 'SET_ERROR', payload: 'Aucune page trouvée dans ce chapitre' });
return false;
}
dispatch({ type: 'SET_PAGES', payload: pages });
dispatch({ type: 'SET_CURRENT_PAGE', payload: 1 });
dispatch({ type: 'SET_LOADING', payload: false });
return true;
} catch (error) {
const errorMessage = error.response?.status === 404
? 'Chapitre introuvable'
: 'Erreur lors du chargement des pages';
dispatch({ type: 'SET_ERROR', payload: errorMessage });
dispatch({ type: 'SET_LOADING', payload: false });
return false;
}
}, []);
const setCurrentPage = useCallback((pageNumber) => {
dispatch({ type: 'SET_CURRENT_PAGE', payload: pageNumber });
}, []);
const setMode = useCallback((mode) => {
dispatch({ type: 'SET_MODE', payload: mode });
}, []);
const value = {
...state,
loadChapterContext,
loadPage,
loadPages,
setCurrentPage,
setMode,
};
return (
<ReaderContext.Provider value={value}>
{children}
</ReaderContext.Provider>
);
}
export function useReader() {
const context = useContext(ReaderContext);
if (!context) {
throw new Error('useReader must be used within a ReaderProvider');
}
return context;
}