Browsing the pages work
This commit is contained in:
parent
0215d94be9
commit
5872e50493
3
elm.json
3
elm.json
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
20
src/Core.elm
20
src/Core.elm
|
@ -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 )
|
||||
|
|
|
@ -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"
|
|
@ -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)
|
||||
|
|
128
src/Views.elm
128
src/Views.elm
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue