160 lines
5.1 KiB
Elm
160 lines
5.1 KiB
Elm
module Screen.Leaderboard exposing (..)
|
|
|
|
{-| Widget module for a leaderboard page.
|
|
-}
|
|
|
|
import Api.Elo exposing (EloStat, Leaderboard, Players)
|
|
import Color
|
|
import Element exposing (Element)
|
|
import Element.Background
|
|
import Element.Border
|
|
import Element.Events
|
|
import Element.Font
|
|
import Layout
|
|
import Pixels exposing (Pixels)
|
|
import Program exposing (ViewBox)
|
|
import Quantity exposing (Quantity)
|
|
import Theme
|
|
|
|
|
|
view : ViewBox { board : Leaderboard, onSelect : String -> msg, selectedName : String } -> Element msg
|
|
view data =
|
|
Element.column
|
|
[]
|
|
[ selectBoard
|
|
{ flavor = data.flavor
|
|
, leaderboard = data.model.board
|
|
, onSelect = data.model.onSelect
|
|
, selectedName = data.model.selectedName
|
|
, width = data.size.width
|
|
}
|
|
, data.model.board
|
|
|> List.map
|
|
(\l ->
|
|
if l.name == data.model.selectedName then
|
|
viewSingleBoard
|
|
{ flavor = data.flavor
|
|
, model = l
|
|
, size = data.size
|
|
}
|
|
|
|
else
|
|
Element.none
|
|
)
|
|
|> Element.column []
|
|
]
|
|
|
|
|
|
selectBoard :
|
|
{ flavor : Theme.Flavor
|
|
, leaderboard : Leaderboard
|
|
, onSelect : String -> msg
|
|
, selectedName : String
|
|
, width : Quantity Int Pixels
|
|
}
|
|
-> Element msg
|
|
selectBoard data =
|
|
data.leaderboard
|
|
|> List.map .name
|
|
|> List.map
|
|
(\s ->
|
|
Element.el
|
|
[ if data.selectedName == s then
|
|
Element.Background.color (Theme.subtext0UI data.flavor)
|
|
|
|
else
|
|
Element.Background.color (Theme.surface1UI data.flavor)
|
|
, Element.Border.rounded 25
|
|
, Element.centerX
|
|
, Element.Events.onClick (data.onSelect s)
|
|
, Element.padding 10
|
|
]
|
|
(Element.text s)
|
|
)
|
|
|> Element.wrappedRow
|
|
[ Element.padding 20
|
|
, Element.spacing 10
|
|
, Element.width <| Element.px <| Pixels.inPixels data.width
|
|
]
|
|
|
|
|
|
viewSingleBoard : ViewBox { name : String, players : Players } -> Element msg
|
|
viewSingleBoard data =
|
|
let
|
|
boardWidth =
|
|
data.size.width
|
|
|> Quantity.toFloatQuantity
|
|
|> Quantity.multiplyBy (2 / 3)
|
|
|> Quantity.floor
|
|
|> Quantity.clamp (Pixels.pixels 600) (Pixels.pixels 1800)
|
|
|> Pixels.inPixels
|
|
|> Element.px
|
|
|> Element.width
|
|
in
|
|
data.model.players
|
|
|> List.map (viewEloStat { flavor = data.flavor })
|
|
|> Element.column [ Element.centerX, boardWidth ]
|
|
|> List.singleton
|
|
|> (::)
|
|
(Element.text data.model.name
|
|
|> Element.el
|
|
[ Element.centerX, Element.Font.size 50 ]
|
|
)
|
|
|> Element.column
|
|
[ Element.padding 15
|
|
, Element.spacing 30
|
|
, Element.width <| Element.px <| Pixels.inPixels data.size.width
|
|
]
|
|
|
|
|
|
viewEloStat : { flavor : Theme.Flavor } -> EloStat -> Element msg
|
|
viewEloStat data stat =
|
|
Element.row
|
|
[ Element.Background.color (Theme.mantleUI data.flavor)
|
|
, Element.Border.rounded 5
|
|
, Element.padding 10
|
|
, Element.spacing 5
|
|
, Element.width Element.fill
|
|
]
|
|
[ Element.column
|
|
[ Element.centerY, Element.spacing 5, Element.width Element.fill ]
|
|
[ Element.text stat.name
|
|
|> Element.el [ Element.Font.size 30 ]
|
|
, Element.el
|
|
[ Element.Font.color (Theme.subtext0UI data.flavor)
|
|
, Element.Font.size 15
|
|
]
|
|
(case stat.version of
|
|
Nothing ->
|
|
Element.text stat.url
|
|
|
|
Just v ->
|
|
Element.text (stat.url ++ " | " ++ v)
|
|
)
|
|
]
|
|
|
|
-- Bar to push the rest to the right
|
|
, Element.column [ Element.width Element.fill ] []
|
|
, field { text = "ELO", value = stat.elo, color = Theme.lavenderUI data.flavor }
|
|
|> Element.el [ Element.paddingEach { top = 0, bottom = 0, left = 0, right = 15 } ]
|
|
, field { text = "WINS", value = stat.wins, color = Theme.greenUI data.flavor }
|
|
, field { text = "DRAWS", value = stat.draws, color = Theme.subtext0UI data.flavor }
|
|
, field { text = "LOSSES", value = stat.losses, color = Theme.redUI data.flavor }
|
|
]
|
|
|
|
|
|
field : { text : String, value : Int, color : Element.Color } -> Element msg
|
|
field { text, value, color } =
|
|
Element.column
|
|
[ Element.Font.color color
|
|
, Element.spacing 3
|
|
, Element.width (Element.px 70)
|
|
]
|
|
[ String.fromInt value
|
|
|> Element.text
|
|
|> Element.el [ Element.centerX, Element.Font.size 25 ]
|
|
, text
|
|
|> Element.text
|
|
|> Element.el [ Element.centerX, Element.Font.size 15 ]
|
|
]
|