Mock out joining a room

This commit is contained in:
Correl Roush 2020-05-04 14:22:24 -04:00
parent 76d19e0937
commit 22436d22f7
4 changed files with 313 additions and 96 deletions

View file

@ -79,7 +79,30 @@ updateUrl url model =
toEntry model (Entry.init ())
Just (Room id) ->
toRoom model (Room.init ())
case model.page of
EntryPage entryModel ->
toRoom model
(Room.init
{ room = id
, roomName =
case String.trim entryModel.roomName of
"" ->
"Planning Poker"
trimmed ->
trimmed
, playerName = entryModel.playerName
}
)
_ ->
toRoom model
(Room.init
{ room = id
, roomName = "Planning Poker"
, playerName = ""
}
)
Nothing ->
( model, Cmd.none )

View file

@ -11,26 +11,25 @@ import Html exposing (Html)
import PlanningPokerUI as UI
type User
= Moderator { name : String }
type alias Model =
{ name : String
, user : Maybe User
{ playerName : String
, roomName : String
, player : Maybe String
, error : Maybe String
}
type Msg
= NameChanged String
= PlayerNameChanged String
| RoomNameChanged String
| CreateRoom
init : () -> ( Model, Cmd Msg )
init _ =
( { name = ""
, user = Nothing
( { playerName = ""
, roomName = ""
, player = Nothing
, error = Nothing
}
, Cmd.none
@ -40,8 +39,11 @@ init _ =
update : Nav.Key -> Msg -> Model -> ( Model, Cmd Msg )
update key msg model =
case msg of
NameChanged newName ->
( { model | name = newName }, Cmd.none )
PlayerNameChanged newName ->
( { model | playerName = newName }, Cmd.none )
RoomNameChanged newName ->
( { model | roomName = newName }, Cmd.none )
CreateRoom ->
( model, Nav.pushUrl key "/room/a0fd1422-abd9-434e-9d7c-883294b2992c" )
@ -62,14 +64,21 @@ layout model =
[ el [ centerX ] (text "Oh, hey!")
, el [ centerX ] (text "Tell us who you are")
, Input.text [ centerX, width (px 300) ]
{ onChange = NameChanged
, text = model.name
{ onChange = PlayerNameChanged
, text = model.playerName
, label = Input.labelHidden "Your name"
, placeholder = Just (Input.placeholder [] (text "Your name"))
}
, el [ centerX ] (text "and what you're up to")
, Input.text [ centerX, width (px 300) ]
{ onChange = RoomNameChanged
, text = model.roomName
, label = Input.labelHidden "Room name"
, placeholder = Just (Input.placeholder [] (text "Planning Poker"))
}
, el [ centerX ] (text "then")
, UI.actionButton [ centerX ]
{ isActive = not (String.isEmpty model.name)
{ isActive = not (String.isEmpty model.playerName)
, onPress = CreateRoom
, label = text "Make a room!"
}

View file

@ -13,8 +13,22 @@ import PlanningPokerUI as UI
type alias Model =
{ name : String
{ room : Maybe Room
, player : String
, playerName : String
}
type Msg
= Vote String
| Reset
| PlayerNameChanged String
| JoinRoom
type alias Room =
{ id : String
, name : String
, players : Dict String Player
}
@ -31,19 +45,19 @@ type alias Player =
}
type Msg
= Vote String
| Reset
init : () -> ( Model, Cmd Msg )
init _ =
( { name = "Planning Poker"
, player = "099b73da-e714-4085-aa33-6419076d0765"
init : { room : String, roomName : String, playerName : String } -> ( Model, Cmd Msg )
init { room, roomName, playerName } =
let
preparedRooms =
Dict.fromList
[ -- Room created from mocked entry page
( "a0fd1422-abd9-434e-9d7c-883294b2992c"
, { id = "a0fd1422-abd9-434e-9d7c-883294b2992c"
, name = roomName
, players =
Dict.fromList
[ ( "099b73da-e714-4085-aa33-6419076d0765"
, { level = Moderator, name = "Me", vote = Nothing }
[ ( "00000000-0000-0000-0000-000000000000"
, { level = Moderator, name = playerName, vote = Nothing }
)
, ( "44db0a59-28bb-4b9f-8e5d-a46f2c2a3266"
, { level = Participant, name = "John", vote = Nothing }
@ -53,71 +67,150 @@ init _ =
)
]
}
)
, -- Room created from direct url access (unjoined)
( "joinable"
, { id = "a0fd1422-abd9-434e-9d7c-883294b2992c"
, name = "Today's Grooming Session"
, players =
Dict.fromList
[ ( "ffffffff-ffff-ffff-ffff-ffffffffffff"
, { level = Moderator, name = "Pat", vote = Nothing }
)
, ( "44db0a59-28bb-4b9f-8e5d-a46f2c2a3266"
, { level = Participant, name = "John", vote = Nothing }
)
, ( "69b8b450-bc2a-4eeb-b056-91c7aa4ba528"
, { level = Participant, name = "Jane", vote = Nothing }
)
]
}
)
]
in
( { room = Dict.get room preparedRooms
, player = "00000000-0000-0000-0000-000000000000"
, playerName = playerName
}
, Cmd.none
)
update : Nav.Key -> Msg -> Model -> ( Model, Cmd Msg )
update key msg model =
case model.room of
Just room ->
case msg of
Vote value ->
( { model
| room =
Just
{ room
| players =
Dict.update
model.player
(Maybe.map (\p -> { p | vote = Just value }))
model.players
room.players
}
}
, Cmd.none
)
Reset ->
( { model
| room =
Just
{ room
| players =
Dict.map
(\k v -> { v | vote = Nothing })
model.players
room.players
}
}
, Cmd.none
)
PlayerNameChanged newName ->
( { model | playerName = newName }, Cmd.none )
JoinRoom ->
let
newRoom =
{ room
| players =
Dict.insert model.player
{ level = Participant
, name = model.playerName
, vote = Nothing
}
room.players
}
in
( { model | room = Just newRoom }, Cmd.none )
Nothing ->
case msg of
_ ->
( model, Cmd.none )
view : Model -> Document Msg
view model =
{ title = model.name
, body = [ layout model ]
case model.room of
Just room ->
let
maybePlayer =
Dict.get model.player room.players
in
case maybePlayer of
Just player ->
UI.toDocument
{ title = room.name
, body =
[ navBar { title = room.name, playerName = player.name }
, viewRoom model.player room
]
}
Nothing ->
UI.toDocument
{ title = room.name
, body =
[ navBar { title = room.name, playerName = "" }
, joinForm room model.playerName
]
}
_ ->
UI.toDocument
{ title = "Loading Room..."
, body =
[ UI.heroText [ centerX, centerY ] "Loading..."
]
}
layout : Model -> Html Msg
layout model =
viewRoom : String -> Room -> Element Msg
viewRoom player room =
let
myVote =
Dict.get model.player model.players
Dict.get player room.players
|> Maybe.andThen .vote
in
Element.layout [] <|
column [ width fill, spacing 20 ]
[ navBar model
, row
[ row
[ width fill ]
[ el [ width (fillPortion 3), alignTop ] <|
cards myVote
viewCards myVote
, el [ width (fillPortion 1), alignTop ] <|
players (Dict.values model.players)
viewPlayers (Dict.values room.players)
]
, moderatorTools
]
navBar : Model -> Element Msg
navBar model =
let
myName =
Dict.get model.player model.players
|> Maybe.map .name
|> Maybe.withDefault ""
in
navBar : { title : String, playerName : String } -> Element Msg
navBar { title, playerName } =
row
[ Background.color UI.blue
, height (px 50)
@ -129,17 +222,17 @@ navBar model =
, Font.color UI.white
, width fill
]
(text model.name)
(text title)
, el
[ Font.alignRight
, Font.color UI.white
]
(text myName)
(text playerName)
]
cards : Maybe String -> Element Msg
cards selected =
viewCards : Maybe String -> Element Msg
viewCards selected =
let
card value =
Input.button
@ -166,8 +259,8 @@ cards selected =
List.map card [ "1", "3", "5", "8", "13" ]
players : List Player -> Element Msg
players playerList =
viewPlayers : List Player -> Element Msg
viewPlayers playerList =
table [ width fill ]
{ data = playerList
, columns =
@ -201,3 +294,47 @@ moderatorTools =
, onPress = Reset
, label = text "Reset"
}
joinForm : Room -> String -> Element Msg
joinForm room playerName =
let
players =
Dict.values room.players
|> List.map .name
in
column [ width fill, spacing 20, centerX, centerY ]
[ UI.heroText [ centerX ] "Welcome!"
, el [ centerX ] (text "Tell us who you are")
, Input.text [ centerX, width (px 300), Font.center ]
{ onChange = PlayerNameChanged
, text = playerName
, label = Input.labelHidden "Your name"
, placeholder = Just (Input.placeholder [] (text "Your name"))
}
, UI.actionButton [ centerX ]
{ isActive = not (String.isEmpty playerName)
, onPress = JoinRoom
, label = text "Join!"
}
, el [ centerX ]
(text <|
case players of
[] ->
"Nobody else has joined yet."
[ player ] ->
player ++ " is already here!"
player :: rest ->
if List.length players <= 3 then
String.join ", " rest
++ ", and "
++ player
++ " are already here!"
else
String.fromInt (List.length players)
++ " People are already here"
)
]

View file

@ -1,33 +1,63 @@
module PlanningPokerUI exposing (actionButton, blue, lightGrey, red, white)
module PlanningPokerUI exposing
( actionButton
, blue
, colors
, fontSizes
, heroText
, lightGrey
, red
, toDocument
, white
)
import Element exposing (Element)
import Browser exposing (Document)
import Element exposing (..)
import Element.Background as Background
import Element.Font as Font
import Element.Input as Input
blue : Element.Color
colors =
let
primary =
blue
in
{ primary = primary
, background = white
, selected = primary
, disabled = lightGrey
, error = red
}
fontSizes =
{ huge = 80
, normal = 18
}
blue : Color
blue =
Element.rgb255 100 100 255
rgb255 100 100 255
lightGrey : Element.Color
lightGrey : Color
lightGrey =
Element.rgb255 200 200 200
rgb255 200 200 200
red : Element.Color
red : Color
red =
Element.rgb255 255 100 100
rgb255 255 100 100
white : Element.Color
white : Color
white =
Element.rgb255 255 255 255
rgb255 255 255 255
actionButton :
List (Element.Attribute msg)
List (Attribute msg)
-> { isActive : Bool, onPress : msg, label : Element msg }
-> Element msg
actionButton attrs { isActive, onPress, label } =
@ -40,7 +70,7 @@ actionButton attrs { isActive, onPress, label } =
( lightGrey, Nothing )
in
Input.button
([ Element.padding 20
([ padding 20
, Background.color color
, Font.color white
]
@ -49,3 +79,21 @@ actionButton attrs { isActive, onPress, label } =
{ onPress = maybeEvent
, label = label
}
heroText :
List (Attribute msg)
-> String
-> Element msg
heroText attrs s =
el ([ Font.size fontSizes.huge ] ++ attrs) (text s)
toDocument : { title : String, body : List (Element msg) } -> Document msg
toDocument { title, body } =
{ title = title
, body =
[ layout [ explain Debug.todo ] <|
column [ width fill, height fill, spacing 20 ] body
]
}