diff options
Diffstat (limited to 'client/src/user.js')
| -rw-r--r-- | client/src/user.js | 68 |
1 files changed, 23 insertions, 45 deletions
diff --git a/client/src/user.js b/client/src/user.js index dfa6384..340a4e3 100644 --- a/client/src/user.js +++ b/client/src/user.js @@ -1,71 +1,49 @@ import { h, createContext } from 'preact'; -import { useRef, useState, useCallback, useEffect, useContext } from 'preact/hooks'; -import { API_PREFIX } from './config'; - -const fetchJSON = async (url, method='GET', data=undefined) => { - const res = await fetch(API_PREFIX + url, { - method, - credentials: 'include', - headers: { 'content-type': data && 'application/json' }, - body: data && JSON.stringify(data), - }); - - if (res.status !== 200) - throw new Error("wrong status"); - - return res.json(); -}; +import { useEffect, useContext } from 'preact/hooks'; +import { useDispatcher, fetchJSON } from './actions'; const initialState = { user: null, discussions: [] }; -const reducer = async (action, ref) => { +const reducer = (action) => { switch (action.type) { case 'login': { const { username, password } = action; - await fetchJSON('/discdag/login', 'POST', { username, password }); - return await reducer({ type: 'refresh' }, ref); + return fetchJSON('/discdag/login', 'POST', { username, password }) + .then(() => reducer({ type: 'refresh' })); } case 'logout': { - await fetchJSON('/discdag/logout', 'POST'); - return await reducer({ type: 'refresh' }, ref); + return fetchJSON('/discdag/logout', 'POST') + .then(() => reducer({ type: 'refresh' })); } case 'refresh': { - const { user, discussions } = await fetchJSON('/discdag/list'); - return { ...ref.current, user, discussions }; + return fetchJSON('/discdag/list') + .then(({ user, discussions }) => + (state) => ({ ...state, user, discussions }) + ); } default: - throw new Error('Unexpected action'); + return undefined; } }; -const UserContext = createContext({ - state: initialState, - dispatch: () => { - throw new Error("no UserContext Provider!"); - }, -}); +const UserContext = createContext(initialState); export const UserContainer = ({ children }) => { - const ref = useRef(); - const [state, setState] = useState(initialState); - ref.current = state; - - const dispatch = useCallback(async (action) => { - const nextState = await reducer(action, ref); - setState(nextState); - }, [ref]); - + const { state, dispatch, DispatchProvider } = useDispatcher({ + reducer, + initialState, + }); useEffect(() => dispatch({ type: 'refresh' }), []); return ( - <UserContext.Provider value={{ state, dispatch }}> - {children} - </UserContext.Provider> + <DispatchProvider> + <UserContext.Provider value={state}> + {children} + </UserContext.Provider> + </DispatchProvider> ); }; -export const useUser = () => useContext(UserContext).state; -export const useDispatch = () => useContext(UserContext).dispatch; -export const useUserCtx = () => useContext(UserContext); +export const useUser = () => useContext(UserContext); |
