Track votes in ETS

This commit is contained in:
Correl Roush 2020-05-08 00:34:42 -04:00
parent d595c5603f
commit 80f96092c9
6 changed files with 59 additions and 23 deletions

View file

@ -27,7 +27,7 @@ socket.connect()
var app = Elm.Main.init({
node: document.getElementById("elm-main"),
flags: {
player: "player:" + player_id,
player: player_id,
room: room_id
}
})
@ -48,6 +48,9 @@ app.ports.joinRoom.subscribe(options => {
app.ports.newProfile.subscribe(profile => {
channel.push("new_profile", { "name": profile.playerName })
})
app.ports.vote.subscribe(value => {
channel.push("vote", value)
})
channel.join()
.receive("ok", resp => {
console.log("Joined successfully", resp);

View file

@ -3,6 +3,7 @@ port module PlanningPokerAPI exposing
, joinRoom
, joinedRoom
, newProfile
, vote
)
import Json.Decode exposing (Value)
@ -14,6 +15,9 @@ port joinRoom : { room : String } -> Cmd msg
port newProfile : { playerName : String } -> Cmd msg
port vote : String -> Cmd msg
port joinedRoom : (String -> msg) -> Sub msg

View file

@ -113,17 +113,8 @@ update key msg model =
in
case msg of
Vote value ->
( { model
| room =
{ room
| players =
Dict.update
model.player
(Maybe.map (\p -> { p | vote = Just value }))
room.players
}
}
, Cmd.none
( model
, API.vote value
)
Reveal ->
@ -368,13 +359,8 @@ playersDecoder : Decode.Decoder (Dict String Player)
playersDecoder =
let
presence =
Decode.field "name" Decode.string
toPlayer id name =
{ level = Participant
, name = name
, vote = Nothing
}
Decode.map2 (Player Participant)
(Decode.field "name" Decode.string)
(Decode.field "vote" (Decode.nullable Decode.string))
in
Decode.dict presence
|> Decode.map (Dict.map toPlayer)

View file

@ -8,6 +8,7 @@ defmodule Planningpoker.Db do
def init(_) do
:ets.new(:users, [:named_table, :public])
:ets.new(:votes, [:named_table, :public])
{:ok, %{}}
end
@ -16,7 +17,24 @@ defmodule Planningpoker.Db do
:ets.insert(:users, {user, name})
end
def save_vote(user, room, value) do
Logger.debug("Storing vote of #{value} for player #{user} in room #{room}")
:ets.insert(:votes, {{user, room}, value})
end
def get_users(keys) do
:ets.select(:users, (for key <- keys, do: {{key, :_}, [], [:"$_"]}))
match = for key <- keys do
{{key, :_}, [], [:"$_"]}
end
Logger.debug("Getting users: #{inspect match}")
:ets.select(:users, match)
end
def get_votes(users, room) do
match = for user <- users do
{{{user, room}, :_}, [], [:"$_"]}
end
Logger.debug("Getting votes: #{inspect match}")
:ets.select(:votes, match)
end
end

View file

@ -10,15 +10,23 @@ defmodule PlanningpokerWeb.Presence do
require Logger
alias Planningpoker.Db
def fetch(_topic, entries) do
def fetch("room:" <> room, entries) do
users =
entries
|> Map.keys()
|> Db.get_users()
|> Enum.into(%{})
votes =
users
|> Map.keys()
|> Db.get_votes(room)
|> Enum.into(%{}, fn {{u, _r}, v} -> {u, v} end)
for {key, %{metas: metas}} <- entries, into: %{} do
{key, %{metas: metas, name: users[key]}}
{key, %{metas: metas,
name: users[key],
vote: Map.get(votes, key)}}
end
end
def fetch(_topic, entries), do: entries
end

View file

@ -25,4 +25,21 @@ defmodule PlanningpokerWeb.RoomChannel do
)
{:noreply, socket}
end
def handle_in("vote", value, socket) do
Db.save_vote(
socket.assigns.player_id,
socket.assigns.room_id,
value
)
votes = Db.get_votes([socket.assigns.player_id], socket.assigns.room_id)
{:ok, _} = Presence.update(
socket,
socket.assigns.player_id,
fn x -> x end
)
{:noreply, socket}
end
def handle_in(_event, _data, socket) do
{:noreply, socket}
end
end