Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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