Skip to content

Instantly share code, notes, and snippets.

@passiomatic
Created January 24, 2018 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save passiomatic/5bdf7172daf5e95256d192e308f8dd3e to your computer and use it in GitHub Desktop.
Save passiomatic/5bdf7172daf5e95256d192e308f8dd3e to your computer and use it in GitHub Desktop.
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