import { useEffect, useState } from 'preact/hooks' import { createContext } from 'preact' import { server } from './api' import { User } from '../shared/model' type Metadata = { title?: string } export const MetadataContext = createContext({}) type CurrentUserHook = ( onLoaded?: (user: User | null) => void ) => [User | null, () => Promise] export const useCurrentUser: CurrentUserHook = onLoaded => { const [user, setUser] = useState(null) const logout = async () => { await server.post('/api/logout') setUser(null) } useEffect(() => { server.get('/api/current-user').then(user => { setUser(user) onLoaded?.(user) }) }, []) return [user, logout] } type ReadResourceFunction = ( url: string | (() => string), initialValue: T ) => [T, () => AbortController] export const useReadResource: ReadResourceFunction = (url, initialValue) => { const [value, setValue] = useState(initialValue) function refresh() { const controller = new AbortController() const realUrl = typeof url === 'function' ? url() : url fetch(realUrl, { signal: controller.signal }) .then(res => { if (res.ok) { return res.json() } else { return initialValue } }) .then(newValue => { setValue(newValue) }) return controller } useEffect(() => { const controller = refresh() return () => { controller.abort() } }, []) return [value, refresh] }