Change miniatures when hover
This commit is contained in:
parent
bf1d35c179
commit
948df5da9a
68
src/Core.elm
68
src/Core.elm
|
@ -5,6 +5,7 @@ import Browser.Events as Events
|
|||
import Browser.Navigation as Nav
|
||||
import Dict exposing (Dict)
|
||||
import Element
|
||||
import Hover exposing (Hover)
|
||||
import Http
|
||||
import Ports
|
||||
import Task
|
||||
|
@ -24,13 +25,14 @@ type alias Model =
|
|||
, page : Page
|
||||
, key : Nav.Key
|
||||
, device : Element.Device
|
||||
, time : Time.Posix
|
||||
}
|
||||
|
||||
|
||||
type Page
|
||||
= Home
|
||||
| Playlist Twitch.Playlist
|
||||
| Video Twitch.Playlist Twitch.Video
|
||||
= Home (Maybe (Hover Twitch.Playlist))
|
||||
| Playlist Twitch.Playlist (Maybe (Hover Twitch.Video))
|
||||
| Video Twitch.Playlist Twitch.Video (Maybe (Hover Twitch.Video))
|
||||
|
||||
|
||||
type Msg
|
||||
|
@ -43,6 +45,10 @@ type Msg
|
|||
| UrlRequested Browser.UrlRequest
|
||||
| SizeReceived Int Int
|
||||
| TimeZoneReceived Time.Zone
|
||||
| HoverPlaylist Twitch.Playlist
|
||||
| HoverVideo Twitch.Video
|
||||
| Unhover
|
||||
| TimeReceived Time.Posix
|
||||
|
||||
|
||||
init : { width : Int, height : Int } -> Url.Url -> Nav.Key -> ( FullModel, Cmd Msg )
|
||||
|
@ -67,7 +73,10 @@ resultToMsg result =
|
|||
|
||||
subscriptions : FullModel -> Sub Msg
|
||||
subscriptions _ =
|
||||
Events.onResize (\w h -> SizeReceived w h)
|
||||
Sub.batch
|
||||
[ Events.onResize (\w h -> SizeReceived w h)
|
||||
, Time.every 200 TimeReceived
|
||||
]
|
||||
|
||||
|
||||
update : Msg -> FullModel -> ( FullModel, Cmd Msg )
|
||||
|
@ -79,6 +88,39 @@ update msg model =
|
|||
( TimeZoneReceived z, Unloaded d u k _ ) ->
|
||||
( Unloaded d u k z, Cmd.none )
|
||||
|
||||
( TimeReceived p, Loaded m ) ->
|
||||
( Loaded { m | time = p }, Cmd.none )
|
||||
|
||||
( HoverPlaylist hover, Loaded m ) ->
|
||||
case m.page of
|
||||
Home Nothing ->
|
||||
( Loaded { m | page = Home (Just (Hover.hover hover m.time)) }, Cmd.none )
|
||||
|
||||
_ ->
|
||||
( Loaded m, Cmd.none )
|
||||
|
||||
( HoverVideo hover, Loaded m ) ->
|
||||
case m.page of
|
||||
Playlist p Nothing ->
|
||||
( Loaded { m | page = Playlist p (Just (Hover.hover hover m.time)) }, Cmd.none )
|
||||
|
||||
Video p v Nothing ->
|
||||
( Loaded { m | page = Video p v (Just (Hover.hover v m.time)) }, Cmd.none )
|
||||
|
||||
_ ->
|
||||
( Loaded m, Cmd.none )
|
||||
|
||||
( Unhover, Loaded m ) ->
|
||||
case m.page of
|
||||
Home _ ->
|
||||
( Loaded { m | page = Home Nothing }, Cmd.none )
|
||||
|
||||
Playlist p _ ->
|
||||
( Loaded { m | page = Playlist p Nothing }, Cmd.none )
|
||||
|
||||
Video p v _ ->
|
||||
( Loaded { m | page = Video p v Nothing }, Cmd.none )
|
||||
|
||||
( TimeZoneReceived z, Loaded m ) ->
|
||||
( Loaded { m | zone = z }, Cmd.none )
|
||||
|
||||
|
@ -90,7 +132,15 @@ update msg model =
|
|||
( PlaylistsReceived playlists, Unloaded device url key zone ) ->
|
||||
update
|
||||
(UrlReceived url)
|
||||
(Loaded { key = key, playlists = playlists, zone = zone, page = Home, device = device })
|
||||
(Loaded
|
||||
{ key = key
|
||||
, playlists = playlists
|
||||
, zone = zone
|
||||
, page = Home Nothing
|
||||
, device = device
|
||||
, time = Time.millisToPosix 0
|
||||
}
|
||||
)
|
||||
|
||||
( HomeClicked, Loaded m ) ->
|
||||
( model
|
||||
|
@ -159,19 +209,19 @@ update msg model =
|
|||
( page, cmd ) =
|
||||
case ( playlist, video ) of
|
||||
( Just p, Just v ) ->
|
||||
( Video p v
|
||||
( Video p v Nothing
|
||||
, Ports.registerVideo ( Twitch.videoId v, "videos/" ++ p.url ++ v.url, time )
|
||||
)
|
||||
|
||||
( Just p, Nothing ) ->
|
||||
( Playlist p, Cmd.none )
|
||||
( Playlist p Nothing, Cmd.none )
|
||||
|
||||
_ ->
|
||||
( Home, Cmd.none )
|
||||
( Home Nothing, Cmd.none )
|
||||
|
||||
extraCmd =
|
||||
case page of
|
||||
Video _ _ ->
|
||||
Video _ _ _ ->
|
||||
Cmd.none
|
||||
|
||||
_ ->
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module Hover exposing (..)
|
||||
|
||||
import Time
|
||||
|
||||
|
||||
type alias Hover a =
|
||||
{ element : a
|
||||
, time : Time.Posix
|
||||
}
|
||||
|
||||
|
||||
hover : a -> Time.Posix -> Hover a
|
||||
hover element time =
|
||||
{ element = element, time = time }
|
|
@ -9,6 +9,7 @@ module Twitch exposing
|
|||
, videoName
|
||||
)
|
||||
|
||||
import Hover exposing (Hover)
|
||||
import Http
|
||||
import Iso8601
|
||||
import Json.Decode as Decode
|
||||
|
@ -70,9 +71,22 @@ videoId video =
|
|||
String.dropLeft 1 video.url |> String.replace "/" "-"
|
||||
|
||||
|
||||
playlistMiniatureUrl : Playlist -> String
|
||||
playlistMiniatureUrl playlist =
|
||||
case List.head playlist.videos of
|
||||
playlistMiniatureUrl : Time.Posix -> Maybe (Hover Playlist) -> Playlist -> String
|
||||
playlistMiniatureUrl currentTime hover playlist =
|
||||
let
|
||||
skip =
|
||||
case hover of
|
||||
Nothing ->
|
||||
0
|
||||
|
||||
Just { element, time } ->
|
||||
if element == playlist then
|
||||
modBy (List.length playlist.videos) ((Time.posixToMillis currentTime - Time.posixToMillis time) // 1000)
|
||||
|
||||
else
|
||||
0
|
||||
in
|
||||
case List.head (List.drop skip playlist.videos) of
|
||||
Just v ->
|
||||
"videos/" ++ playlist.url ++ v.url ++ "miniature-050.png"
|
||||
|
||||
|
@ -80,6 +94,30 @@ playlistMiniatureUrl playlist =
|
|||
""
|
||||
|
||||
|
||||
videoMiniatureUrl : Playlist -> Video -> String
|
||||
videoMiniatureUrl playlist video =
|
||||
"videos/" ++ playlist.url ++ video.url ++ "miniature-050.png"
|
||||
videoMiniatureUrl : Time.Posix -> Maybe (Hover Video) -> Playlist -> Video -> String
|
||||
videoMiniatureUrl currentTime hover playlist video =
|
||||
let
|
||||
index =
|
||||
case hover of
|
||||
Nothing ->
|
||||
5
|
||||
|
||||
Just { element, time } ->
|
||||
if element == video then
|
||||
modBy 11 ((Time.posixToMillis currentTime - Time.posixToMillis time) // 1000)
|
||||
|
||||
else
|
||||
5
|
||||
|
||||
indexString =
|
||||
case index of
|
||||
10 ->
|
||||
"100"
|
||||
|
||||
0 ->
|
||||
"000"
|
||||
|
||||
n ->
|
||||
"0" ++ String.fromInt n ++ "0"
|
||||
in
|
||||
"videos/" ++ playlist.url ++ video.url ++ "miniature-" ++ indexString ++ ".png"
|
||||
|
|
|
@ -7,9 +7,11 @@ import Core
|
|||
import Element exposing (Element)
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
import Element.Events as Events
|
||||
import Element.Font as Font
|
||||
import Element.Input as Input
|
||||
import Element.Keyed as Keyed
|
||||
import Hover exposing (Hover)
|
||||
import Html
|
||||
import Html.Attributes
|
||||
import Json.Encode as Encode
|
||||
|
@ -53,27 +55,27 @@ title model =
|
|||
|
||||
Core.Loaded m ->
|
||||
case m.page of
|
||||
Core.Home ->
|
||||
Core.Home _ ->
|
||||
Consts.url
|
||||
|
||||
Core.Playlist p ->
|
||||
Core.Playlist p _ ->
|
||||
Consts.url ++ " - " ++ p.name
|
||||
|
||||
Core.Video p v ->
|
||||
Core.Video p v _ ->
|
||||
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
|
||||
|
||||
|
||||
viewContent : Core.Model -> Element Core.Msg
|
||||
viewContent model =
|
||||
case model.page of
|
||||
Core.Home ->
|
||||
playlistsView model.device model.playlists
|
||||
Core.Home hover ->
|
||||
playlistsView model.device model.playlists model.time hover
|
||||
|
||||
Core.Playlist playlist ->
|
||||
videoMiniaturesView model.device model.zone playlist
|
||||
Core.Playlist playlist hover ->
|
||||
videoMiniaturesView model.device model.zone model.time hover playlist
|
||||
|
||||
Core.Video playlist video ->
|
||||
videoView model.device model.zone playlist video
|
||||
Core.Video playlist video hover ->
|
||||
videoView model.device model.zone model.time hover playlist video
|
||||
|
||||
|
||||
topBar : Element Core.Msg
|
||||
|
@ -99,14 +101,14 @@ homeButton =
|
|||
}
|
||||
|
||||
|
||||
playlistsView : Element.Device -> List Twitch.Playlist -> Element Core.Msg
|
||||
playlistsView device playlists =
|
||||
playlistsView : Element.Device -> List Twitch.Playlist -> Time.Posix -> Maybe (Hover Twitch.Playlist) -> Element Core.Msg
|
||||
playlistsView device playlists time hover =
|
||||
let
|
||||
empty =
|
||||
Element.el [ Element.width Element.fill ] Element.none
|
||||
|
||||
views =
|
||||
List.map playlistView playlists
|
||||
List.map (playlistView time hover) playlists
|
||||
|
||||
grouped =
|
||||
group (numberOfVideosPerRow device) views
|
||||
|
@ -122,15 +124,23 @@ playlistsView device playlists =
|
|||
final
|
||||
|
||||
|
||||
playlistView : Twitch.Playlist -> Element Core.Msg
|
||||
playlistView playlist =
|
||||
playlistView : Time.Posix -> Maybe (Hover Twitch.Playlist) -> Twitch.Playlist -> Element Core.Msg
|
||||
playlistView time hover playlist =
|
||||
let
|
||||
key =
|
||||
Twitch.playlistMiniatureUrl time Nothing playlist
|
||||
|
||||
src =
|
||||
Twitch.playlistMiniatureUrl playlist
|
||||
Twitch.playlistMiniatureUrl time hover playlist
|
||||
|
||||
image =
|
||||
Keyed.el [ Element.width Element.fill, Element.height Element.fill ]
|
||||
( src
|
||||
Keyed.el
|
||||
[ Element.width Element.fill
|
||||
, Element.height Element.fill
|
||||
, Events.onMouseEnter (Core.HoverPlaylist playlist)
|
||||
, Events.onMouseLeave Core.Unhover
|
||||
]
|
||||
( key
|
||||
, Element.image
|
||||
[ Element.width Element.fill
|
||||
, Element.height Element.fill
|
||||
|
@ -187,14 +197,14 @@ playlistView playlist =
|
|||
button
|
||||
|
||||
|
||||
videoMiniaturesView : Element.Device -> Time.Zone -> Twitch.Playlist -> Element Core.Msg
|
||||
videoMiniaturesView device zone playlist =
|
||||
videoMiniaturesView : Element.Device -> Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Element Core.Msg
|
||||
videoMiniaturesView device zone time hover playlist =
|
||||
let
|
||||
empty =
|
||||
Element.el [ Element.width Element.fill ] Element.none
|
||||
|
||||
views =
|
||||
List.map (videoMiniatureView zone playlist) playlist.videos
|
||||
List.map (videoMiniatureView zone time hover playlist) playlist.videos
|
||||
|
||||
grouped =
|
||||
group (numberOfVideosPerRow device) views
|
||||
|
@ -210,8 +220,8 @@ videoMiniaturesView device zone playlist =
|
|||
final
|
||||
|
||||
|
||||
videoMiniature : Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoMiniature playlist video =
|
||||
videoMiniature : Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoMiniature time hover playlist video =
|
||||
let
|
||||
inFront =
|
||||
Element.text label
|
||||
|
@ -227,12 +237,20 @@ videoMiniature playlist video =
|
|||
, Element.padding 5
|
||||
]
|
||||
|
||||
key =
|
||||
Twitch.videoMiniatureUrl time Nothing playlist video
|
||||
|
||||
src =
|
||||
Twitch.videoMiniatureUrl playlist video
|
||||
Twitch.videoMiniatureUrl time hover playlist video
|
||||
|
||||
image =
|
||||
Keyed.el [ Element.width Element.fill, Element.height Element.fill ]
|
||||
( src
|
||||
Keyed.el
|
||||
[ Element.width Element.fill
|
||||
, Element.height Element.fill
|
||||
, Events.onMouseEnter (Core.HoverVideo video)
|
||||
, Events.onMouseLeave Core.Unhover
|
||||
]
|
||||
( key
|
||||
, Element.image
|
||||
[ Element.width Element.fill
|
||||
, Element.height Element.fill
|
||||
|
@ -247,12 +265,12 @@ videoMiniature playlist video =
|
|||
image
|
||||
|
||||
|
||||
videoMiniatureView : Time.Zone -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoMiniatureView zone playlist video =
|
||||
videoMiniatureView : Time.Zone -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoMiniatureView zone time hover playlist video =
|
||||
let
|
||||
display =
|
||||
Element.column [ Element.width Element.fill, Element.spacing 10 ]
|
||||
[ videoMiniature playlist video
|
||||
[ videoMiniature time hover playlist video
|
||||
, videoDescription zone video
|
||||
]
|
||||
|
||||
|
@ -265,13 +283,13 @@ videoMiniatureView zone playlist video =
|
|||
button
|
||||
|
||||
|
||||
videoInList : Time.Zone -> Twitch.Playlist -> Twitch.Video -> Twitch.Video -> Element Core.Msg
|
||||
videoInList zone playlist activeVideo video =
|
||||
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 =
|
||||
let
|
||||
label =
|
||||
Element.row [ Element.width Element.fill, Element.spacing 10 ]
|
||||
[ Element.el [ Element.width (Element.fillPortion 2) ]
|
||||
(videoMiniature playlist video)
|
||||
(videoMiniature time hover playlist video)
|
||||
, Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ]
|
||||
(videoDescription zone video)
|
||||
]
|
||||
|
@ -292,8 +310,8 @@ videoInList zone playlist activeVideo video =
|
|||
}
|
||||
|
||||
|
||||
videoView : Element.Device -> Time.Zone -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoView device zone playlist 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 =
|
||||
let
|
||||
( builder, contentPadding ) =
|
||||
case device.class of
|
||||
|
@ -360,7 +378,7 @@ videoView device zone playlist video =
|
|||
, Element.height Element.fill
|
||||
, Element.scrollbarY
|
||||
]
|
||||
(List.map (videoInList zone playlist video) playlist.videos)
|
||||
(List.map (videoInList zone time hover playlist video) playlist.videos)
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue