Skip to content

Commit 05c0ce3

Browse files
committed
add edit checkbox to new game dialog
1 parent a217922 commit 05c0ce3

File tree

5 files changed

+92
-81
lines changed

5 files changed

+92
-81
lines changed

src/main/client/src/Lobby.jsx

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ import {
1010
import {
1111
useNavigate,
1212
} from "react-router-dom"
13-
import {
14-
Form,
15-
} from "./component/Form.jsx"
1613
import {
1714
Button,
1815
} from "./component/Button.jsx"
@@ -34,6 +31,12 @@ import {
3431
import {
3532
useAuthStore,
3633
} from "./store.js"
34+
import {
35+
CgClose,
36+
} from "react-icons/cg"
37+
import {
38+
IconContext,
39+
} from "react-icons"
3740

3841
const detailData = [
3942
["open", "Open Games"],
@@ -42,7 +45,6 @@ const detailData = [
4245

4346
export function Lobby() {
4447
let [isNewGameOpen, setNewGameOpen] = useState(false)
45-
let [isStartEditOpen, setStartEditOpen] = useState(false)
4648
let [detail, setDetail] = useState("open")
4749
let stompClient = useContext(StompContext)
4850
let navigate = useNavigate()
@@ -75,59 +77,31 @@ export function Lobby() {
7577
navigate(base + "/game/" + response.id)
7678
}), [auth, navigate])
7779
return (
78-
<div className="mt-4">
79-
<div className={twJoin(
80-
"inline-flex py-2 pr-6 gap-x-1",
81-
isStartEditOpen && "rounded-r-full bg-slate-400",
82-
)}>
83-
{isStartEditOpen ? (
84-
<StartEditDialog onStartEdit={onStartEdit} setStartEditOpen={setStartEditOpen} />
85-
) : (
86-
<Button className="ml-2"
87-
onClick={() => {
88-
setStartEditOpen(true)
89-
setNewGameOpen(false)
90-
}}>
91-
Editor
92-
</Button>
93-
)}
94-
</div>
95-
<div className="clear-both" />
80+
<div>
9681
<div className={twJoin(
97-
"mt-2 inline-flex py-2 pr-6 gap-x-1",
98-
isNewGameOpen && "rounded-r-full bg-slate-400",
82+
"mt-2 inline-flex py-2 pr-4 gap-x-1 border-r-2 border-y-2",
83+
isNewGameOpen && "rounded-r-full border-slate-600",
84+
!isNewGameOpen && "border-transparent",
9985
)}>
10086
{isNewGameOpen ? (
101-
<NewGameDialog onNewGame={onNewGame} setNewGameOpen={setNewGameOpen} />
87+
<NewGameDialog
88+
onNewGame={onNewGame}
89+
onStartEdit={onStartEdit}
90+
setNewGameOpen={setNewGameOpen} />
10291
) : (
103-
<Button className="ml-2"
92+
<button className={twJoin(
93+
"ml-2 border-2 border-transparent px-4 py-2 rounded-lg",
94+
"hover:border-sky-700",
95+
)}
10496
onClick={() => {
105-
setStartEditOpen(false)
10697
setNewGameOpen(true)
10798
}}>
10899
New Game
109-
</Button>
100+
</button>
110101
)}
111102
</div>
112103
<div className="clear-both" />
113-
<div className="mt-2">
114-
<div className={twJoin(
115-
"float-left py-3 pl-2 pr-3 bg-slate-700 border-r-2 border-y-2 border-slate-600",
116-
"rounded-r-lg flex flex-col gap-y-2",
117-
)}>
118-
{detailData.map(([id, label]) => (
119-
<button
120-
key={id}
121-
onClick={() => setDetail(id)}
122-
disabled={id === detail}
123-
className={twJoin(
124-
"px-2 py-2 rounded-lg border-2",
125-
id === detail && "border-slate-600",
126-
id !== detail && "border-transparent hover:bg-slate-800 hover:border-slate-600",
127-
)}>{label}</button>
128-
))}
129-
</div>
130-
</div>
104+
<DetailNavigation detail={detail} setDetail={setDetail} />
131105
{detail === "open" && (
132106
<OpenGames />
133107
)}
@@ -139,34 +113,55 @@ export function Lobby() {
139113
)
140114
}
141115

142-
function NewGameDialog({onNewGame, setNewGameOpen}) {
116+
function NewGameDialog({onNewGame, onStartEdit, setNewGameOpen}) {
143117
let dimRef = useRef(9)
118+
let [edit, setEdit] = useState(false)
144119
return (
145-
<Form className="contents" onSubmit={() => onNewGame({dim: dimRef.current})}>
146-
<Button onClick={() => setNewGameOpen(false)} className="ml-2 bg-slate-800 hover:border-slate-800">Cancel</Button>
120+
<form className="contents" onSubmit={(e) => {
121+
e.preventDefault()
122+
let game = {dim: dimRef.current}
123+
if (edit) {
124+
onStartEdit(game)
125+
} else {
126+
onNewGame(game)
127+
}
128+
}}>
129+
<Button type="submit" className="ml-2">OK</Button>
147130
<input id="dim-9" type="radio" name="dim" value="9" className="ml-2" defaultChecked={true} onClick={() => dimRef.current = 9} />
148-
<label htmlFor="dim-9" className="text-black pt-[0.625rem] pr-1" onClick={() => dimRef.current = 9}>9x9</label>
131+
<label htmlFor="dim-9" className="pt-[0.625rem] pr-1" >9x9</label>
149132
<input id="dim-13" type="radio" name="dim" value="13" onClick={() => dimRef.current = 13} />
150-
<label htmlFor="dim-13" className="text-black pt-[0.625rem] pr-1" onClick={() => dimRef.current = 13}>13x13</label>
133+
<label htmlFor="dim-13" className="pt-[0.625rem] pr-1">13x13</label>
151134
<input id="dim-19" type="radio" name="dim" value="19" onClick={() => dimRef.current = 19} />
152-
<label htmlFor="dim-19" className="text-black pt-[0.625rem] mr-2" onClick={() => dimRef.current = 19}>19x19</label>
153-
<Button type="submit" className="bg-slate-800 hover:border-slate-800">OK</Button>
154-
</Form>
135+
<label htmlFor="dim-19" className="pt-[0.625rem] pr-1">19x19</label>
136+
<input id="cb-edit" type="checkbox" name="edit" checked={edit} onChange={() => setEdit(!edit)} />
137+
<label htmlFor="cb-edit" className="pt-[0.625rem] ml-1">Edit</label>
138+
<button onClick={() => setNewGameOpen(false)} className="ml-1 text-stone-100 hover:text-stone-300">
139+
<IconContext.Provider value={{ size: "1.25em" }}>
140+
<CgClose />
141+
</IconContext.Provider>
142+
</button>
143+
</form>
155144
)
156145
}
157-
158-
function StartEditDialog({onStartEdit, setStartEditOpen}) {
159-
let dimRef = useRef(9)
146+
function DetailNavigation({detail, setDetail}) {
160147
return (
161-
<Form className="contents" onSubmit={() => onStartEdit({dim: dimRef.current, editMode: true})}>
162-
<Button onClick={() => setStartEditOpen(false)} className="ml-2 bg-slate-800 hover:border-slate-800">Cancel</Button>
163-
<input id="dim-9" type="radio" name="dim" value="9" className="ml-2" defaultChecked={true} onClick={() => dimRef.current = 9} />
164-
<label htmlFor="dim-9" className="text-black pt-[0.625rem] pr-1" onClick={() => dimRef.current = 9}>9x9</label>
165-
<input id="dim-13" type="radio" name="dim" value="13" onClick={() => dimRef.current = 13} />
166-
<label htmlFor="dim-13" className="text-black pt-[0.625rem] pr-1" onClick={() => dimRef.current = 13}>13x13</label>
167-
<input id="dim-19" type="radio" name="dim" value="19" onClick={() => dimRef.current = 19} />
168-
<label htmlFor="dim-19" className="text-black pt-[0.625rem] mr-2" onClick={() => dimRef.current = 19}>19x19</label>
169-
<Button type="submit" className="bg-slate-800 hover:border-slate-800">OK</Button>
170-
</Form>
148+
<div className="mt-2">
149+
<div className={twJoin(
150+
"float-left py-3 pl-2 pr-3 border-r-2 border-y-2 border-slate-600",
151+
"rounded-r-xl flex flex-col gap-y-2",
152+
)}>
153+
{detailData.map(([id, label]) => (
154+
<button
155+
key={id}
156+
onClick={() => setDetail(id)}
157+
disabled={id === detail}
158+
className={twJoin(
159+
"px-2 py-2 rounded-lg border-2 hover:border-sky-700",
160+
id === detail && "border-slate-600",
161+
id !== detail && "border-transparent hover:bg-stone-800",
162+
)}>{label}</button>
163+
))}
164+
</div>
165+
</div>
171166
)
172167
}

src/main/client/src/component/Button.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const Button = ({ type, children, disabled, className, onClick, ...rest }
66
let classes = twJoin(
77
"border-2 border-slate-600 rounded-lg px-8 py-2",
88
disabled && "text-slate-500 bg-slate-200 border-slate-400 border-2",
9-
!disabled && "hover:bg-slate-800 bg-slate-700 hover:text-white text-slate-200 hover:border-sky-700",
9+
!disabled && "hover:text-white text-slate-200 hover:border-sky-700",
1010
className,
1111
)
1212
return (

src/main/client/src/feature/GamePanel.jsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import {
1010
FaAngleLeft,
1111
FaAngleRight,
1212
} from "react-icons/fa"
13+
import {
14+
IoMdExit,
15+
} from "react-icons/io"
1316
import {
1417
IconContext,
1518
} from "react-icons"
@@ -32,7 +35,7 @@ import {
3235
export const GamePanel = ({zoom, setZoom}) => {
3336
return (
3437
<div className="fixed top-0 right-0 h-full bg-slate-800 border-l-2 border-slate-700">
35-
<div className="pr-12 pt-8 pl-8">
38+
<div className="w-64 pr-3 pt-4 pl-4">
3639
<Panel zoom={zoom} setZoom={setZoom} />
3740
</div>
3841
</div>
@@ -43,9 +46,10 @@ function Panel({zoom, setZoom}) {
4346
let { gameId } = useParams()
4447
let stompClient = useContext(StompContext)
4548
let auth = useAuthStore(state => state.auth)
49+
let { black, white} = useGameStore(state => state)
4650
let { board, currentPlayer, counting } = useGameStore(state => state.gameState)
4751
let navigate = useNavigate()
48-
let onLobby = useCallback(() => {
52+
let onExit = useCallback(() => {
4953
navigate(base + "/lobby")
5054
}, [navigate])
5155
let onPass = useCallback(() => {
@@ -72,12 +76,6 @@ function Panel({zoom, setZoom}) {
7276
let result = counting ? getScore(board) : undefined
7377
return (
7478
<>
75-
<div className="mt-2 py-4">
76-
<Button
77-
onClick={onLobby}>
78-
Lobby
79-
</Button>
80-
</div>
8179
<div className="inline-flex gap-x-2">
8280
<button
8381
onClick={() => setZoom(zoom - 1)}>
@@ -105,6 +103,20 @@ function Panel({zoom, setZoom}) {
105103
</IconContext.Provider>
106104
</button>
107105
</div>
106+
<button title="Leave the game" onClick={onExit}
107+
className="float-right">
108+
<IconContext.Provider value={{
109+
size: "1.5em",
110+
className: "pr-[4px]",
111+
}}>
112+
<IoMdExit />
113+
</IconContext.Provider>
114+
</button>
115+
<div className="flex gap-x-1">
116+
<div>{white.name}</div>
117+
<div>vs</div>
118+
<div>{black.name}</div>
119+
</div>
108120
<div className="mt-2">
109121
<Button
110122
onClick={onPass}

src/main/client/src/index.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
@layer base {
66
body, input {
7-
@apply bg-slate-800;
7+
@apply bg-stone-800;
88
@apply font-sans;
9-
@apply text-slate-100;
9+
@apply text-stone-100;
1010
}
1111

1212
input {

src/main/java/com/bernd/LobbyController.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bernd;
22

3+
import com.bernd.model.ActiveGame;
34
import com.bernd.model.ActiveGameList;
45
import com.bernd.model.Game;
56
import com.bernd.model.MatchRequest;
@@ -67,20 +68,23 @@ public OpenGameList getOpenGames() {
6768
@PostMapping(value = "/api/start_edit", consumes = "application/json")
6869
public Game startEdit(@RequestBody MatchRequest request) {
6970
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
70-
User user = lobbyUsers.remove(Objects.toString(principal));
71+
lobbyUsers.remove(Objects.toString(principal));
72+
User user = new User(Objects.toString(principal));
7173
operations.convertAndSend("/topic/lobby/users", lobbyUsers.users());
72-
return games.put(new Game(
74+
Game game = games.put(new Game(
7375
RandomString.get(),
7476
user,
7577
user,
7678
true,
7779
false,
78-
user.name(),
80+
Objects.toString(principal),
7981
B,
8082
false,
8183
createEmptyBoard(request.dim()),
8284
0,
8385
new int[]{-1, -1}));
86+
activeGames.put(ActiveGame.fromGame(game));
87+
return game;
8488
}
8589

8690
public static int[][] createEmptyBoard(int dimension) {

0 commit comments

Comments
 (0)