Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Thomas Forgione | 138433d32a | |
Thomas Forgione | a770755e67 | |
Thomas Forgione | dcfc677331 | |
Thomas Forgione | 62004d9e56 | |
Thomas Forgione | e706447e42 | |
Thomas Forgione | a8cba787bc | |
Thomas Forgione | b26cc79787 | |
Thomas Forgione | ab510e4ec2 | |
Thomas Forgione | 31cc8a1bb9 |
|
@ -1,6 +1,4 @@
|
||||||
videos
|
videos
|
||||||
elm-stuff
|
elm-stuff
|
||||||
js/main.js
|
js
|
||||||
js/main.tmp.js
|
|
||||||
js/main.min.js
|
|
||||||
deploy.sh
|
deploy.sh
|
||||||
|
|
|
@ -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
|
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
|
$(ELM) make src/Main.elm --output $(BUILD_DIR)/main.js
|
||||||
|
|
||||||
js/main.min.js: js/main.tmp.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
|
@$(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
|
@$(ELM) make src/Main.elm --optimize --output $(BUILD_DIR)/main.tmp.js
|
||||||
|
|
||||||
watch:
|
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
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 087c3d594b62b6617954fc31a58576f12752d75a
|
8
elm.json
8
elm.json
|
@ -1,25 +1,29 @@
|
||||||
{
|
{
|
||||||
"type": "application",
|
"type": "application",
|
||||||
"source-directories": [
|
"source-directories": [
|
||||||
"src"
|
"src",
|
||||||
|
"elm-video/src"
|
||||||
],
|
],
|
||||||
"elm-version": "0.19.1",
|
"elm-version": "0.19.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
"STTR13/ziplist": "1.3.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",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
"elm/http": "2.0.0",
|
"elm/http": "2.0.0",
|
||||||
"elm/json": "1.1.3",
|
"elm/json": "1.1.3",
|
||||||
|
"elm/svg": "1.0.1",
|
||||||
"elm/time": "1.0.0",
|
"elm/time": "1.0.0",
|
||||||
"elm/url": "1.0.0",
|
"elm/url": "1.0.0",
|
||||||
|
"icidasset/elm-material-icons": "9.0.0",
|
||||||
"jims/html-parser": "1.0.0",
|
"jims/html-parser": "1.0.0",
|
||||||
"justinmimbs/timezone-data": "3.0.3",
|
"justinmimbs/timezone-data": "3.0.3",
|
||||||
"mdgriffith/elm-ui": "1.1.8",
|
"mdgriffith/elm-ui": "1.1.8",
|
||||||
"rtfeldman/elm-iso8601-date-strings": "1.1.3"
|
"rtfeldman/elm-iso8601-date-strings": "1.1.3"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
|
"avh4/elm-color": "1.0.0",
|
||||||
"elm/bytes": "1.0.8",
|
"elm/bytes": "1.0.8",
|
||||||
"elm/file": "1.0.5",
|
"elm/file": "1.0.5",
|
||||||
"elm/parser": "1.1.0",
|
"elm/parser": "1.1.0",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
100
index.html
100
index.html
|
@ -4,91 +4,13 @@
|
||||||
<title>twitch.tforgione.fr</title>
|
<title>twitch.tforgione.fr</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/ico" href="/favicon.ico"/>
|
<link rel="icon" type="image/ico" href="favicon.ico"/>
|
||||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.6.7/plyr.css" />
|
|
||||||
<link href="css/spinner.css" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
video, .plyr, .plyr__video-wrapper {
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<script src="https://cdn.plyr.io/3.6.7/plyr.polyfilled.js"></script>
|
<script src="js/polymny-video-elm.min.js"></script>
|
||||||
<script src="https://cdn.rawgit.com/video-dev/hls.js/18bb552/dist/hls.min.js"></script>
|
|
||||||
<script src="js/main.js"></script>
|
<script src="js/main.js"></script>
|
||||||
<script>
|
<script>
|
||||||
customElements.define('plyr-video',
|
|
||||||
class PlyrVideo extends HTMLElement {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.videoElement = document.createElement('video');
|
|
||||||
this.videoElement.setAttribute('controls', 'true');
|
|
||||||
}
|
|
||||||
|
|
||||||
static get observedAttributes() { return []; }
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
this.appendChild(this.videoElement)
|
|
||||||
|
|
||||||
const hls = new Hls();
|
|
||||||
hls.loadSource(this.getAttribute('src'));
|
|
||||||
|
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
|
|
||||||
|
|
||||||
// Transform available levels into an array of integers (height values).
|
|
||||||
const availableQualities = hls.levels.map((l) => l.height);
|
|
||||||
availableQualities.unshift(0);
|
|
||||||
|
|
||||||
// Initialize here
|
|
||||||
new Plyr(this.videoElement, {
|
|
||||||
quality: {
|
|
||||||
default: 0,
|
|
||||||
options: availableQualities,
|
|
||||||
// this ensures Plyr to use Hls to update quality level
|
|
||||||
forced: true,
|
|
||||||
onChange: updateQuality,
|
|
||||||
debug: true,
|
|
||||||
},
|
|
||||||
fullscreen: {
|
|
||||||
enabled: true,
|
|
||||||
fallback: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
hls.on(Hls.Events.LEVEL_SWITCHED, function (event, data) {
|
|
||||||
var span = document.querySelector(".plyr__menu__container [data-plyr='quality'][value='0'] span");
|
|
||||||
if (hls.autoLevelEnabled) {
|
|
||||||
span.innerHTML = "Auto (" + hls.levels[data.level].height + "p)";
|
|
||||||
} else {
|
|
||||||
span.innerHTML = "Auto";
|
|
||||||
}
|
|
||||||
var x = document.querySelectorAll(".plyr__menu__container [data-plyr='settings'] span")[3];
|
|
||||||
if (x.innerHTML.startsWith("Auto") || x.innerHTML === "0p") {
|
|
||||||
x.innerHTML = span.innerHTML;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
hls.attachMedia(this.videoElement);
|
|
||||||
|
|
||||||
function updateQuality(newQuality) {
|
|
||||||
if (newQuality === 0) {
|
|
||||||
hls.currentLevel = -1;
|
|
||||||
} else {
|
|
||||||
hls.levels.forEach((level, levelIndex) => {
|
|
||||||
if (level.height === newQuality) {
|
|
||||||
hls.currentLevel = levelIndex;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function isDarkMode(e) {
|
function isDarkMode(e) {
|
||||||
var darkMode = JSON.parse(localStorage.getItem('darkMode'));
|
var darkMode = JSON.parse(localStorage.getItem('darkMode'));
|
||||||
|
|
||||||
|
@ -113,7 +35,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var lastId;
|
PolymnyVideo.setup(app);
|
||||||
|
|
||||||
if (app.ports !== undefined) {
|
if (app.ports !== undefined) {
|
||||||
if (app.ports.setDarkMode !== undefined) {
|
if (app.ports.setDarkMode !== undefined) {
|
||||||
|
@ -128,9 +50,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
if (app.ports !== undefined) {
|
||||||
app.ports.darkMode.send(isDarkMode(e));
|
if (app.ports.eraseVideo !== undefined) {
|
||||||
});
|
app.ports.eraseVideo.subscribe(function() {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
lastId = undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
||||||
|
app.ports.darkMode.send(isDarkMode(e));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
63
src/Core.elm
63
src/Core.elm
|
@ -13,6 +13,8 @@ import Time
|
||||||
import TimeZone
|
import TimeZone
|
||||||
import Twitch
|
import Twitch
|
||||||
import Url
|
import Url
|
||||||
|
import Video
|
||||||
|
import Video.Events
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
|
@ -32,7 +34,7 @@ type alias Model =
|
||||||
type Page
|
type Page
|
||||||
= Home (Maybe (Hover Twitch.Playlist))
|
= Home (Maybe (Hover Twitch.Playlist))
|
||||||
| Playlist Twitch.Playlist (Maybe (Hover Twitch.Video))
|
| 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
|
type Msg
|
||||||
|
@ -53,6 +55,7 @@ type Msg
|
||||||
| CurrentDateReceived Time.Posix
|
| CurrentDateReceived Time.Posix
|
||||||
| DarkMode Bool
|
| DarkMode Bool
|
||||||
| DarkModeClicked
|
| DarkModeClicked
|
||||||
|
| VideoMsg Video.Msg
|
||||||
|
|
||||||
|
|
||||||
init : { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
|
init : { width : Int, height : Int, darkMode : Bool, darkSetting : Maybe Bool } -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
|
||||||
|
@ -87,11 +90,19 @@ resultToMsg result =
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions _ =
|
subscriptions model =
|
||||||
Sub.batch
|
Sub.batch
|
||||||
[ Events.onResize (\w h -> SizeReceived w h)
|
[ Events.onResize (\w h -> SizeReceived w h)
|
||||||
, Time.every 200 TimeReceived
|
, Time.every 200 TimeReceived
|
||||||
, Ports.darkMode DarkMode
|
, Ports.darkMode DarkMode
|
||||||
|
, Sub.map VideoMsg
|
||||||
|
(case model.page of
|
||||||
|
Video _ _ v _ ->
|
||||||
|
Video.Events.subs v
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Sub.none
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,8 +140,8 @@ update msg model =
|
||||||
Playlist p Nothing ->
|
Playlist p Nothing ->
|
||||||
( { model | page = Playlist p (Just (Hover.hover hover model.time)) }, Cmd.none )
|
( { model | page = Playlist p (Just (Hover.hover hover model.time)) }, Cmd.none )
|
||||||
|
|
||||||
Video p v Nothing ->
|
Video p v x Nothing ->
|
||||||
( { model | page = Video p v (Just (Hover.hover v model.time)) }, Cmd.none )
|
( { model | page = Video p v x (Just (Hover.hover hover model.time)) }, Cmd.none )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
@ -143,8 +154,8 @@ update msg model =
|
||||||
Playlist p _ ->
|
Playlist p _ ->
|
||||||
( { model | page = Playlist p Nothing }, Cmd.none )
|
( { model | page = Playlist p Nothing }, Cmd.none )
|
||||||
|
|
||||||
Video p v _ ->
|
Video p v x _ ->
|
||||||
( { model | page = Video p v Nothing }, Cmd.none )
|
( { model | page = Video p v x Nothing }, Cmd.none )
|
||||||
|
|
||||||
SizeReceived w h ->
|
SizeReceived w h ->
|
||||||
( { model | device = Element.classifyDevice { width = w, height = h } }
|
( { model | device = Element.classifyDevice { width = w, height = h } }
|
||||||
|
@ -231,18 +242,32 @@ update msg model =
|
||||||
_ ->
|
_ ->
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
page =
|
( page, cmd ) =
|
||||||
case ( playlist, video ) of
|
case ( playlist, video ) of
|
||||||
( Just p, Just v ) ->
|
( Just p, Just v ) ->
|
||||||
Video p v Nothing
|
let
|
||||||
|
( el, 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
|
||||||
|
}
|
||||||
|
in
|
||||||
|
( Video p v el Nothing, Cmd.map VideoMsg videoCommand )
|
||||||
|
|
||||||
( Just p, Nothing ) ->
|
( Just p, Nothing ) ->
|
||||||
Playlist p Nothing
|
( Playlist p Nothing, Cmd.none )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
Home Nothing
|
( Home Nothing, Cmd.none )
|
||||||
in
|
in
|
||||||
( { model | page = page }, Cmd.none )
|
( { model | page = page }, cmd )
|
||||||
|
|
||||||
UrlRequested u ->
|
UrlRequested u ->
|
||||||
case u of
|
case u of
|
||||||
|
@ -255,6 +280,22 @@ update msg model =
|
||||||
DarkMode dark ->
|
DarkMode dark ->
|
||||||
( { model | darkMode = dark }, Cmd.none )
|
( { 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 : String -> Maybe ( String, String )
|
||||||
splitter input =
|
splitter input =
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
port module Ports exposing (darkMode, eraseVideo, registerVideo, setDarkMode)
|
port module Ports exposing (darkMode, setDarkMode)
|
||||||
|
|
||||||
|
|
||||||
port registerVideo : ( String, String, Maybe String ) -> Cmd msg
|
|
||||||
|
|
||||||
|
|
||||||
port eraseVideo : () -> Cmd msg
|
|
||||||
|
|
||||||
|
|
||||||
port setDarkMode : Maybe Bool -> Cmd msg
|
port setDarkMode : Maybe Bool -> Cmd msg
|
||||||
|
|
|
@ -12,13 +12,13 @@ import Element.Font as Font
|
||||||
import Element.Input as Input
|
import Element.Input as Input
|
||||||
import Element.Keyed as Keyed
|
import Element.Keyed as Keyed
|
||||||
import Hover exposing (Hover)
|
import Hover exposing (Hover)
|
||||||
import Html
|
|
||||||
import Html.Attributes
|
import Html.Attributes
|
||||||
import Json.Encode as Encode
|
|
||||||
import Time
|
import Time
|
||||||
import TimeUtils
|
import TimeUtils
|
||||||
import Twitch
|
import Twitch
|
||||||
import Ui
|
import Ui
|
||||||
|
import Video
|
||||||
|
import Video.Views
|
||||||
|
|
||||||
|
|
||||||
view : Core.Model -> Browser.Document Core.Msg
|
view : Core.Model -> Browser.Document Core.Msg
|
||||||
|
@ -57,7 +57,7 @@ title model =
|
||||||
Core.Playlist p _ ->
|
Core.Playlist p _ ->
|
||||||
Consts.url ++ " - " ++ p.name
|
Consts.url ++ " - " ++ p.name
|
||||||
|
|
||||||
Core.Video p v _ ->
|
Core.Video p v _ _ ->
|
||||||
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
|
Consts.url ++ " - " ++ p.name ++ " - " ++ v.name
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ viewContent model =
|
||||||
Core.Playlist playlist hover ->
|
Core.Playlist playlist hover ->
|
||||||
videoMiniaturesView model.darkMode model.device model.zone model.currentDate model.time hover playlist
|
videoMiniaturesView model.darkMode model.device model.zone model.currentDate model.time hover playlist
|
||||||
|
|
||||||
Core.Video playlist video hover ->
|
Core.Video playlist video v hover ->
|
||||||
videoView model.darkMode model.device model.zone model.currentDate model.time hover playlist video
|
videoView model.darkMode model.device model.zone model.currentDate model.time hover playlist video v
|
||||||
|
|
||||||
|
|
||||||
topBar : Maybe Bool -> Element Core.Msg
|
topBar : Maybe Bool -> Element Core.Msg
|
||||||
|
@ -293,8 +293,6 @@ videoMiniature currentDate time hover playlist video =
|
||||||
, Element.height (Element.px 0)
|
, Element.height (Element.px 0)
|
||||||
, Element.htmlAttribute (Html.Attributes.style "padding-top" "56.25%")
|
, Element.htmlAttribute (Html.Attributes.style "padding-top" "56.25%")
|
||||||
, Element.htmlAttribute (Html.Attributes.style "position" "relative")
|
, Element.htmlAttribute (Html.Attributes.style "position" "relative")
|
||||||
, Events.onMouseEnter (Core.HoverVideo video)
|
|
||||||
, Events.onMouseLeave Core.Unhover
|
|
||||||
]
|
]
|
||||||
( key
|
( key
|
||||||
, Element.image
|
, Element.image
|
||||||
|
@ -318,9 +316,14 @@ videoMiniatureView : Bool -> Time.Zone -> Time.Posix -> Time.Posix -> Maybe (Hov
|
||||||
videoMiniatureView darkMode zone currentDate time hover playlist video =
|
videoMiniatureView darkMode zone currentDate time hover playlist video =
|
||||||
let
|
let
|
||||||
display =
|
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
|
[ videoMiniature currentDate time hover playlist video
|
||||||
, videoDescription darkMode zone video
|
, videoDate darkMode zone video
|
||||||
]
|
]
|
||||||
|
|
||||||
button =
|
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 =
|
videoInList darkMode zone currentDate time hover playlist activeVideo video =
|
||||||
let
|
let
|
||||||
label =
|
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) ]
|
[ Element.el [ Element.width (Element.fillPortion 2) ]
|
||||||
(videoMiniature currentDate time hover playlist video)
|
(videoMiniature currentDate time hover playlist video)
|
||||||
, Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ]
|
, Element.el [ Element.width (Element.fillPortion 3), Element.paddingXY 0 10, Element.alignTop ]
|
||||||
(videoDescription darkMode zone video)
|
(videoDate darkMode zone video)
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
if video == activeVideo then
|
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 : 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 =
|
videoView darkMode device zone currentDate time hover playlist video v =
|
||||||
let
|
let
|
||||||
( builder, contentPadding ) =
|
( builder, contentPadding ) =
|
||||||
case device.class of
|
case device.class of
|
||||||
|
@ -379,13 +387,8 @@ videoView darkMode device zone currentDate time hover playlist video =
|
||||||
[ Element.width (Element.fillPortion 2)
|
[ Element.width (Element.fillPortion 2)
|
||||||
, Element.spacing 10
|
, Element.spacing 10
|
||||||
, Element.alignTop
|
, Element.alignTop
|
||||||
, Element.height Element.fill
|
|
||||||
]
|
]
|
||||||
[ Element.html
|
[ Video.Views.embedElement v |> Element.map Core.VideoMsg
|
||||||
(Html.node "plyr-video"
|
|
||||||
[ Html.Attributes.attribute "src" ("videos/" ++ playlist.url ++ video.url ++ "manifest.m3u8") ]
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
, Element.paragraph
|
, Element.paragraph
|
||||||
[ Font.size Consts.homeFontSize
|
[ Font.size Consts.homeFontSize
|
||||||
, Font.bold
|
, Font.bold
|
||||||
|
@ -413,8 +416,8 @@ videoView darkMode device zone currentDate time hover playlist video =
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
videoDescription : Bool -> Time.Zone -> Twitch.Video -> Element Core.Msg
|
videoDate : Bool -> Time.Zone -> Twitch.Video -> Element Core.Msg
|
||||||
videoDescription darkMode zone video =
|
videoDate darkMode zone video =
|
||||||
Element.column [ Element.spacing 10 ]
|
Element.column [ Element.spacing 10 ]
|
||||||
[ Element.paragraph
|
[ Element.paragraph
|
||||||
[ Font.bold
|
[ Font.bold
|
||||||
|
@ -559,22 +562,7 @@ groupAux size list acc =
|
||||||
|
|
||||||
spinner : Element Core.Msg
|
spinner : Element Core.Msg
|
||||||
spinner =
|
spinner =
|
||||||
Element.html
|
Element.none
|
||||||
(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 [] []
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
newBadge : Element Core.Msg
|
newBadge : Element Core.Msg
|
||||||
|
|
Loading…
Reference in New Issue