@@ -6,15 +6,23 @@ import { Dice } from "./Scene/Dice";
66import { ThrowHint } from "./Ui/Hints/ThrowHint" ;
77import { PickHint } from "./Ui/Hints/PickHint" ;
88import { PullHint } from "./Ui/Hints/PullHint" ;
9- import { isDiceValue , isScoreSheetEmpty } from "../gameRules/types" ;
10- import { Overlay } from "./Ui/Overlay" ;
11- import { ScoreSheet } from "./Ui/ScoreSheet/ScoreSheet" ;
9+ import {
10+ type Category ,
11+ categories ,
12+ isDiceValue ,
13+ isScoreSheetEmpty ,
14+ isScoreSheetFinished ,
15+ } from "../gameRules/types" ;
1216import { ScaleOnPulse } from "./Scene/ScaleOnPulse" ;
1317import { SelectedDiceHint } from "./Scene/SelectedDiceHint" ;
1418import { useDelay } from "./Ui/useDelay" ;
1519import { Target } from "./Scene/Target" ;
1620import { createGameWorld } from "../gameWorld/state" ;
1721import { type Game as IGame , isBlank , nReroll } from "../gameRules/game" ;
22+ import { createSceneScreenshot } from "./createSceneScreenshot" ;
23+ import { ScoreSheetContent } from "./Ui/ScoreSheet/ScoreSheetContent" ;
24+ import { LeaderboardSubmission } from "./Ui/ScoreSheet/LeaderboardSubmission" ;
25+ import { DialogModal } from "./Ui/DialogModal-fallback" ;
1826
1927export const Game_ = ( {
2028 UiPortal,
@@ -23,6 +31,16 @@ export const Game_ = ({
2331} ) => {
2432 const world = React . useMemo ( createGameWorld , [ ] ) ;
2533
34+ const [ screenshots , saveScreenshot ] = React . useReducer (
35+ ( s , { category, blob } : { category : Category ; blob : Blob } ) => ( {
36+ ...s ,
37+ [ category ] : blob ,
38+ } ) ,
39+ { } as Record < Category , Blob >
40+ ) ;
41+ const { scene } = useThree ( ) ;
42+ const { getImage } = React . useMemo ( createSceneScreenshot , [ ] ) ;
43+
2644 const [ dragging , setDragging ] = React . useState ( false ) ;
2745 const [ scoresheetOpen , setScoresheetOpen ] = React . useState ( false ) ;
2846
@@ -75,6 +93,7 @@ export const Game_ = ({
7593 e . stopPropagation ( ) ;
7694 world . toggleDicePicked ( i ) ;
7795 } }
96+ userData = { { diceIndex : i } }
7897 />
7998 </ ScaleOnPulse >
8099 ) ) }
@@ -105,49 +124,62 @@ export const Game_ = ({
105124
106125 { ! dragging && ! scoresheetOpen && < Hint game = { world . state . game } /> }
107126
108- { scoresheetOpen && (
109- < Overlay >
110- < ScoreSheet
111- style = { {
112- width : "calc( 100% - 40px )" ,
113- maxWidth : "600px" ,
114- pointerEvents : "auto" ,
115- } }
116- scoreSheet = { world . state . game . scoreSheet }
117- onClose = { ( ) => setScoresheetOpen ( false ) }
118- onSelectCategory = {
119- world . state . game . roll . every ( isDiceValue )
120- ? ( c ) => {
121- world . selectCategoryForDiceRoll ( c ) ;
127+ < DialogModal
128+ open = { scoresheetOpen }
129+ onClose = { ( ) => setScoresheetOpen ( false ) }
130+ style = { { width : "min(100%,600px)" } }
131+ >
132+ < h3 style = { { paddingLeft : "10px" } } > Score Sheet</ h3 >
133+
134+ < ScoreSheetContent
135+ scoreSheet = { world . state . game . scoreSheet }
136+ rollCandidate = {
137+ ( world . state . game . roll . every ( isDiceValue ) &&
138+ world . state . game . roll ) ||
139+ null
140+ }
141+ onSelectCategory = {
142+ world . state . game . roll . every ( isDiceValue )
143+ ? ( category ) => {
144+ const roll = world . state . game . roll ;
145+ if ( ! roll . every ( isDiceValue ) ) return ;
146+
147+ getImage ( scene , roll , category ) . then ( ( blob ) =>
148+ saveScreenshot ( { blob, category } )
149+ ) ;
150+
151+ world . selectCategoryForDiceRoll ( category ) ;
152+ if ( ! isScoreSheetFinished ( world . state . game . scoreSheet ) )
122153 setScoresheetOpen ( false ) ;
123- }
124- : undefined
125- }
126- rollCandidate = {
127- world . state . game . roll . every ( isDiceValue )
128- ? world . state . game . roll
129- : undefined
130- }
131- />
132- </ Overlay >
133- ) }
134-
135- { ! scoresheetOpen && (
136- < button
137- style = { {
138- position : "absolute" ,
139- width : "160px" ,
140- height : "40px" ,
141- bottom : "10px" ,
142- right : "60px" ,
143- zIndex : 1 ,
144- pointerEvents : "auto" ,
145- } }
146- onClick = { ( ) => setScoresheetOpen ( true ) }
147- >
148- score sheet
149- </ button >
150- ) }
154+ }
155+ : undefined
156+ }
157+ />
158+
159+ { isScoreSheetFinished ( world . state . game . scoreSheet ) && (
160+ < div style = { { marginTop : "16px" , minHeight : "30px" } } >
161+ < LeaderboardSubmission
162+ scoreSheet = { world . state . game . scoreSheet }
163+ screenshots = { screenshots }
164+ />
165+ </ div >
166+ ) }
167+ </ DialogModal >
168+
169+ < button
170+ style = { {
171+ position : "absolute" ,
172+ width : "160px" ,
173+ height : "40px" ,
174+ bottom : "10px" ,
175+ right : "60px" ,
176+ zIndex : 1 ,
177+ pointerEvents : "auto" ,
178+ } }
179+ onClick = { ( ) => setScoresheetOpen ( true ) }
180+ >
181+ score sheet
182+ </ button >
151183 </ UiPortal >
152184 </ >
153185 ) ;
0 commit comments