feat: Reader working, some work still need to be done
This commit is contained in:
parent
33f5a5568a
commit
668702b1fb
99
assets/react/app/presentation/context/MangaContext.jsx
Normal file
99
assets/react/app/presentation/context/MangaContext.jsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React, { createContext, useContext, useReducer, useCallback } from 'react';
|
||||
import { ApiMangaRepository } from '../../infrastructure/api/apiMangaRepository';
|
||||
import { GetMangaCollection } from '../../application/useCases/getMangaCollection';
|
||||
import { GetMangaDetail } from '../../application/useCases/getMangaDetail';
|
||||
|
||||
const mangaRepository = new ApiMangaRepository();
|
||||
const getMangaCollection = new GetMangaCollection(mangaRepository);
|
||||
const getMangaDetail = new GetMangaDetail(mangaRepository);
|
||||
|
||||
const MangaContext = createContext(null);
|
||||
|
||||
const initialState = {
|
||||
collection: null,
|
||||
detailedMangas: {},
|
||||
loading: false,
|
||||
error: null
|
||||
};
|
||||
|
||||
function mangaReducer(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_COLLECTION':
|
||||
return { ...state, collection: action.payload, loading: false, error: null };
|
||||
case 'SET_MANGA_DETAIL':
|
||||
return {
|
||||
...state,
|
||||
detailedMangas: {
|
||||
...state.detailedMangas,
|
||||
[action.payload.slug]: action.payload
|
||||
},
|
||||
loading: false,
|
||||
error: null
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export function MangaProvider({ children }) {
|
||||
const [state, dispatch] = useReducer(mangaReducer, initialState);
|
||||
|
||||
const loadCollection = useCallback(async () => {
|
||||
if (state.collection) return; // Return if already loaded
|
||||
|
||||
dispatch({ type: 'SET_LOADING', payload: true });
|
||||
try {
|
||||
const collection = await getMangaCollection.execute(1);
|
||||
dispatch({ type: 'SET_COLLECTION', payload: collection });
|
||||
} catch (error) {
|
||||
dispatch({ type: 'SET_ERROR', payload: 'Failed to load manga collection' });
|
||||
console.error(error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const loadMangaDetail = useCallback(async (slug) => {
|
||||
// Return cached data if available
|
||||
if (state.detailedMangas[slug]) return state.detailedMangas[slug];
|
||||
|
||||
dispatch({ type: 'SET_LOADING', payload: true });
|
||||
try {
|
||||
const manga = await getMangaDetail.execute(slug);
|
||||
dispatch({ type: 'SET_MANGA_DETAIL', payload: manga });
|
||||
return manga;
|
||||
} catch (error) {
|
||||
dispatch({ type: 'SET_ERROR', payload: 'Failed to load manga details' });
|
||||
console.error(error);
|
||||
return null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const getMangaFromCollection = useCallback((slug) => {
|
||||
if (!state.collection) return null;
|
||||
return state.collection.items.find(manga => manga.slug === slug);
|
||||
}, [state.collection]);
|
||||
|
||||
const value = {
|
||||
...state,
|
||||
loadCollection,
|
||||
loadMangaDetail,
|
||||
getMangaFromCollection
|
||||
};
|
||||
|
||||
return (
|
||||
<MangaContext.Provider value={value}>
|
||||
{children}
|
||||
</MangaContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useManga() {
|
||||
const context = useContext(MangaContext);
|
||||
if (!context) {
|
||||
throw new Error('useManga must be used within a MangaProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user