From da7221bcb089e224f59c803413037e5b3d5b5912 Mon Sep 17 00:00:00 2001 From: Simon Lemieux <1105380+simlmx@users.noreply.github.com> Date: Sun, 7 Jul 2024 16:17:16 +0000 Subject: [PATCH] View the game Rules in `dev-server` --- packages/dev-server/src/App.tsx | 287 +++++++++++++++++++++---------- packages/dev-server/src/store.ts | 10 ++ 2 files changed, 203 insertions(+), 94 deletions(-) diff --git a/packages/dev-server/src/App.tsx b/packages/dev-server/src/App.tsx index ee3cca7..157474b 100644 --- a/packages/dev-server/src/App.tsx +++ b/packages/dev-server/src/App.tsx @@ -152,6 +152,26 @@ const BoardForPlayer = ({ ); }; +function RulesWrapper({ + children, + messages, + locale, +}: { + children: ReactNode; + messages: Record; + locale: Locale; +}) { + useEffect(() => { + i18n.loadAndActivate({ locale, messages }); + }, [locale, messages]); + + return ( + +
{children}
+
+ ); +} + function getUserIds(numPlayers: number) { return Array(numPlayers) .fill(null) @@ -249,6 +269,10 @@ function ButtonRow({ children }: { children: ReactNode }) { return
{children}
; } +function capitalize(s: string): string { + return s && s[0].toUpperCase() + s.slice(1); +} + function Settings({ matchRef, resetMatch, @@ -275,6 +299,8 @@ function Settings({ const setVisibleUserId = useStore((state) => state.setVisibleUserId); const showDim = useStore((state) => state.showDimensions); const visibleUserId = useStore((state) => state.visibleUserId); + const view = useStore((state) => state.view); + const setView = useStore((state) => state.setView); const userIds = getUserIds(numPlayers); @@ -295,6 +321,15 @@ function Settings({
+ + + {(["game", "rules"] as const).map((v) => ( + + ))} + + @@ -308,73 +343,148 @@ function Settings({ ))} - - {userIds.map((userId) => ( - - ))} - - - - - - - - - - + {view === "game" && ( + <> + + {userIds.map((userId) => ( + + ))} + + + + + + + + + + + + )}
matchRef={matchRef} /> ); } +function PlayersIframes() { + const numPlayers = useStore((state) => state.numPlayers); + const visibleUserId = useStore((state) => state.visibleUserId); + const locale = useStore((state) => state.locale); + + const ref = useRef(null); + + return ( + <> + {getUserIds(numPlayers).map((userId) => { + if (visibleUserId === "all" || visibleUserId === userId) { + const { href } = window.location; + return ( +
+ + +
+ ); + } + return null; + })} + + ); +} + +function RulesIframe() { + const locale = useStore((state) => state.locale); + const { href } = window.location; + + const ref = useRef(null); + + return ( +
+ + +
+ ); +} + +function Dimensions({ + componentRef, +}: { + componentRef: RefObject; +}) { + const showDim = useStore((state) => state.showDimensions); + + const { width, height } = useSetDimensionCssVariablesOnResize(componentRef); + + if (!showDim) { + return null; + } + return ( +
+ {Math.round(width)} x {Math.round(height)} +
+ ); +} + function Main({ gameDef, matchSettings, @@ -386,6 +496,7 @@ function Main({ matchData?: any; gameData?: any; }) { + const view = useStore((state) => state.view); const locale = useStore((state) => state.locale); const layout = useStore((state) => state.layout); const visibleUserId = useStore((state) => state.visibleUserId); @@ -464,11 +575,6 @@ function Main({ setLoading(false); }, [resetMatch, locale, numPlayers]); - const ref = useRef(null); - const { width, height } = useSetDimensionCssVariablesOnResize(ref); - - const showDim = useStore((state) => state.showDimensions); - if (loading || !visibleUserId) { return
Loading
; } @@ -481,29 +587,7 @@ function Main({ layout === "row" ? "flex-row" : "flex-col", )} > - {getUserIds(numPlayers).map((userId) => { - if (visibleUserId === "all" || visibleUserId === userId) { - const { href } = window.location; - return ( -
- {showDim && ( -
- {Math.round(width)} x {Math.round(height)} -
- )} - -
- ); - } - return null; - })} + {view === "rules" ? : } {matchRef && ( @@ -526,6 +610,7 @@ type AllMessages = Record>; async function render({ gameDef, board, + rules, matchSettings = {}, matchData, gameData, @@ -534,25 +619,39 @@ async function render({ }: { gameDef: GameDef; board: () => Promise; + rules?: () => Promise; matchSettings?: MatchSettings; matchData?: any; gameData?: any; idName?: string; messages?: AllMessages; }) { - const urlParams = new URLSearchParams(window.location.search); - const userId = urlParams.get("u"); - function renderComponent(content: ReactNode) { const container = document.getElementById(idName); const root = createRoot(container!); return root.render(content); } + const urlParams = new URLSearchParams(window.location.search); + const locale = urlParams.get("l") as Locale; + const isRules = urlParams.get("v") === "rules"; + console.log(locale, isRules); + + if (isRules) { + if (!rules) { + throw new Error("Rules not provided"); + } + return renderComponent( + + {await rules()} + , + ); + } + + const userId = urlParams.get("u"); + // Is it the player's board? if (userId !== null) { - const locale = urlParams.get("l") as Locale; - const content = ( void; toggleCollapsed: () => void; setLayout: (layout: Layout) => void; setNumPlayers: (numPlayers: number) => void; setLocale: (locale: Locale) => void; setVisibleUserId: (userId: UserId | "all") => void; + setView: (view: View) => void; }; function saveToLocalStorage(state: Partial): void { @@ -63,6 +68,7 @@ function createStore({ showDimensions: false, locale: locales[0], locales, + view: "game", // toggleShowDimensions: () => { set((state) => ({ showDimensions: !state.showDimensions })); @@ -88,6 +94,10 @@ function createStore({ set({ visibleUserId: userId }); saveToLocalStorage(store.getState()); }, + setView: (view: View) => { + set({ view }); + saveToLocalStorage(store.getState()); + }, })); loadFromLocalStorage(store);