dockercon2021
Efertone 2 years ago
parent 87e6d42cf5
commit 4310c54f93
No known key found for this signature in database
GPG Key ID: 07AB750DDFD9EE50
  1. 102
      src/Main.elm
  2. 10
      src/Msg.elm
  3. 9
      src/Request.elm
  4. 10
      src/Types.elm
  5. 14
      src/Update.elm
  6. 18
      src/Video.elm
  7. 47
      src/View.elm

@ -1,101 +1,25 @@
module Main exposing (..)
import Browser exposing (Document)
import Browser
import Browser.Navigation
import Html
import Html.Attributes
import Url
import Html.Events as Events
import Json.Decode
import Http
import Msg
import Update
import Request
import Types
import View
main : Program Flags Model Msg
main : Program Types.Flags Types.Model Msg.Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, view = View.view
, update = Update.update
, subscriptions = \_ -> Sub.none
, onUrlChange = \_ -> NoOp
, onUrlRequest = \_ -> NoOp
, onUrlChange = \_ -> Msg.NoOp
, onUrlRequest = \_ -> Msg.NoOp
}
type alias Flags = { }
type Msg
= NoOp
| VideoSelected String
| VideoListLanded (Result Http.Error (List Video))
type alias Video =
{ title : String
, path : String
}
type alias Model =
{ selected : String
, videos : List Video
}
init : flags -> Url.Url -> Browser.Navigation.Key -> ( Model, Cmd Msg )
init _ _ _ = ({ selected = "", videos = [] }, requestVideoList)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
VideoSelected path -> ({model | selected = path}, Cmd.none)
VideoListLanded response ->
case response of
Ok videos -> ({model | videos = videos}, Cmd.none)
Err _ -> (model, Cmd.none)
NoOp -> (model, Cmd.none)
view : Model -> Document Msg
view model =
{ title = "Minimal WebPlayer"
, body =
[ if List.length model.videos == 0 then Html.div [] [] else makeDropDown model.videos
, if model.selected == "" then Html.div [] [] else makePlayer model.selected
, Html.footer []
[ Html.text "Handmade with love (and Vim and elm) ;)"
, Html.a
[ Html.Attributes.href "https://gitea.code-infection.com/efertone/minimal-webplayer"
, Html.Attributes.target "_blank"
] [ Html.text "source" ]
]
]
}
makeDropDown : List Video -> Html.Html Msg
makeDropDown videos =
Html.select [ Events.onInput VideoSelected ]
<| makeOption {title = "Select one please ;)", path = ""} :: (List.map makeOption videos)
makeOption : Video -> Html.Html Msg
makeOption video =
Html.option
[ Html.Attributes.value video.path ] [ Html.text video.title ]
makePlayer : String -> Html.Html Msg
makePlayer path =
Html.video
[ Html.Attributes.width 960
, Html.Attributes.height 650
, Html.Attributes.controls True
]
[ Html.source [Html.Attributes.src (path ++ ".mkv"), Html.Attributes.type_ "video/x-matroska"] []
, Html.source [Html.Attributes.src (path ++ ".mp4"), Html.Attributes.type_ "video/mp4"] []
]
requestVideoList : Cmd Msg
requestVideoList = Http.get { url = "videos.json", expect = Http.expectJson VideoListLanded videoListDecoder }
videoListDecoder : Json.Decode.Decoder (List Video)
videoListDecoder = Json.Decode.list videoDecoder
videoDecoder : Json.Decode.Decoder Video
videoDecoder =
Json.Decode.map2 Video
(Json.Decode.field "Title" Json.Decode.string)
(Json.Decode.field "Path" Json.Decode.string)
init : Types.Flags -> Url.Url -> Browser.Navigation.Key -> ( Types.Model, Cmd Msg.Msg )
init _ _ _ = ({ selected = "", videos = [] }, Request.videoList)

@ -0,0 +1,10 @@
module Msg exposing (..)
import Http
import Video
type Msg
= NoOp
| VideoSelected String
| VideoListLanded (Result Http.Error (List Video.Video))

@ -0,0 +1,9 @@
module Request exposing (..)
import Http
import Msg
import Video
videoList : Cmd Msg.Msg
videoList = Http.get { url = "videos.json", expect = Http.expectJson Msg.VideoListLanded Video.videoListDecoder }

@ -0,0 +1,10 @@
module Types exposing (..)
import Video
type alias Flags = { }
type alias Model =
{ selected : String
, videos : List Video.Video
}

@ -0,0 +1,14 @@
module Update exposing (..)
import Msg
import Types
update : Msg.Msg -> Types.Model -> ( Types.Model, Cmd Msg.Msg )
update msg model =
case msg of
Msg.VideoSelected path -> ({model | selected = path}, Cmd.none)
Msg.VideoListLanded response ->
case response of
Ok videos -> ({model | videos = videos}, Cmd.none)
Err _ -> (model, Cmd.none)
Msg.NoOp -> (model, Cmd.none)

@ -0,0 +1,18 @@
module Video exposing (..)
import Json.Decode
import Http
type alias Video =
{ title : String
, path : String
}
videoListDecoder : Json.Decode.Decoder (List Video)
videoListDecoder = Json.Decode.list videoDecoder
videoDecoder : Json.Decode.Decoder Video
videoDecoder =
Json.Decode.map2 Video
(Json.Decode.field "Title" Json.Decode.string)
(Json.Decode.field "Path" Json.Decode.string)

@ -0,0 +1,47 @@
module View exposing (..)
import Browser exposing (Document)
import Html
import Html.Attributes
import Html.Events as Events
import Msg
import Types
import Video
view : Types.Model -> Document Msg.Msg
view model =
{ title = "Minimal WebPlayer"
, body =
[ if List.length model.videos == 0 then Html.div [] [] else makeDropDown model.videos
, if model.selected == "" then Html.div [] [] else makePlayer model.selected
, Html.footer []
[ Html.text "Handmade with love (and Vim and elm) ;)"
, Html.a
[ Html.Attributes.href "https://gitea.code-infection.com/efertone/minimal-webplayer"
, Html.Attributes.target "_blank"
] [ Html.text "source" ]
]
]
}
makeDropDown : List Video.Video -> Html.Html Msg.Msg
makeDropDown videos =
Html.select [ Events.onInput Msg.VideoSelected ]
<| makeOption {title = "Select one please ;)", path = ""} :: (List.map makeOption videos)
makeOption : Video.Video -> Html.Html Msg.Msg
makeOption video =
Html.option
[ Html.Attributes.value video.path ] [ Html.text video.title ]
makePlayer : String -> Html.Html Msg.Msg
makePlayer path =
Html.video
[ Html.Attributes.width 960
, Html.Attributes.height 650
, Html.Attributes.controls True
]
[ Html.source [Html.Attributes.src (path ++ ".mkv"), Html.Attributes.type_ "video/x-matroska"] []
, Html.source [Html.Attributes.src (path ++ ".mp4"), Html.Attributes.type_ "video/mp4"] []
]
Loading…
Cancel
Save