elm-twitch/src/Core.elm

121 lines
3.3 KiB
Elm

module Core exposing (FullModel(..), Model, Msg(..), Page(..), init, update)
import Browser.Navigation as Nav
import Consts
import Json.Decode as Decode
import Ports
import Task
import Time
import Twitch
import Url
type FullModel
= Unloaded Url.Url Nav.Key
| Loaded Model
type alias Model =
{ playlists : List Twitch.Playlist
, zone : Time.Zone
, page : Page
, key : Nav.Key
}
type Page
= Home
| Playlist Twitch.Playlist
| Video Twitch.Playlist Twitch.Video
type Msg
= Noop
| PlaylistsReceived ( List Twitch.Playlist, Time.Zone )
| HomeClicked
| PlaylistClicked Twitch.Playlist
| VideoClicked Twitch.Playlist Twitch.Video
| UrlReceived Url.Url
init : Decode.Value -> Url.Url -> Nav.Key -> ( FullModel, Cmd Msg )
init _ url key =
( Unloaded url key
, Task.perform PlaylistsReceived Twitch.fetchPlaylists
)
update : Msg -> FullModel -> ( FullModel, Cmd Msg )
update msg model =
case ( msg, model ) of
( Noop, _ ) ->
( model, Cmd.none )
( PlaylistsReceived ( playlists, zone ), Unloaded url key ) ->
update
(UrlReceived url)
(Loaded { key = key, playlists = playlists, zone = zone, page = Home })
( HomeClicked, Loaded m ) ->
( Loaded { m | page = Home }
, Nav.pushUrl m.key "#"
)
( PlaylistClicked playlist, Loaded m ) ->
( Loaded { m | page = Playlist playlist }
, Nav.pushUrl m.key ("#" ++ playlist.url)
)
( VideoClicked playlist video, Loaded m ) ->
( Loaded { m | page = Video playlist video }
, Cmd.batch
[ Nav.pushUrl m.key ("#" ++ playlist.url ++ Twitch.videoName video)
, Ports.registerVideo ( "video", video.url )
]
)
( UrlReceived url, Loaded m ) ->
let
split =
String.split "/" (Maybe.withDefault "" url.fragment)
( playlistName, videoName ) =
case split of
p :: v :: _ ->
( Just (p ++ "/"), Just (v ++ "/") )
p :: _ ->
( Just (p ++ "/"), Nothing )
_ ->
( Nothing, Nothing )
playlist =
List.head (List.filter (\x -> Just x.url == playlistName) m.playlists)
video =
case playlist of
Just p ->
List.head (List.filter (\x -> Just (Twitch.videoName x) == videoName) p.videos)
_ ->
Nothing
( page, cmd ) =
case ( playlist, video ) of
( Just p, Just v ) ->
( Video p v
, Ports.registerVideo ( Consts.videoId, v.url )
)
( Just p, Nothing ) ->
( Playlist p, Cmd.none )
_ ->
( Home, Cmd.none )
in
( Loaded { m | page = page }, cmd )
_ ->
( model, Cmd.none )