diff --git a/src/Colors.elm b/src/Colors.elm index f7a7ed5..c782a72 100644 --- a/src/Colors.elm +++ b/src/Colors.elm @@ -1,4 +1,4 @@ -module Colors exposing (blackFont, greyBackground, greyFont, primary, primaryOver, selected, white) +module Colors exposing (blackFont, greyBackground, greyFont, primary, primaryOver, red, selected, white) import Element @@ -18,6 +18,11 @@ white = Element.rgb255 255 255 255 +red : Element.Color +red = + Element.rgb255 255 0 0 + + greyBackground : Element.Color greyBackground = Element.rgba255 0 0 0 0.7 diff --git a/src/Core.elm b/src/Core.elm index 2dd62e7..31d5b6d 100644 --- a/src/Core.elm +++ b/src/Core.elm @@ -22,6 +22,7 @@ type alias Model = , key : Nav.Key , device : Element.Device , time : Time.Posix + , currentDate : Time.Posix , url : Url.Url } @@ -47,13 +48,23 @@ type Msg | HoverVideo Twitch.Video | Unhover | TimeReceived Time.Posix + | CurrentDateReceived Time.Posix init : { width : Int, height : Int } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) init { width, height } url key = - ( Model [] Time.utc (Home Nothing) key (Element.classifyDevice { width = width, height = height }) (Time.millisToPosix 0) url + ( Model + [] + Time.utc + (Home Nothing) + key + (Element.classifyDevice { width = width, height = height }) + (Time.millisToPosix 0) + (Time.millisToPosix 0) + url , Cmd.batch [ Task.attempt TimeZoneReceivedResult TimeZone.getZone + , Task.perform CurrentDateReceived Time.now , Twitch.fetchPlaylists resultToMsg ] ) @@ -79,80 +90,83 @@ subscriptions _ = update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = - case ( msg, model ) of - ( Noop, _ ) -> + case msg of + Noop -> ( model, Cmd.none ) - ( TimeZoneReceived z, m ) -> - ( { m | zone = z }, Cmd.none ) + TimeZoneReceived z -> + ( { model | zone = z }, Cmd.none ) - ( TimeZoneReceivedResult (Ok ( _, zone )), m ) -> - ( { m | zone = zone }, Cmd.none ) + TimeZoneReceivedResult (Ok ( _, zone )) -> + ( { model | zone = zone }, Cmd.none ) - ( TimeZoneReceivedResult (Err _), _ ) -> + TimeZoneReceivedResult (Err _) -> ( model, Task.perform TimeZoneReceived Time.here ) - ( TimeReceived p, m ) -> - ( { m | time = p }, Cmd.none ) + TimeReceived p -> + ( { model | time = p }, Cmd.none ) - ( HoverPlaylist hover, m ) -> - case m.page of + CurrentDateReceived d -> + ( { model | currentDate = d }, Cmd.none ) + + HoverPlaylist hover -> + case model.page of Home Nothing -> - ( { m | page = Home (Just (Hover.hover hover m.time)) }, Cmd.none ) + ( { model | page = Home (Just (Hover.hover hover model.time)) }, Cmd.none ) _ -> - ( m, Cmd.none ) + ( model, Cmd.none ) - ( HoverVideo hover, m ) -> - case m.page of + HoverVideo hover -> + case model.page of Playlist p Nothing -> - ( { m | page = Playlist p (Just (Hover.hover hover m.time)) }, Cmd.none ) + ( { model | page = Playlist p (Just (Hover.hover hover model.time)) }, Cmd.none ) Video p v Nothing -> - ( { m | page = Video p v (Just (Hover.hover v m.time)) }, Cmd.none ) + ( { model | page = Video p v (Just (Hover.hover v model.time)) }, Cmd.none ) _ -> - ( m, Cmd.none ) + ( model, Cmd.none ) - ( Unhover, m ) -> - case m.page of + Unhover -> + case model.page of Home _ -> - ( { m | page = Home Nothing }, Cmd.none ) + ( { model | page = Home Nothing }, Cmd.none ) Playlist p _ -> - ( { m | page = Playlist p Nothing }, Cmd.none ) + ( { model | page = Playlist p Nothing }, Cmd.none ) Video p v _ -> - ( { m | page = Video p v Nothing }, Cmd.none ) + ( { model | page = Video p v Nothing }, Cmd.none ) - ( SizeReceived w h, m ) -> - ( { m | device = Element.classifyDevice { width = w, height = h } } + SizeReceived w h -> + ( { model | device = Element.classifyDevice { width = w, height = h } } , Cmd.none ) - ( PlaylistsReceived playlists, m ) -> + PlaylistsReceived playlists -> update - (UrlReceived m.url) - { m | playlists = playlists, page = Home Nothing } + (UrlReceived model.url) + { model | playlists = playlists, page = Home Nothing } - ( HomeClicked, m ) -> + HomeClicked -> ( model - , Nav.pushUrl m.key "#" + , Nav.pushUrl model.key "#" ) - ( PlaylistClicked playlist, m ) -> + PlaylistClicked playlist -> ( model - , Nav.pushUrl m.key ("#" ++ playlist.url) + , Nav.pushUrl model.key ("#" ++ playlist.url) ) - ( VideoClicked playlist video, m ) -> + VideoClicked playlist video -> ( model - , Nav.pushUrl m.key ("#" ++ playlist.url ++ video.url) + , Nav.pushUrl model.key ("#" ++ playlist.url ++ video.url) ) - ( UrlReceived url, m ) -> - if List.isEmpty m.playlists then - ( { m | url = url }, Cmd.none ) + UrlReceived url -> + if List.isEmpty model.playlists then + ( { model | url = url }, Cmd.none ) else let @@ -193,7 +207,7 @@ update msg model = ( Nothing, Nothing ) playlist = - List.head (List.filter (\x -> Just x.url == playlistName) m.playlists) + List.head (List.filter (\x -> Just x.url == playlistName) model.playlists) video = case playlist of @@ -224,12 +238,12 @@ update msg model = _ -> Ports.eraseVideo () in - ( { m | page = page }, Cmd.batch [ cmd, extraCmd ] ) + ( { model | page = page }, Cmd.batch [ cmd, extraCmd ] ) - ( UrlRequested u, m ) -> + UrlRequested u -> case u of Browser.Internal url -> - ( model, Nav.pushUrl m.key (Url.toString url) ) + ( model, Nav.pushUrl model.key (Url.toString url) ) Browser.External s -> ( model, Nav.load s ) diff --git a/src/Twitch.elm b/src/Twitch.elm index e388c19..64bc63b 100644 --- a/src/Twitch.elm +++ b/src/Twitch.elm @@ -3,6 +3,7 @@ module Twitch exposing , Video , decodePlaylists , fetchPlaylists + , playlistDate , playlistMiniatureUrl , videoId , videoMiniatureUrl diff --git a/src/Views.elm b/src/Views.elm index c059d07..cc8d1d0 100644 --- a/src/Views.elm +++ b/src/Views.elm @@ -64,13 +64,13 @@ viewContent : Core.Model -> Element Core.Msg viewContent model = case model.page of Core.Home hover -> - playlistsView model.device model.playlists model.time hover + playlistsView model.device model.playlists model.currentDate model.time hover Core.Playlist playlist hover -> - videoMiniaturesView model.device model.zone model.time hover playlist + videoMiniaturesView model.device model.zone model.currentDate model.time hover playlist Core.Video playlist video hover -> - videoView model.device model.zone model.time hover playlist video + videoView model.device model.zone model.currentDate model.time hover playlist video topBar : Element Core.Msg @@ -95,14 +95,14 @@ homeButton = } -playlistsView : Element.Device -> List Twitch.Playlist -> Time.Posix -> Maybe (Hover Twitch.Playlist) -> Element Core.Msg -playlistsView device playlists time hover = +playlistsView : Element.Device -> List Twitch.Playlist -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Playlist) -> Element Core.Msg +playlistsView device playlists currentDate time hover = let empty = Element.el [ Element.width Element.fill ] Element.none views = - List.map (playlistView time hover) playlists + List.map (playlistView currentDate time hover) playlists grouped = group (numberOfVideosPerRow device) views @@ -118,8 +118,8 @@ playlistsView device playlists time hover = final -playlistView : Time.Posix -> Maybe (Hover Twitch.Playlist) -> Twitch.Playlist -> Element Core.Msg -playlistView time hover playlist = +playlistView : Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Playlist) -> Twitch.Playlist -> Element Core.Msg +playlistView currentDate time hover playlist = let key = Twitch.playlistMiniatureUrl time Nothing playlist @@ -139,6 +139,7 @@ playlistView time hover playlist = [ Element.width Element.fill , Element.height Element.fill , Element.inFront inFront + , Element.inFront new ] { description = "", src = src } ) @@ -170,6 +171,13 @@ playlistView time hover playlist = , Element.padding 5 ] + new = + if Time.posixToMillis currentDate - Twitch.playlistDate playlist > week then + Element.none + + else + newBadge + display = Element.column [ Element.width Element.fill, Element.spacing 10 ] [ image @@ -191,14 +199,14 @@ playlistView time hover playlist = button -videoMiniaturesView : Element.Device -> Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Element Core.Msg -videoMiniaturesView device zone time hover playlist = +videoMiniaturesView : Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Element Core.Msg +videoMiniaturesView device zone currentDate time hover playlist = let empty = Element.el [ Element.width Element.fill ] Element.none views = - List.map (videoMiniatureView zone time hover playlist) playlist.videos + List.map (videoMiniatureView zone currentDate time hover playlist) playlist.videos grouped = group (numberOfVideosPerRow device) views @@ -214,8 +222,8 @@ videoMiniaturesView device zone time hover playlist = final -videoMiniature : Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg -videoMiniature time hover playlist video = +videoMiniature : Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoMiniature currentDate time hover playlist video = let inFront = Element.text label @@ -231,6 +239,18 @@ videoMiniature time hover playlist video = , Element.padding 5 ] + date = + video.date + |> Maybe.map Time.posixToMillis + |> Maybe.withDefault 0 + + new = + if Time.posixToMillis currentDate - date > week then + Element.none + + else + newBadge + key = Twitch.videoMiniatureUrl time Nothing playlist video @@ -249,6 +269,7 @@ videoMiniature time hover playlist video = [ Element.width Element.fill , Element.height Element.fill , Element.inFront inFront + , Element.inFront new ] { description = "", src = src } ) @@ -259,12 +280,12 @@ videoMiniature time hover playlist video = image -videoMiniatureView : Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg -videoMiniatureView zone time hover playlist video = +videoMiniatureView : Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoMiniatureView zone currentDate time hover playlist video = let display = Element.column [ Element.width Element.fill, Element.spacing 10 ] - [ videoMiniature time hover playlist video + [ videoMiniature currentDate time hover playlist video , videoDescription zone video ] @@ -277,13 +298,13 @@ videoMiniatureView zone time hover playlist video = button -videoInList : Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Twitch.Video -> Element Core.Msg -videoInList zone time hover playlist activeVideo video = +videoInList : Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Twitch.Video -> Element Core.Msg +videoInList zone currentDate time hover playlist activeVideo video = let label = Element.row [ Element.width Element.fill, Element.spacing 10 ] [ Element.el [ Element.width (Element.fillPortion 2) ] - (videoMiniature time hover playlist video) + (videoMiniature currentDate time hover playlist video) , Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ] (videoDescription zone video) ] @@ -304,8 +325,8 @@ videoInList zone time hover playlist activeVideo video = } -videoView : Element.Device -> Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg -videoView device zone time hover playlist video = +videoView : Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoView device zone currentDate time hover playlist video = let ( builder, contentPadding ) = case device.class of @@ -372,7 +393,7 @@ videoView device zone time hover playlist video = , Element.height Element.fill , Element.scrollbarY ] - (List.map (videoInList zone time hover playlist video) playlist.videos) + (List.map (videoInList zone currentDate time hover playlist video) playlist.videos) ] @@ -538,3 +559,25 @@ spinner = , Html.div [] [] ] ) + + +newBadge : Element Core.Msg +newBadge = + Element.text "NOUV." + |> Element.el + [ Background.color Colors.red + , Border.rounded 5 + , Element.padding 5 + , Font.color Colors.white + , Font.bold + ] + |> Element.el + [ Element.alignBottom + , Element.alignLeft + , Element.padding 5 + ] + + +week : Int +week = + 1000 * 60 * 60 * 24 * 7