Created
January 24, 2018 19:42
-
-
Save passiomatic/5bdf7172daf5e95256d192e308f8dd3e to your computer and use it in GitHub Desktop.
Source code for http://lab.passiomatic.com/boris/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
port module Main exposing (..) | |
import Html exposing (program, div, button, text, Html, Attribute) | |
import Html.Events as Events | |
import Html.Attributes as Attributes | |
import Dict exposing (Dict) | |
import Json.Decode as Json | |
baseUrl = | |
"http://lab.passiomatic.com/boris/" | |
-- MODEL | |
type alias Model = | |
Dict Int AudioClip | |
type Status | |
= Loading | |
| Ready | |
| Playing | |
type alias AudioClip = | |
{ label : String | |
, filename : String | |
, status : Status | |
} | |
initialModel = | |
Dict.fromList | |
[ ( "audio1", AudioClip "A cazzo di cane" "01.mp3" Loading ) | |
, ( "audio2", AudioClip "Cagna maledetta" "02.mp3" Loading ) | |
, ( "audio3", AudioClip "Genio" "03.mp3" Loading ) | |
, ( "audio4", AudioClip "Non me frega..." "04.mp3" Loading ) | |
, ( "audio5", AudioClip "Qua-li-tà" "05.mp3" Loading ) | |
, ( "audio6", AudioClip "Graaande" "06.mp3" Loading ) | |
] | |
-- MESSAGES | |
type Msg | |
= Play String AudioClip | |
| Loaded String AudioClip | |
| Ended String AudioClip | |
{-| | |
Event sent when media's metadata has finished loading; all attributes | |
now contain as much useful information as they're going to. | |
This is good tradeoff to make it work o desktop browser and mobile ones, | |
since the latter do not even try to preload media. | |
-} | |
onLoaded : Msg -> Attribute Msg | |
onLoaded message = | |
Events.on "loadedmetadata" (Json.succeed message) | |
{-| | |
Sent when playback completes. | |
-} | |
onEnded : Msg -> Attribute Msg | |
onEnded message = | |
Events.on "ended" (Json.succeed message) | |
-- VIEW | |
view model = | |
let | |
viewEntry id ({ label, filename, status } as audioClip) = | |
let | |
className = | |
case status of | |
Ready -> | |
"ready" | |
Loading -> | |
"loading" | |
Playing -> | |
"playing" | |
in | |
[ button | |
[ Attributes.class className | |
, Events.onClick (Play id audioClip) | |
] | |
[ text label ] | |
, audioNode id audioClip | |
] | |
in | |
Dict.map viewEntry model | |
|> Dict.values | |
|> List.concat | |
|> div [ Attributes.class "container" ] | |
audioNode : String -> AudioClip -> Html Msg | |
audioNode id ({ filename } as audioClip) = | |
Html.audio | |
[ Attributes.id id | |
, Attributes.src (baseUrl ++ filename) | |
, Attributes.preload "metadata" | |
--, Attributes.controls True | |
, onLoaded (Loaded id audioClip) | |
, onEnded (Ended id audioClip) | |
] | |
[] | |
-- UPDATE | |
update msg model = | |
case msg of | |
Loaded id audioClip -> | |
( Dict.insert id { audioClip | status = Ready } model, Cmd.none ) | |
Play id audioClip -> | |
if audioClip.status == Playing then | |
( model, Cmd.none ) | |
else | |
( Dict.insert id { audioClip | status = Playing } model, playAudio id ) | |
Ended id audioClip -> | |
( Dict.insert id { audioClip | status = Ready } model, Cmd.none ) | |
-- PORT | |
port playAudio : String -> Cmd msg | |
-- ENTRY POINT | |
main = | |
program | |
{ init = ( initialModel, Cmd.none ) | |
, view = view | |
, update = update | |
, subscriptions = \_ -> Sub.none | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment