From fde2c8c0c704455dc5800d9b834d084f3a2037a3 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 22 Aug 2025 10:25:03 +0200 Subject: [PATCH] Prefer using vertical volume control Better UX/control --- .../src/sass/shared/_player-variables.scss | 8 +- .../player/src/sass/shared/control-bar.scss | 169 +++++++----------- .../control-bar-options-builder.ts | 5 +- 3 files changed, 70 insertions(+), 112 deletions(-) diff --git a/client/src/standalone/player/src/sass/shared/_player-variables.scss b/client/src/standalone/player/src/sass/shared/_player-variables.scss index 9e0f41363..809693b10 100644 --- a/client/src/standalone/player/src/sass/shared/_player-variables.scss +++ b/client/src/standalone/player/src/sass/shared/_player-variables.scss @@ -1,5 +1,5 @@ -@use 'sass:color'; -@use 'bootstrap/scss/functions' as *; +@use "sass:color"; +@use "bootstrap/scss/functions" as *; $primary-foreground-color: #fff; $primary-foreground-opacity: 0.9; @@ -10,15 +10,11 @@ $font-size: 13px; $control-bar-height: 38px; $control-bar-icon-size: 26px; -$control-bar-volume-slider-height: 16px; -$control-bar-slider-top: -15px; $control-bar-font-size: 14px; $control-bar-play-font-size: 34px; $control-bar-next-previous-play-font-size: 14px; $control-bar-button-width: 34px; -$control-bar-total-height: $control-bar-height - $control-bar-slider-top; - $progress-margin: 10px; $dock-padding: 20px; diff --git a/client/src/standalone/player/src/sass/shared/control-bar.scss b/client/src/standalone/player/src/sass/shared/control-bar.scss index 14d7b1c8b..aa7f17cf5 100644 --- a/client/src/standalone/player/src/sass/shared/control-bar.scss +++ b/client/src/standalone/player/src/sass/shared/control-bar.scss @@ -1,7 +1,7 @@ -@use 'sass:math'; -@use '_variables' as *; -@use '_mixins' as *; -@use './_player-variables' as *; +@use "sass:math"; +@use "_variables" as *; +@use "_mixins" as *; +@use "./_player-variables" as *; $slider-height: 3px; $slider-hover-height: 5px; @@ -20,12 +20,12 @@ $chapter-marker-size: 9px; .vjs-chapter-marker { position: absolute; - top: - math.floor(math.div($chapter-marker-size - $slider-height, 2)); + top: math.floor(math.div($chapter-marker-size - $slider-height, 2)) * -1; height: $chapter-marker-size; width: $chapter-marker-size; border-radius: $chapter-marker-size; - margin-left: - math.div($chapter-marker-size, 2); + margin-left: math.div($chapter-marker-size, 2) * -1; background-color: #fff; cursor: pointer; @@ -70,7 +70,6 @@ $chapter-marker-size: 9px; .vjs-play-control, .vjs-playback-rate, .vjs-mute-control, - .vjs-volume-control, .vjs-resolution-control, .vjs-fullscreen-control, .vjs-peertube-link, @@ -80,13 +79,49 @@ $chapter-marker-size: 9px; color: pvar(--embed-fg) !important; opacity: $primary-foreground-opacity; - transition: opacity .1s; + transition: opacity 0.1s; &:hover { opacity: $primary-foreground-opacity-hover; } } + .vjs-volume-panel { + width: $control-bar-button-width; + + &.vjs-hover .vjs-volume-control, + &:active .vjs-volume-control, + &:focus .vjs-volume-control, + &.vjs-hover .vjs-mute-control ~ .vjs-volume-control, + // Use same code as videojs + &.vjs-hover .vjs-volume-control, + &:active .vjs-volume-control, + &:focus .vjs-volume-control, + & .vjs-volume-control:active, + &.vjs-hover .vjs-mute-control ~ .vjs-volume-control, + & .vjs-volume-control.vjs-slider-active { + &.vjs-volume-vertical { + left: -2.5em; + } + } + } + + .vjs-volume-vertical { + bottom: 6.75em; + height: 7em; + } + + .vjs-volume-bar.vjs-slider-vertical { + margin: 1em auto; + } + + .vjs-volume-vertical { + // On top of the progress bar + z-index: 120; + background-color: var(--embed-background-color); + border-radius: 10px; + } + .vjs-current-time, .vjs-duration, .vjs-peertube { @@ -96,17 +131,18 @@ $chapter-marker-size: 9px; .vjs-progress-control { position: absolute; - top: $control-bar-slider-top; + top: -18px; z-index: 100; // On top of the progress bar - width: calc(100% - (2 * #{$progress-margin})); + width: calc(100% - 2 * #{$progress-margin}); height: 20px; + align-items: flex-end; @include margin-left($progress-margin); .vjs-slider { - margin: 0; + margin: 0 0 5px; border-radius: 0; - background-color: rgba(255, 255, 255, .2); + background-color: rgba(255, 255, 255, 0.2); height: $slider-height; transition: none; @@ -130,7 +166,7 @@ $chapter-marker-size: 9px; .vjs-load-progress { &, div { - background: rgba(255, 255, 255, .2); + background: rgba(255, 255, 255, 0.2); } } } @@ -145,7 +181,7 @@ $chapter-marker-size: 9px; } .vjs-chapter-marker { - top: - math.floor(math.div($chapter-marker-size - $slider-hover-height, 2)); + top: math.floor(math.div($chapter-marker-size - $slider-hover-height, 2)) * -1; } } @@ -171,13 +207,13 @@ $chapter-marker-size: 9px; display: inline-block; padding: 0; - @include margin-left(.5em); + @include margin-left(0.5em); .vjs-current-time-display { line-height: calc(#{$control-bar-height} - 1px); &::after { - content: '/'; + content: "/"; @include margin(0, 1px, 0, 2px); } @@ -270,11 +306,11 @@ $chapter-marker-size: 9px; @include margin-right(2px); &.icon-download { - background-image: url('./svg/arrow-down.svg'); + background-image: url("./svg/arrow-down.svg"); } &.icon-upload { - background-image: url('./svg/arrow-up.svg'); + background-image: url("./svg/arrow-up.svg"); } } } @@ -291,8 +327,8 @@ $chapter-marker-size: 9px; .icon { &.icon-next, &.icon-previous { - mask-image: url('./svg/next.svg'); - -webkit-mask-image: url('./svg/next.svg'); + mask-image: url("./svg/next.svg"); + -webkit-mask-image: url("./svg/next.svg"); mask-size: cover; -webkit-mask-size: cover; @@ -319,91 +355,20 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size; height: $control-bar-icon-size; vertical-align: middle; - background: url('./svg/volume.svg') no-repeat; + background: url("./svg/volume.svg") no-repeat; background-size: contain; &::before { - content: ''; + content: ""; } } &.vjs-vol-0 .vjs-icon-placeholder { - background: url('./svg/volume-mute.svg') no-repeat; + background: url("./svg/volume-mute.svg") no-repeat; background-size: contain; } } - .vjs-volume-control { - width: 28px; - display: flex; - align-items: center; - - @include margin(0, 5px, 0, 5px); - } - - .vjs-volume-bar { - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcCAQAAACw95UnAAAAMElEQVRIx2NgoBL4n4YKGUYNHkEG4zJg1OCRYDCpBowaPJwMppbLRg0eNXjUYBLEAXWNUA6QNm1lAAAAAElFTkSuQmCC') no-repeat; - background-size: $control-bar-icon-size $control-bar-volume-slider-height; - height: 100%; - width: 100%; - max-width: $control-bar-icon-size; - max-height: $control-bar-volume-slider-height; - margin: 0; - border-radius: 0; - - .vjs-volume-level { - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcAQAAAAAyhWABAAAAAnRSTlMAAHaTzTgAAAAZSURBVHgBYwAB/g9EUv+JokCqiaT+U4MCAPKPS7WUUOc1AAAAAElFTkSuQmCC') no-repeat; - background-size: $control-bar-icon-size $control-bar-volume-slider-height; - max-width: $control-bar-icon-size; - height: 100%; - max-height: $control-bar-volume-slider-height; - - &::before { - // Remove circle - content: ''; - } - } - - &:focus { - text-shadow: none; - box-shadow: none; - } - } - - .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active, - .vjs-volume-panel.vjs-volume-panel-horizontal:active, - .vjs-volume-panel.vjs-volume-panel-horizontal:focus, - .vjs-volume-panel.vjs-volume-panel-horizontal:hover { - width: 6em; - transition-property: none; - } - - .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal { - width: 3em; - height: auto; - } - - .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control { - transition-property: none; - } - - .vjs-volume-panel { - .vjs-mute-control { - width: 2em; - z-index: 1; - padding: 0; - } - - .vjs-volume-control { - display: inline-block; - position: relative; - left: 5px; - opacity: 1; - width: 3em; - height: auto; - } - } - .vjs-settings { cursor: pointer; width: $control-bar-button-width; @@ -415,11 +380,11 @@ $chapter-marker-size: 9px; height: $control-bar-icon-size - 4px; width: $control-bar-icon-size - 4px; vertical-align: middle; - background: url('./svg/settings.svg') no-repeat; + background: url("./svg/settings.svg") no-repeat; background-size: contain; &::before { - content: ''; + content: ""; } } } @@ -448,11 +413,11 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size - 4px; height: $control-bar-icon-size - 4px; vertical-align: middle; - background: url('./svg/theater.svg') no-repeat; + background: url("./svg/theater.svg") no-repeat; background-size: contain; &::before { - content: ''; + content: ""; } } } @@ -493,11 +458,11 @@ $chapter-marker-size: 9px; width: $control-bar-icon-size; height: $control-bar-icon-size; vertical-align: middle; - background: url('./svg/fullscreen.svg') no-repeat; + background: url("./svg/fullscreen.svg") no-repeat; background-size: contain; &::before { - content: ''; + content: ""; } } } @@ -518,10 +483,6 @@ $chapter-marker-size: 9px; } .video-js.vjs-peertube-skin.vjs-size-570 .vjs-control-bar { - .vjs-volume-control { - display: none; - } - .vjs-mute-control { @include margin(0, 4px, 0, 4px); } diff --git a/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts b/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts index 55f89c50f..3de511046 100644 --- a/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts +++ b/client/src/standalone/player/src/shared/player-options-builder/control-bar-options-builder.ts @@ -34,8 +34,9 @@ export class ControlBarOptionsBuilder { p2PInfoButton: {}, - muteToggle: {}, - volumeControl: {}, + volumePanel: { + inline: false + }, captionToggleButton: {},