Basic sound controls ° keybaord shortcuts
This commit is contained in:
parent
e99a5ed1e3
commit
37a8253387
|
@ -79,6 +79,7 @@
|
||||||
|
|
||||||
app.ports.seek.subscribe(function(arg) {
|
app.ports.seek.subscribe(function(arg) {
|
||||||
const video = document.getElementById('video');
|
const video = document.getElementById('video');
|
||||||
|
console.log(arg);
|
||||||
video.currentTime = arg;
|
video.currentTime = arg;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,6 +114,12 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.ports.setVolume.subscribe(function(arg) {
|
||||||
|
const video = document.getElementById('video');
|
||||||
|
video.volume = arg.volume;
|
||||||
|
video.muted = arg.muted;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -78,3 +78,35 @@ check =
|
||||||
svgFeatherIcon "check"
|
svgFeatherIcon "check"
|
||||||
[ Svg.polyline [ points "20 6 9 17 4 12" ] []
|
[ Svg.polyline [ points "20 6 9 17 4 12" ] []
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
volume : Bool -> Element msg
|
||||||
|
volume =
|
||||||
|
svgFeatherIcon "volume"
|
||||||
|
[ Svg.polygon [ points "11 5 6 9 2 9 2 15 6 15 11 19 11 5" ] []
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
volume1 : Bool -> Element msg
|
||||||
|
volume1 =
|
||||||
|
svgFeatherIcon "volume-1"
|
||||||
|
[ Svg.polygon [ points "11 5 6 9 2 9 2 15 6 15 11 19 11 5" ] []
|
||||||
|
, Svg.path [ d "M15.54 8.46a5 5 0 0 1 0 7.07" ] []
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
volume2 : Bool -> Element msg
|
||||||
|
volume2 =
|
||||||
|
svgFeatherIcon "volume-2"
|
||||||
|
[ Svg.polygon [ points "11 5 6 9 2 9 2 15 6 15 11 19 11 5" ] []
|
||||||
|
, Svg.path [ d "M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" ] []
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
volumeX : Bool -> Element msg
|
||||||
|
volumeX =
|
||||||
|
svgFeatherIcon "volume-x"
|
||||||
|
[ Svg.polygon [ points "11 5 6 9 2 9 2 15 6 15 11 19 11 5" ] []
|
||||||
|
, Svg.line [ x1 "23", y1 "9", x2 "17", y2 "15" ] []
|
||||||
|
, Svg.line [ x1 "17", y1 "9", x2 "23", y2 "15" ] []
|
||||||
|
]
|
||||||
|
|
108
src/Main.elm
108
src/Main.elm
|
@ -26,7 +26,7 @@ main =
|
||||||
, update = update
|
, update = update
|
||||||
, view = view
|
, view = view
|
||||||
, subscriptions =
|
, subscriptions =
|
||||||
\_ ->
|
\model ->
|
||||||
Sub.batch
|
Sub.batch
|
||||||
[ nowHasQualities NowHasQualities
|
[ nowHasQualities NowHasQualities
|
||||||
, nowHasQuality
|
, nowHasQuality
|
||||||
|
@ -40,6 +40,7 @@ main =
|
||||||
)
|
)
|
||||||
, Browser.Events.onAnimationFrameDelta AnimationFrameDelta
|
, Browser.Events.onAnimationFrameDelta AnimationFrameDelta
|
||||||
, Browser.Events.onResize (\x y -> NowHasWindowSize ( x, y ))
|
, Browser.Events.onResize (\x y -> NowHasWindowSize ( x, y ))
|
||||||
|
, Browser.Events.onKeyDown (decodeKeyDown model)
|
||||||
]
|
]
|
||||||
, onUrlChange = \_ -> Noop
|
, onUrlChange = \_ -> Noop
|
||||||
, onUrlRequest = \_ -> Noop
|
, onUrlRequest = \_ -> Noop
|
||||||
|
@ -81,6 +82,7 @@ type Msg
|
||||||
| SetSettings Settings
|
| SetSettings Settings
|
||||||
| SetPlaybackRate Float
|
| SetPlaybackRate Float
|
||||||
| SetQuality Quality.Quality
|
| SetQuality Quality.Quality
|
||||||
|
| SetVolume Float Bool
|
||||||
| RequestFullscreen
|
| RequestFullscreen
|
||||||
| ExitFullscreen
|
| ExitFullscreen
|
||||||
| AnimationFrameDelta Float
|
| AnimationFrameDelta Float
|
||||||
|
@ -145,8 +147,8 @@ update msg model =
|
||||||
PlayPause ->
|
PlayPause ->
|
||||||
( model, playPause () )
|
( model, playPause () )
|
||||||
|
|
||||||
Seek ratio ->
|
Seek time ->
|
||||||
( model, seek (ratio * model.duration) )
|
( model, seek time )
|
||||||
|
|
||||||
SetPlaybackRate rate ->
|
SetPlaybackRate rate ->
|
||||||
( { model | showSettings = False, settings = All }, setPlaybackRate rate )
|
( { model | showSettings = False, settings = All }, setPlaybackRate rate )
|
||||||
|
@ -166,6 +168,9 @@ update msg model =
|
||||||
SetQuality q ->
|
SetQuality q ->
|
||||||
( { model | showSettings = False, settings = All }, setQuality q )
|
( { model | showSettings = False, settings = All }, setQuality q )
|
||||||
|
|
||||||
|
SetVolume v m ->
|
||||||
|
( model, setVolume { volume = v, muted = m } )
|
||||||
|
|
||||||
AnimationFrameDelta delta ->
|
AnimationFrameDelta delta ->
|
||||||
if model.animationFrame + delta > 3500 then
|
if model.animationFrame + delta > 3500 then
|
||||||
( { model | animationFrame = model.animationFrame + delta, showSettings = False, settings = All }, Cmd.none )
|
( { model | animationFrame = model.animationFrame + delta, showSettings = False, settings = All }, Cmd.none )
|
||||||
|
@ -301,7 +306,7 @@ video model =
|
||||||
(Element.width Element.fill
|
(Element.width Element.fill
|
||||||
:: Element.height Element.fill
|
:: Element.height Element.fill
|
||||||
:: Element.pointer
|
:: Element.pointer
|
||||||
:: seekBarEvents
|
:: seekBarEvents model
|
||||||
)
|
)
|
||||||
Element.none
|
Element.none
|
||||||
)
|
)
|
||||||
|
@ -320,6 +325,7 @@ video model =
|
||||||
, Element.row
|
, Element.row
|
||||||
[ Element.spacing 10, Element.width Element.fill ]
|
[ Element.spacing 10, Element.width Element.fill ]
|
||||||
[ playPauseButton model.playing
|
[ playPauseButton model.playing
|
||||||
|
, volumeButton model.volume model.muted
|
||||||
, Element.el [ Element.moveDown 2.5 ] (Element.text (formatTime model.position ++ " / " ++ formatTime model.duration))
|
, Element.el [ Element.moveDown 2.5 ] (Element.text (formatTime model.position ++ " / " ++ formatTime model.duration))
|
||||||
, Element.row [ Element.spacing 10, Element.alignRight ]
|
, Element.row [ Element.spacing 10, Element.alignRight ]
|
||||||
[ settingsButton, fullscreenButton model.isFullscreen ]
|
[ settingsButton, fullscreenButton model.isFullscreen ]
|
||||||
|
@ -534,6 +540,28 @@ fullscreenButton isFullscreen =
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
volumeButton : Float -> Bool -> Element Msg
|
||||||
|
volumeButton volume muted =
|
||||||
|
let
|
||||||
|
icon =
|
||||||
|
if muted then
|
||||||
|
Icons.volumeX
|
||||||
|
|
||||||
|
else if volume < 0.3 then
|
||||||
|
Icons.volume
|
||||||
|
|
||||||
|
else if volume < 0.6 then
|
||||||
|
Icons.volume1
|
||||||
|
|
||||||
|
else
|
||||||
|
Icons.volume2
|
||||||
|
in
|
||||||
|
Input.button []
|
||||||
|
{ label = icon True
|
||||||
|
, onPress = Just (SetVolume volume (not muted))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
settingsButton : Element Msg
|
settingsButton : Element Msg
|
||||||
settingsButton =
|
settingsButton =
|
||||||
Input.button []
|
Input.button []
|
||||||
|
@ -564,10 +592,10 @@ videoEvents =
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
seekBarEvents : List (Element.Attribute Msg)
|
seekBarEvents : Model -> List (Element.Attribute Msg)
|
||||||
seekBarEvents =
|
seekBarEvents model =
|
||||||
List.map Element.htmlAttribute
|
List.map Element.htmlAttribute
|
||||||
[ Html.Events.on "click" decodeSeek
|
[ Html.Events.on "click" (decodeSeek model)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,9 +621,9 @@ decodeVolumeChange =
|
||||||
(Decode.field "muted" Decode.bool)
|
(Decode.field "muted" Decode.bool)
|
||||||
|
|
||||||
|
|
||||||
decodeSeek : Decode.Decoder Msg
|
decodeSeek : Model -> Decode.Decoder Msg
|
||||||
decodeSeek =
|
decodeSeek model =
|
||||||
Decode.map2 (\x y -> Seek (toFloat x / toFloat y))
|
Decode.map2 (\x y -> Seek (toFloat x / toFloat y * model.duration))
|
||||||
(Decode.field "layerX" Decode.int)
|
(Decode.field "layerX" Decode.int)
|
||||||
(Dom.target <| Decode.field "offsetWidth" Decode.int)
|
(Dom.target <| Decode.field "offsetWidth" Decode.int)
|
||||||
|
|
||||||
|
@ -646,6 +674,63 @@ decodePlaybackRateChange =
|
||||||
(Decode.field "playbackRate" Decode.float)
|
(Decode.field "playbackRate" Decode.float)
|
||||||
|
|
||||||
|
|
||||||
|
decodeKeyDown : Model -> Decode.Decoder Msg
|
||||||
|
decodeKeyDown model =
|
||||||
|
Decode.field "keyCode" Decode.int
|
||||||
|
|> Decode.andThen
|
||||||
|
(\x ->
|
||||||
|
case x of
|
||||||
|
-- Enter key
|
||||||
|
32 ->
|
||||||
|
Decode.succeed PlayPause
|
||||||
|
|
||||||
|
-- J key
|
||||||
|
74 ->
|
||||||
|
Decode.succeed (Seek (max 0 (model.position - 10)))
|
||||||
|
|
||||||
|
-- L key
|
||||||
|
76 ->
|
||||||
|
Decode.succeed (Seek (min model.duration (model.position + 10)))
|
||||||
|
|
||||||
|
-- K key
|
||||||
|
75 ->
|
||||||
|
Decode.succeed PlayPause
|
||||||
|
|
||||||
|
-- Left arrow
|
||||||
|
37 ->
|
||||||
|
Decode.succeed (Seek (max 0 (model.position - 5)))
|
||||||
|
|
||||||
|
-- Right arrow
|
||||||
|
39 ->
|
||||||
|
Decode.succeed (Seek (min model.duration (model.position + 5)))
|
||||||
|
|
||||||
|
-- Down arrow
|
||||||
|
40 ->
|
||||||
|
Decode.succeed (SetVolume (max 0 (model.volume - 0.1)) model.muted)
|
||||||
|
|
||||||
|
-- Top arrow
|
||||||
|
38 ->
|
||||||
|
Decode.succeed (SetVolume (min 1 (model.volume + 0.1)) model.muted)
|
||||||
|
|
||||||
|
-- M key
|
||||||
|
77 ->
|
||||||
|
Decode.succeed (SetVolume model.volume (not model.muted))
|
||||||
|
|
||||||
|
-- F key
|
||||||
|
70 ->
|
||||||
|
Decode.succeed
|
||||||
|
(if model.isFullscreen then
|
||||||
|
ExitFullscreen
|
||||||
|
|
||||||
|
else
|
||||||
|
RequestFullscreen
|
||||||
|
)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Decode.fail ("no shortcut for code " ++ String.fromInt x)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
every : Float -> List ( Float, Float ) -> List ( Float, Float, Bool )
|
every : Float -> List ( Float, Float ) -> List ( Float, Float, Bool )
|
||||||
every duration input =
|
every duration input =
|
||||||
everyAux duration 0.0 [] input |> List.reverse |> List.filter (\( x, y, _ ) -> x /= y)
|
everyAux duration 0.0 [] input |> List.reverse |> List.filter (\( x, y, _ ) -> x /= y)
|
||||||
|
@ -724,6 +809,9 @@ port setPlaybackRate : Float -> Cmd msg
|
||||||
port setQuality : Quality.Quality -> Cmd msg
|
port setQuality : Quality.Quality -> Cmd msg
|
||||||
|
|
||||||
|
|
||||||
|
port setVolume : { volume : Float, muted : Bool } -> Cmd msg
|
||||||
|
|
||||||
|
|
||||||
port nowHasQualities : (List Int -> msg) -> Sub msg
|
port nowHasQualities : (List Int -> msg) -> Sub msg
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue