Remove DOM, adds support for thumbnails
This commit is contained in:
		
							parent
							
								
									b4705905e1
								
							
						
					
					
						commit
						638faccdb0
					
				
							
								
								
									
										1
									
								
								elm.json
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								elm.json
									
									
									
									
									
								
							| @ -6,7 +6,6 @@ | |||||||
|     "elm-version": "0.19.1", |     "elm-version": "0.19.1", | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "direct": { |         "direct": { | ||||||
|             "K-Adam/elm-dom": "1.0.0", |  | ||||||
|             "andrewMacmurray/elm-simple-animation": "2.1.0", |             "andrewMacmurray/elm-simple-animation": "2.1.0", | ||||||
|             "elm/browser": "1.0.2", |             "elm/browser": "1.0.2", | ||||||
|             "elm/core": "1.0.5", |             "elm/core": "1.0.5", | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| module Events exposing (player, seekBar, subs, video) | module Events exposing (player, seekBar, subs, video) | ||||||
| 
 | 
 | ||||||
| import Browser.Events | import Browser.Events | ||||||
| import DOM as Dom |  | ||||||
| import Element | import Element | ||||||
| import Html | import Html | ||||||
| import Html.Attributes | import Html.Attributes | ||||||
| @ -73,26 +72,29 @@ seekBar : Video -> List (Element.Attribute Video.Msg) | |||||||
| seekBar model = | seekBar model = | ||||||
|     List.map Element.htmlAttribute |     List.map Element.htmlAttribute | ||||||
|         [ Html.Events.on "click" (decodeSeek model) |         [ Html.Events.on "click" (decodeSeek model) | ||||||
|  |         , Html.Events.on "mouseenter" decodeMouseEnter | ||||||
|  |         , Html.Events.on "mouseleave" decodeMouseLeave | ||||||
|  |         , Html.Events.on "mousemove" decodeMouseEnter | ||||||
|         ] |         ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| decodeDurationChanged : Decode.Decoder Video.Msg | decodeDurationChanged : Decode.Decoder Video.Msg | ||||||
| decodeDurationChanged = | decodeDurationChanged = | ||||||
|     Dom.target <| |     Decode.field "target" <| | ||||||
|         Decode.map Video.NowHasDuration |         Decode.map Video.NowHasDuration | ||||||
|             (Decode.field "duration" Decode.float) |             (Decode.field "duration" Decode.float) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| decodePosition : Decode.Decoder Video.Msg | decodePosition : Decode.Decoder Video.Msg | ||||||
| decodePosition = | decodePosition = | ||||||
|     Dom.target <| |     Decode.field "target" <| | ||||||
|         Decode.map Video.NowAtPosition |         Decode.map Video.NowAtPosition | ||||||
|             (Decode.field "currentTime" Decode.float) |             (Decode.field "currentTime" Decode.float) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| decodeVolumeChange : Decode.Decoder Video.Msg | decodeVolumeChange : Decode.Decoder Video.Msg | ||||||
| decodeVolumeChange = | decodeVolumeChange = | ||||||
|     Dom.target <| |     Decode.field "target" <| | ||||||
|         Decode.map2 Video.NowAtVolume |         Decode.map2 Video.NowAtVolume | ||||||
|             (Decode.field "volume" Decode.float) |             (Decode.field "volume" Decode.float) | ||||||
|             (Decode.field "muted" Decode.bool) |             (Decode.field "muted" Decode.bool) | ||||||
| @ -102,15 +104,15 @@ decodeSeek : Video -> Decode.Decoder Video.Msg | |||||||
| decodeSeek model = | decodeSeek model = | ||||||
|     Decode.map2 (\x y -> Video.Seek (toFloat x / toFloat y * model.duration)) |     Decode.map2 (\x y -> Video.Seek (toFloat x / toFloat y * model.duration)) | ||||||
|         (Decode.field "layerX" Decode.int) |         (Decode.field "layerX" Decode.int) | ||||||
|         (Dom.target <| Decode.field "offsetWidth" Decode.int) |         (Decode.field "target" <| Decode.field "offsetWidth" Decode.int) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| decodeProgress : Decode.Decoder Video.Msg | decodeProgress : Decode.Decoder Video.Msg | ||||||
| decodeProgress = | decodeProgress = | ||||||
|     decodeTimeRanges |     decodeTimeRanges | ||||||
|         |> Decode.field "asArray" |         |> Decode.field "polymnyVideoAsArray" | ||||||
|         |> Decode.field "buffered" |         |> Decode.field "buffered" | ||||||
|         |> Dom.target |         |> Decode.field "target" | ||||||
|         |> Decode.map Video.NowLoaded |         |> Decode.map Video.NowLoaded | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -131,14 +133,14 @@ decodeFullscreenChange = | |||||||
|     Decode.value |     Decode.value | ||||||
|         |> Decode.nullable |         |> Decode.nullable | ||||||
|         |> Decode.field "fullscreenElement" |         |> Decode.field "fullscreenElement" | ||||||
|         |> Decode.field "document" |         |> Decode.field "polymnyVideoDocument" | ||||||
|         |> Dom.target |         |> Decode.field "target" | ||||||
|         |> Decode.map (\x -> Video.NowIsFullscreen (x /= Nothing)) |         |> Decode.map (\x -> Video.NowIsFullscreen (x /= Nothing)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| decodeVideoResize : Decode.Decoder Video.Msg | decodeVideoResize : Decode.Decoder Video.Msg | ||||||
| decodeVideoResize = | decodeVideoResize = | ||||||
|     Dom.target <| |     Decode.field "target" <| | ||||||
|         Decode.map2 (\x y -> Video.NowHasSize ( x, y )) |         Decode.map2 (\x y -> Video.NowHasSize ( x, y )) | ||||||
|             (Decode.field "videoWidth" Decode.int) |             (Decode.field "videoWidth" Decode.int) | ||||||
|             (Decode.field "videoHeight" Decode.int) |             (Decode.field "videoHeight" Decode.int) | ||||||
| @ -146,11 +148,23 @@ decodeVideoResize = | |||||||
| 
 | 
 | ||||||
| decodePlaybackRateChange : Decode.Decoder Video.Msg | decodePlaybackRateChange : Decode.Decoder Video.Msg | ||||||
| decodePlaybackRateChange = | decodePlaybackRateChange = | ||||||
|     Dom.target <| |     Decode.field "target" <| | ||||||
|         Decode.map Video.NowHasPlaybackRate |         Decode.map Video.NowHasPlaybackRate | ||||||
|             (Decode.field "playbackRate" Decode.float) |             (Decode.field "playbackRate" Decode.float) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | decodeMouseEnter : Decode.Decoder Video.Msg | ||||||
|  | decodeMouseEnter = | ||||||
|  |     Decode.map2 (\x y -> Video.NowHasMiniature (Just ( x, y ))) | ||||||
|  |         (Decode.field "offsetX" Decode.int) | ||||||
|  |         (Decode.field "target" <| Decode.field "offsetWidth" Decode.int) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | decodeMouseLeave : Decode.Decoder Video.Msg | ||||||
|  | decodeMouseLeave = | ||||||
|  |     Decode.succeed (Video.NowHasMiniature Nothing) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| decodeKeyDown : Video -> Decode.Decoder Video.Msg | decodeKeyDown : Video -> Decode.Decoder Video.Msg | ||||||
| decodeKeyDown model = | decodeKeyDown model = | ||||||
|     Decode.field "keyCode" Decode.int |     Decode.field "keyCode" Decode.int | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ module Main exposing (..) | |||||||
| 
 | 
 | ||||||
| import Browser | import Browser | ||||||
| import Browser.Events | import Browser.Events | ||||||
| import DOM as Dom |  | ||||||
| import Element exposing (Element) | import Element exposing (Element) | ||||||
| import Element.Background as Background | import Element.Background as Background | ||||||
| import Element.Border as Border | import Element.Border as Border | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ type alias Video = | |||||||
|     , showSettings : Bool |     , showSettings : Bool | ||||||
|     , subtitles : List SubtitleTrack |     , subtitles : List SubtitleTrack | ||||||
|     , subtitleTrack : Maybe SubtitleTrack |     , subtitleTrack : Maybe SubtitleTrack | ||||||
|  |     , showMiniature : Maybe ( Int, Int ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -58,6 +59,7 @@ fromUrl url = | |||||||
|     , showSettings = False |     , showSettings = False | ||||||
|     , subtitles = [] |     , subtitles = [] | ||||||
|     , subtitleTrack = Nothing |     , subtitleTrack = Nothing | ||||||
|  |     , showMiniature = Nothing | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -105,6 +107,7 @@ type Msg | |||||||
|     | NowHasPlaybackRate Float |     | NowHasPlaybackRate Float | ||||||
|     | NowHasSubtitles (List SubtitleTrack) |     | NowHasSubtitles (List SubtitleTrack) | ||||||
|     | NowHasSubtitleTrack (Maybe SubtitleTrack) |     | NowHasSubtitleTrack (Maybe SubtitleTrack) | ||||||
|  |     | NowHasMiniature (Maybe ( Int, Int )) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| update : Msg -> Video -> ( Video, Cmd Msg ) | update : Msg -> Video -> ( Video, Cmd Msg ) | ||||||
| @ -192,6 +195,9 @@ update msg model = | |||||||
|         NowHasSubtitleTrack track -> |         NowHasSubtitleTrack track -> | ||||||
|             ( { model | subtitleTrack = track }, Cmd.none ) |             ( { model | subtitleTrack = track }, Cmd.none ) | ||||||
| 
 | 
 | ||||||
|  |         NowHasMiniature miniature -> | ||||||
|  |             ( { model | showMiniature = miniature }, Cmd.none ) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| port polymnyVideoInit : String -> Cmd msg | port polymnyVideoInit : String -> Cmd msg | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -101,6 +101,60 @@ embed screenSize model = | |||||||
|                                     ) |                                     ) | ||||||
|                                     Element.none |                                     Element.none | ||||||
|                                 ) |                                 ) | ||||||
|  |                             , Element.above | ||||||
|  |                                 (case model.showMiniature of | ||||||
|  |                                     Just ( position, size ) -> | ||||||
|  |                                         let | ||||||
|  |                                             relativePosition = | ||||||
|  |                                                 toFloat position / toFloat size | ||||||
|  | 
 | ||||||
|  |                                             percentage = | ||||||
|  |                                                 String.fromFloat (relativePosition * 100) ++ "%" | ||||||
|  | 
 | ||||||
|  |                                             miniatureId = | ||||||
|  |                                                 round (relativePosition * 100) | ||||||
|  | 
 | ||||||
|  |                                             miniatureIdString = | ||||||
|  |                                                 "miniature-" ++ String.padLeft 3 '0' (String.fromInt miniatureId) ++ ".png" | ||||||
|  | 
 | ||||||
|  |                                             miniatureUrl = | ||||||
|  |                                                 model.url | ||||||
|  |                                                     |> String.split "/" | ||||||
|  |                                                     |> List.reverse | ||||||
|  |                                                     |> List.drop 1 | ||||||
|  |                                                     |> (\list -> miniatureIdString :: list) | ||||||
|  |                                                     |> List.reverse | ||||||
|  |                                                     |> String.join "/" | ||||||
|  | 
 | ||||||
|  |                                             rightPosition = | ||||||
|  |                                                 (position - 180 - 6) | ||||||
|  |                                                     |> max 0 | ||||||
|  |                                                     |> min (size - 360 - 28) | ||||||
|  |                                                     |> toFloat | ||||||
|  |                                         in | ||||||
|  |                                         Element.column | ||||||
|  |                                             [ Element.moveRight rightPosition | ||||||
|  |                                             , Element.spacing 10 | ||||||
|  |                                             ] | ||||||
|  |                                             [ Element.image | ||||||
|  |                                                 [ Border.color (Element.rgb 1 1 1) | ||||||
|  |                                                 , Border.width 2 | ||||||
|  |                                                 ] | ||||||
|  |                                                 { src = miniatureUrl, description = "miniature" } | ||||||
|  |                                             , Element.el | ||||||
|  |                                                 [ Element.centerX | ||||||
|  |                                                 , Font.shadow | ||||||
|  |                                                     { offset = ( 0, 0 ) | ||||||
|  |                                                     , blur = 4 | ||||||
|  |                                                     , color = Element.rgb 0 0 0 | ||||||
|  |                                                     } | ||||||
|  |                                                 ] | ||||||
|  |                                                 (Element.text (formatTime (relativePosition * model.duration))) | ||||||
|  |                                             ] | ||||||
|  | 
 | ||||||
|  |                                     _ -> | ||||||
|  |                                         Element.none | ||||||
|  |                                 ) | ||||||
|                             ] |                             ] | ||||||
|                             [ Element.el |                             [ Element.el | ||||||
|                                 [ Background.color (Element.rgba 1 0 0 0.75) |                                 [ Background.color (Element.rgba 1 0 0 0.75) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user