129 lines
4.1 KiB
JavaScript
129 lines
4.1 KiB
JavaScript
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;
|
|
} |