Improve room joining

This commit is contained in:
Correl Roush 2020-05-06 20:03:31 -04:00
parent a534184ff1
commit 8e4a7ff564
5 changed files with 100 additions and 114 deletions

View file

@ -29,23 +29,26 @@ var app = Elm.Main.init({
}) })
app.ports.joinRoom.subscribe(options => { app.ports.joinRoom.subscribe(options => {
let channel = socket.channel( let channel = socket.channel("room:" + options.room, {})
"room:" + options.room,
{playerName: options.playerName}
)
let presences = {} let presences = {}
channel.on("presence_state", state => {
console.log("presence state", state)
presences = Presence.syncState(presences, state)
app.ports.gotPresence.send(presences)
})
channel.on("presence_diff", diff => {
console.log("presence diff", diff)
presences = Presence.syncDiff(presences, diff)
app.ports.gotPresence.send(presences)
})
app.ports.newProfile.subscribe(profile => {
channel.push("new_profile", { "name": profile.playerName })
})
channel.join() channel.join()
.receive("ok", resp => { .receive("ok", resp => {
console.log("Joined successfully", resp); console.log("Joined successfully", resp);
app.ports.joinedRoom.send(options.room); app.ports.joinedRoom.send(options.room);
}) })
.receive("error", resp => { console.log("Unable to join", resp) }) .receive("error", resp => { console.log("Unable to join", resp) })
channel.on("presence_state", state => {
presences = Presence.syncState(presences, state)
app.ports.gotPresence.send(presences)
})
channel.on("presence_diff", diff => {
presences = Presence.syncDiff(presences, diff)
app.ports.gotPresence.send(presences)
})
}) })

View file

@ -2,12 +2,16 @@ port module PlanningPokerAPI exposing
( gotPresence ( gotPresence
, joinRoom , joinRoom
, joinedRoom , joinedRoom
, newProfile
) )
import Json.Decode exposing (Value) import Json.Decode exposing (Value)
port joinRoom : { room : String, playerName : String } -> Cmd msg port joinRoom : { room : String } -> Cmd msg
port newProfile : { playerName : String } -> Cmd msg
port joinedRoom : (String -> msg) -> Sub msg port joinedRoom : (String -> msg) -> Sub msg

View file

@ -53,7 +53,10 @@ update key msg model =
"a0fd1422-abd9-434e-9d7c-883294b2992c" "a0fd1422-abd9-434e-9d7c-883294b2992c"
in in
( model ( model
, API.joinRoom { room = room, playerName = model.playerName } , Cmd.batch
[ API.joinRoom { room = room }
, API.newProfile { playerName = model.playerName }
]
) )
JoinedRoom room -> JoinedRoom room ->

View file

@ -22,7 +22,7 @@ import PlanningPokerUI as UI
type alias Model = type alias Model =
{ room : Maybe Room { room : Room
, player : String , player : String
, playerName : String , playerName : String
, showVotes : Bool , showVotes : Bool
@ -77,125 +77,98 @@ init { id, player, roomName, playerName } =
, players = Dict.empty , players = Dict.empty
} }
in in
( { room = Just room ( { room = room
, player = player , player = player
, playerName = playerName , playerName = playerName
, showVotes = False , showVotes = False
} }
, Cmd.none , API.joinRoom { room = id }
) )
update : Nav.Key -> Msg -> Model -> ( Model, Cmd Msg ) update : Nav.Key -> Msg -> Model -> ( Model, Cmd Msg )
update key msg model = update key msg model =
case model.room of let
Just room -> room =
case msg of model.room
Vote value -> in
( { model case msg of
| room = Vote value ->
Just ( { model
{ room | room =
| players = { room
Dict.update | players =
model.player Dict.update
(Maybe.map (\p -> { p | vote = Just value })) model.player
room.players (Maybe.map (\p -> { p | vote = Just value }))
} room.players
} }
, Cmd.none }
) , Cmd.none
)
Reveal -> Reveal ->
( { model | showVotes = True } ( { model | showVotes = True }
, Cmd.none , Cmd.none
) )
Reset -> Reset ->
( { model ( { model
| room = | room =
Just { room
{ room | players =
| players = Dict.map
Dict.map (\k v -> { v | vote = Nothing })
(\k v -> { v | vote = Nothing }) room.players
room.players }
} , showVotes = False
, showVotes = False }
} , Cmd.none
, Cmd.none )
)
PlayerNameChanged newName -> PlayerNameChanged newName ->
( { model | playerName = newName }, Cmd.none ) ( { model | playerName = newName }, Cmd.none )
JoinRoom -> JoinRoom ->
( model
, API.newProfile { playerName = model.playerName }
)
GotPresence value ->
case Decode.decodeValue playersDecoder value of
Ok players ->
let let
newRoom = newRoom =
{ room { room | players = players }
| players =
Dict.insert model.player
{ level = Participant
, name = model.playerName
, vote = Nothing
}
room.players
}
in in
( model ( { model | room = newRoom }, Cmd.none )
, API.joinRoom { room = room.id, playerName = model.playerName }
)
GotPresence value -> Err _ ->
case Decode.decodeValue playersDecoder value of
Ok players ->
let
newRoom =
{ room | players = players }
in
( { model | room = Just newRoom }, Cmd.none )
Err _ ->
( model, Cmd.none )
Nothing ->
case msg of
_ ->
( model, Cmd.none ) ( model, Cmd.none )
view : Model -> Document Msg view : Model -> Document Msg
view model = view model =
case model.room of let
Just room -> maybePlayer =
let Dict.get model.player model.room.players
maybePlayer = in
Dict.get model.player room.players case maybePlayer of
in Just player ->
case maybePlayer of
Just player ->
UI.toDocument
{ title = room.name
, body =
[ navBar { title = room.name, playerName = player.name }
, viewRoom model.player room model.showVotes
]
}
Nothing ->
UI.toDocument
{ title = room.name
, body =
[ navBar { title = room.name, playerName = "" }
, joinForm room model.playerName
]
}
_ ->
UI.toDocument UI.toDocument
{ title = "Loading Room..." { title = model.room.name
, body = , body =
[ UI.heroText [ centerX, centerY ] "Loading..." [ navBar { title = model.room.name, playerName = player.name }
, viewRoom model.player model.room model.showVotes
]
}
Nothing ->
UI.toDocument
{ title = model.room.name
, body =
[ navBar { title = model.room.name, playerName = "" }
, joinForm model.room model.playerName
] ]
} }

View file

@ -10,14 +10,17 @@ defmodule PlanningpokerWeb.RoomChannel do
|> assign(:player_name, params["playerName"])} |> assign(:player_name, params["playerName"])}
end end
def handle_info(:after_join, socket) do def handle_info(:after_join, socket) do
push(socket, "presence_state", Presence.list(socket))
{:noreply, socket}
end
def handle_in("new_profile", %{"name" => name}, socket) do
{:ok, _} = Presence.track( {:ok, _} = Presence.track(
socket, socket,
"player:#{socket.assigns.player_id}", "player:#{socket.assigns.player_id}",
%{ %{
name: socket.assigns.player_name, name: name
online_at: inspect(System.system_time(:second)) }
}) )
push(socket, "presence_state", Presence.list(socket))
{:noreply, socket} {:noreply, socket}
end end
end end