From df821e07afd6029d6b0b9d5f5114c10df37d5dc5 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Sat, 3 Apr 2021 23:33:01 +0200 Subject: [PATCH] Add support for dark mode --- index.html | 83 +++++++++++++++++++++++++++++++++++++------------- src/Colors.elm | 41 +++++++++++++++++++------ src/Core.elm | 34 +++++++++++++++++++-- src/Main.elm | 2 +- src/Ports.elm | 8 ++++- src/Views.elm | 72 +++++++++++++++++++++++++++++-------------- 6 files changed, 181 insertions(+), 59 deletions(-) diff --git a/index.html b/index.html index 1fd5cf3..ddf5113 100644 --- a/index.html +++ b/index.html @@ -13,40 +13,79 @@ diff --git a/src/Colors.elm b/src/Colors.elm index c782a72..1dd3f51 100644 --- a/src/Colors.elm +++ b/src/Colors.elm @@ -1,4 +1,4 @@ -module Colors exposing (blackFont, greyBackground, greyFont, primary, primaryOver, red, selected, white) +module Colors exposing (..) import Element @@ -28,16 +28,37 @@ greyBackground = Element.rgba255 0 0 0 0.7 -blackFont : Element.Color -blackFont = - Element.rgb255 54 54 54 +background : Bool -> Element.Color +background darkMode = + if darkMode then + Element.rgb255 47 49 54 + + else + Element.rgb255 245 245 245 -greyFont : Element.Color -greyFont = - Element.rgb255 128 128 128 +font : Bool -> Element.Color +font darkMode = + if darkMode then + Element.rgb255 245 245 245 + + else + Element.rgb255 54 57 63 -selected : Element.Color -selected = - Element.rgb255 223 233 250 +detailFont : Bool -> Element.Color +detailFont darkMode = + if darkMode then + Element.rgb255 160 160 160 + + else + Element.rgb255 128 128 128 + + +selected : Bool -> Element.Color +selected darkMode = + if darkMode then + Element.rgb255 64 68 75 + + else + Element.rgb255 223 233 250 diff --git a/src/Core.elm b/src/Core.elm index 31d5b6d..3c7b327 100644 --- a/src/Core.elm +++ b/src/Core.elm @@ -24,6 +24,8 @@ type alias Model = , time : Time.Posix , currentDate : Time.Posix , url : Url.Url + , darkMode : Bool + , darkSetting : Maybe Bool } @@ -49,10 +51,12 @@ type Msg | Unhover | TimeReceived Time.Posix | CurrentDateReceived Time.Posix + | DarkMode Bool + | DarkModeClicked -init : { width : Int, height : Int } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) -init { width, height } url key = +init : { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) +init { width, height, darkMode, darkSetting } url key = ( Model [] Time.utc @@ -62,6 +66,8 @@ init { width, height } url key = (Time.millisToPosix 0) (Time.millisToPosix 0) url + darkMode + darkSetting , Cmd.batch [ Task.attempt TimeZoneReceivedResult TimeZone.getZone , Task.perform CurrentDateReceived Time.now @@ -85,6 +91,7 @@ subscriptions _ = Sub.batch [ Events.onResize (\w h -> SizeReceived w h) , Time.every 200 TimeReceived + , Ports.darkMode DarkMode ] @@ -154,6 +161,13 @@ update msg model = , Nav.pushUrl model.key "#" ) + DarkModeClicked -> + let + next = + nextDarkSetting model.darkSetting + in + ( { model | darkSetting = next }, Ports.setDarkMode next ) + PlaylistClicked playlist -> ( model , Nav.pushUrl model.key ("#" ++ playlist.url) @@ -248,6 +262,9 @@ update msg model = Browser.External s -> ( model, Nav.load s ) + DarkMode dark -> + ( { model | darkMode = dark }, Cmd.none ) + splitter : String -> Maybe ( String, String ) splitter input = @@ -262,3 +279,16 @@ splitter input = parseQueryString : String -> Dict String String parseQueryString input = Dict.fromList (List.filterMap splitter (String.split "&" input)) + + +nextDarkSetting : Maybe Bool -> Maybe Bool +nextDarkSetting current = + case current of + Nothing -> + Just True + + Just True -> + Just False + + Just False -> + Nothing diff --git a/src/Main.elm b/src/Main.elm index 608b42b..63d968b 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -5,7 +5,7 @@ import Core import Views -main : Program { width : Int, height : Int } Core.Model Core.Msg +main : Program { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } Core.Model Core.Msg main = Browser.application { init = Core.init diff --git a/src/Ports.elm b/src/Ports.elm index 9756a7b..fa832aa 100644 --- a/src/Ports.elm +++ b/src/Ports.elm @@ -1,7 +1,13 @@ -port module Ports exposing (eraseVideo, registerVideo) +port module Ports exposing (darkMode, eraseVideo, registerVideo, setDarkMode) port registerVideo : ( String, String, Maybe String ) -> Cmd msg port eraseVideo : () -> Cmd msg + + +port setDarkMode : Maybe Bool -> Cmd msg + + +port darkMode : (Bool -> msg) -> Sub msg diff --git a/src/Views.elm b/src/Views.elm index e0fd704..192a94b 100644 --- a/src/Views.elm +++ b/src/Views.elm @@ -35,13 +35,14 @@ view model = { title = title model , body = [ Element.layout - [ Font.color Colors.blackFont + [ Font.color (Colors.font model.darkMode) + , Background.color (Colors.background model.darkMode) , Font.size Consts.normalFontSize , Font.family [ Font.typeface "Cantarell" ] ] (Element.column [ Element.width Element.fill, Element.height Element.fill ] - [ topBar, element ] + [ topBar model.darkSetting, element ] ) ] } @@ -67,21 +68,46 @@ viewContent model = playlistsView model.device model.playlists model.currentDate model.time hover Core.Playlist playlist hover -> - videoMiniaturesView model.device model.zone model.currentDate model.time hover playlist + videoMiniaturesView model.darkMode model.device model.zone model.currentDate model.time hover playlist Core.Video playlist video hover -> - videoView model.device model.zone model.currentDate model.time hover playlist video + videoView model.darkMode model.device model.zone model.currentDate model.time hover playlist video -topBar : Element Core.Msg -topBar = +topBar : Maybe Bool -> Element Core.Msg +topBar darkSetting = Element.row [ Element.width Element.fill , Background.color Colors.primary , Font.color Colors.white , Font.size Consts.homeFontSize ] - [ homeButton ] + [ homeButton, mode darkSetting ] + + +mode : Maybe Bool -> Element Core.Msg +mode current = + let + ( label, icon ) = + case current of + Nothing -> + ( "Par défaut", "🌓" ) + + Just True -> + ( "Mode nuit", "🌑" ) + + Just False -> + ( "Mode jour", "🌕" ) + in + Input.button + [ Element.height Element.fill, Element.alignRight, Element.padding 10 ] + { label = + Element.row [ Element.spacing 5 ] + [ Element.el [ Font.size Consts.titleFontSize ] (Element.text label) + , Element.el [ Font.size Consts.homeFontSize ] (Element.text icon) + ] + , onPress = Just Core.DarkModeClicked + } homeButton : Element Core.Msg @@ -203,14 +229,14 @@ playlistView currentDate time hover playlist = button -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 = +videoMiniaturesView : Bool -> Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Element Core.Msg +videoMiniaturesView darkMode device zone currentDate time hover playlist = let empty = Element.el [ Element.width Element.fill ] Element.none views = - List.map (videoMiniatureView zone currentDate time hover playlist) playlist.videos + List.map (videoMiniatureView darkMode zone currentDate time hover playlist) playlist.videos grouped = group (numberOfVideosPerRow device) views @@ -288,13 +314,13 @@ videoMiniature currentDate time hover playlist video = image -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 = +videoMiniatureView : Bool -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoMiniatureView darkMode zone currentDate time hover playlist video = let display = Element.column [ Element.width Element.fill, Element.spacing 10 ] [ videoMiniature currentDate time hover playlist video - , videoDescription zone video + , videoDescription darkMode zone video ] button = @@ -306,21 +332,21 @@ videoMiniatureView zone currentDate time hover playlist video = button -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 = +videoInList : Bool -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Twitch.Video -> Element Core.Msg +videoInList darkMode 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 currentDate time hover playlist video) , Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ] - (videoDescription zone video) + (videoDescription darkMode zone video) ] in if video == activeVideo then Element.el [ Element.width Element.fill - , Background.color Colors.selected + , Background.color (Colors.selected darkMode) , Border.color Colors.primary , Border.width 2 ] @@ -333,8 +359,8 @@ videoInList zone currentDate time hover playlist activeVideo 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 = +videoView : Bool -> Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg +videoView darkMode device zone currentDate time hover playlist video = let ( builder, contentPadding ) = case device.class of @@ -401,12 +427,12 @@ videoView device zone currentDate time hover playlist video = , Element.height Element.fill , Element.scrollbarY ] - (List.map (videoInList zone currentDate time hover playlist video) playlist.videos) + (List.map (videoInList darkMode zone currentDate time hover playlist video) playlist.videos) ] -videoDescription : Time.Zone -> Twitch.Video -> Element Core.Msg -videoDescription zone video = +videoDescription : Bool -> Time.Zone -> Twitch.Video -> Element Core.Msg +videoDescription darkMode zone video = Element.column [ Element.spacing 10 ] [ Element.paragraph [ Font.bold @@ -416,7 +442,7 @@ videoDescription zone video = , case video.date of Just date -> Element.paragraph - [ Font.color Colors.greyFont + [ Font.color (Colors.detailFont darkMode) ] [ Element.text ("Diffusé le " ++ formatDate zone date) ]