From a7f2c89a08eea5dc18ef12c5812e408ee76456bb Mon Sep 17 00:00:00 2001 From: Pavel Prichodko <14926950+prichodko@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:37:46 +0100 Subject: [PATCH] feat(react): add global app context --- .../status-react/src/contexts/app-context.tsx | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 packages/status-react/src/contexts/app-context.tsx diff --git a/packages/status-react/src/contexts/app-context.tsx b/packages/status-react/src/contexts/app-context.tsx new file mode 100644 index 00000000..26517a73 --- /dev/null +++ b/packages/status-react/src/contexts/app-context.tsx @@ -0,0 +1,66 @@ +import React, { createContext, useContext, useMemo, useReducer } from 'react' + +import type { Dispatch, Reducer } from 'react' + +type Context = { + state: State + dispatch: Dispatch +} + +const AppContext = createContext(undefined) + +interface State { + view: 'loading' | 'error' | 'chat' | 'group-chat' | 'channel' | 'new-chat' + showMembers: boolean +} + +type Action = + | { type: 'NEW_CHAT' } + | { type: 'SET_CHANNEL'; channelId: string } + | { type: 'SET_CHAT'; chatId: string } + | { type: 'TOGGLE_MEMBERS' } + +const reducer: Reducer = (state, action) => { + switch (action.type) { + case 'NEW_CHAT': { + return { ...state, view: 'new-chat' } + } + case 'SET_CHAT': { + return { ...state, view: 'chat' } + } + case 'SET_CHANNEL': { + return { ...state, view: 'channel' } + } + case 'TOGGLE_MEMBERS': { + return { ...state, showMembers: !state.showMembers } + } + } +} + +const initialState: State = { + view: 'channel', + showMembers: true, +} + +interface Props { + children: React.ReactNode +} + +export const AppProvider = (props: Props) => { + const { children } = props + + const [state, dispatch] = useReducer(reducer, initialState) + const value = useMemo(() => ({ state, dispatch }), [state]) + + return {children} +} + +export function useAppState() { + const context = useContext(AppContext) + + if (!context) { + throw new Error('useAppState must be used within a AppProvider') + } + + return context +}