diff --git a/packages/client/src/dungeon.client.ts b/packages/client/src/dungeon.client.ts index b7ea3d3..70dcb68 100644 --- a/packages/client/src/dungeon.client.ts +++ b/packages/client/src/dungeon.client.ts @@ -37,6 +37,14 @@ export class DungeonClient { return [...this.session.participants]; } + public setName(name: string): void { + this.socket.emit('setup/name', name); + } + + public setReady(isReady: boolean): void { + this.socket.emit('setup/ready', isReady); + } + private subscribeToSocket(): void { this.socket.on('participant/join', (participant: Participant) => { this.addParticipant(participant); diff --git a/packages/client/src/index.tsx b/packages/client/src/index.tsx index 96df522..b50d03f 100644 --- a/packages/client/src/index.tsx +++ b/packages/client/src/index.tsx @@ -7,6 +7,7 @@ import globalStyle from './views/style.css'; import { ErrorBoundary } from 'react-error-boundary'; import { ErrorView } from './views/error/error.view'; import { ExternalStyle } from './components/external.style'; +import { ParticipantSetupView } from './views/participant.setup/participant.setup.view'; function getRootContainer(): Element { const container = document.querySelector('#root'); @@ -23,6 +24,10 @@ createRoot(getRootContainer()).render( } /> } /> + } + /> diff --git a/packages/client/src/views/participant.setup/participant.setup.view.tsx b/packages/client/src/views/participant.setup/participant.setup.view.tsx new file mode 100644 index 0000000..e1a6cf5 --- /dev/null +++ b/packages/client/src/views/participant.setup/participant.setup.view.tsx @@ -0,0 +1,56 @@ +import { useState, type ChangeEvent, type JSX } from 'react'; +import viewStyle from './style.css'; +import { app } from '#src/app'; +import { ExternalStyle } from '#src/components/external.style'; + +function NameInput(props: { onChange: (name: string) => void }): JSX.Element { + const changeHandler = (event: ChangeEvent): void => { + props.onChange(event.target.value); + }; + + return ; +} + +function ReadyButton(props: { + onChange: (isReady: boolean) => void; +}): JSX.Element { + const [isReady, setReady] = useState(); + + const clickHandler = (): void => { + setReady(!isReady); + props.onChange(isReady ?? false); + }; + + return ( + + ); +} + +export function ParticipantSetupView(): JSX.Element { + const dungeonClient = app.items.dungeonClient; + + return ( + <> + +
+

Your name:

+ { + dungeonClient.setName(name); + }} + /> +

Ready?

+ { + dungeonClient.setReady(isReady); + }} + /> +
+ + ); +} diff --git a/packages/client/src/views/participant.setup/style.css b/packages/client/src/views/participant.setup/style.css new file mode 100644 index 0000000..3196ed4 --- /dev/null +++ b/packages/client/src/views/participant.setup/style.css @@ -0,0 +1,49 @@ +.setup.main { + background-color: #262b44; + font-size: 2rem; + border: 4px solid #5a6988; + padding: 1rem; +} + +input { + background-color: #181425; + border: 2px solid #5a6988; + font-size: 1em; + color: white; + text-align: center; +} + +.setup.ready { + border: none; + + font-size: 1.5em; + width: 1.5em; + height: 1.5em; + border-radius: 100%; + text-align: center; + vertical-align: center; + + color: #ff0044; + + background: rgb(139, 155, 180); + background: radial-gradient( + circle, + rgba(139, 155, 180, 1) 9%, + rgba(90, 105, 136, 1) 51%, + rgba(58, 68, 102, 1) 100% + ); +} + +.setup.ready:active { + background: rgb(58, 68, 102); + background: radial-gradient( + circle, + rgba(58, 68, 102, 1) 9%, + rgba(58, 68, 102, 1) 51%, + rgba(90, 105, 136, 1) 100% + ); +} + +.setup.ready.active { + color: #63c74d; +} diff --git a/packages/shared/src/api/frontend.routes.ts b/packages/shared/src/api/frontend.routes.ts index f91bdab..8ef594a 100644 --- a/packages/shared/src/api/frontend.routes.ts +++ b/packages/shared/src/api/frontend.routes.ts @@ -1,5 +1,6 @@ export const frontendRoutes = { index: '/', - lobby: '/lobby/:id', - join: '/join/:id', + lobby: '/watch/:id/lobby', + join: '/play/:id', + participantSetup: '/play/:id/setup', }; diff --git a/packages/shared/src/api/socket.events.ts b/packages/shared/src/api/socket.events.ts index 218a874..dc33d39 100644 --- a/packages/shared/src/api/socket.events.ts +++ b/packages/shared/src/api/socket.events.ts @@ -14,4 +14,9 @@ interface ParticipantEventMap extends EventMap { 'participant/update': (participant: Participant) => void; } -export type SocketEventMap = ParticipantEventMap; +interface SetupEventMap extends EventMap { + 'setup/name': (name: string) => void; + 'setup/ready': (isReady: boolean) => void; +} + +export interface SocketEventMap extends ParticipantEventMap, SetupEventMap {}