Browsing the pages work

This commit is contained in:
Thomas Forgione 2020-10-04 15:24:04 +02:00
parent 0215d94be9
commit 5872e50493
7 changed files with 202 additions and 49 deletions

View File

@ -15,7 +15,8 @@
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"jims/html-parser": "1.0.0",
"mdgriffith/elm-ui": "1.1.8"
"mdgriffith/elm-ui": "1.1.8",
"rtfeldman/elm-iso8601-date-strings": "1.1.3"
},
"indirect": {
"elm/bytes": "1.0.8",

View File

@ -1,4 +1,4 @@
module Colors exposing (blackFont, greyBackground, primary, primaryOver, white)
module Colors exposing (blackFont, greyBackground, greyFont, primary, primaryOver, white)
import Element
@ -26,3 +26,8 @@ greyBackground =
blackFont : Element.Color
blackFont =
Element.rgb255 54 54 54
greyFont : Element.Color
greyFont =
Element.rgb255 128 128 128

View File

@ -1,4 +1,11 @@
module Consts exposing (homeFontSize, homePadding, name, url)
module Consts exposing
( homeFontSize
, homePadding
, name
, normalFontSize
, titleFontSize
, url
)
url : String
@ -11,6 +18,16 @@ name =
url
normalFontSize : Int
normalFontSize =
13
titleFontSize : Int
titleFontSize =
15
homeFontSize : Int
homeFontSize =
25

View File

@ -3,6 +3,7 @@ module Core exposing (FullModel(..), Model, Msg(..), Page(..), init, update)
import Browser.Navigation
import Json.Decode as Decode
import Task
import Time
import Twitch
import Url
@ -14,6 +15,7 @@ type FullModel
type alias Model =
{ playlists : List Twitch.Playlist
, zone : Time.Zone
, page : Page
}
@ -26,7 +28,7 @@ type Page
type Msg
= Noop
| PlaylistsReceived (List Twitch.Playlist)
| PlaylistsReceived ( List Twitch.Playlist, Time.Zone )
| HomeClicked
| PlaylistClicked Twitch.Playlist
| VideoClicked Twitch.Playlist Twitch.Video
@ -45,17 +47,17 @@ update msg model =
( Noop, _ ) ->
( model, Cmd.none )
( PlaylistsReceived playlists, _ ) ->
( Loaded { playlists = playlists, page = Home }, Cmd.none )
( PlaylistsReceived ( playlists, zone ), _ ) ->
( Loaded { playlists = playlists, zone = zone, page = Home }, Cmd.none )
( HomeClicked, Loaded { playlists } ) ->
( Loaded { playlists = playlists, page = Home }, Cmd.none )
( HomeClicked, Loaded m ) ->
( Loaded { m | page = Home }, Cmd.none )
( PlaylistClicked playlist, Loaded { playlists } ) ->
( Loaded { playlists = playlists, page = Playlist playlist }, Cmd.none )
( PlaylistClicked playlist, Loaded m ) ->
( Loaded { m | page = Playlist playlist }, Cmd.none )
( VideoClicked playlist video, Loaded { playlists } ) ->
( Loaded { playlists = playlists, page = Video playlist video }, Cmd.none )
( VideoClicked playlist video, Loaded m ) ->
( Loaded { m | page = Video playlist video }, Cmd.none )
_ ->
( model, Cmd.none )

52
src/TimeUtils.elm Normal file
View File

@ -0,0 +1,52 @@
module TimeUtils exposing (monthToString, pad2)
import Time
pad2 : String -> String
pad2 input =
if String.length input == 1 then
"0" ++ input
else
input
monthToString : Time.Month -> String
monthToString month =
case month of
Time.Jan ->
"01"
Time.Feb ->
"02"
Time.Mar ->
"03"
Time.Apr ->
"04"
Time.May ->
"05"
Time.Jun ->
"06"
Time.Jul ->
"07"
Time.Aug ->
"08"
Time.Sep ->
"09"
Time.Oct ->
"10"
Time.Nov ->
"11"
Time.Dec ->
"12"

View File

@ -8,8 +8,10 @@ module Twitch exposing
import Html.Parser
import Http
import Iso8601
import Json.Decode as Decode
import Task exposing (Task)
import Time
type alias Playlist =
@ -23,6 +25,7 @@ type alias Video =
{ name : String
, url : String
, duration : Int
, date : Time.Posix
}
@ -63,9 +66,17 @@ sortPlaylists playlists =
List.sortBy .url (List.map sortPlaylist playlists) |> List.reverse
fetchPlaylists : Task x (List Playlist)
fetchPlaylists : Task x ( List Playlist, Time.Zone )
fetchPlaylists =
fetchPlaylistPath |> Task.andThen fetchPlaylistsMapper |> Task.map sortPlaylists
fetchPlaylistPath
|> Task.andThen fetchPlaylistsMapper
|> Task.map sortPlaylists
|> Task.andThen fetchTimezone
fetchTimezone : List Playlist -> Task x ( List Playlist, Time.Zone )
fetchTimezone playlists =
Task.map (\zone -> ( playlists, zone )) Time.here
fetchPlaylistPath : Task x (List String)
@ -129,10 +140,10 @@ parseVideo url result =
Ok v
_ ->
Ok { name = "", url = url, duration = 0 }
Ok { name = "", url = url, duration = 0, date = Time.millisToPosix 0 }
_ ->
Ok { name = "", url = url, duration = 0 }
Ok { name = "", url = url, duration = 0, date = Time.millisToPosix 0 }
fetchPlaylistsMapper : List String -> Task x (List Playlist)
@ -221,6 +232,7 @@ decodePlaylistName =
decodeVideo : String -> Decode.Decoder Video
decodeVideo url =
Decode.map2 (\x y -> Video x url y)
Decode.map3 (\x y -> Video x url y)
(Decode.field "title" Decode.string)
(Decode.map Basics.round (Decode.field "duration" Decode.float))
(Decode.field "date" Iso8601.decoder)

View File

@ -9,13 +9,18 @@ import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Element.Input as Input
import Time
import TimeUtils
import Twitch
view : Core.FullModel -> Browser.Document Core.Msg
view model =
{ title = Consts.url
, body = [ Element.layout [] (viewContent model) ]
, body =
[ Element.layout [ Font.color Colors.blackFont, Font.size Consts.normalFontSize ]
(viewContent model)
]
}
@ -40,10 +45,10 @@ mainView model =
playlistsView model.playlists
Core.Playlist playlist ->
videoMiniaturesView playlist
videoMiniaturesView model.zone playlist
Core.Video playlist video ->
videoView playlist video
videoView model.zone playlist video
topBar : Element Core.Msg
@ -135,7 +140,7 @@ playlistView playlist =
Element.column [ Element.width Element.fill, Element.spacing 10 ]
[ image
, Element.paragraph
[ Font.bold, Font.color Colors.blackFont ]
[ Font.bold, Font.size Consts.titleFontSize ]
[ Element.text playlist.name ]
]
@ -148,14 +153,14 @@ playlistView playlist =
button
videoMiniaturesView : Twitch.Playlist -> Element Core.Msg
videoMiniaturesView playlist =
videoMiniaturesView : Time.Zone -> Twitch.Playlist -> Element Core.Msg
videoMiniaturesView zone playlist =
let
empty =
Element.el [ Element.width Element.fill ] Element.none
views =
List.map (videoMiniatureView playlist) playlist.videos
List.map (videoMiniatureView zone playlist) playlist.videos
grouped =
group 4 views
@ -171,20 +176,9 @@ videoMiniaturesView playlist =
final
videoMiniatureView : Twitch.Playlist -> Twitch.Video -> Element Core.Msg
videoMiniatureView playlist video =
videoMiniature : Twitch.Video -> Element Core.Msg
videoMiniature video =
let
image =
Element.image
[ Element.width Element.fill
, Element.height Element.fill
, Element.inFront inFront
]
{ description = "", src = Twitch.videoMiniatureUrl video }
label =
formatTime video.duration
inFront =
Element.text label
|> Element.el
@ -199,12 +193,27 @@ videoMiniatureView playlist video =
, Element.padding 5
]
image =
Element.image
[ Element.width Element.fill
, Element.height Element.fill
, Element.inFront inFront
]
{ description = "", src = Twitch.videoMiniatureUrl video }
label =
formatTime video.duration
in
image
videoMiniatureView : Time.Zone -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
videoMiniatureView zone playlist video =
let
display =
Element.column [ Element.width Element.fill, Element.spacing 10 ]
[ image
, Element.paragraph
[ Font.bold, Font.color Colors.blackFont ]
[ Element.text video.name ]
[ videoMiniature video
, videoDescription zone video
]
button =
@ -216,17 +225,72 @@ videoMiniatureView playlist video =
button
videoView : Twitch.Playlist -> Twitch.Video -> Element Core.Msg
videoView playlist video =
Element.row [ Element.padding 10, Element.width Element.fill, Element.spacing 20 ]
[ Element.image [ Element.width (Element.fillPortion 2) ]
{ description = "", src = Twitch.videoMiniatureUrl video }
, Element.column [ Element.alignTop, Element.width (Element.fillPortion 1) ]
[ Element.text "sup"
]
videoInList : Time.Zone -> Twitch.Video -> Element Core.Msg
videoInList zone video =
Element.row [ Element.width Element.fill, Element.spacing 10 ]
[ Element.el [ Element.width (Element.fillPortion 1) ]
(videoMiniature video)
, Element.el [ Element.width (Element.fillPortion 2), Element.paddingXY 0 10, Element.alignTop ]
(videoDescription zone video)
]
videoView : Time.Zone -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
videoView zone playlist video =
Element.row [ Element.padding 10, Element.width Element.fill, Element.spacing 20 ]
[ Element.column [ Element.spacing 10, Element.width (Element.fillPortion 2) ]
[ Element.image [ Element.width Element.fill ]
{ description = "", src = Twitch.videoMiniatureUrl video }
, Element.paragraph
[ Font.size Consts.homeFontSize
, Font.bold
]
[ Element.text video.name ]
, Element.paragraph
[ Font.size Consts.titleFontSize ]
[ Element.text ("Diffusé le " ++ formatDate zone video.date) ]
]
, Element.column [ Element.alignTop, Element.spacing 10, Element.width (Element.fillPortion 1) ]
(List.map (videoInList zone) playlist.videos)
]
videoDescription : Time.Zone -> Twitch.Video -> Element Core.Msg
videoDescription zone video =
Element.column [ Element.spacing 10 ]
[ Element.paragraph
[ Font.bold
, Font.size Consts.titleFontSize
]
[ Element.text video.name ]
, Element.paragraph
[ Font.color Colors.greyFont
]
[ Element.text ("Diffusé le " ++ formatDate zone video.date) ]
]
formatDate : Time.Zone -> Time.Posix -> String
formatDate zone time =
let
day =
Time.toDay zone time |> String.fromInt |> TimeUtils.pad2
month =
Time.toMonth zone time |> TimeUtils.monthToString
year =
Time.toYear zone time |> String.fromInt |> TimeUtils.pad2
hours =
Time.toHour zone time |> String.fromInt
minutes =
Time.toMinute zone time |> String.fromInt |> TimeUtils.pad2
in
day ++ "/" ++ month ++ "/" ++ year ++ " à " ++ hours ++ "h" ++ minutes
formatTime : Int -> String
formatTime time =
let