65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import React, { createContext, PropsWithChildren, useCallback, useEffect, useReducer } from "react";
|
|
import { Status, Tabletop } from "visions-types";
|
|
import { Client } from "../client";
|
|
import { assertNever } from "../plugins/Candela";
|
|
|
|
type AuthState = { type: "NoAdmin" } | { type: "Unauthed" } | { type: "Authed", username: string };
|
|
|
|
type TabletopState = {
|
|
auth: AuthState;
|
|
tabletop: Tabletop;
|
|
}
|
|
|
|
type StateAction = { type: "SetAuthState", state: AuthState }
|
|
| { type: "HandleMessage" };
|
|
|
|
const initialState = (): TabletopState => (
|
|
{
|
|
auth: { type: "Unauthed" },
|
|
tabletop: { backgroundColor: { red: 0, green: 0, blue: 0 }, backgroundImage: undefined }
|
|
}
|
|
);
|
|
|
|
export const AppContext = createContext<TabletopState>(initialState());
|
|
|
|
interface StateProviderProps { client: Client; }
|
|
|
|
export const StateProvider = ({ client, children }: PropsWithChildren<StateProviderProps>) => {
|
|
console.log("StateProvider");
|
|
const [state, dispatch] = useReducer(stateReducer, initialState());
|
|
|
|
useEffect(() => {
|
|
console.log("useCallback");
|
|
client.status().then((status: Status) => {
|
|
console.log("status: ", status);
|
|
if (status.admin_enabled) {
|
|
dispatch({ type: "SetAuthState", state: { type: "Unauthed" } });
|
|
} else {
|
|
dispatch({ type: "SetAuthState", state: { type: "NoAdmin" } });
|
|
}
|
|
})
|
|
},
|
|
[client]
|
|
);
|
|
|
|
return <AppContext.Provider value={state}>
|
|
{children}
|
|
</AppContext.Provider>;
|
|
}
|
|
|
|
const stateReducer = (state: TabletopState, action: StateAction): TabletopState => {
|
|
switch (action.type) {
|
|
case "SetAuthState": {
|
|
return { ...state, auth: action.state };
|
|
}
|
|
case "HandleMessage": {
|
|
return state;
|
|
}
|
|
default: {
|
|
assertNever(action);
|
|
return state;
|
|
}
|
|
}
|
|
}
|
|
|