Bot-Man-Toe/elm/EloTracker.elm

206 lines
5.2 KiB
Elm

module EloTracker exposing (main)
import Api.Elo as Elo
import Element exposing (Element)
import Element.Background
import Element.Font
import Http
import Json.Decode as D
import Layout
import Pixels
import Program
import Screen.Leaderboard
import Theme
import Time
import Widget.Icon
main =
Program.document
{ flagsDecoder = D.field "baseUrl" D.string
, headers = headers
, init = init
, subscriptions = subscriptions
, title = title
, update = update
, view = view
}
-- MODEL
type alias Model =
{ baseUrl : String
, leaderboard : Result Int Elo.Leaderboard
, matches : Result Int (List Elo.Match)
, selectedName : String
}
type Msg
= OnLeaderboard (Result Http.Error Elo.Leaderboard)
| OnMatches (Result Http.Error (List Elo.Match))
| OnSelectLeaderboardName String
| RefreshLeaderboard
| RefreshMatches
init : Result D.Error String -> ( Model, Cmd Msg )
init flag =
let
baseUrl =
case flag of
Err _ ->
"http://localhost:5000"
Ok v ->
v
model =
{ baseUrl = baseUrl
, leaderboard = Err 0
, matches = Err 0
, selectedName = "tic-tac-toe"
}
in
( model
, Cmd.batch
[ getLeaderboard model
, getMatches model
]
)
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
OnLeaderboard (Err _) ->
case model.leaderboard of
Err n ->
( { model | leaderboard = Err (n + 1) }, Cmd.none )
Ok _ ->
( model, Cmd.none )
OnLeaderboard (Ok v) ->
( { model | leaderboard = Ok v }, Cmd.none )
OnMatches (Err _) ->
case model.matches of
Err n ->
( { model | matches = Err (n + 1) }, Cmd.none )
Ok _ ->
( model, Cmd.none )
OnMatches (Ok v) ->
( { model | matches = Ok v }, Cmd.none )
OnSelectLeaderboardName name ->
( { model | selectedName = name }, Cmd.none )
RefreshLeaderboard ->
( model, getLeaderboard model )
RefreshMatches ->
( model, getMatches model )
getLeaderboard : Model -> Cmd Msg
getLeaderboard model =
Elo.getLeaderboard { baseUrl = model.baseUrl, toMsg = OnLeaderboard }
getMatches : Model -> Cmd Msg
getMatches model =
Elo.getMatches { baseUrl = model.baseUrl, toMsg = OnMatches }
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.batch
[ Time.every (5 * 1000) (always RefreshLeaderboard)
, Time.every (1 * 60 * 1000) (always RefreshMatches)
]
-- VIEW
headers : Model -> List { icon : Widget.Icon.Icon msg, onPress : msg }
headers _ =
[]
title : Model -> String
title model =
case model.leaderboard of
Err _ ->
"EloTracker | Loading..."
Ok _ ->
"EloTracker | Leaderboard"
view : Program.ViewBox Model -> Element Msg
view data =
case data.model.leaderboard of
Err 0 ->
Element.column
[ Element.width <| Element.px <| Pixels.inPixels data.size.width
, Element.height <| Element.px <| Pixels.inPixels data.size.height
]
[ Element.column
[ Element.centerX
, Element.centerY
, Element.Background.color (Theme.mantleUI data.flavor)
, Element.padding 15
, Element.spacing 10
]
[ Element.text "Loading leaderboard..."
, Layout.loadingIndicator { color = Theme.lavender data.flavor }
|> Element.el [ Element.centerX ]
]
]
Err n ->
Element.column
[ Element.width <| Element.px <| Pixels.inPixels data.size.width
, Element.height <| Element.px <| Pixels.inPixels data.size.height
]
[ Element.column
[ Element.centerX
, Element.centerY
, Element.Background.color (Theme.mantleUI data.flavor)
, Element.padding 15
, Element.spacing 10
]
[ Element.text "Loading leaderboard..."
, Element.el [ Element.centerX, Element.Font.color (Theme.redUI data.flavor) ] (Element.text ("Failed " ++ String.fromInt n ++ " times"))
, Layout.loadingIndicator { color = Theme.lavender data.flavor }
|> Element.el [ Element.centerX ]
]
]
Ok leaderboard ->
Screen.Leaderboard.view
{ flavor = data.flavor
, model =
{ board = leaderboard
, onSelect = OnSelectLeaderboardName
, selectedName = data.model.selectedName
}
, size = data.size
}