elm-twitch/src/Twitch.elm

150 lines
3.5 KiB
Elm
Raw Normal View History

2020-10-04 13:15:57 +02:00
module Twitch exposing
( Playlist
, Video
2020-10-05 11:26:11 +02:00
, decodePlaylists
2020-10-04 13:15:57 +02:00
, fetchPlaylists
2020-11-06 12:19:42 +01:00
, playlistDate
2020-10-04 13:15:57 +02:00
, playlistMiniatureUrl
2020-10-04 17:06:03 +02:00
, videoId
2020-10-04 14:24:16 +02:00
, videoMiniatureUrl
2020-10-04 16:02:54 +02:00
, videoName
2020-10-04 13:15:57 +02:00
)
2020-10-03 18:44:16 +02:00
2020-10-16 12:03:07 +02:00
import Hover exposing (Hover)
2020-10-03 18:44:16 +02:00
import Http
2020-10-04 15:24:04 +02:00
import Iso8601
2020-10-03 18:44:16 +02:00
import Json.Decode as Decode
2020-10-04 15:24:04 +02:00
import Time
2020-10-03 18:44:16 +02:00
2020-10-05 11:26:11 +02:00
type alias Video =
{ name : String
, url : String
, duration : Int
, date : Maybe Time.Posix
2020-10-04 23:03:38 +02:00
}
2020-10-05 11:26:11 +02:00
type alias Playlist =
2020-10-04 13:15:57 +02:00
{ url : String
, name : String
2020-10-03 18:44:16 +02:00
, videos : List Video
}
2020-10-05 11:26:11 +02:00
decodeVideo : Decode.Decoder Video
decodeVideo =
Decode.map4 Video
(Decode.field "title" Decode.string)
(Decode.field "url" Decode.string)
2020-10-05 11:33:49 +02:00
(Decode.map Basics.round (Decode.field "duration" Decode.float))
2020-10-05 11:26:11 +02:00
(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 =
2020-11-06 11:15:54 +01:00
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
2020-10-05 11:26:11 +02:00
fetchPlaylists : (Result Http.Error (List Playlist) -> msg) -> Cmd msg
fetchPlaylists resultToMsg =
Http.get
2020-10-05 11:56:14 +02:00
{ url = "videos/index.json"
2020-10-05 11:26:11 +02:00
, expect = Http.expectJson resultToMsg decodePlaylists
}
2020-10-03 18:44:16 +02:00
2020-10-04 16:02:54 +02:00
videoName : Video -> String
videoName video =
2020-10-05 11:26:11 +02:00
video.url
2020-10-04 16:02:54 +02:00
2020-10-04 17:06:03 +02:00
videoId : Video -> String
videoId video =
String.dropLeft 1 video.url |> String.replace "/" "-"
2020-10-16 12:03:07 +02:00
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
2020-10-04 13:15:57 +02:00
Just v ->
2020-10-05 11:26:11 +02:00
"videos/" ++ playlist.url ++ v.url ++ "miniature-050.png"
2020-10-04 13:15:57 +02:00
_ ->
""
2020-10-16 12:03:07 +02:00
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"