single game fix

This commit is contained in:
Lett Osprey 2026-04-13 12:17:50 +02:00
parent 09bf741997
commit f3020b7cb0
6 changed files with 195 additions and 128 deletions

View file

@ -12,7 +12,7 @@ import lustre/element/html
import lustre/server_component
import shared/message.{type NotifyClient, type NotifyServer, type User, User}
import web/components/shared.{
step_prompt, view_input, view_named_input, view_yes_no,
input_new_player, step_prompt, view_named_input, view_players,
}
pub fn component() -> lustre.App(message.ClientsServer, Model, Msg) {
@ -29,6 +29,7 @@ type State {
pub opaque type Model {
Model(
state: State,
players: List(#(String, String)),
lobby: #(String, List(User)),
registry: GroupRegistry(NotifyClient),
handler: Started(Subject(NotifyServer)),
@ -38,7 +39,14 @@ pub opaque type Model {
fn init(handlers: message.ClientsServer) -> #(Model, Effect(Msg)) {
let #(registry, handler) = handlers
let model = Model(AskName, #("", []), registry, handler)
let model =
Model(
AskName,
actor.call(handler.data, 1000, message.FetchPlayers),
#("", []),
registry,
handler,
)
#(model, subscribe(registry, SharedMessage))
}
@ -58,8 +66,8 @@ fn subscribe(
pub opaque type Msg {
SharedMessage(message: NotifyClient)
ReceiveName(message: String)
AcceptName(accept: Option(String))
ReceiveName(Option(String))
AcceptName(Option(#(String, String)))
GiveAnswer(name: String, answer: String)
}
@ -67,9 +75,13 @@ fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
let handler = model.handler
case msg {
ReceiveName(name) -> #(Model(..model, state: NameOk(name)), effect.none())
ReceiveName(Some(name)) -> #(
Model(..model, state: NameOk(name)),
effect.none(),
)
AcceptName(Some(name)) -> {
actor.send(handler.data, message.GiveName(name:))
let #(_, name) = name
actor.send(handler.data, message.GiveName(name))
#(Model(..model, state: WaitForQuiz(name)), effect.none())
}
AcceptName(None) -> #(Model(..model, state: AskName), effect.none())
@ -81,13 +93,15 @@ fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
handle_server_message(model, shared_msg),
effect.none(),
)
_ -> #(model, effect.none())
}
}
fn handle_server_message(model: Model, notify_client) {
case notify_client {
message.Lobby(question, lobby) -> Model(..model, lobby: #(question, lobby))
message.Exit -> Model(AskName, #("", []), model.registry, model.handler)
message.Exit ->
Model(AskName, model.players, #("", []), model.registry, model.handler)
message.Answer ->
case model.state {
// We are currently waiting for next quiz question, ok to switch to answer mode
@ -117,20 +131,21 @@ fn handle_server_message(model: Model, notify_client) {
fn view(model: Model) -> Element(Msg) {
let #(question, lobby) = model.lobby
element.fragment([
html.div([attribute.class("terminal-prompt")], [
case model.state {
AskName ->
step_prompt(
"Hello stranger. To join the quiz, I need to know your name",
fn() { view_input(ReceiveName) },
)
NameOk(name) ->
step_prompt(
"Your name is " <> name <> "? Are you absolutely sure???",
fn() { view_yes_no(name, AcceptName) },
case model.players {
[] -> input_new_player(ReceiveName)
_ -> view_players(model.players, AcceptName)
}
NameOk(name) -> {
shared.confirm_cells(
Some("Join as this player: " <> name <> "?"),
#("", name),
AcceptName,
)
}
Answer(name) ->
step_prompt(
"The Quiz Lead will now ask the question, and you may answer.",