elm-twitch/src/Views.elm

198 lines
4.7 KiB
Elm
Raw Normal View History

2020-10-03 18:44:16 +02:00
module Views exposing (view)
import Browser
2020-10-04 13:15:57 +02:00
import Colors
import Consts
2020-10-03 18:44:16 +02:00
import Core
2020-10-04 13:15:57 +02:00
import Element exposing (Element)
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Element.Input as Input
import Twitch
2020-10-03 18:44:16 +02:00
2020-10-04 13:15:57 +02:00
view : Core.FullModel -> Browser.Document Core.Msg
2020-10-03 18:44:16 +02:00
view model =
2020-10-04 13:15:57 +02:00
{ title = Consts.url
, body = [ Element.layout [] (viewContent model) ]
2020-10-03 18:44:16 +02:00
}
2020-10-04 13:15:57 +02:00
viewContent : Core.FullModel -> Element Core.Msg
viewContent model =
let
content =
case model of
Core.Unloaded ->
Element.none
Core.Loaded submodel ->
mainView submodel
in
Element.column [ Element.width Element.fill ] [ topBar, content ]
mainView : Core.Model -> Element Core.Msg
mainView model =
case model.page of
Core.Home ->
playlistsView model.playlists
topBar : Element Core.Msg
topBar =
Element.row
[ Element.width Element.fill
, Background.color Colors.primary
, Font.color Colors.white
, Font.size Consts.homeFontSize
]
[ homeButton ]
homeButton : Element Core.Msg
homeButton =
Input.button
[ Element.padding Consts.homePadding
, Element.height Element.fill
, Element.mouseOver [ Background.color Colors.primaryOver ]
, Font.bold
]
{ label = Element.text Consts.name
, onPress = Nothing
}
playlistsView : List Twitch.Playlist -> Element Core.Msg
playlistsView playlists =
let
empty =
Element.el [ Element.width Element.fill ] Element.none
views =
List.map playlistView playlists
grouped =
group 4 views
rows =
grouped
|> List.map (\x -> List.map (Maybe.withDefault empty) x)
|> List.map (Element.row [ Element.spacing 10, Element.width Element.fill ])
final =
Element.column [ Element.padding 10, Element.spacing 10, Element.width Element.fill ] rows
in
final
playlistView : Twitch.Playlist -> Element Core.Msg
playlistView playlist =
let
image =
Element.image [ Element.width Element.fill, Element.height Element.fill, Element.inFront inFront ]
{ description = "", src = Twitch.playlistMiniatureUrl playlist }
length =
List.length playlist.videos
label =
String.fromInt length
++ " video"
++ (if length > 1 then
"s"
else
""
)
inFront =
Element.el
[ Element.alignBottom
, Element.alignRight
, Background.color Colors.greyBackground
, Border.rounded 5
, Element.padding 5
, Font.color Colors.white
]
(Element.text label)
|> Element.el [ Element.alignBottom, Element.alignRight, Element.padding 5 ]
display =
Element.column [ Element.width Element.fill, Element.spacing 10 ]
[ image
, Element.paragraph [ Font.bold, Font.color Colors.blackFont ] [ Element.text playlist.name ]
]
button =
Input.button [ Element.width Element.fill, Element.alignTop ]
{ label = display
, onPress = Nothing
}
in
button
formatTime : Int -> String
formatTime time =
String.fromInt (toHours time)
++ ":"
++ String.fromInt (toMinutes time)
++ ":"
++ String.fromInt (toSeconds time)
toHours : Int -> Int
toHours i =
i // 3600
toMinutes : Int -> Int
toMinutes i =
modBy 3600 i // 60
toSeconds : Int -> Int
toSeconds i =
modBy 60 i
group : Int -> List a -> List (List (Maybe a))
group size list =
let
grouped =
List.map (List.map Just) (groupAux size list [])
groupedRev =
List.reverse grouped
( firstFixed, tail ) =
case groupedRev of
h :: t ->
( List.concat [ h, List.repeat (size - List.length h) Nothing ], t )
[] ->
( [], [] )
fixed =
(firstFixed :: tail) |> List.reverse
in
fixed
groupAux : Int -> List a -> List (List a) -> List (List a)
groupAux size list acc =
if List.isEmpty list then
acc
else
let
groupHead =
List.take size list
groupTail =
List.drop size list
in
groupAux size groupTail (groupHead :: acc)