Initial commit

dockercon2021
Efertone 2021-03-22 17:48:51 +01:00
commit b491b548a4
No known key found for this signature in database
GPG Key ID: 07AB750DDFD9EE50
5 changed files with 218 additions and 0 deletions

4
.gitignore vendored Normal file
View File

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

29
Makefile Normal file
View File

@ -0,0 +1,29 @@
REMOTE := "efertone"
BUCKET := "share-efertone"
BASE_PATH := "final-space"
.PHONY: dev-build
dev-build:
elm make src/Main.elm --output=public/application.js --debug
.PHONY: prod-build
prod-build:
elm make src/Main.elm --output=public/application.js
.PHONY: upload
upload: prod-build
mc cp public/index.html $(REMOTE)/$(BUCKET)/$(BASE_PATH)/index.html
mc cp public/application.js $(REMOTE)/$(BUCKET)/$(BASE_PATH)/application.js
.PHONY: gen-videos-json
gen-videos-json:
@echo '[$(shell mc ls $(REMOTE)/$(BUCKET)/$(BASE_PATH)/videos/ --json | \
jq -r '.key' | \
sed -Ee 's/\.mkv$$|\.mp4$$//g' | \
sort -u | \
sed -Ee 's/^(.*)$$/{"Title":"\1","Path":"videos\/\1"}/g' | \
paste -sd "," -)]' > public/videos.json
.PHONY: update-videos
update-videos: gen-videos-json
mc cp public/videos.json $(REMOTE)/$(BUCKET)/$(BASE_PATH)/videos.json

27
elm.json Normal file
View File

@ -0,0 +1,27 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/http": "2.0.0",
"elm/json": "1.1.3",
"elm/url": "1.0.0"
},
"indirect": {
"elm/bytes": "1.0.8",
"elm/file": "1.0.5",
"elm/time": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}

61
public/index.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Minimalistic WebPlayer</title>
<style>
html {
margin: 0;
padding: 0;
background-color: #161616;
color: #ccc;
}
video {
margin-left: auto;
margin-right: auto;
display: block;
margin-top: 1em;
}
select,
footer {
margin-left: auto;
margin-right: auto;
margin-top: 1em;
margin-bottom: 1em;
display: block;
width: 960px;
}
footer {
text-align: center;
}
select {
background-color: #333;
color: #ccc;
border: 1px solid #555;
padding: 0.2em;
}
</style>
<script type="text/javascript" src="application.js"></script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="elm"></div>
<script>
const app = Elm.Main.init({
node: document.getElementById('elm'),
flags: {}
});
</script>
</body>
</html>

97
src/Main.elm Normal file
View File

@ -0,0 +1,97 @@
module Main exposing (..)
import Browser exposing (Document)
import Browser.Navigation
import Html
import Html.Attributes
import Url
import Html.Events as Events
import Json.Decode
import Http
main : Program Flags Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = \_ -> Sub.none
, onUrlChange = \_ -> NoOp
, onUrlRequest = \_ -> 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 = [{title="asd", path="kjhkj"}] }, 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 = "My Title"
, 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) ;)" ]
]
}
makeDropDown : List Video -> Html.Html Msg
makeDropDown videos =
Html.select []
<| makeOption {title = "Select one please ;)", path = ""} :: (List.map makeOption videos)
makeOption : Video -> Html.Html Msg
makeOption video =
Html.option
[ Events.onClick (VideoSelected video.path)
, 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)