]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/sass/video-js-custom.scss
Add context menu to player
[github/Chocobozzz/PeerTube.git] / client / src / sass / video-js-custom.scss
1 @import '_variables';
2 @import '_mixins';
3
4 @mixin big-play-button-triangle-size($triangle-size) {
5 width: $triangle-size;
6 height: $triangle-size;
7 top: calc(50% - #{$triangle-size / 2});
8 left: calc(53% - #{($triangle-size / 2)});
9 }
10
11 $primary-foreground-color: #fff;
12 $primary-foreground-opacity: 0.9;
13 $primary-foreground-opacity-hover: 1;
14 $primary-background-color: #000;
15
16 $font-size: 13px;
17 $control-bar-height: 34px;
18
19 $slider-bg-color: lighten($primary-background-color, 33%);
20
21 $setting-transition-duration: 0.15s;
22 $setting-transition-easing: ease-out;
23
24 $context-menu-width: 350px;
25
26 .video-js.vjs-peertube-skin {
27 font-size: $font-size;
28 color: $primary-foreground-color;
29
30 .vjs-dock-text {
31 padding-right: 10px;
32 }
33
34 .vjs-dock-description {
35 font-size: 11px;
36
37 &::before, &::after {
38 display: inline-block;
39 content: '\1F308';
40 }
41
42 &::before {
43 margin-right: 4px;
44 }
45
46 &::after {
47 margin-left: 4px;
48 transform: scale(-1, 1);
49 }
50 }
51
52 .vjs-button > .vjs-icon-placeholder::before {
53 line-height: $control-bar-height;
54 }
55
56 .vjs-volume-level::before {
57 content: ''; /* Remove Circle From Progress Bar */
58 }
59
60 .vjs-audio-button {
61 display: none;
62 }
63
64 .vjs-big-play-button {
65 outline: 0;
66 font-size: 6em;
67
68 $big-play-width: 1.2em;
69 $big-play-height: 1.2em;
70
71 border: 6px solid #fff;
72 border-radius: 100%;
73
74 left: 50%;
75 top: 50%;
76 width: $big-play-width;
77 height: $big-play-height;
78 line-height: $big-play-height;
79 margin-left: -($big-play-width / 2);
80 margin-top: -($big-play-height / 2);
81 transition: 0.4s opacity;
82
83 &::-moz-focus-inner {
84 border: 0;
85 padding: 0
86 }
87
88 .vjs-icon-placeholder::before {
89 @include big-play-button-triangle-size(45px);
90
91 content: '';
92 background-image: url('../assets/player/images/big-play-button.svg');
93 }
94
95 &:hover {
96 opacity: 0.8;
97 }
98 }
99
100 // Small effect when we click on the play button
101 &.vjs-has-big-play-button-clicked {
102
103 .vjs-big-play-button, .vjs-poster {
104 display: block;
105 visibility: hidden;
106
107 &.vjs-big-play-button, &.vjs-big-play-button::before {
108 opacity: 0;
109 transition: visibility 0.2s, opacity 0.2s;
110 }
111
112 &.vjs-poster, &.vjs-poster::before {
113 opacity: 0;
114 transition: visibility 0.3s, opacity 0.3s;
115 transition-delay: 0.05s;
116 }
117 }
118 }
119
120 // Hide the big play button on autoplay
121 &.vjs-has-autoplay {
122 .vjs-big-play-button {
123 display: none !important;
124 }
125 }
126
127 .vjs-control-bar,
128 .vjs-big-play-button,
129 .vjs-settings-dialog {
130 background-color: rgba($primary-background-color, 0.5);
131 }
132
133 .vjs-slider {
134 background-color: rgba(255, 255, 255, .3);
135 border-radius: 2px;
136 height: 5px;
137
138 .vjs-slider-bar {
139 background: $primary-foreground-color;
140 }
141 }
142
143 .vjs-play-progress {
144
145 &::before {
146 top: -0.3em;
147
148 &:hover {
149 top: -0.372em;
150 }
151 }
152
153 .vjs-time-tooltip {
154 display: none;
155 }
156 }
157
158 .vjs-load-progress {
159 background: rgba($slider-bg-color, 0.5);
160
161 div {
162 background: rgba($slider-bg-color, 0.75);
163 }
164 }
165
166 .vjs-poster {
167 outline: none; /* Remove Blue Outline on Click*/
168 outline: 0;
169 }
170
171 .vjs-control-bar {
172 height: $control-bar-height;
173
174 .vjs-progress-control,
175 .vjs-play-control,
176 .vjs-playback-rate,
177 .vjs-mute-control,
178 .vjs-volume-control,
179 .vjs-resolution-control,
180 .vjs-fullscreen-control,
181 .vjs-peertube-link,
182 .vjs-settings
183 {
184 color: $primary-foreground-color !important;
185 opacity: $primary-foreground-opacity;
186 transition: opacity .1s;
187
188 &:hover {
189 opacity: $primary-foreground-opacity-hover;
190 }
191 }
192
193 .vjs-current-time,
194 .vjs-duration,
195 .vjs-peertube {
196 color: $primary-foreground-color;
197 opacity: $primary-foreground-opacity;
198 }
199
200 .vjs-progress-control {
201 bottom: 34px;
202 width: 100%;
203 position: absolute;
204 height: 5px;
205
206 .vjs-progress-holder {
207 margin: 0;
208 border-radius: 0;
209 }
210 }
211
212 .vjs-play-control {
213 @include disable-outline;
214
215 cursor: pointer;
216 font-size: $font-size;
217 padding: 0 17px;
218 margin-right: 5px;
219 }
220
221 .vjs-time-control {
222 &.vjs-current-time {
223 font-size: $font-size;
224 display: inline-block;
225 padding: 0;
226
227 .vjs-current-time-display {
228 line-height: calc(#{$control-bar-height} + 1px);
229
230 &::after {
231 content: "/";
232 margin: 0 1px 0 2px;
233 }
234 }
235 }
236
237 &.vjs-duration {
238 font-size: $font-size;
239 display: inline-block;
240 padding: 0;
241 .vjs-duration-display {
242 line-height: calc(#{$control-bar-height} + 1px);
243 }
244 }
245
246 &.vjs-remaining-time {
247 display: none;
248 }
249 }
250
251 .vjs-peertube {
252 width: 100%;
253 line-height: $control-bar-height;
254 text-align: right;
255
256 .vjs-peertube-displayed {
257 display: block;
258 }
259
260 .vjs-peertube-hidden {
261 display: none;
262 }
263
264 .download-speed-number, .upload-speed-number, .peers-number {
265 font-weight: $font-semibold;
266 }
267
268 .download-speed-text, .upload-speed-text, .peers-text {
269 margin-right: 15px;
270 }
271
272 .icon {
273 display: inline-block;
274 width: 15px;
275 height: 15px;
276 background-size: contain;
277 vertical-align: middle;
278 background-repeat: no-repeat;
279 margin-right: 6px;
280 position: relative;
281 top: -1px;
282
283 &.icon-download {
284 background-image: url('../assets/player/images/arrow-down.svg');
285 }
286
287 &.icon-upload {
288 background-image: url('../assets/player/images/arrow-up.svg');
289 }
290 }
291 }
292
293 .vjs-playback-rate {
294 font-size: 10px;
295 width: 37px !important;
296
297 .vjs-playback-rate-value {
298 font-size: 13px;
299 line-height: $control-bar-height;
300 }
301
302 .vjs-menu .vjs-menu-content {
303 width: 37px !important;
304 }
305 }
306
307 .vjs-mute-control {
308 @include disable-outline;
309
310 line-height: $control-bar-height;
311 padding: 0;
312 width: 30px;
313
314 .vjs-icon-placeholder {
315 display: inline-block;
316 width: 22px;
317 height: 22px;
318 vertical-align: middle;
319 background: url('../assets/player/images/volume.svg') no-repeat;
320 background-size: contain;
321
322 &::before {
323 content: '';
324 }
325 }
326
327 &.vjs-vol-0 .vjs-icon-placeholder {
328 background: url('../assets/player/images/volume-mute.svg') no-repeat;
329 background-size: contain;
330 }
331 }
332
333 .vjs-volume-control {
334 width: 30px;
335 margin: 0 5px 0 0;
336 }
337
338 .vjs-volume-bar {
339 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcCAQAAACw95UnAAAAMElEQVRIx2NgoBL4n4YKGUYNHkEG4zJg1OCRYDCpBowaPJwMppbLRg0eNXjUYBLEAXWNUA6QNm1lAAAAAElFTkSuQmCC) no-repeat;
340 background-size: 22px 14px;
341 height: 100%;
342 width: 100%;
343 max-width: 22px;
344 max-height: 14px;
345 margin: 7px 4px;
346 border-radius: 0;
347 top: 3px;
348
349 .vjs-volume-level {
350 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcAQAAAAAyhWABAAAAAnRSTlMAAHaTzTgAAAAZSURBVHgBYwAB/g9EUv+JokCqiaT+U4MCAPKPS7WUUOc1AAAAAElFTkSuQmCC) no-repeat;
351 background-size: 22px 14px;
352 max-width: 22px;
353 max-height: 14px;
354 height: 100%;
355 }
356 }
357
358 .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,
359 .vjs-volume-panel.vjs-volume-panel-horizontal:active,
360 .vjs-volume-panel.vjs-volume-panel-horizontal:focus,
361 .vjs-volume-panel.vjs-volume-panel-horizontal:hover {
362 width: 6em;
363 transition-property: none;
364 }
365
366 .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal {
367 width: 3em;
368 height: auto;
369 }
370
371 .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control {
372 transition-property: none;
373 }
374
375 .vjs-volume-panel {
376 .vjs-mute-control {
377 width: 2em;
378 z-index: 1;
379 padding: 0;
380 }
381
382 .vjs-volume-control {
383 display: inline-block;
384 position: relative;
385 left: 5px;
386 opacity: 1;
387 width: 3em;
388 height: auto;
389 }
390 }
391
392 .vjs-peertube-link {
393 @include disable-outline;
394 @include disable-default-a-behaviour;
395
396 text-decoration: none;
397 line-height: $control-bar-height;
398 font-weight: $font-semibold;
399 padding: 0 5px;
400 }
401
402 .vjs-fullscreen-control {
403 @include disable-outline;
404
405 width: 37px;
406
407 .vjs-icon-placeholder {
408 display: inline-block;
409 width: 22px;
410 height: 22px;
411 vertical-align: middle;
412 background: url('../assets/player/images/fullscreen.svg') no-repeat;
413 background-size: contain;
414
415 &::before {
416 content: '';
417 }
418 }
419 }
420
421 .vjs-menu-button-popup {
422 font-weight: $font-semibold;
423 width: 50px;
424
425 .vjs-resolution-button {
426 @include disable-outline;
427 }
428
429 .vjs-menu {
430 top: 20px;
431 left: 0;
432
433 .vjs-menu-content {
434 width: 50px;
435 bottom: 20px;
436 }
437
438 li {
439 text-transform: none;
440 font-size: 13px;
441 }
442 }
443 }
444 }
445
446 @media screen and (max-width: 750px) {
447 .vjs-dock-text {
448 font-size: 16px;
449 }
450
451 .vjs-dock-description {
452 font-size: 9px;
453 }
454
455 .vjs-big-play-button {
456 font-size: 5em;
457 border-width: 5px;
458
459 .vjs-icon-placeholder::before {
460 @include big-play-button-triangle-size(32px);
461 }
462 }
463 }
464
465 @media screen and (max-width: 570px) {
466 .vjs-dock-text {
467 font-size: 14px;
468 }
469
470 .vjs-big-play-button {
471 font-size: 4.5em;
472 border-width: 4.5px;
473
474 .vjs-icon-placeholder::before {
475 @include big-play-button-triangle-size(27px);
476 }
477 }
478
479 .vjs-playback-rate {
480 display: none;
481 }
482
483 .vjs-peertube {
484 padding: 0 !important;
485
486 .vjs-peertube-displayed {
487 display: none !important;
488 }
489 }
490 }
491
492 @media screen and (max-width: 300px) {
493 .vjs-dock-text {
494 font-size: 13px;
495 }
496
497 .vjs-big-play-button {
498 font-size: 3em;
499 border-width: 3px;
500
501 .vjs-icon-placeholder::before {
502 @include big-play-button-triangle-size(20px);
503 }
504 }
505
506 .vjs-volume-control {
507 display: none !important;
508 }
509
510 .vjs-peertube-link {
511 padding: 0 !important;
512 }
513
514 .vjs-settings {
515 width: 33px;
516 }
517 }
518 }
519
520 // Play/pause animations
521 .vjs-has-started .vjs-play-control {
522 &.vjs-playing {
523 animation: remove-pause-button 0.25s ease;
524 }
525
526 &.vjs-paused {
527 animation: add-play-button 0.25s ease;
528 }
529
530 @keyframes remove-pause-button {
531 0% {
532 transform: rotate(90deg);
533 }
534 100% {
535 transform: rotate(0deg);
536 }
537 }
538
539 @keyframes add-play-button {
540 0% {
541 transform: rotate(-90deg);
542 }
543 100% {
544 transform: rotate(0deg);
545 }
546 }
547 }
548
549 // Thanks: https://projects.lukehaas.me/css-loaders/
550 .vjs-loading-spinner {
551 left: 50%;
552 font-size: 10px;
553 text-indent: -9999em;
554 border: 0.7em solid rgba(255, 255, 255, 0.2);
555 border-left-color: #ffffff;
556 transform: translateZ(0);
557 animation: 0.3s ease-out 1.1s forwards vjs-spinner-show, spinner 1.4s infinite linear !important;
558 overflow: hidden;
559 visibility: hidden;
560
561 &::before {
562 animation: none !important;
563 }
564
565 &::after {
566 border-radius: 50%;
567 width: 6em;
568 height: 6em;
569 animation: none !important;
570 }
571
572 @keyframes spinner {
573 0% {
574 transform: rotate(0deg);
575 }
576 100% {
577 transform: rotate(360deg);
578 }
579 }
580
581 @keyframes vjs-spinner-show {
582 0% {
583 display: none;
584 opacity: 0;
585 }
586
587 1% {
588 display: block;
589 visibility: visible;
590 opacity: 0;
591 }
592
593 100% {
594 display: block;
595 visibility: visible;
596 opacity: 1;
597 }
598 }
599 }
600
601 // Error display disabled
602 .vjs-error:not(.vjs-error-display-enabled) {
603 .vjs-error-display {
604 display: none;
605 }
606
607 .vjs-loading-spinner {
608 display: block;
609 }
610 }
611
612 // Error display enabled
613 .vjs-error.vjs-error-display-enabled {
614 .vjs-error-display {
615 display: block;
616 }
617 }
618
619
620 /* Sass for videojs-settings-menu */
621
622 .video-js {
623
624 .vjs-settings {
625 @include disable-outline;
626
627 cursor: pointer;
628 width: 37px;
629
630 .vjs-icon-placeholder {
631 display: inline-block;
632 width: 17px;
633 height: 17px;
634 vertical-align: middle;
635 background: url('../assets/player/images/settings.svg') no-repeat;
636 background-size: contain;
637
638 &::before {
639 content: '';
640 }
641 }
642 }
643
644 .vjs-settings-sub-menu-title {
645 width: 4em;
646 text-transform: initial;
647 }
648
649 .vjs-settings-dialog {
650 position: absolute;
651 right: .5em;
652 bottom: 3.5em;
653 color: $primary-foreground-color;
654 opacity: $primary-foreground-opacity;
655 margin: 0 auto;
656 font-size: $font-size !important;
657
658 width: auto;
659 overflow: hidden;
660
661 transition: width $setting-transition-duration $setting-transition-easing, height $setting-transition-duration $setting-transition-easing;
662
663 .vjs-settings-sub-menu-value,
664 .vjs-settings-sub-menu-title {
665 display: table-cell;
666 padding: 0 5px;
667 }
668
669 .vjs-settings-sub-menu-title {
670 text-align: left;
671 font-weight: $font-semibold;
672 }
673
674 .vjs-settings-sub-menu-value {
675 width: 100%;
676 text-align: right;
677
678 small {
679 font-size: 0.85em;
680 opacity: 0.8;
681 }
682 }
683
684 .vjs-settings-panel {
685 position: absolute;
686 bottom: 0;
687 right: 0;
688 overflow-y: auto;
689 overflow-x: hidden;
690 border-radius: 1px;
691 }
692
693 .vjs-settings-panel-child {
694 display: flex;
695
696 align-items: flex-end;
697 white-space: nowrap;
698
699 &:focus,
700 &:active {
701 outline: none;
702 }
703
704 > .vjs-menu {
705 flex: 1;
706 min-width: 200px;
707 }
708
709 > .vjs-menu,
710 > .vjs-settings-sub-menu {
711 transition: all $setting-transition-duration $setting-transition-easing;
712
713 .vjs-menu-item {
714
715 &:hover {
716 background-color: rgba(255, 255, 255, 0.2);
717 }
718
719 &:first-child {
720 margin-top: 5px;
721 }
722
723 &:last-child {
724 margin-bottom: 5px;
725 }
726 }
727
728 li {
729 font-size: 1em;
730 text-transform: initial;
731
732 &:hover {
733 cursor: pointer;
734 }
735 }
736 }
737
738 > .vjs-menu {
739 .vjs-menu-item {
740 padding: 8px 16px;
741 }
742
743 .vjs-settings-sub-menu-value::after {
744 @include chevron-right(9px, 2px);
745
746 margin-left: 5px;
747 }
748 }
749
750 > .vjs-settings-sub-menu {
751 width: 80px;
752
753 .vjs-menu-item {
754 outline: 0;
755 font-weight: $font-semibold;
756
757 padding: 5px 8px;
758 text-align: right;
759
760 &.vjs-back-button {
761 background-color: inherit;
762 padding: 8px 8px 13px 8px;
763 margin-bottom: 5px;
764 border-bottom: 1px solid grey;
765
766 &::before {
767 @include chevron-left(9px, 2px);
768
769 margin-right: 5px;
770 }
771 }
772
773 &.vjs-selected {
774 background-color: inherit;
775 color: inherit;
776 position: relative;
777
778 &::before {
779 @include icon(15px);
780
781 position: absolute;
782 left: 8px;
783 content: ' ';
784 margin-top: 1px;
785 background-image: url('../assets/player/images/tick.svg');
786 }
787 }
788 }
789 }
790 }
791 }
792 }
793
794 /* Sass for videojs-contextmenu-ui */
795
796 .video-js .vjs-contextmenu-ui-menu {
797 position: absolute;
798 background-color: rgba(0, 0, 0, 0.5);
799 padding: 5px 0;
800 width: $context-menu-width;
801
802 .vjs-menu-content {
803 opacity: $primary-foreground-opacity;
804 color: $primary-foreground-color;
805 font-size: $font-size !important;
806 font-weight: $font-semibold;
807 }
808
809 .vjs-menu-item {
810 cursor: pointer;
811 font-size: 1em;
812 padding: 8px 16px;
813 text-align: left;
814 text-transform: none;
815
816 &:hover {
817 background-color: rgba(255, 255, 255, 0.2);
818 }
819 }
820 }