diff --git a/visions/ui/src/components/StateProvider.tsx b/visions/ui/src/components/StateProvider.tsx new file mode 100644 index 0000000..0d9f1fb --- /dev/null +++ b/visions/ui/src/components/StateProvider.tsx @@ -0,0 +1,48 @@ +import React, { createContext, PropsWithChildren, useEffect, useReducer } from "react"; +import { Tabletop } from "visions-types"; +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(initialState()); + +interface StateProviderProps { } + +export const StateProvider = ({ children }: PropsWithChildren) => { + const [state, dispatch] = useReducer(stateReducer, initialState()); + + return + {children} + ; +} + +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; + } + } +} + diff --git a/visions/ui/src/components/WebsocketProvider.tsx b/visions/ui/src/components/WebsocketProvider.tsx index 2358c69..90862de 100644 --- a/visions/ui/src/components/WebsocketProvider.tsx +++ b/visions/ui/src/components/WebsocketProvider.tsx @@ -2,19 +2,17 @@ import React, { createContext, PropsWithChildren, useEffect, useReducer } from " import useWebSocket from "react-use-websocket"; import { Message, Tabletop } from "visions-types"; -type TabletopState = { - tabletop: Tabletop; -} +type WebsocketState = { } -const initialState = (): TabletopState => ({ tabletop: { backgroundColor: { red: 0, green: 0, blue: 0 }, backgroundImage: undefined } }); - -export const WebsocketContext = createContext(initialState()); +export const WebsocketContext = createContext({}); interface WebsocketProviderProps { websocketUrl: string; } export const WebsocketProvider = ({ websocketUrl, children }: PropsWithChildren) => { + return
{children}
; +/* const { lastMessage } = useWebSocket(websocketUrl); const [state, dispatch] = useReducer(handleMessage, initialState()); @@ -29,8 +27,10 @@ export const WebsocketProvider = ({ websocketUrl, children }: PropsWithChildren< return ( {children} ); + */ } +/* const handleMessage = (state: TabletopState, message: Message): TabletopState => { console.log(message); switch (message.type) { @@ -42,3 +42,4 @@ const handleMessage = (state: TabletopState, message: Message): TabletopState => } } } +*/ diff --git a/visions/ui/src/views/Authentication/Authentication.css b/visions/ui/src/views/Authentication/Authentication.css index ca86baf..a938112 100644 --- a/visions/ui/src/views/Authentication/Authentication.css +++ b/visions/ui/src/views/Authentication/Authentication.css @@ -8,12 +8,6 @@ height: 100vh; } -.auth > div { - border: var(--border-standard); - border-radius: var(--border-radius-standard); - padding: var(--padding-m); -} - .auth__input-line { display: flex; justify-content: space-between; diff --git a/visions/ui/src/views/Authentication/Authentication.tsx b/visions/ui/src/views/Authentication/Authentication.tsx index 6997fe2..0315a8e 100644 --- a/visions/ui/src/views/Authentication/Authentication.tsx +++ b/visions/ui/src/views/Authentication/Authentication.tsx @@ -1,5 +1,6 @@ import React, { PropsWithChildren, ReactNode, useContext, useEffect, useState } from 'react'; import { Client } from '../../client'; +import { AppContext } from '../../components/StateProvider'; import { assertNever } from '../../plugins/Candela'; import './Authentication.css'; @@ -7,16 +8,14 @@ interface AuthenticationProps { client: Client; } -type AuthState = "NoAdmin" | "Unauthed" | "Authed"; - export const Authentication = ({ client, children }: PropsWithChildren) => { // No admin password set: prompt for the admin password // Password set, nobody logged in: prompt for login // User logged in: show the children - let [state, setState] = useState("Unauthed"); + let { auth } = useContext(AppContext); - switch (state) { + switch (auth.type) { case "NoAdmin": { return
@@ -43,7 +42,7 @@ export const Authentication = ({ client, children }: PropsWithChildren {children}
; } default: { - assertNever(state); + assertNever(auth); return
; } } diff --git a/visions/ui/src/views/GmView/GmView.tsx b/visions/ui/src/views/GmView/GmView.tsx index cc697f3..5d43745 100644 --- a/visions/ui/src/views/GmView/GmView.tsx +++ b/visions/ui/src/views/GmView/GmView.tsx @@ -1,5 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; import { Client, PlayingField } from '../../client'; +import { AppContext } from '../../components/StateProvider'; import { TabletopElement } from '../../components/Tabletop/Tabletop'; import { ThumbnailElement } from '../../components/Thumbnail/Thumbnail'; import { WebsocketContext } from '../../components/WebsocketProvider'; @@ -10,7 +11,7 @@ interface GmViewProps { } export const GmView = ({ client }: GmViewProps) => { - const { tabletop } = useContext(WebsocketContext); + const { tabletop } = useContext(AppContext); const [images, setImages] = useState([]); useEffect(() => { diff --git a/visions/ui/src/views/PlayerView/PlayerView.tsx b/visions/ui/src/views/PlayerView/PlayerView.tsx index a77125d..5ead8d2 100644 --- a/visions/ui/src/views/PlayerView/PlayerView.tsx +++ b/visions/ui/src/views/PlayerView/PlayerView.tsx @@ -4,6 +4,7 @@ import { WebsocketContext } from '../../components/WebsocketProvider'; import { Client } from '../../client'; import { TabletopElement } from '../../components/Tabletop/Tabletop'; import Candela from '../../plugins/Candela'; +import { AppContext } from '../../components/StateProvider'; const TEST_CHARSHEET_UUID = "12df9c09-1f2f-4147-8eda-a97bd2a7a803"; @@ -12,7 +13,7 @@ interface PlayerViewProps { } export const PlayerView = ({ client }: PlayerViewProps) => { - const { tabletop } = useContext(WebsocketContext); + const { tabletop } = useContext(AppContext); const [charsheet, setCharsheet] = useState(undefined);