Browse Source

feat: improve video player styles

Miguel Ángel Moreno 11 months ago
parent
commit
ed540859f6

+ 15 - 0
resources/src/styles/index.scss

@@ -0,0 +1,15 @@
+@use "./videojs";
+@use "@fontsource/nunito-sans/scss/mixins" as NunitoSans;
+$fontsourceDir: "~@fontsource";
+@include NunitoSans.faces($weights: (200, 300, 400, 500, 600, 700, 800, 900));
+$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
+@import "@fortawesome/fontawesome-free/scss/brands";
+@import "@fortawesome/fontawesome-free/scss/regular";
+@import "@fortawesome/fontawesome-free/scss/solid";
+@import "@fortawesome/fontawesome-free/scss/fontawesome";
+@import "tailwindcss/base";
+@import "tailwindcss/components";
+@import "tailwindcss/utilities";
+@import "video.js/dist/video-js.css";
+@import "videojs-mobile-ui/dist/videojs-mobile-ui.css";
+@import "@silvermine/videojs-quality-selector/dist/css/quality-selector.css";

+ 0 - 46
resources/src/styles/tubo.scss

@@ -1,46 +0,0 @@
-@use "@fontsource/nunito-sans/scss/mixins" as NunitoSans;
-$fontsourceDir: "~@fontsource";
-@include NunitoSans.faces($weights: (200, 300, 400, 500, 600, 700, 800, 900));
-$fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
-@import "@fortawesome/fontawesome-free/scss/brands";
-@import "@fortawesome/fontawesome-free/scss/regular";
-@import "@fortawesome/fontawesome-free/scss/solid";
-@import "@fortawesome/fontawesome-free/scss/fontawesome";
-@import "tailwindcss/base";
-@import "tailwindcss/components";
-@import "tailwindcss/utilities";
-@import "video.js/dist/video-js.css";
-@import "videojs-mobile-ui/dist/videojs-mobile-ui.css";
-@import "@silvermine/videojs-quality-selector/dist/css/quality-selector.css";
-
-.vjs-tubo .vjs-poster img {
-  object-fit: cover;
-}
-
-.vjs-tubo .vjs-control-bar {
-  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
-}
-
-.vjs-tubo .vjs-volume-control {
-  background: radial-gradient(rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 45%);
-  backdrop-filter: blur(1px);
-}
-
-.vjs-tubo .vjs-menu-button-popup .vjs-menu .vjs-menu-content {
-  background: rgba(0, 0, 0, 0.5);
-  backdrop-filter: blur(6px);
-}
-
-.vjs-tubo .vjs-current-time, .vjs-tubo .vjs-time-divider, .vjs-tubo .vjs-duration {
-  display: block;
-}
-
-.vjs-tubo .vjs-big-play-button, .vjs-tubo.vjs-paused .vjs-big-play-button, .vjs-tubo:hover .vjs-big-play-button {
-  content: '';
-  background-size: 60%;
-  background-position: center center;
-  background-repeat: no-repeat;
-  background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
-  background-color: transparent;
-  border: none;
-}

+ 130 - 0
resources/src/styles/videojs.scss

@@ -0,0 +1,130 @@
+.vjs-tubo .vjs-poster img {
+  object-fit: cover;
+}
+
+.vjs-tubo .vjs-control-bar {
+  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
+}
+
+.vjs-tubo .vjs-menu-button-popup .vjs-menu .vjs-menu-content {
+  background: rgba(0, 0, 0, 0.5);
+  backdrop-filter: blur(6px);
+}
+
+.vjs-tubo .vjs-current-time, .vjs-tubo .vjs-time-divider, .vjs-tubo .vjs-duration {
+  display: block;
+}
+
+.vjs-tubo .vjs-big-play-button, .vjs-tubo.vjs-paused .vjs-big-play-button, .vjs-tubo:hover .vjs-big-play-button {
+  content: '';
+  background-size: 60%;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+  background-color: transparent;
+  border: none;
+}
+
+.vjs-tubo .vjs-progress-control {
+  position: absolute;
+  width: 100%;
+  top: -.5em;
+  height: 0.5em;
+}
+
+.vjs-tubo .vjs-progress-control .vjs-progress-holder {
+  position: relative;
+  margin: 0px !important;
+  top: 0;
+  width: 100%;
+  font-size: 13px;
+  padding: 8px 0 15px 0;
+  background: none;
+}
+
+.vjs-tubo .vjs-progress-control .vjs-progress-holder::before {
+  content: '';
+  display: block;
+  width: 100%;
+  height: 5px;
+  background: rgba(115, 133, 159, 0.3);
+}
+
+.vjs-tubo .vjs-progress-control .vjs-load-progress,
+.vjs-tubo .vjs-progress-control .vjs-play-progress {
+  height: 5px;
+  top: 8px;
+}
+
+.vjs-tubo .vjs-progress-control .vjs-mouse-display {
+  background: none;
+}
+
+.vjs-tubo .vjs-spacer {
+  display: flex;
+  flex: 1 1 auto;
+}
+
+.vjs-tubo .vjs-volume-bar.vjs-slider-horizontal {
+  background: none;
+  padding: 0px 0 15px 0;
+}
+
+.vjs-tubo .vjs-volume-bar.vjs-slider-horizontal::before {
+  content: '';
+  display: block;
+  width: 100%;
+  height: 3px;
+  background: rgba(115, 133, 159, 0.3);
+}
+
+.vjs-tubo .vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level {
+  height: 3px;
+  top: 0;
+}
+
+.vjs-tubo .vjs-volume-bar.vjs-slider-horizontal .vjs-mouse-display {
+  display: none;
+}
+
+.vjs-tubo.vjs-layout-x-small .vjs-progress-control,
+.vjs-tubo.vjs-layout-tiny .vjs-progress-control {
+  display: block;
+}
+
+.vjs-tubo.vjs-layout-x-small .vjs-play-control,
+.vjs-tubo.vjs-layout-tiny .vjs-play-control {
+  display: none;
+}
+
+.vjs-tubo.vjs-layout-small .vjs-current-time,
+.vjs-tubo.vjs-layout-small .vjs-time-divider,
+.vjs-tubo.vjs-layout-small .vjs-duration,
+.vjs-tubo.vjs-layout-x-small .vjs-current-time,
+.vjs-tubo.vjs-layout-x-small .vjs-time-divider,
+.vjs-tubo.vjs-layout-x-small .vjs-duration,
+.vjs-tubo.vjs-layout-tiny .vjs-current-time,
+.vjs-tubo.vjs-layout-tiny .vjs-time-divider,
+.vjs-tubo.vjs-layout-tiny .vjs-duration {
+  display: inline-block;
+}
+
+.vjs-tubo.vjs-layout-small .vjs-progress-control .vjs-load-progress,
+.vjs-tubo.vjs-layout-small .vjs-progress-control .vjs-play-progress,
+.vjs-tubo.vjs-layout-x-small .vjs-progress-control .vjs-load-progress,
+.vjs-tubo.vjs-layout-x-small .vjs-progress-control .vjs-play-progress,
+.vjs-tubo.vjs-layout-tiny .vjs-progress-control .vjs-load-progress
+.vjs-tubo.vjs-layout-tiny .vjs-progress-control .vjs-play-progress {
+  top: 0;
+}
+
+.vjs-tubo.vjs-layout-small .vjs-progress-control .vjs-progress-holder,
+.vjs-tubo.vjs-layout-x-small .vjs-progress-control .vjs-progress-holder,
+.vjs-tubo.vjs-layout-tiny-small .vjs-progress-control .vjs-progress-holder {
+  padding: 0 0 15px 0;
+}
+
+.vjs-tubo.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,
+.vjs-tubo.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content {
+  max-height: 10em;
+}

+ 1 - 1
src/backend/tubo/handler.clj

@@ -20,7 +20,7 @@
        :content "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"}]
      [:title "Tubo"]
      [:link {:rel "icon" :type "image/png" :href "/icons/tubo.svg"}]
-     (hiccup/include-css "/styles/tubo.css")]
+     (hiccup/include-css "/styles/index.css")]
     [:body
      [:div#app]
      (hiccup/include-js "/js/main.js")

+ 4 - 5
src/frontend/tubo/views/stream.cljs

@@ -40,9 +40,9 @@
                                                            (when-not resolution
                                                              (str " " averageBitrate "kbit/s")))})
                                             available-streams))
-            player-elements   ["playToggle" "CurrentTimeDisplay" "progressControl"
-                               "DurationDisplay" "volumePanel" "playbackRateMenuButton"
-                               "QualitySelector" "fullscreenToggle"]]
+            player-elements   ["PlayToggle" "ProgressControl" "VolumePanel" "CurrentTimeDisplay"
+                               "TimeDivider" "DurationDisplay" "Spacer" "PlaybackRateMenuButton"
+                               "QualitySelector" "FullscreenToggle"]]
         [layout/content-container
          [:div.flex.justify-center.relative
           {:class "h-[300px] md:h-[450px] lg:h-[600px]"}
@@ -50,8 +50,7 @@
            {:sources       sources
             :poster        thumbnail-url
             :controls      true
-            :controlBar    {:volumePanel {:inline false}
-                            :children player-elements}
+            :controlBar    {:children player-elements}
             :preload       "metadata"
             :responsive    true
             :fill          true

+ 1 - 1
webpack.config.js

@@ -6,7 +6,7 @@ const CopyPlugin = require("copy-webpack-plugin")
 module.exports = {
   mode: process.env.NODE_ENV,
   entry: {
-    tubo: path.resolve(__dirname, "resources/src/styles/tubo.scss")
+    index: path.resolve(__dirname, "resources/src/styles/index.scss")
   },
   output: {
     path: path.resolve(__dirname, "resources/public")