Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
e9db1724ac | |||
138433d32a | |||
a770755e67 | |||
dcfc677331 | |||
62004d9e56 | |||
e706447e42 | |||
a8cba787bc | |||
b26cc79787 | |||
ab510e4ec2 | |||
31cc8a1bb9 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,4 @@
|
||||
videos
|
||||
elm-stuff
|
||||
js/main.js
|
||||
js/main.tmp.js
|
||||
js/main.min.js
|
||||
js
|
||||
deploy.sh
|
||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "elm-video"]
|
||||
path = elm-video
|
||||
url = https://github.com/polymny/elm-video
|
4
Makefile
4
Makefile
@ -18,13 +18,13 @@ dev: js/main.js
|
||||
|
||||
release: js/main.min.js
|
||||
|
||||
js/main.js: src/**
|
||||
js/main.js: src/** elm-video/src/**
|
||||
$(ELM) make src/Main.elm --output $(BUILD_DIR)/main.js
|
||||
|
||||
js/main.min.js: js/main.tmp.js
|
||||
@$(UGLIFYJS) $(BUILD_DIR)/main.tmp.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle > $(BUILD_DIR)/main.min.js
|
||||
|
||||
js/main.tmp.js: src/**
|
||||
js/main.tmp.js: src/** elm-video/src/**
|
||||
@$(ELM) make src/Main.elm --optimize --output $(BUILD_DIR)/main.tmp.js
|
||||
|
||||
watch:
|
||||
|
@ -1,78 +0,0 @@
|
||||
.lds-spinner {
|
||||
color: official;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.lds-spinner div {
|
||||
transform-origin: 40px 40px;
|
||||
animation: lds-spinner 1.2s linear infinite;
|
||||
}
|
||||
.lds-spinner div:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 37px;
|
||||
width: 6px;
|
||||
height: 18px;
|
||||
border-radius: 20%;
|
||||
background: #cef;
|
||||
}
|
||||
.lds-spinner div:nth-child(1) {
|
||||
transform: rotate(0deg);
|
||||
animation-delay: -1.1s;
|
||||
}
|
||||
.lds-spinner div:nth-child(2) {
|
||||
transform: rotate(30deg);
|
||||
animation-delay: -1s;
|
||||
}
|
||||
.lds-spinner div:nth-child(3) {
|
||||
transform: rotate(60deg);
|
||||
animation-delay: -0.9s;
|
||||
}
|
||||
.lds-spinner div:nth-child(4) {
|
||||
transform: rotate(90deg);
|
||||
animation-delay: -0.8s;
|
||||
}
|
||||
.lds-spinner div:nth-child(5) {
|
||||
transform: rotate(120deg);
|
||||
animation-delay: -0.7s;
|
||||
}
|
||||
.lds-spinner div:nth-child(6) {
|
||||
transform: rotate(150deg);
|
||||
animation-delay: -0.6s;
|
||||
}
|
||||
.lds-spinner div:nth-child(7) {
|
||||
transform: rotate(180deg);
|
||||
animation-delay: -0.5s;
|
||||
}
|
||||
.lds-spinner div:nth-child(8) {
|
||||
transform: rotate(210deg);
|
||||
animation-delay: -0.4s;
|
||||
}
|
||||
.lds-spinner div:nth-child(9) {
|
||||
transform: rotate(240deg);
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
.lds-spinner div:nth-child(10) {
|
||||
transform: rotate(270deg);
|
||||
animation-delay: -0.2s;
|
||||
}
|
||||
.lds-spinner div:nth-child(11) {
|
||||
transform: rotate(300deg);
|
||||
animation-delay: -0.1s;
|
||||
}
|
||||
.lds-spinner div:nth-child(12) {
|
||||
transform: rotate(330deg);
|
||||
animation-delay: 0s;
|
||||
}
|
||||
@keyframes lds-spinner {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
1664
css/video-js.css
1664
css/video-js.css
File diff suppressed because one or more lines are too long
1
elm-video
Submodule
1
elm-video
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 4193ac975dbde45010664be1f8595451fc86c418
|
8
elm.json
8
elm.json
@ -1,25 +1,29 @@
|
||||
{
|
||||
"type": "application",
|
||||
"source-directories": [
|
||||
"src"
|
||||
"src",
|
||||
"elm-video/src"
|
||||
],
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"STTR13/ziplist": "1.3.0",
|
||||
"andrewMacmurray/elm-simple-animation": "2.1.0",
|
||||
"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/svg": "1.0.1",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/url": "1.0.0",
|
||||
"icidasset/elm-material-icons": "9.0.0",
|
||||
"jims/html-parser": "1.0.0",
|
||||
"justinmimbs/timezone-data": "3.0.3",
|
||||
"mdgriffith/elm-ui": "1.1.8",
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.1.3"
|
||||
},
|
||||
"indirect": {
|
||||
"avh4/elm-color": "1.0.0",
|
||||
"elm/bytes": "1.0.8",
|
||||
"elm/file": "1.0.5",
|
||||
"elm/parser": "1.1.0",
|
||||
|
24
embed.html
Normal file
24
embed.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!doctype HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>twitch.tforgione.fr</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/ico" href="favicon.ico"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="js/polymny-video-full.min.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script>
|
||||
PolymnyVideo.fullpage({
|
||||
node: document.getElementById('container'),
|
||||
url: "videos/" + PolymnyVideo.getArgumentFromUrl("v") + "/manifest.m3u8",
|
||||
autoplay: true,
|
||||
startTime: PolymnyVideo.getArgumentFromUrl("t"),
|
||||
enableMiniatures: true,
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
32
index.html
32
index.html
@ -4,13 +4,11 @@
|
||||
<title>twitch.tforgione.fr</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/ico" href="/favicon.ico"/>
|
||||
<link href="css/video-js.css" rel="stylesheet">
|
||||
<link href="css/spinner.css" rel="stylesheet">
|
||||
<link rel="icon" type="image/ico" href="favicon.ico"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="js/vd.js"></script>
|
||||
<script src="js/polymny-video-elm.min.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script>
|
||||
function isDarkMode(e) {
|
||||
@ -33,34 +31,14 @@
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
darkMode: isDarkMode(),
|
||||
darkSetting: JSON.parse(localStorage.getItem('darkMode'))
|
||||
darkSetting: JSON.parse(localStorage.getItem('darkMode')),
|
||||
mobile: PolymnyVideo.isDeviceMobile(),
|
||||
}
|
||||
});
|
||||
|
||||
var lastId, player;
|
||||
PolymnyVideo.setup(app);
|
||||
|
||||
if (app.ports !== undefined) {
|
||||
if (app.ports.registerVideo !== undefined) {
|
||||
app.ports.registerVideo.subscribe(function(args) {
|
||||
window.scrollTo(0, 0);
|
||||
var time = vd.parseTime(args[2]) || undefined;
|
||||
|
||||
requestAnimationFrame(function() {
|
||||
if (args[0] !== lastId) {
|
||||
lastId = args[0];
|
||||
|
||||
player = vd.setup(args[0], {
|
||||
v: args[1] + "/manifest.m3u8",
|
||||
t: time,
|
||||
focus: true
|
||||
});
|
||||
} else if (time !== undefined ){
|
||||
player.currentTime(time);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (app.ports.setDarkMode !== undefined) {
|
||||
app.ports.setDarkMode.subscribe(function(arg) {
|
||||
if (arg === null) {
|
||||
|
@ -1,24 +1,12 @@
|
||||
module Consts exposing
|
||||
( homeFontSize
|
||||
, homePadding
|
||||
, name
|
||||
, normalFontSize
|
||||
, titleFontSize
|
||||
, url
|
||||
, videoId
|
||||
)
|
||||
|
||||
|
||||
url : String
|
||||
url =
|
||||
"twitch.tforgione.fr"
|
||||
|
||||
|
||||
name : String
|
||||
name =
|
||||
url
|
||||
|
||||
|
||||
normalFontSize : Int
|
||||
normalFontSize =
|
||||
13
|
||||
|
104
src/Core.elm
104
src/Core.elm
@ -13,10 +13,13 @@ import Time
|
||||
import TimeZone
|
||||
import Twitch
|
||||
import Url
|
||||
import Video
|
||||
import Video.Events
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ playlists : List Twitch.Playlist
|
||||
{ title : String
|
||||
, playlists : List Twitch.Playlist
|
||||
, zone : Time.Zone
|
||||
, page : Page
|
||||
, key : Nav.Key
|
||||
@ -26,13 +29,15 @@ type alias Model =
|
||||
, url : Url.Url
|
||||
, darkMode : Bool
|
||||
, darkSetting : Maybe Bool
|
||||
, reverseVideos : Bool
|
||||
, mobile : Bool
|
||||
}
|
||||
|
||||
|
||||
type Page
|
||||
= Home (Maybe (Hover Twitch.Playlist))
|
||||
| Playlist Twitch.Playlist (Maybe (Hover Twitch.Video))
|
||||
| Video Twitch.Playlist Twitch.Video (Maybe (Hover Twitch.Video))
|
||||
| Video Twitch.Playlist Twitch.Video Video.Video (Maybe (Hover Twitch.Video))
|
||||
|
||||
|
||||
type Msg
|
||||
@ -53,11 +58,24 @@ type Msg
|
||||
| CurrentDateReceived Time.Posix
|
||||
| DarkMode Bool
|
||||
| DarkModeClicked
|
||||
| VideoMsg Video.Msg
|
||||
|
||||
|
||||
init : { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
|
||||
init { width, height, darkMode, darkSetting } url key =
|
||||
init :
|
||||
{ title : Maybe String
|
||||
, width : Int
|
||||
, height : Int
|
||||
, darkMode : Bool
|
||||
, darkSetting : Maybe Bool
|
||||
, reverseVideos : Maybe Bool
|
||||
, mobile : Maybe Bool
|
||||
}
|
||||
-> Url.Url
|
||||
-> Nav.Key
|
||||
-> ( Model, Cmd Msg )
|
||||
init { title, width, height, darkMode, darkSetting, reverseVideos, mobile } url key =
|
||||
( Model
|
||||
(Maybe.withDefault "elm-video-example" title)
|
||||
[]
|
||||
Time.utc
|
||||
(Home Nothing)
|
||||
@ -68,6 +86,8 @@ init { width, height, darkMode, darkSetting } url key =
|
||||
url
|
||||
darkMode
|
||||
darkSetting
|
||||
(Maybe.withDefault False reverseVideos)
|
||||
(Maybe.withDefault False mobile)
|
||||
, Cmd.batch
|
||||
[ Task.attempt TimeZoneReceivedResult TimeZone.getZone
|
||||
, Task.perform CurrentDateReceived Time.now
|
||||
@ -87,11 +107,19 @@ resultToMsg result =
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
subscriptions model =
|
||||
Sub.batch
|
||||
[ Events.onResize (\w h -> SizeReceived w h)
|
||||
, Time.every 200 TimeReceived
|
||||
, Ports.darkMode DarkMode
|
||||
, Sub.map VideoMsg
|
||||
(case model.page of
|
||||
Video _ _ v _ ->
|
||||
Video.Events.subs v
|
||||
|
||||
_ ->
|
||||
Sub.none
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@ -129,8 +157,8 @@ update msg model =
|
||||
Playlist p Nothing ->
|
||||
( { model | page = Playlist p (Just (Hover.hover hover model.time)) }, Cmd.none )
|
||||
|
||||
Video p v Nothing ->
|
||||
( { model | page = Video p v (Just (Hover.hover v model.time)) }, Cmd.none )
|
||||
Video p v x Nothing ->
|
||||
( { model | page = Video p v x (Just (Hover.hover hover model.time)) }, Cmd.none )
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
@ -143,8 +171,8 @@ update msg model =
|
||||
Playlist p _ ->
|
||||
( { model | page = Playlist p Nothing }, Cmd.none )
|
||||
|
||||
Video p v _ ->
|
||||
( { model | page = Video p v Nothing }, Cmd.none )
|
||||
Video p v x _ ->
|
||||
( { model | page = Video p v x Nothing }, Cmd.none )
|
||||
|
||||
SizeReceived w h ->
|
||||
( { model | device = Element.classifyDevice { width = w, height = h } }
|
||||
@ -152,9 +180,18 @@ update msg model =
|
||||
)
|
||||
|
||||
PlaylistsReceived playlists ->
|
||||
let
|
||||
sortedPlaylists =
|
||||
if model.reverseVideos then
|
||||
List.reverse playlists
|
||||
|> List.map (\x -> { x | videos = List.reverse x.videos })
|
||||
|
||||
else
|
||||
playlists
|
||||
in
|
||||
update
|
||||
(UrlReceived model.url)
|
||||
{ model | playlists = playlists, page = Home Nothing }
|
||||
{ model | playlists = sortedPlaylists, page = Home Nothing }
|
||||
|
||||
HomeClicked ->
|
||||
( model
|
||||
@ -234,25 +271,32 @@ update msg model =
|
||||
( page, cmd ) =
|
||||
case ( playlist, video ) of
|
||||
( Just p, Just v ) ->
|
||||
( Video p v Nothing
|
||||
, Ports.registerVideo ( Twitch.videoId v, "videos/" ++ p.url ++ v.url, time )
|
||||
)
|
||||
let
|
||||
( rawVideo, videoCommand ) =
|
||||
Video.fromConfig
|
||||
{ url = "/videos/" ++ p.url ++ v.url ++ "/manifest.m3u8"
|
||||
, id = "video"
|
||||
, autoplay = True
|
||||
, enableMiniatures = True
|
||||
, startTime = time
|
||||
, customElement = Nothing
|
||||
, live = Just False
|
||||
, miniaturesUrl = Nothing
|
||||
, muted = False
|
||||
}
|
||||
|
||||
el =
|
||||
{ rawVideo | mobile = model.mobile }
|
||||
in
|
||||
( Video p v el Nothing, Cmd.map VideoMsg videoCommand )
|
||||
|
||||
( Just p, Nothing ) ->
|
||||
( Playlist p Nothing, Cmd.none )
|
||||
|
||||
_ ->
|
||||
( Home Nothing, Cmd.none )
|
||||
|
||||
extraCmd =
|
||||
case page of
|
||||
Video _ _ _ ->
|
||||
Cmd.none
|
||||
|
||||
_ ->
|
||||
Ports.eraseVideo ()
|
||||
in
|
||||
( { model | page = page }, Cmd.batch [ cmd, extraCmd ] )
|
||||
( { model | page = page }, cmd )
|
||||
|
||||
UrlRequested u ->
|
||||
case u of
|
||||
@ -265,6 +309,22 @@ update msg model =
|
||||
DarkMode dark ->
|
||||
( { model | darkMode = dark }, Cmd.none )
|
||||
|
||||
VideoMsg vMsg ->
|
||||
let
|
||||
( newPage, newCommand ) =
|
||||
case model.page of
|
||||
Video a b v c ->
|
||||
let
|
||||
( newVideo, cmd ) =
|
||||
Video.update vMsg v
|
||||
in
|
||||
( Video a b newVideo c, cmd )
|
||||
|
||||
_ ->
|
||||
( model.page, Cmd.none )
|
||||
in
|
||||
( { model | page = newPage }, Cmd.map VideoMsg newCommand )
|
||||
|
||||
|
||||
splitter : String -> Maybe ( String, String )
|
||||
splitter input =
|
||||
|
13
src/Main.elm
13
src/Main.elm
@ -5,7 +5,18 @@ import Core
|
||||
import Views
|
||||
|
||||
|
||||
main : Program { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } Core.Model Core.Msg
|
||||
main :
|
||||
Program
|
||||
{ title : Maybe String
|
||||
, width : Int
|
||||
, height : Int
|
||||
, darkMode : Bool
|
||||
, darkSetting : Maybe Bool
|
||||
, reverseVideos : Maybe Bool
|
||||
, mobile : Maybe Bool
|
||||
}
|
||||
Core.Model
|
||||
Core.Msg
|
||||
main =
|
||||
Browser.application
|
||||
{ init = Core.init
|
||||
|
@ -1,10 +1,4 @@
|
||||
port module Ports exposing (darkMode, eraseVideo, registerVideo, setDarkMode)
|
||||
|
||||
|
||||
port registerVideo : ( String, String, Maybe String ) -> Cmd msg
|
||||
|
||||
|
||||
port eraseVideo : () -> Cmd msg
|
||||
port module Ports exposing (darkMode, setDarkMode)
|
||||
|
||||
|
||||
port setDarkMode : Maybe Bool -> Cmd msg
|
||||
|
@ -46,12 +46,12 @@ decodePlaylist =
|
||||
Decode.map3 Playlist
|
||||
(Decode.field "url" Decode.string)
|
||||
(Decode.field "title" Decode.string)
|
||||
(Decode.field "videos" (Decode.map (List.sortBy .url >> List.reverse) (Decode.list decodeVideo)))
|
||||
(Decode.field "videos" (Decode.map (List.sortBy .url) (Decode.list decodeVideo)))
|
||||
|
||||
|
||||
decodePlaylists : Decode.Decoder (List Playlist)
|
||||
decodePlaylists =
|
||||
Decode.map (sortPlaylists >> List.reverse) (Decode.list decodePlaylist)
|
||||
Decode.map sortPlaylists (Decode.list decodePlaylist)
|
||||
|
||||
|
||||
mostRecentVideo : List Video -> Maybe Time.Posix
|
||||
|
116
src/Views.elm
116
src/Views.elm
@ -12,13 +12,13 @@ import Element.Font as Font
|
||||
import Element.Input as Input
|
||||
import Element.Keyed as Keyed
|
||||
import Hover exposing (Hover)
|
||||
import Html
|
||||
import Html.Attributes
|
||||
import Json.Encode as Encode
|
||||
import Time
|
||||
import TimeUtils
|
||||
import Twitch
|
||||
import Ui
|
||||
import Video
|
||||
import Video.Views
|
||||
|
||||
|
||||
view : Core.Model -> Browser.Document Core.Msg
|
||||
@ -42,7 +42,7 @@ view model =
|
||||
]
|
||||
(Element.column
|
||||
[ Element.width Element.fill, Element.height Element.fill ]
|
||||
[ topBar model.darkSetting, element ]
|
||||
[ topBar model.title model.darkSetting, element ]
|
||||
)
|
||||
]
|
||||
}
|
||||
@ -52,13 +52,13 @@ title : Core.Model -> String
|
||||
title model =
|
||||
case model.page of
|
||||
Core.Home _ ->
|
||||
Consts.url
|
||||
model.title
|
||||
|
||||
Core.Playlist p _ ->
|
||||
Consts.url ++ " - " ++ p.name
|
||||
model.title ++ " - " ++ p.name
|
||||
|
||||
Core.Video p v _ ->
|
||||
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
|
||||
Core.Video p v _ _ ->
|
||||
model.title ++ " - " ++ p.name ++ " - " ++ v.name
|
||||
|
||||
|
||||
viewContent : Core.Model -> Element Core.Msg
|
||||
@ -70,19 +70,19 @@ viewContent model =
|
||||
Core.Playlist playlist hover ->
|
||||
videoMiniaturesView model.darkMode model.device model.zone model.currentDate model.time hover playlist
|
||||
|
||||
Core.Video playlist video hover ->
|
||||
videoView model.darkMode model.device model.zone model.currentDate model.time hover playlist video
|
||||
Core.Video playlist video v hover ->
|
||||
videoView model.darkMode model.device model.zone model.currentDate model.time hover playlist video v
|
||||
|
||||
|
||||
topBar : Maybe Bool -> Element Core.Msg
|
||||
topBar darkSetting =
|
||||
topBar : String -> Maybe Bool -> Element Core.Msg
|
||||
topBar pageTitle darkSetting =
|
||||
Element.row
|
||||
[ Element.width Element.fill
|
||||
, Background.color Colors.primary
|
||||
, Font.color Colors.white
|
||||
, Font.size Consts.homeFontSize
|
||||
]
|
||||
[ homeButton, mode darkSetting ]
|
||||
[ homeButton pageTitle, mode darkSetting ]
|
||||
|
||||
|
||||
mode : Maybe Bool -> Element Core.Msg
|
||||
@ -110,13 +110,13 @@ mode current =
|
||||
}
|
||||
|
||||
|
||||
homeButton : Element Core.Msg
|
||||
homeButton =
|
||||
homeButton : String -> Element Core.Msg
|
||||
homeButton pageTitle =
|
||||
Ui.link
|
||||
[ Element.height Element.fill
|
||||
, Font.bold
|
||||
]
|
||||
{ label = Element.el [ Element.padding 10 ] (Element.text Consts.name)
|
||||
{ label = Element.el [ Element.padding 10 ] (Element.text pageTitle)
|
||||
, url = "/"
|
||||
}
|
||||
|
||||
@ -293,8 +293,6 @@ videoMiniature currentDate time hover playlist video =
|
||||
, Element.height (Element.px 0)
|
||||
, Element.htmlAttribute (Html.Attributes.style "padding-top" "56.25%")
|
||||
, Element.htmlAttribute (Html.Attributes.style "position" "relative")
|
||||
, Events.onMouseEnter (Core.HoverVideo video)
|
||||
, Events.onMouseLeave Core.Unhover
|
||||
]
|
||||
( key
|
||||
, Element.image
|
||||
@ -318,9 +316,14 @@ videoMiniatureView : Bool -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hov
|
||||
videoMiniatureView darkMode zone currentDate time hover playlist video =
|
||||
let
|
||||
display =
|
||||
Element.column [ Element.width Element.fill, Element.spacing 10 ]
|
||||
Element.column
|
||||
[ Element.width Element.fill
|
||||
, Element.spacing 10
|
||||
, Events.onMouseEnter (Core.HoverVideo video)
|
||||
, Events.onMouseLeave Core.Unhover
|
||||
]
|
||||
[ videoMiniature currentDate time hover playlist video
|
||||
, videoDescription darkMode zone video
|
||||
, videoDate darkMode zone video
|
||||
]
|
||||
|
||||
button =
|
||||
@ -336,11 +339,16 @@ videoInList : Bool -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twit
|
||||
videoInList darkMode zone currentDate time hover playlist activeVideo video =
|
||||
let
|
||||
label =
|
||||
Element.row [ Element.width Element.fill, Element.spacing 10 ]
|
||||
Element.row
|
||||
[ Element.width Element.fill
|
||||
, Element.spacing 10
|
||||
, Events.onMouseEnter (Core.HoverVideo video)
|
||||
, Events.onMouseLeave Core.Unhover
|
||||
]
|
||||
[ Element.el [ Element.width (Element.fillPortion 2) ]
|
||||
(videoMiniature currentDate time hover playlist video)
|
||||
, Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ]
|
||||
(videoDescription darkMode zone video)
|
||||
(videoDate darkMode zone video)
|
||||
]
|
||||
in
|
||||
if video == activeVideo then
|
||||
@ -359,8 +367,8 @@ videoInList darkMode zone currentDate time hover playlist activeVideo video =
|
||||
}
|
||||
|
||||
|
||||
videoView : Bool -> Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Element Core.Msg
|
||||
videoView darkMode device zone currentDate time hover playlist video =
|
||||
videoView : Bool -> Element.Device -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hover Twitch.Video) -> Twitch.Playlist -> Twitch.Video -> Video.Video -> Element Core.Msg
|
||||
videoView darkMode device zone currentDate time hover playlist video v =
|
||||
let
|
||||
( builder, contentPadding ) =
|
||||
case device.class of
|
||||
@ -379,31 +387,8 @@ videoView darkMode device zone currentDate time hover playlist video =
|
||||
[ Element.width (Element.fillPortion 2)
|
||||
, Element.spacing 10
|
||||
, Element.alignTop
|
||||
, Element.height Element.fill
|
||||
]
|
||||
[ Keyed.el
|
||||
[ Element.width Element.fill
|
||||
, Element.height (Element.px 0)
|
||||
, Element.htmlAttribute (Html.Attributes.style "padding-top" "56.25%")
|
||||
, Element.htmlAttribute (Html.Attributes.style "position" "relative")
|
||||
]
|
||||
( video.url
|
||||
, Element.html
|
||||
(Html.video
|
||||
[ Html.Attributes.id (Twitch.videoId video)
|
||||
, Html.Attributes.class "video-js"
|
||||
, Html.Attributes.class "vjs-default-skin"
|
||||
, Html.Attributes.class "wf"
|
||||
, Html.Attributes.property "data-setup" (Encode.string "{\"fluid\": true}")
|
||||
, Html.Attributes.style "position" "absolute"
|
||||
, Html.Attributes.style "top" "0"
|
||||
, Html.Attributes.style "height" "100%"
|
||||
, Html.Attributes.controls True
|
||||
, Html.Attributes.autoplay True
|
||||
]
|
||||
[]
|
||||
)
|
||||
)
|
||||
[ Video.Views.embedElement v |> Element.map Core.VideoMsg
|
||||
, Element.paragraph
|
||||
[ Font.size Consts.homeFontSize
|
||||
, Font.bold
|
||||
@ -431,8 +416,8 @@ videoView darkMode device zone currentDate time hover playlist video =
|
||||
]
|
||||
|
||||
|
||||
videoDescription : Bool -> Time.Zone -> Twitch.Video -> Element Core.Msg
|
||||
videoDescription darkMode zone video =
|
||||
videoDate : Bool -> Time.Zone -> Twitch.Video -> Element Core.Msg
|
||||
videoDate darkMode zone video =
|
||||
Element.column [ Element.spacing 10 ]
|
||||
[ Element.paragraph
|
||||
[ Font.bold
|
||||
@ -501,11 +486,17 @@ formatTime time =
|
||||
else
|
||||
String.fromInt seconds
|
||||
in
|
||||
hoursString
|
||||
++ ":"
|
||||
++ minutesString
|
||||
++ ":"
|
||||
++ secondsString
|
||||
if hours >= 1 then
|
||||
hoursString
|
||||
++ ":"
|
||||
++ minutesString
|
||||
++ ":"
|
||||
++ secondsString
|
||||
|
||||
else
|
||||
minutesString
|
||||
++ ":"
|
||||
++ secondsString
|
||||
|
||||
|
||||
toHours : Int -> Int
|
||||
@ -577,22 +568,7 @@ groupAux size list acc =
|
||||
|
||||
spinner : Element Core.Msg
|
||||
spinner =
|
||||
Element.html
|
||||
(Html.div [ Html.Attributes.class "lds-spinner" ]
|
||||
[ Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
, Html.div [] []
|
||||
]
|
||||
)
|
||||
Element.none
|
||||
|
||||
|
||||
newBadge : Element Core.Msg
|
||||
|
Loading…
x
Reference in New Issue
Block a user