From 0215d94be9c7cd1d7c45be39cdea1103b90b244b Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Sun, 4 Oct 2020 14:24:16 +0200 Subject: [PATCH] Video --- .gitignore | 1 + src/Core.elm | 23 +++++++- src/Twitch.elm | 20 ++++++- src/Views.elm | 156 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 177 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 41db249..5053d72 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ elm-stuff js/main.js js/main.tmp.js js/main.min.js +deploy.sh diff --git a/src/Core.elm b/src/Core.elm index 0f30d23..75b4802 100644 --- a/src/Core.elm +++ b/src/Core.elm @@ -20,11 +20,16 @@ type alias Model = type Page = Home + | Playlist Twitch.Playlist + | Video Twitch.Playlist Twitch.Video type Msg = Noop | PlaylistsReceived (List Twitch.Playlist) + | HomeClicked + | PlaylistClicked Twitch.Playlist + | VideoClicked Twitch.Playlist Twitch.Video init : Decode.Value -> Url.Url -> Browser.Navigation.Key -> ( FullModel, Cmd Msg ) @@ -36,9 +41,21 @@ init _ _ _ = update : Msg -> FullModel -> ( FullModel, Cmd Msg ) update msg model = - case msg of - Noop -> + case ( msg, model ) of + ( Noop, _ ) -> ( model, Cmd.none ) - PlaylistsReceived playlists -> + ( PlaylistsReceived playlists, _ ) -> ( Loaded { playlists = playlists, page = Home }, Cmd.none ) + + ( HomeClicked, Loaded { playlists } ) -> + ( Loaded { playlists = playlists, page = Home }, Cmd.none ) + + ( PlaylistClicked playlist, Loaded { playlists } ) -> + ( Loaded { playlists = playlists, page = Playlist playlist }, Cmd.none ) + + ( VideoClicked playlist video, Loaded { playlists } ) -> + ( Loaded { playlists = playlists, page = Video playlist video }, Cmd.none ) + + _ -> + ( model, Cmd.none ) diff --git a/src/Twitch.elm b/src/Twitch.elm index 219bb09..180547e 100644 --- a/src/Twitch.elm +++ b/src/Twitch.elm @@ -3,6 +3,7 @@ module Twitch exposing , Video , fetchPlaylists , playlistMiniatureUrl + , videoMiniatureUrl ) import Html.Parser @@ -47,9 +48,24 @@ playlistMiniatureUrl playlist = "" +videoMiniatureUrl : Video -> String +videoMiniatureUrl video = + video.url ++ "miniature-050.png" + + +sortPlaylist : Playlist -> Playlist +sortPlaylist playlist = + { playlist | videos = List.sortBy .url playlist.videos |> List.reverse } + + +sortPlaylists : List Playlist -> List Playlist +sortPlaylists playlists = + List.sortBy .url (List.map sortPlaylist playlists) |> List.reverse + + fetchPlaylists : Task x (List Playlist) fetchPlaylists = - fetchPlaylistPath |> Task.andThen fetchPlaylistsMapper + fetchPlaylistPath |> Task.andThen fetchPlaylistsMapper |> Task.map sortPlaylists fetchPlaylistPath : Task x (List String) @@ -174,7 +190,7 @@ findHrefsAux acc node = Html.Parser.Element string (( key, value ) :: t) nodes -> let newAcc = - if key == "href" then + if key == "href" && String.endsWith "/" value && value /= "../" then value :: acc else diff --git a/src/Views.elm b/src/Views.elm index bfce5a8..443b8ec 100644 --- a/src/Views.elm +++ b/src/Views.elm @@ -39,6 +39,12 @@ mainView model = Core.Home -> playlistsView model.playlists + Core.Playlist playlist -> + videoMiniaturesView playlist + + Core.Video playlist video -> + videoView playlist video + topBar : Element Core.Msg topBar = @@ -60,7 +66,7 @@ homeButton = , Font.bold ] { label = Element.text Consts.name - , onPress = Nothing + , onPress = Just Core.HomeClicked } @@ -91,7 +97,11 @@ playlistView : Twitch.Playlist -> Element Core.Msg playlistView playlist = let image = - Element.image [ Element.width Element.fill, Element.height Element.fill, Element.inFront inFront ] + Element.image + [ Element.width Element.fill + , Element.height Element.fill + , Element.inFront inFront + ] { description = "", src = Twitch.playlistMiniatureUrl playlist } length = @@ -108,39 +118,149 @@ playlistView playlist = ) 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 ] + Element.text label + |> Element.el + [ Background.color Colors.greyBackground + , Border.rounded 5 + , Element.padding 5 + , Font.color Colors.white + ] + |> 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 ] + , 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 + , onPress = Just (Core.PlaylistClicked playlist) } in button +videoMiniaturesView : Twitch.Playlist -> Element Core.Msg +videoMiniaturesView playlist = + let + empty = + Element.el [ Element.width Element.fill ] Element.none + + views = + List.map (videoMiniatureView playlist) playlist.videos + + 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 + + +videoMiniatureView : Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoMiniatureView playlist 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 + [ Background.color Colors.greyBackground + , Border.rounded 5 + , Element.padding 5 + , Font.color Colors.white + ] + |> 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 video.name ] + ] + + button = + Input.button [ Element.width Element.fill, Element.alignTop ] + { label = display + , onPress = Just (Core.VideoClicked playlist video) + } + in + 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" + ] + ] + + formatTime : Int -> String formatTime time = - String.fromInt (toHours time) + let + hours = + toHours time + + minutes = + toMinutes time + + seconds = + toSeconds time + + hoursString = + String.fromInt hours + + minutesString = + if minutes < 10 then + "0" ++ String.fromInt minutes + + else + String.fromInt minutes + + secondsString = + if seconds < 10 then + "0" ++ String.fromInt seconds + + else + String.fromInt seconds + in + hoursString ++ ":" - ++ String.fromInt (toMinutes time) + ++ minutesString ++ ":" - ++ String.fromInt (toSeconds time) + ++ secondsString toHours : Int -> Int @@ -184,7 +304,7 @@ group size list = groupAux : Int -> List a -> List (List a) -> List (List a) groupAux size list acc = if List.isEmpty list then - acc + List.reverse acc else let