mirror of
https://github.com/correl/planning-poker.git
synced 2024-11-21 19:18:37 +00:00
Handle presence events in Elm
Pass state and diff events to elm, where the state can be managed accordingly. Because vote events are used to update player state, we don't want to blindly overwrite it by passing a separately synced presence list through, as it will lack vote data. Fixes #1
This commit is contained in:
parent
4e8ac6f8d2
commit
e5777f6f7a
3 changed files with 74 additions and 26 deletions
|
@ -38,17 +38,8 @@ app.ports.joinRoom.subscribe(options => {
|
|||
let channel = socket.channel("room:" + options.room, {})
|
||||
|
||||
// Presence events
|
||||
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)
|
||||
})
|
||||
channel.on("presence_state", app.ports.gotPresenceState.send)
|
||||
channel.on("presence_diff", app.ports.gotPresenceDiff.send)
|
||||
|
||||
// Incoming room events
|
||||
channel.on("vote", app.ports.gotVote.send)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
port module PlanningPokerAPI exposing
|
||||
( gotPresence
|
||||
( gotPresenceDiff
|
||||
, gotPresenceState
|
||||
, gotReset
|
||||
, gotReveal
|
||||
, gotVote
|
||||
|
@ -73,7 +74,10 @@ encodeAction action =
|
|||
wrap "reveal" (Encode.object [])
|
||||
|
||||
|
||||
port gotPresence : (Decode.Value -> msg) -> Sub msg
|
||||
port gotPresenceState : (Decode.Value -> msg) -> Sub msg
|
||||
|
||||
|
||||
port gotPresenceDiff : (Decode.Value -> msg) -> Sub msg
|
||||
|
||||
|
||||
port gotVote : (Decode.Value -> msg) -> Sub msg
|
||||
|
|
|
@ -41,12 +41,25 @@ type Msg
|
|||
| Reveal
|
||||
| PlayerNameChanged String
|
||||
| JoinRoom
|
||||
| GotPresence Decode.Value
|
||||
| GotPresence Presence
|
||||
| GotPresenceDiff Decode.Value
|
||||
| GotVote Decode.Value
|
||||
| GotReveal
|
||||
| GotReset
|
||||
|
||||
|
||||
type Presence
|
||||
= PresenceState (Dict String Player)
|
||||
| PresenceDiff (Diff (Dict String Player))
|
||||
| PresenceError Decode.Error
|
||||
|
||||
|
||||
type alias Diff a =
|
||||
{ joins : a
|
||||
, leaves : a
|
||||
}
|
||||
|
||||
|
||||
type alias Room =
|
||||
{ id : String
|
||||
, name : String
|
||||
|
@ -138,17 +151,30 @@ update key msg model =
|
|||
, API.newProfile { playerName = model.playerName }
|
||||
)
|
||||
|
||||
GotPresence value ->
|
||||
case Decode.decodeValue playersDecoder value of
|
||||
Ok players ->
|
||||
let
|
||||
newRoom =
|
||||
{ room | players = players }
|
||||
in
|
||||
( { model | room = newRoom }, Cmd.none )
|
||||
GotPresence (PresenceState players) ->
|
||||
let
|
||||
newRoom =
|
||||
{ room | players = players }
|
||||
in
|
||||
( { model | room = newRoom }, Cmd.none )
|
||||
|
||||
Err _ ->
|
||||
( model, Cmd.none )
|
||||
GotPresence (PresenceDiff { joins, leaves }) ->
|
||||
let
|
||||
newPlayers =
|
||||
room.players
|
||||
|> Dict.filter (\id _ -> not (Dict.member id leaves))
|
||||
|> Dict.union joins
|
||||
|
||||
newRoom =
|
||||
{ room | players = newPlayers }
|
||||
in
|
||||
( { model | room = newRoom }, Cmd.none )
|
||||
|
||||
GotPresence _ ->
|
||||
( model, Cmd.none )
|
||||
|
||||
GotPresenceDiff _ ->
|
||||
( model, Cmd.none )
|
||||
|
||||
GotVote value ->
|
||||
case Decode.decodeValue voteDecoder value of
|
||||
|
@ -194,7 +220,6 @@ view dimensions model =
|
|||
let
|
||||
device =
|
||||
classifyDevice dimensions
|
||||
|> Debug.log "device"
|
||||
|
||||
playerName =
|
||||
Dict.get model.player model.room.players
|
||||
|
@ -439,13 +464,41 @@ joinForm room playerName =
|
|||
subscriptions : Sub Msg
|
||||
subscriptions =
|
||||
Sub.batch
|
||||
[ API.gotPresence GotPresence
|
||||
[ API.gotPresenceState (decodePresenceState >> GotPresence)
|
||||
, API.gotPresenceDiff (decodePresenceDiff >> GotPresence)
|
||||
, API.gotReset (\_ -> GotReset)
|
||||
, API.gotReveal (\_ -> GotReveal)
|
||||
, API.gotVote GotVote
|
||||
]
|
||||
|
||||
|
||||
decodePresenceState : Decode.Value -> Presence
|
||||
decodePresenceState value =
|
||||
case Decode.decodeValue playersDecoder value of
|
||||
Ok players ->
|
||||
PresenceState players
|
||||
|
||||
Err error ->
|
||||
PresenceError error
|
||||
|
||||
|
||||
decodePresenceDiff : Decode.Value -> Presence
|
||||
decodePresenceDiff value =
|
||||
let
|
||||
diffDecoder =
|
||||
Decode.map PresenceDiff <|
|
||||
Decode.map2 Diff
|
||||
(Decode.field "joins" playersDecoder)
|
||||
(Decode.field "leaves" playersDecoder)
|
||||
in
|
||||
case Decode.decodeValue diffDecoder value of
|
||||
Ok diff ->
|
||||
diff
|
||||
|
||||
Err error ->
|
||||
PresenceError error
|
||||
|
||||
|
||||
playersDecoder : Decode.Decoder (Dict String Player)
|
||||
playersDecoder =
|
||||
let
|
||||
|
|
Loading…
Reference in a new issue