more work on pre-game pages
This commit is contained in:
parent
987e2b5576
commit
7a8acf27a7
5 changed files with 259 additions and 180 deletions
|
|
@ -1,20 +1,20 @@
|
||||||
import gleam/dynamic/decode
|
import gleam/dynamic/decode
|
||||||
import gleam/int
|
|
||||||
import gleam/json
|
import gleam/json
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/option.{type Option, None, Some}
|
import gleam/option.{type Option, None, Some}
|
||||||
import gleam/result
|
import gleam/result
|
||||||
import gleam/string
|
import gleam/string
|
||||||
import lustre
|
import lustre
|
||||||
import lustre/attribute.{class}
|
|
||||||
import lustre/effect.{type Effect}
|
import lustre/effect.{type Effect}
|
||||||
import lustre/element.{type Element}
|
import model.{
|
||||||
import lustre/element/html
|
type Model, type Msg, AwaitPlayers, Empty, EnterPin, Initialize, KeyPin, Model,
|
||||||
import lustre/event
|
PickPlayer, Players, SelectedGamestyle, SelectedPlayer, SelectedRoom,
|
||||||
|
}
|
||||||
import plinth/browser/document
|
import plinth/browser/document
|
||||||
import plinth/browser/element as plinth_element
|
import plinth/browser/element as plinth_element
|
||||||
import rsvp
|
import rsvp
|
||||||
import shared.{type Room}
|
import shared.{type Room}
|
||||||
|
import view.{view}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let initial_items =
|
let initial_items =
|
||||||
|
|
@ -32,10 +32,6 @@ pub fn main() {
|
||||||
Nil
|
Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Model {
|
|
||||||
Model(rooms: List(Room), state: State, ohno: Option(String))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(initial: #(List(Room), Option(String))) -> #(Model, Effect(Msg)) {
|
fn init(initial: #(List(Room), Option(String))) -> #(Model, Effect(Msg)) {
|
||||||
let #(rooms, ohno) = initial
|
let #(rooms, ohno) = initial
|
||||||
let model = Model(rooms:, state: Empty, ohno:)
|
let model = Model(rooms:, state: Empty, ohno:)
|
||||||
|
|
@ -43,67 +39,68 @@ fn init(initial: #(List(Room), Option(String))) -> #(Model, Effect(Msg)) {
|
||||||
#(model, effect.none())
|
#(model, effect.none())
|
||||||
}
|
}
|
||||||
|
|
||||||
type State {
|
|
||||||
Empty
|
|
||||||
EnterPin(room: String, pin: String)
|
|
||||||
AwaitPlayers(room: String, pin: String)
|
|
||||||
PickPlayer(room: String, pin: String, players: List(String))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Msg {
|
|
||||||
Initialize
|
|
||||||
SelectRoom(String)
|
|
||||||
SelectPlayer(String)
|
|
||||||
KeyPin(String)
|
|
||||||
Players(Result(String, rsvp.Error))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
|
fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
|
||||||
case msg {
|
case msg {
|
||||||
Initialize -> init(#(model.rooms, None))
|
Initialize -> init(#(model.rooms, None))
|
||||||
SelectRoom(room) -> #(
|
SelectedRoom(room) -> #(
|
||||||
Model(..model, state: EnterPin(room:, pin: "")),
|
Model(..model, state: EnterPin(room:, pin: "")),
|
||||||
effect.none(),
|
effect.none(),
|
||||||
)
|
)
|
||||||
KeyPin(pin) ->
|
KeyPin(pin) -> {
|
||||||
|
//let _decode_answer = {
|
||||||
|
// use id <- decode.field("id", decode.string)
|
||||||
|
// use text <- decode.field("text", decode.string)
|
||||||
|
// decode.success(id)
|
||||||
|
// }
|
||||||
|
// let decode_list = {
|
||||||
|
// decode.list(decode.string)
|
||||||
|
// }
|
||||||
case model.state {
|
case model.state {
|
||||||
EnterPin(room, _) -> {
|
EnterPin(room, _) -> #(
|
||||||
let decode_answer = {
|
Model(..model, state: case string.length(pin) < 4 {
|
||||||
use id <- decode.field("id", decode.string)
|
False -> model.SelectGamestyle(room:, pin:)
|
||||||
// use text <- decode.field("text", decode.string)
|
True -> EnterPin(room:, pin:)
|
||||||
decode.success(id)
|
}),
|
||||||
}
|
effect.none(),
|
||||||
// let decode_list = {
|
)
|
||||||
// decode.list(decode.string)
|
|
||||||
// }
|
|
||||||
case string.length(pin) < 4 {
|
|
||||||
False -> {
|
|
||||||
#(
|
|
||||||
Model(
|
|
||||||
..model,
|
|
||||||
state: PickPlayer(room:, pin:, players: ["Player a", "Player b", "Player c", "Player d", "Player e", "Player f"]),
|
|
||||||
),
|
|
||||||
effect.none(),
|
|
||||||
)
|
|
||||||
// Model(..model, state: AwaitPlayers(room:, pin:)),
|
|
||||||
// rsvp.post(
|
|
||||||
// "http://localhost:1234/api/room/players",
|
|
||||||
// json.object([#("id", json.string("1234"))]),
|
|
||||||
// rsvp.expect_json(decode_answer, Players),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
True -> #(
|
|
||||||
Model(..model, state: EnterPin(room:, pin:)),
|
|
||||||
effect.none(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ ->
|
_ ->
|
||||||
init(#(model.rooms, Some("(EnterPin) Invalid state, starting over")))
|
init(#(
|
||||||
// Invalid model state, start over
|
model.rooms,
|
||||||
|
Some("(fail: enterpin) Invalid state, starting over"),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
SelectedGamestyle(style) -> {
|
||||||
|
case model.state {
|
||||||
|
model.SelectGamestyle(room:, pin:) -> #(
|
||||||
|
Model(..model, state: case style {
|
||||||
|
"Single Game" ->
|
||||||
|
PickPlayer(room:, pin:, players: [
|
||||||
|
"Player a",
|
||||||
|
"Player b",
|
||||||
|
"Player c",
|
||||||
|
"Player d",
|
||||||
|
"Player e",
|
||||||
|
"Player f",
|
||||||
|
])
|
||||||
|
_ -> model.JoinLive(room:, pin:)
|
||||||
|
}),
|
||||||
|
effect.none(),
|
||||||
|
)
|
||||||
|
_ ->
|
||||||
|
init(#(
|
||||||
|
model.rooms,
|
||||||
|
Some("(fail: selectgamestyle) Invalid state, starting over"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
// Model(..model, state: AwaitPlayers(room:, pin:)),
|
||||||
|
// rsvp.post(
|
||||||
|
// "http://localhost:1234/api/room/players",
|
||||||
|
// json.object([#("id", json.string("1234"))]),
|
||||||
|
// rsvp.expect_json(decode_answer, Players),
|
||||||
|
// ),
|
||||||
|
// )
|
||||||
|
}
|
||||||
Players(Ok(players)) -> {
|
Players(Ok(players)) -> {
|
||||||
echo "got players"
|
echo "got players"
|
||||||
case model.state {
|
case model.state {
|
||||||
|
|
@ -111,8 +108,11 @@ fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
|
||||||
Model(..model, state: PickPlayer(room:, pin:, players: [players])),
|
Model(..model, state: PickPlayer(room:, pin:, players: [players])),
|
||||||
effect.none(),
|
effect.none(),
|
||||||
)
|
)
|
||||||
_ -> init(#(model.rooms, Some("Invalid state, expected AwaitPlayers")))
|
_ ->
|
||||||
// invalid state, start over
|
init(#(
|
||||||
|
model.rooms,
|
||||||
|
Some("(fail: awaitplayers) Invalid state, starting over"),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Players(Error(x)) ->
|
Players(Error(x)) ->
|
||||||
|
|
@ -120,15 +120,26 @@ fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
|
||||||
model.rooms,
|
model.rooms,
|
||||||
Some("Error fetching players " <> decode_rsvp_error(x)),
|
Some("Error fetching players " <> decode_rsvp_error(x)),
|
||||||
))
|
))
|
||||||
SelectPlayer(x) -> init(#(model.rooms, Some("Players " <> x)))
|
SelectedPlayer(player) ->
|
||||||
|
case model.state {
|
||||||
|
PickPlayer(room:, pin:, players: _) -> #(
|
||||||
|
Model(..model, state: model.JoinSingle(room:, pin:, player:)),
|
||||||
|
effect.none(),
|
||||||
|
)
|
||||||
|
_ ->
|
||||||
|
init(#(
|
||||||
|
model.rooms,
|
||||||
|
Some("(fail: pickplayer) Invalid state, starting over"),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_rsvp_error(rsvp_error: rsvp.Error) {
|
fn decode_rsvp_error(rsvp_error: rsvp.Error) {
|
||||||
case rsvp_error {
|
case rsvp_error {
|
||||||
rsvp.BadBody -> "Bad body"
|
rsvp.BadBody -> "Bad body"
|
||||||
rsvp.BadUrl(x) -> "Bad url"
|
rsvp.BadUrl(_x) -> "Bad url"
|
||||||
rsvp.HttpError(x) -> "Http error"
|
rsvp.HttpError(_x) -> "Http error"
|
||||||
rsvp.JsonError(x) -> "Json error" <> decode_decode_error(x)
|
rsvp.JsonError(x) -> "Json error" <> decode_decode_error(x)
|
||||||
rsvp.NetworkError -> "Network error"
|
rsvp.NetworkError -> "Network error"
|
||||||
rsvp.UnhandledResponse(_) -> "Unhandled response"
|
rsvp.UnhandledResponse(_) -> "Unhandled response"
|
||||||
|
|
@ -155,103 +166,3 @@ fn decode_ddecode_error(decode_error: decode.DecodeError) -> String {
|
||||||
"(e: " <> expected <> ", f: " <> found <> ", p: " <> string.concat(path)
|
"(e: " <> expected <> ", f: " <> found <> ", p: " <> string.concat(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view(model: Model) -> 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 model.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. >>"),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
case model.state {
|
|
||||||
Empty -> view_room_list(model.rooms)
|
|
||||||
EnterPin(_, _) -> pin()
|
|
||||||
AwaitPlayers(_, _) -> html.text("FETCHING USERS FOR ROOM")
|
|
||||||
PickPlayer(_, _, players) -> view_player_list(players)
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pin() -> Element(Msg) {
|
|
||||||
html.div([attribute.class("terminal-section")], [
|
|
||||||
html.div([attribute.class("terminal-label mb-4")], [
|
|
||||||
html.text("Select room to play in"),
|
|
||||||
]),
|
|
||||||
html.div([attribute.class("participants-grid")], [
|
|
||||||
html.text("Enter PIN code for room"),
|
|
||||||
html.input([
|
|
||||||
attribute.type_("password"),
|
|
||||||
event.on_input(KeyPin),
|
|
||||||
attribute.autofocus(True),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn view_room_list(items: List(Room)) -> Element(Msg) {
|
|
||||||
html.div([attribute.class("terminal-section")], [
|
|
||||||
html.div([attribute.class("terminal-label mb-4")], [
|
|
||||||
html.text("Select room to play in"),
|
|
||||||
]),
|
|
||||||
html.div([attribute.class("participants-grid")], case items {
|
|
||||||
[] -> [html.text("No items in your list yet.")]
|
|
||||||
_ -> {
|
|
||||||
list.index_map(items, fn(item, index) {
|
|
||||||
room_cell(index, item, SelectRoom)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn view_player_list(items: List(String)) -> Element(Msg) {
|
|
||||||
html.div([attribute.class("terminal-section")], [
|
|
||||||
html.div([attribute.class("terminal-label mb-4")], [
|
|
||||||
html.text("Select room to play in"),
|
|
||||||
]),
|
|
||||||
html.div([attribute.class("participants-grid")], case items {
|
|
||||||
[] -> [html.text("No items in your list yet.")]
|
|
||||||
_ -> {
|
|
||||||
list.index_map(items, fn(item, index) {
|
|
||||||
player_cell(index, item, SelectPlayer)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn player_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.name))], [
|
|
||||||
html.div([class("participant-name")], [
|
|
||||||
html.text("► " <> "[#" <> int.to_string(number) <> "] Team " <> room.name),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
|
||||||
26
client/src/model.gleam
Normal file
26
client/src/model.gleam
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import gleam/option.{type Option}
|
||||||
|
import rsvp.{type Error}
|
||||||
|
import shared.{type Room}
|
||||||
|
|
||||||
|
pub type Model {
|
||||||
|
Model(rooms: List(Room), state: State, ohno: Option(String))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type State {
|
||||||
|
Empty
|
||||||
|
EnterPin(room: String, pin: String)
|
||||||
|
SelectGamestyle(room: String, pin: String)
|
||||||
|
AwaitPlayers(room: String, pin: String)
|
||||||
|
PickPlayer(room: String, pin: String, players: List(String))
|
||||||
|
JoinLive(room: String, pin: String)
|
||||||
|
JoinSingle(room: String, pin: String, player: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Msg {
|
||||||
|
Initialize
|
||||||
|
SelectedRoom(String)
|
||||||
|
SelectedPlayer(String)
|
||||||
|
SelectedGamestyle(String)
|
||||||
|
KeyPin(String)
|
||||||
|
Players(Result(String, Error))
|
||||||
|
}
|
||||||
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),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
@ -8,24 +8,24 @@
|
||||||
<script id="model" type="application/json">
|
<script id="model" type="application/json">
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": "abt",
|
"id": "1234",
|
||||||
"name": "Billettering",
|
"name": "Team A",
|
||||||
"key": "T5X6"
|
"key": "1234"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "slg",
|
"id": "1235",
|
||||||
"name": "Salg",
|
"name": "Team B",
|
||||||
"key": "6B4T"
|
"key": "1235"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "prs",
|
"id": "1236",
|
||||||
"name": "Personalisering",
|
"name": "Team C",
|
||||||
"key": "P2Q5"
|
"key": "1236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "srp",
|
"id": "1237",
|
||||||
"name": "Support",
|
"name": "Team D",
|
||||||
"key": "P2Q5"
|
"key": "1237"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,11 @@ pub fn main() {
|
||||||
[] | ["index.html"] -> serve_static("root.html")
|
[] | ["index.html"] -> serve_static("root.html")
|
||||||
["client.js"] -> serve_static("client.js")
|
["client.js"] -> serve_static("client.js")
|
||||||
["static", file] -> serve_static(file)
|
["static", file] -> serve_static(file)
|
||||||
["socket", "card", id] ->
|
["socket", "live", id] ->
|
||||||
sockethandler.serve(req, card.component(), id, room_handler)
|
sockethandler.serve(req, card.component(), id, room_handler)
|
||||||
["socket", "control", id] ->
|
["socket", "control", id] ->
|
||||||
sockethandler.serve(req, control.component(), id, room_handler)
|
sockethandler.serve(req, control.component(), id, room_handler)
|
||||||
["socket", "slow", id] ->
|
["socket", "single", id] ->
|
||||||
sockethandler.serve_slow(
|
sockethandler.serve_slow(
|
||||||
req,
|
req,
|
||||||
answerlist.component(),
|
answerlist.component(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue