-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathInProgressGame.tsx
99 lines (90 loc) · 3.32 KB
/
InProgressGame.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"use client"
import React, { useMemo } from "react"
import { useMediaQuery } from "@react-hook/media-query"
import type { ClientQuestionStrategy } from "~/lib/games/question-types/base"
import { ChatHistoryPanelImpl } from "~/components/game-screen/ChatHistoryPanel"
import MobileMultiSelectPanel from "~/components/game-screen/MobileMultiSelectPanel"
import QuestionDescription from "~/components/game-screen/QuestionDescription"
import { getQuestionType } from "~/lib/games/question-types/base"
import { createClientQuestionStrategy } from "~/lib/games/question-types/client_create"
import { type NotWaitingForPlayersGameState } from "~/lib/games/types"
import { createDefaultLayout, createDefaultMobileLayout } from "~/lib/surfaces/panels/layouts"
import PanelSkeleton from "~/lib/surfaces/panels/PanelSkeleton"
import CodeRunning from "./CodeRunning"
import CodeRunningFooter from "./CodeRunningFooter"
import { CodeViewImpl } from "./CodeView"
import MultiSelectPanel from "./MultiSelectPanel"
export const MOBILE_VIEWPORT = "(max-width: 640px)"
function useViews(props: {
gameInfo: NotWaitingForPlayersGameState
questionStrategy: ClientQuestionStrategy
}) {
return useMemo(() => {
const QuestionViewImpl = {
key: "description",
className: "bg-card p-4",
component: (
<QuestionDescription
questionStrategy={props.questionStrategy}
gameMode={props.gameInfo.mode}
/>
),
}
const CodeRunningViewImpl = {
key: "run-code",
className: "p-4",
component: <CodeRunning questionStrategy={props.questionStrategy} />,
footer: <CodeRunningFooter />,
footerClassName: "px-4 pb-4 pt-2",
}
const MobileLayout = {
key: "mobile-layout",
className: "",
component: (
<MobileMultiSelectPanel
panels={[
{ ...QuestionViewImpl, title: "Question" },
{ ...CodeRunningViewImpl, title: "Run code", footerClassName: "p-0" },
{ ...ChatHistoryPanelImpl, title: "Chat log" },
]}
/>
),
}
const QuestionAndTestCasesImpl = {
key: "question-and-testcases",
className: "bg-card",
component: (
<MultiSelectPanel
panels={[
{ ...QuestionViewImpl, title: "Question" },
{ ...ChatHistoryPanelImpl, title: "Chat log" },
]}
/>
),
}
return {
MobileLayout,
QuestionAndTestCasesImpl,
CodeRunningViewImpl,
}
}, [props.gameInfo.mode, props.questionStrategy])
}
export function InProgressGame(props: { gameInfo: NotWaitingForPlayersGameState }) {
const isMobile = useMediaQuery(MOBILE_VIEWPORT)
const questionType = getQuestionType(props.gameInfo.question)
const questionStrategy = createClientQuestionStrategy(questionType, props.gameInfo.question)
const { MobileLayout, QuestionAndTestCasesImpl, CodeRunningViewImpl } = useViews({
gameInfo: props.gameInfo,
questionStrategy,
})
const defaultDesktopLayout = createDefaultLayout({
rightSection: { top: CodeViewImpl, bottom: CodeRunningViewImpl },
leftSection: QuestionAndTestCasesImpl,
})
const defaultMobileLayout = createDefaultMobileLayout({
top: CodeViewImpl,
bottom: MobileLayout,
})
const layout = isMobile ? defaultMobileLayout : defaultDesktopLayout
return <PanelSkeleton layout={layout} />
}