more work on pre-game pages
This commit is contained in:
parent
987e2b5576
commit
7a8acf27a7
5 changed files with 259 additions and 180 deletions
142
client/src/view.gleam
Normal file
142
client/src/view.gleam
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import gleam/int
|
||||
import gleam/list
|
||||
import gleam/option.{None, Some}
|
||||
import lustre/attribute.{class}
|
||||
import lustre/element.{type Element}
|
||||
import lustre/element/html
|
||||
import lustre/event
|
||||
import lustre/server_component
|
||||
import model.{
|
||||
type Model, type Msg, AwaitPlayers, Empty, EnterPin, JoinLive, JoinSingle,
|
||||
KeyPin, PickPlayer, SelectGamestyle, SelectedPlayer, SelectedRoom,
|
||||
}
|
||||
import shared.{type Room}
|
||||
|
||||
pub fn view(model: Model) -> Element(Msg) {
|
||||
case model.state {
|
||||
Empty -> view_room_list(model.rooms)
|
||||
EnterPin(_, _) -> view_enter_pin()
|
||||
SelectGamestyle(_, _) -> view_live_or_single()
|
||||
AwaitPlayers(_, _) -> html.text("FETCHING USERS FOR ROOM")
|
||||
PickPlayer(_, _, players) -> view_player_list(players)
|
||||
JoinLive(room:, pin:) -> view_join_live(room, pin)
|
||||
JoinSingle(room:, pin:, player:) -> view_join_single(room, pin, player)
|
||||
}
|
||||
}
|
||||
|
||||
fn layout(header: String, ohno: option.Option(String), body: List(Element(Msg))) {
|
||||
html.div([], [
|
||||
html.div([class("terminal-header")], [
|
||||
html.div([class("terminal-status")], [
|
||||
html.span([class("status-blink")], [html.text("●")]),
|
||||
html.div([], [
|
||||
html.text(" SYSTEM READY"),
|
||||
]),
|
||||
html.div([], [
|
||||
case ohno {
|
||||
None -> element.none()
|
||||
Some(x) -> html.h3([], [html.text("Fail: " <> x)])
|
||||
},
|
||||
]),
|
||||
html.span([class("ml-8")], [
|
||||
html.text("<< Please Log On to use QuizTerm. >>"),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
html.div([attribute.class("terminal-section")], [
|
||||
html.div([attribute.class("terminal-label mb-4")], [
|
||||
html.text(header),
|
||||
]),
|
||||
html.div([attribute.class("participants-grid")], body),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
fn view_room_list(items: List(Room)) -> Element(Msg) {
|
||||
layout("Select room to play in", None, case items {
|
||||
[] -> [html.text("No items in your list yet.")]
|
||||
_ -> {
|
||||
list.index_map(items, fn(item, index) {
|
||||
room_cell(index, item, SelectedRoom)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn view_enter_pin() -> Element(Msg) {
|
||||
layout("Enter PIN code for room", None, [
|
||||
html.input([
|
||||
attribute.type_("password"),
|
||||
event.on_input(KeyPin),
|
||||
attribute.autofocus(True),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
fn view_join_live(room: String, pin: String) -> Element(Msg) {
|
||||
html.div([attribute.class("terminal-section")], [
|
||||
html.div([attribute.class("terminal-label mb-4")], [
|
||||
server_component.element(
|
||||
[server_component.route("/socket/live/" <> room)],
|
||||
[],
|
||||
),
|
||||
server_component.element(
|
||||
[server_component.route("/socket/control/" <> room)],
|
||||
[],
|
||||
),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
fn view_join_single(room: String, pin: String, player: String) -> Element(Msg) {
|
||||
html.div([attribute.class("terminal-section")], [
|
||||
html.div([attribute.class("terminal-label mb-4")], [
|
||||
server_component.element(
|
||||
[server_component.route("/socket/single/" <> room)],
|
||||
[],
|
||||
),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
fn view_live_or_single() -> Element(Msg) {
|
||||
layout("Select type of play", None, [
|
||||
click_cell(1, "Live Game", model.SelectedGamestyle),
|
||||
click_cell(2, "Single Game", model.SelectedGamestyle),
|
||||
])
|
||||
}
|
||||
|
||||
fn view_player_list(items: List(String)) -> Element(Msg) {
|
||||
layout("Select or enter your player", None, case items {
|
||||
[] -> [html.text("No items in your list yet.")]
|
||||
_ -> {
|
||||
list.index_map(items, fn(item, index) {
|
||||
click_cell(index, item, SelectedPlayer)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn click_cell(
|
||||
number: Int,
|
||||
player: String,
|
||||
on_click: fn(String) -> msg,
|
||||
) -> Element(msg) {
|
||||
html.div([class("participant-login"), event.on_click(on_click(player))], [
|
||||
html.div([class("participant-name")], [
|
||||
html.text("► " <> "[#" <> int.to_string(number) <> "] " <> player),
|
||||
]),
|
||||
])
|
||||
}
|
||||
|
||||
fn room_cell(
|
||||
number: Int,
|
||||
room: Room,
|
||||
on_click: fn(String) -> msg,
|
||||
) -> Element(msg) {
|
||||
html.div([class("participant-login"), event.on_click(on_click(room.id))], [
|
||||
html.div([class("participant-name")], [
|
||||
html.text("► " <> "[#" <> int.to_string(number) <> "] Team " <> room.name),
|
||||
]),
|
||||
])
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue