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

View file

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

View file

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

View file

@ -8,6 +8,7 @@ defmodule Planningpoker.Db do
def init(_) do def init(_) do
:ets.new(:users, [:named_table, :public]) :ets.new(:users, [:named_table, :public])
:ets.new(:votes, [:named_table, :public])
{:ok, %{}} {:ok, %{}}
end end
@ -16,7 +17,24 @@ defmodule Planningpoker.Db do
:ets.insert(:users, {user, name}) :ets.insert(:users, {user, name})
end 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 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
end end

View file

@ -10,15 +10,23 @@ defmodule PlanningpokerWeb.Presence do
require Logger require Logger
alias Planningpoker.Db alias Planningpoker.Db
def fetch(_topic, entries) do def fetch("room:" <> room, entries) do
users = users =
entries entries
|> Map.keys() |> Map.keys()
|> Db.get_users() |> Db.get_users()
|> Enum.into(%{}) |> 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 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
end end
def fetch(_topic, entries), do: entries
end end

View file

@ -25,4 +25,21 @@ defmodule PlanningpokerWeb.RoomChannel do
) )
{:noreply, socket} {:noreply, socket}
end 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 end