module Twitch exposing ( Playlist , Video , decodePlaylists , fetchPlaylists , playlistDate , playlistMiniatureUrl , videoId , videoMiniatureUrl , videoName ) import Hover exposing (Hover) import Http import Iso8601 import Json.Decode as Decode import Time type alias Video = { name : String , url : String , duration : Int , date : Maybe Time.Posix } type alias Playlist = { url : String , name : String , videos : List Video } decodeVideo : Decode.Decoder Video decodeVideo = Decode.map4 Video (Decode.field "title" Decode.string) (Decode.field "url" Decode.string) (Decode.map Basics.round (Decode.field "duration" Decode.float)) (Decode.maybe (Decode.field "date" Iso8601.decoder)) decodePlaylist : Decode.Decoder Playlist decodePlaylist = Decode.map3 Playlist (Decode.field "url" Decode.string) (Decode.field "title" Decode.string) (Decode.field "videos" (Decode.map (List.sortBy .url >> List.reverse) (Decode.list decodeVideo))) decodePlaylists : Decode.Decoder (List Playlist) decodePlaylists = Decode.map (sortPlaylists >> List.reverse) (Decode.list decodePlaylist) mostRecentVideo : List Video -> Maybe Time.Posix mostRecentVideo videos = case ( videos, List.map .date videos ) of ( _, (Just t) :: _ ) -> Just t ( _ :: t, Nothing :: _ ) -> mostRecentVideo t _ -> Nothing playlistDate : Playlist -> Int playlistDate playlist = mostRecentVideo playlist.videos |> Maybe.map Time.posixToMillis |> Maybe.withDefault 0 sortPlaylists : List Playlist -> List Playlist sortPlaylists list = List.sortBy playlistDate list fetchPlaylists : (Result Http.Error (List Playlist) -> msg) -> Cmd msg fetchPlaylists resultToMsg = Http.get { url = "videos/index.json" , expect = Http.expectJson resultToMsg decodePlaylists } videoName : Video -> String videoName video = video.url videoId : Video -> String videoId video = String.dropLeft 1 video.url |> String.replace "/" "-" 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" _ -> "" 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"