Fix: load() on video select + telm-format
parent
f9cfc28ded
commit
7b1ee76d48
|
@ -1,4 +1,5 @@
|
|||
elm-stuff
|
||||
repl-temp-*
|
||||
public/application.js
|
||||
public/videos.json
|
||||
public/videos.json
|
||||
public/videos/
|
5
Makefile
5
Makefile
|
@ -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
|
||||
|
|
|
@ -101,6 +101,14 @@
|
|||
]
|
||||
}
|
||||
});
|
||||
|
||||
app.ports.reloadVideoSource.subscribe(function() {
|
||||
document.querySelector("video").load();
|
||||
});
|
||||
|
||||
app.ports.reloadVideoSource = function(a) {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
95
src/View.elm
95
src/View.elm
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue