Fix: load() on video select + telm-format

dockercon2021
Efertone 2021-03-29 09:53:57 +02:00
parent f9cfc28ded
commit 7b1ee76d48
No known key found for this signature in database
GPG Key ID: 07AB750DDFD9EE50
9 changed files with 150 additions and 86 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
elm-stuff
repl-temp-*
public/application.js
public/videos.json
public/videos.json
public/videos/

View File

@ -26,4 +26,7 @@ gen-videos-json:
.PHONY: update-videos
update-videos: gen-videos-json
mc cp public/videos.json $(REMOTE)/$(BUCKET)/$(BASE_PATH)/videos.json
mc cp public/videos.json $(REMOTE)/$(BUCKET)/$(BASE_PATH)/videos.json
start-dev-server:
python3 -m http.server --directory public

View File

@ -101,6 +101,14 @@
]
}
});
app.ports.reloadVideoSource.subscribe(function() {
document.querySelector("video").load();
});
app.ports.reloadVideoSource = function(a) {
}
</script>
</body>

View File

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

View File

@ -1,9 +1,10 @@
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 }
videoList =
Http.get { url = "videos.json", expect = Http.expectJson Msg.VideoListLanded Video.videoListDecoder }

View File

@ -2,26 +2,36 @@ module Types exposing (..)
import Video
type alias Flags =
{ debug : Bool
, extentions : List Video.FileFormat
}
{ debug : Bool
, extentions : List Video.FileFormat
}
type alias Model =
{ selected : Maybe String
, videos : List Video.Video
, extensions : List Video.FileFormat
, withDownload : Bool
}
{ selected : Maybe String
, videos : List Video.Video
, extensions : List Video.FileFormat
, withDownload : Bool
}
videos : Model -> List Video.Video
videos model = model.videos
videos model =
model.videos
-- These functions may seem useless, but that way it's easier to swap out
-- from flags without changing the init function.
-- These functions may seem useless, but that way it's easier to swap out
-- from flags without changing the init function.
debugEnabled : Flags -> Bool
debugEnabled flags = flags.debug
debugEnabled flags =
flags.debug
withDownload : Flags -> Bool
withDownload flags = flags.debug
withDownload flags =
flags.debug

View File

@ -1,14 +1,25 @@
module Update exposing (..)
port 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 = Just 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)
case msg of
Msg.VideoSelected path ->
( { model | selected = Just path }, reloadVideoSource () )
Msg.VideoListLanded response ->
case response of
Ok videos ->
( { model | videos = videos }, Cmd.none )
Err _ ->
( model, Cmd.none )
Msg.NoOp ->
( model, Cmd.none )
port reloadVideoSource : () -> Cmd msg

View File

@ -4,40 +4,49 @@ import Html
import Html.Attributes
import Json.Decode
type alias Video =
{ title : String
, path : String
}
{ title : String
, path : String
}
type alias FileFormat =
{ extention : String
, mime : String
}
{ extention : String
, mime : String
}
videoListDecoder : Json.Decode.Decoder (List Video)
videoListDecoder = Json.Decode.list videoDecoder
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)
Json.Decode.map2 Video
(Json.Decode.field "Title" Json.Decode.string)
(Json.Decode.field "Path" Json.Decode.string)
htmlSourceElem : String -> FileFormat -> Html.Html msg
htmlSourceElem path format =
Html.source
[ Html.Attributes.src (path ++ "." ++ format.extention)
, Html.Attributes.type_ format.mime
] []
Html.source
[ Html.Attributes.src (path ++ "." ++ format.extention)
, Html.Attributes.type_ format.mime
]
[]
downloadLink : String -> FileFormat -> Html.Html msg
downloadLink path format =
Html.a
[ Html.Attributes.href (path ++ "." ++ format.extention)
, Html.Attributes.download <| filename path format
]
[ Html.text <| filename path format ]
Html.a
[ Html.Attributes.href (path ++ "." ++ format.extention)
, Html.Attributes.download <| filename path format
]
[ Html.text <| filename path format ]
filename : String -> FileFormat -> String
filename path format =
(Maybe.withDefault "unknown" <| List.head <| List.drop 1 <| String.split "/" path) ++ "." ++ format.extention
(Maybe.withDefault "unknown" <| List.head <| List.drop 1 <| String.split "/" path) ++ "." ++ format.extention

View File

@ -4,62 +4,83 @@ 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 =
[ makeDropDown model.videos
, makePlayer model
, downloadList model
, 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" ]
{ title = "Minimal WebPlayer"
, body =
[ makeDropDown model.videos
, makePlayer model
, downloadList model
, 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" ]
]
]
]
}
}
empty : Html.Html Msg.Msg
empty = Html.div [] []
empty =
Html.div [] []
makeDropDown : List Video.Video -> Html.Html Msg.Msg
makeDropDown videos =
if List.isEmpty videos
then empty
if List.isEmpty videos then
empty
else
Html.select [ Events.onInput Msg.VideoSelected ]
<| makeOption {title = "Select one please ;)", path = ""} :: (List.map makeOption 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 ]
Html.option
[ Html.Attributes.value video.path ]
[ Html.text video.title ]
makePlayer : Types.Model -> Html.Html Msg.Msg
makePlayer model =
case model.selected of
Nothing -> empty
Just path ->
Html.video
[ Html.Attributes.width 960
, Html.Attributes.height 650
, Html.Attributes.controls True
] <| List.map (Video.htmlSourceElem path) model.extensions
makePlayer model =
case model.selected of
Nothing ->
empty
Just path ->
Html.video
[ Html.Attributes.width 960
, Html.Attributes.height 650
, Html.Attributes.controls True
]
<|
List.map (Video.htmlSourceElem path) model.extensions
downloadList : Types.Model -> Html.Html Msg.Msg
downloadList model =
let
selected = if not model.withDownload then Nothing else model.selected
in
let
selected =
if not model.withDownload then
Nothing
else
model.selected
in
case selected of
Nothing -> empty
Just path ->
Html.div [ Html.Attributes.class "downloadList" ]
<| List.map (\e -> Video.downloadLink path e) model.extensions
Nothing ->
empty
Just path ->
Html.div [ Html.Attributes.class "downloadList" ] <|
List.map (\e -> Video.downloadLink path e) model.extensions