This commit is contained in:
Thomas Forgione 2020-11-06 11:43:28 +01:00
parent 5b902ec915
commit cace6f09f8
3 changed files with 103 additions and 125 deletions

View File

@ -1,4 +1,4 @@
module Core exposing (FullModel(..), Model, Msg(..), Page(..), init, subscriptions, update)
module Core exposing (Model, Msg(..), Page(..), init, subscriptions, update)
import Browser
import Browser.Events as Events
@ -15,11 +15,6 @@ import Twitch
import Url
type FullModel
= Unloaded Element.Device Url.Url Nav.Key Time.Zone
| Loaded Model
type alias Model =
{ playlists : List Twitch.Playlist
, zone : Time.Zone
@ -27,6 +22,7 @@ type alias Model =
, key : Nav.Key
, device : Element.Device
, time : Time.Posix
, url : Url.Url
}
@ -53,9 +49,9 @@ type Msg
| TimeReceived Time.Posix
init : { width : Int, height : Int } -> Url.Url -> Nav.Key -> ( FullModel, Cmd Msg )
init : { width : Int, height : Int } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init { width, height } url key =
( Unloaded (Element.classifyDevice { width = width, height = height }) url key Time.utc
( Model [] Time.utc (Home Nothing) key (Element.classifyDevice { width = width, height = height }) (Time.millisToPosix 0) url
, Cmd.batch
[ Task.attempt TimeZoneReceivedResult TimeZone.getZone
, Twitch.fetchPlaylists resultToMsg
@ -73,7 +69,7 @@ resultToMsg result =
Noop
subscriptions : FullModel -> Sub Msg
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.batch
[ Events.onResize (\w h -> SizeReceived w h)
@ -81,166 +77,156 @@ subscriptions _ =
]
update : Msg -> FullModel -> ( FullModel, Cmd Msg )
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case ( msg, model ) of
( Noop, _ ) ->
( model, Cmd.none )
( TimeZoneReceived z, Unloaded d u k _ ) ->
( Unloaded d u k z, Cmd.none )
( TimeZoneReceived z, m ) ->
( { m | zone = z }, Cmd.none )
( TimeZoneReceived z, Loaded m ) ->
( Loaded { m | zone = z }, Cmd.none )
( TimeZoneReceivedResult (Ok ( _, zone )), Unloaded d u k _ ) ->
( Unloaded d u k zone, Cmd.none )
( TimeZoneReceivedResult (Ok ( _, zone )), Loaded m ) ->
( Loaded { m | zone = zone }, Cmd.none )
( TimeZoneReceivedResult (Ok ( _, zone )), m ) ->
( { m | zone = zone }, Cmd.none )
( TimeZoneReceivedResult (Err _), _ ) ->
( model, Task.perform TimeZoneReceived Time.here )
( TimeReceived p, Loaded m ) ->
( Loaded { m | time = p }, Cmd.none )
( TimeReceived p, m ) ->
( { m | time = p }, Cmd.none )
( HoverPlaylist hover, Loaded m ) ->
( HoverPlaylist hover, m ) ->
case m.page of
Home Nothing ->
( Loaded { m | page = Home (Just (Hover.hover hover m.time)) }, Cmd.none )
( { m | page = Home (Just (Hover.hover hover m.time)) }, Cmd.none )
_ ->
( Loaded m, Cmd.none )
( m, Cmd.none )
( HoverVideo hover, Loaded m ) ->
( HoverVideo hover, m ) ->
case m.page of
Playlist p Nothing ->
( Loaded { m | page = Playlist p (Just (Hover.hover hover m.time)) }, Cmd.none )
( { 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 )
( { m | page = Video p v (Just (Hover.hover v m.time)) }, Cmd.none )
_ ->
( Loaded m, Cmd.none )
( m, Cmd.none )
( Unhover, Loaded m ) ->
( Unhover, m ) ->
case m.page of
Home _ ->
( Loaded { m | page = Home Nothing }, Cmd.none )
( { m | page = Home Nothing }, Cmd.none )
Playlist p _ ->
( Loaded { m | page = Playlist p Nothing }, Cmd.none )
( { m | page = Playlist p Nothing }, Cmd.none )
Video p v _ ->
( Loaded { m | page = Video p v Nothing }, Cmd.none )
( { m | page = Video p v Nothing }, Cmd.none )
( SizeReceived w h, Loaded m ) ->
( Loaded { m | device = Element.classifyDevice { width = w, height = h } }
( SizeReceived w h, m ) ->
( { m | device = Element.classifyDevice { width = w, height = h } }
, Cmd.none
)
( PlaylistsReceived playlists, Unloaded device url key zone ) ->
( PlaylistsReceived playlists, m ) ->
update
(UrlReceived url)
(Loaded
{ key = key
, playlists = playlists
, zone = zone
, page = Home Nothing
, device = device
, time = Time.millisToPosix 0
}
)
(UrlReceived m.url)
{ m | playlists = playlists, page = Home Nothing }
( HomeClicked, Loaded m ) ->
( HomeClicked, m ) ->
( model
, Nav.pushUrl m.key "#"
)
( PlaylistClicked playlist, Loaded m ) ->
( PlaylistClicked playlist, m ) ->
( model
, Nav.pushUrl m.key ("#" ++ playlist.url)
)
( VideoClicked playlist video, Loaded m ) ->
( VideoClicked playlist video, m ) ->
( model
, Nav.pushUrl m.key ("#" ++ playlist.url ++ video.url)
)
( UrlReceived url, Loaded m ) ->
let
splits =
String.split "?" (Maybe.withDefault "" url.fragment)
( UrlReceived url, m ) ->
if List.isEmpty m.playlists then
( { m | url = url }, Cmd.none )
( split, args ) =
case splits of
h1 :: h2 :: _ ->
( String.split "/" h1, parseQueryString h2 )
else
let
splits =
String.split "?" (Maybe.withDefault "" url.fragment)
h1 :: _ ->
( String.split "/" h1, Dict.empty )
( split, args ) =
case splits of
h1 :: h2 :: _ ->
( String.split "/" h1, parseQueryString h2 )
_ ->
( [], Dict.empty )
h1 :: _ ->
( String.split "/" h1, Dict.empty )
time =
case Dict.get "t" args of
Just "0" ->
Nothing
_ ->
( [], Dict.empty )
Just t ->
Just t
time =
case Dict.get "t" args of
Just "0" ->
Nothing
_ ->
Nothing
Just t ->
Just t
( playlistName, videoName ) =
case split of
p :: v :: _ ->
( Just (p ++ "/"), Just (v ++ "/") )
_ ->
Nothing
p :: _ ->
( Just (p ++ "/"), Nothing )
( playlistName, videoName ) =
case split of
p :: v :: _ ->
( Just (p ++ "/"), Just (v ++ "/") )
_ ->
( Nothing, Nothing )
p :: _ ->
( Just (p ++ "/"), Nothing )
playlist =
List.head (List.filter (\x -> Just x.url == playlistName) m.playlists)
_ ->
( Nothing, Nothing )
video =
case playlist of
Just p ->
List.head (List.filter (\x -> Just x.url == videoName) p.videos)
playlist =
List.head (List.filter (\x -> Just x.url == playlistName) m.playlists)
_ ->
Nothing
video =
case playlist of
Just p ->
List.head (List.filter (\x -> Just x.url == videoName) p.videos)
( page, cmd ) =
case ( playlist, video ) of
( Just p, Just v ) ->
( Video p v Nothing
, Ports.registerVideo ( Twitch.videoId v, "videos/" ++ p.url ++ v.url, time )
)
_ ->
Nothing
( Just p, Nothing ) ->
( Playlist p Nothing, Cmd.none )
( page, cmd ) =
case ( playlist, video ) of
( Just p, Just v ) ->
( Video p v Nothing
, Ports.registerVideo ( Twitch.videoId v, "videos/" ++ p.url ++ v.url, time )
)
_ ->
( Home Nothing, Cmd.none )
( Just p, Nothing ) ->
( Playlist p Nothing, Cmd.none )
extraCmd =
case page of
Video _ _ _ ->
Cmd.none
_ ->
( Home Nothing, Cmd.none )
_ ->
Ports.eraseVideo ()
in
( Loaded { m | page = page }, Cmd.batch [ cmd, extraCmd ] )
extraCmd =
case page of
Video _ _ _ ->
Cmd.none
( UrlRequested u, Loaded m ) ->
_ ->
Ports.eraseVideo ()
in
( { m | page = page }, Cmd.batch [ cmd, extraCmd ] )
( UrlRequested u, m ) ->
case u of
Browser.Internal url ->
( model, Nav.pushUrl m.key (Url.toString url) )
@ -248,9 +234,6 @@ update msg model =
Browser.External s ->
( model, Nav.load s )
_ ->
( model, Cmd.none )
splitter : String -> Maybe ( String, String )
splitter input =

View File

@ -5,7 +5,7 @@ import Core
import Views
main : Program { width : Int, height : Int } Core.FullModel Core.Msg
main : Program { width : Int, height : Int } Core.Model Core.Msg
main =
Browser.application
{ init = Core.init

View File

@ -21,16 +21,16 @@ import Twitch
import Ui
view : Core.FullModel -> Browser.Document Core.Msg
view : Core.Model -> Browser.Document Core.Msg
view model =
let
element =
case model of
Core.Unloaded _ _ _ _ ->
case model.playlists of
[] ->
Element.el [ Element.padding 10, Element.centerX ] spinner
Core.Loaded m ->
viewContent m
_ ->
viewContent model
in
{ title = title model
, body =
@ -47,22 +47,17 @@ view model =
}
title : Core.FullModel -> String
title : Core.Model -> String
title model =
case model of
Core.Unloaded _ _ _ _ ->
case model.page of
Core.Home _ ->
Consts.url
Core.Loaded m ->
case m.page of
Core.Home _ ->
Consts.url
Core.Playlist p _ ->
Consts.url ++ " - " ++ p.name
Core.Playlist p _ ->
Consts.url ++ " - " ++ p.name
Core.Video p v _ ->
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
Core.Video p v _ ->
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
viewContent : Core.Model -> Element Core.Msg