diff --git a/public/index.html b/public/index.html
index a2be7da..7fcc7bd 100644
--- a/public/index.html
+++ b/public/index.html
@@ -19,7 +19,8 @@
}
select,
- footer {
+ footer,
+ .downloadList {
margin-left: auto;
margin-right: auto;
margin-top: 1em;
@@ -53,6 +54,31 @@
background-color: #cc60b6;
color: #ccc;
}
+
+ .downloadList:before {
+ content: "Direct Download";
+ font-weight: bold;
+ text-decoration: underline;
+ margin-bottom: 1em;
+ display: block;
+ }
+
+ .downloadList {
+ margin-top: 2em;
+ width: 500px;
+ margin-bottom: 2em;
+ }
+
+ .downloadList > a {
+ color: #60b5cc;
+ display: list-item;
+ margin-top: 0.2em;
+ text-decoration: none;
+ }
+
+ .downloadList > a:hover {
+ color: #ccc;
+ }
@@ -67,7 +93,13 @@
diff --git a/src/Main.elm b/src/Main.elm
index 2f160e4..beb8fc9 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,15 +1,13 @@
module Main exposing (..)
import Browser
-import Browser.Navigation
-import Url
-
import Msg
-import Update
import Request
import Types
+import Update
import View
+
main : Program Types.Flags Types.Model Msg.Msg
main =
Browser.application
@@ -21,5 +19,16 @@ main =
, onUrlRequest = \_ -> Msg.NoOp
}
-init : Types.Flags -> Url.Url -> Browser.Navigation.Key -> ( Types.Model, Cmd Msg.Msg )
-init _ _ _ = ({ selected = "", videos = [] }, Request.videoList)
+
+init : Types.Flags -> a -> b -> ( Types.Model, Cmd Msg.Msg )
+init flags _ _ =
+ ( initialState flags, Request.videoList )
+
+
+initialState : Types.Flags -> Types.Model
+initialState flags =
+ { selected = Nothing
+ , videos = []
+ , extensions = flags.extentions
+ , withDownload = Types.withDownload flags
+ }
diff --git a/src/Types.elm b/src/Types.elm
index 58d48d4..0912649 100644
--- a/src/Types.elm
+++ b/src/Types.elm
@@ -2,9 +2,26 @@ module Types exposing (..)
import Video
-type alias Flags = { }
+type alias Flags =
+ { debug : Bool
+ , extentions : List Video.FileFormat
+ }
type alias Model =
- { selected : String
+ { selected : Maybe String
, videos : List Video.Video
- }
\ No newline at end of file
+ , extensions : List Video.FileFormat
+ , withDownload : Bool
+ }
+
+videos : Model -> List Video.Video
+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.
+
+debugEnabled : Flags -> Bool
+debugEnabled flags = flags.debug
+
+withDownload : Flags -> Bool
+withDownload flags = flags.debug
\ No newline at end of file
diff --git a/src/Update.elm b/src/Update.elm
index a847cfc..c2c836c 100644
--- a/src/Update.elm
+++ b/src/Update.elm
@@ -6,7 +6,7 @@ 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.VideoSelected path -> ({model | selected = Just path}, Cmd.none)
Msg.VideoListLanded response ->
case response of
Ok videos -> ({model | videos = videos}, Cmd.none)
diff --git a/src/Video.elm b/src/Video.elm
index 0b3767a..7af1846 100644
--- a/src/Video.elm
+++ b/src/Video.elm
@@ -1,13 +1,19 @@
module Video exposing (..)
+import Html
+import Html.Attributes
import Json.Decode
-import Http
type alias Video =
{ title : String
, path : String
}
+type alias FileFormat =
+ { extention : String
+ , mime : String
+ }
+
videoListDecoder : Json.Decode.Decoder (List Video)
videoListDecoder = Json.Decode.list videoDecoder
@@ -15,4 +21,23 @@ videoDecoder : Json.Decode.Decoder Video
videoDecoder =
Json.Decode.map2 Video
(Json.Decode.field "Title" Json.Decode.string)
- (Json.Decode.field "Path" Json.Decode.string)
\ No newline at end of file
+ (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
+ ] []
+
+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 ]
+
+filename : String -> FileFormat -> String
+filename path format =
+ (Maybe.withDefault "unknown" <| List.head <| List.drop 1 <| String.split "/" path) ++ "." ++ format.extention
\ No newline at end of file
diff --git a/src/View.elm b/src/View.elm
index 9131b1e..bcd1795 100644
--- a/src/View.elm
+++ b/src/View.elm
@@ -8,13 +8,15 @@ import Html.Events as Events
import Msg
import Types
import Video
+import Types exposing (withDownload)
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
+ [ makeDropDown model.videos
+ , makePlayer model
+ , downloadList model
, Html.footer []
[ Html.text "Handmade with love (and Vim and elm) ;)"
, Html.a
@@ -25,23 +27,40 @@ view model =
]
}
+empty : Html.Html Msg.Msg
+empty = Html.div [] []
+
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)
+ if List.isEmpty videos
+ then empty
+ else
+ 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"] []
- ]
\ No newline at end of file
+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
+
+downloadList : Types.Model -> Html.Html Msg.Msg
+downloadList model =
+ 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
\ No newline at end of file