]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+videos/+video-watch/video-watch.component.scss
7b79344567300fef46db701eca1664c042d3be98
[github/Chocobozzz/PeerTube.git] / client / src / app / +videos / +video-watch / video-watch.component.scss
1 @use 'sass:math';
2 @use '_variables' as *;
3 @use '_mixins' as *;
4 @use '_bootstrap-variables';
5 @use '_miniature' as *;
6
7 $player-factor: math.div(16, 9);
8 $video-info-margin-left: 44px;
9
10 @function getPlayerHeight ($width) {
11 @return calc(#{$width} / #{$player-factor});
12 }
13
14 @function getPlayerWidth ($height) {
15 @return calc(#{$height} * #{$player-factor});
16 }
17
18 @mixin playlist-below-player {
19 width: 100% !important;
20 height: auto !important;
21 max-height: 300px !important;
22 max-width: initial;
23 border-bottom: 1px solid $separator-border-color !important;
24 }
25
26 .root {
27 &.theater-enabled #video-wrapper {
28 $height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
29
30 flex-direction: column;
31 justify-content: center;
32
33 #videojs-wrapper {
34 width: 100%;
35 height: $height;
36 }
37
38 ::ng-deep .video-js {
39 height: $height;
40 width: 100%;
41 max-width: initial;
42 }
43
44 my-video-watch-playlist ::ng-deep .playlist {
45 @include playlist-below-player;
46 }
47 }
48 }
49
50 .blocked-label {
51 font-weight: $font-semibold;
52 }
53
54 .placeholder-image {
55 height: 100%;
56 }
57
58 #video-wrapper {
59 $video-height: 66vh;
60
61 background-color: #000;
62 display: flex;
63 justify-content: center;
64
65 #videojs-wrapper {
66 display: flex;
67 justify-content: center;
68 flex-grow: 1;
69 height: $video-height;
70 }
71
72 .remote-server-down {
73 color: #fff;
74 display: flex;
75 flex-direction: column;
76 align-items: center;
77 text-align: center;
78 justify-content: center;
79 background-color: #141313;
80 width: 100%;
81 font-size: 24px;
82 height: 500px;
83
84 @media screen and (max-width: 1000px) {
85 font-size: 20px;
86 }
87
88 @media screen and (max-width: 600px) {
89 font-size: 16px;
90 }
91 }
92
93 ::ng-deep .video-js {
94 width: 100%;
95 max-width: getPlayerWidth(66vh);
96 height: $video-height;
97
98 // VideoJS create an inner video player
99 video {
100 outline: 0;
101 position: relative !important;
102 }
103 }
104
105 @media screen and (max-width: 600px) {
106 #videojs-wrapper {
107 height: getPlayerHeight(100vw) !important;
108 }
109
110 .remote-server-down,
111 ::ng-deep .video-js {
112 width: 100vw;
113 height: getPlayerHeight(100vw) !important;
114 }
115 }
116 }
117
118 .alert {
119 text-align: center;
120 border-radius: 0;
121 }
122
123 .flex-direction-column {
124 flex-direction: column;
125 }
126
127 #video-not-found {
128 height: 300px;
129 line-height: 300px;
130 margin-top: 50px;
131 text-align: center;
132 font-weight: $font-semibold;
133 font-size: 15px;
134 }
135
136 .video-bottom {
137 display: flex;
138 margin-top: 1.5rem;
139
140 .video-info {
141 flex-grow: 1;
142 // Set min width for flex item
143 min-width: 1px;
144 max-width: 100%;
145
146 .video-info-first-row {
147 display: flex;
148
149 > div:first-child {
150 flex-grow: 1;
151 }
152
153 .video-info-name {
154 @include peertube-word-wrap;
155
156 @include margin-right(30px);
157 min-height: 40px; // Align with the action buttons
158 font-size: 27px;
159 font-weight: $font-semibold;
160 flex-grow: 1;
161 }
162
163 .video-info-first-row-bottom {
164 display: flex;
165 flex-wrap: wrap;
166 align-items: center;
167 width: 100%;
168 }
169
170 .video-info-date-views {
171 @include margin-right(10px);
172
173 margin-bottom: 10px;
174 align-self: start;
175 font-size: 1em;
176 }
177
178 .video-info-channel {
179 font-weight: $font-semibold;
180 font-size: 15px;
181
182 a {
183 @include disable-default-a-behaviour;
184 @include peertube-word-wrap;
185
186 color: pvar(--mainForegroundColor);
187
188 &:hover {
189 opacity: 0.8;
190 }
191 }
192
193 .video-info-channel-left {
194 flex-grow: 1;
195
196 .video-info-channel-left-links {
197 display: flex;
198 flex-direction: column;
199 position: relative;
200 line-height: 1.37;
201
202 a:nth-of-type(2) {
203 font-weight: $font-regular;
204 font-size: 90%;
205 }
206
207 a.single-link {
208 margin-top: 7px;
209 }
210 }
211 }
212
213 my-subscribe-button {
214 @include margin-left(5px);
215 }
216 }
217
218 .video-actions-rates {
219 @include margin-left(auto);
220 @include margin-right(0);
221
222 margin-top: 0;
223 margin-bottom: 10px;
224
225 align-items: start;
226 width: max-content;
227
228 .video-actions {
229 height: 40px; // Align with the title
230 display: flex;
231 align-items: center;
232
233 .action-button:not(:first-child),
234 .action-dropdown,
235 my-video-actions-dropdown {
236 @include margin-left(5px);
237 }
238
239 ::ng-deep.action-button {
240 @include peertube-button;
241 @include button-with-icon(21px, 0, -1px);
242 @include apply-svg-color(pvar(--actionButtonColor));
243
244 font-size: 100%;
245 font-weight: $font-semibold;
246 display: inline-block;
247 padding: 0 10px;
248 white-space: nowrap;
249 background-color: transparent !important;
250 color: pvar(--actionButtonColor);
251 text-transform: uppercase;
252
253 &::after {
254 display: none;
255 }
256
257 &:hover {
258 opacity: 0.9;
259 }
260
261 &.action-button-like,
262 &.action-button-dislike {
263 filter: brightness(120%);
264
265 .count {
266 margin: 0 5px;
267 }
268 }
269
270 &.action-button-like.activated {
271 .count {
272 color: pvar(--activatedActionButtonColor);
273 }
274
275 my-global-icon {
276 @include apply-svg-color(pvar(--activatedActionButtonColor));
277 }
278 }
279
280 &.action-button-dislike.activated {
281 .count {
282 color: pvar(--activatedActionButtonColor);
283 }
284
285 my-global-icon {
286 @include apply-svg-color(pvar(--activatedActionButtonColor));
287 }
288 }
289
290 &.action-button-support {
291 color: pvar(--supportButtonColor);
292
293 my-global-icon {
294 @include apply-svg-color(pvar(--supportButtonColor));
295 }
296 }
297
298 &.action-button-support {
299 my-global-icon {
300 ::ng-deep path:first-child {
301 fill: pvar(--supportButtonHeartColor) !important;
302 }
303 }
304 }
305
306 &.action-button-save {
307 my-global-icon {
308 top: 0 !important;
309 right: -1px;
310 }
311 }
312
313 .icon-text {
314 @include margin-left(3px);
315 }
316 }
317 }
318
319 .video-info-likes-dislikes-bar-outer-container {
320 position: relative;
321 }
322
323 .video-info-likes-dislikes-bar-inner-container {
324 position: absolute;
325 height: 20px;
326 }
327
328 .video-info-likes-dislikes-bar {
329 $likes-bar-height: 2px;
330 height: $likes-bar-height;
331 margin-top: -$likes-bar-height;
332 width: 120px;
333 background-color: #ccc;
334 position: relative;
335 top: 10px;
336
337 .likes-bar {
338 height: 100%;
339 background-color: #909090;
340
341 &.liked {
342 background-color: pvar(--activatedActionButtonColor);
343 }
344 }
345 }
346 }
347 }
348
349 .video-info-description {
350 @include margin-left($video-info-margin-left);
351 @include margin-right(0);
352
353 margin-top: 20px;
354 margin-bottom: 20px;
355 font-size: 15px;
356
357 .video-info-description-html {
358 @include peertube-word-wrap;
359
360 ::ng-deep a {
361 text-decoration: none;
362 }
363 }
364
365 .glyphicon,
366 .description-loading {
367 @include margin-left(3px);
368 }
369
370 .description-loading {
371 display: inline-block;
372 }
373
374 .video-info-description-more {
375 cursor: pointer;
376 font-weight: $font-semibold;
377 color: pvar(--greyForegroundColor);
378 font-size: 14px;
379
380 .glyphicon {
381 position: relative;
382 top: 2px;
383 }
384 }
385 }
386
387 .video-attributes {
388 @include margin-left($video-info-margin-left);
389 }
390
391 .video-attributes .video-attribute {
392 font-size: 13px;
393 display: block;
394 margin-bottom: 12px;
395
396 .video-attribute-label {
397 @include padding-right(5px);
398
399 min-width: 142px;
400 display: inline-block;
401 color: pvar(--greyForegroundColor);
402 font-weight: $font-bold;
403 }
404
405 a.video-attribute-value {
406 @include disable-default-a-behaviour;
407 color: pvar(--mainForegroundColor);
408
409 &:hover {
410 opacity: 0.9;
411 }
412 }
413
414 &.video-attribute-tags {
415 .video-attribute-value:not(:nth-child(2)) {
416 &::before {
417 content: ', ';
418 }
419 }
420 }
421 }
422 }
423 }
424
425 my-recommended-videos {
426 @include padding-left(15px);
427
428 display: block;
429 min-width: 250px;
430 }
431
432 my-video-comments {
433 display: inline-block;
434 width: 100%;
435 margin-bottom: 20px;
436 }
437
438 // If the view is not expanded, take into account the menu
439 .privacy-concerns {
440 z-index: z(dropdown) + 1;
441 width: calc(100% - #{$menu-width});
442 }
443
444 @media screen and (max-width: $small-view) {
445 .privacy-concerns {
446 @include margin-left($menu-width - 15px); // Menu is absolute
447 }
448 }
449
450 :host-context(.expanded) {
451 .privacy-concerns {
452 @include margin-left(-15px);
453
454 width: 100%;
455 }
456 }
457
458 .privacy-concerns {
459 position: fixed;
460 bottom: 0;
461 z-index: z(privacymsg);
462
463 padding: 5px 15px;
464
465 display: flex;
466 flex-wrap: nowrap;
467 align-items: center;
468 justify-content: space-between;
469 background-color: rgba(0, 0, 0, 0.9);
470 color: #fff;
471
472 .privacy-concerns-text {
473 margin: 0 5px;
474 }
475
476 a {
477 @include disable-default-a-behaviour;
478
479 color: pvar(--mainColor);
480 transition: color 0.3s;
481
482 &:hover {
483 color: #fff;
484 }
485 }
486
487 .privacy-concerns-button {
488 @include margin-left(auto);
489
490 padding: 5px 8px 5px 7px;
491 border-radius: 3px;
492 white-space: nowrap;
493 cursor: pointer;
494 transition: background-color 0.3s;
495 font-weight: $font-semibold;
496
497 &:hover {
498 background-color: #000;
499 }
500 }
501
502 .privacy-concerns-okay {
503 @include margin-left(10px);
504
505 background-color: pvar(--mainColor);
506 }
507 }
508
509 @media screen and (max-width: 1600px) {
510 .video-bottom .video-info .video-attributes .video-attribute {
511 margin-bottom: 5px;
512 }
513 }
514
515 @media screen and (max-width: 1300px) {
516 .privacy-concerns {
517 font-size: 12px;
518 padding: 2px 5px;
519
520 .privacy-concerns-text {
521 margin: 0;
522 }
523 }
524 }
525
526 // Use the same breakpoint than in the typescript component to display the other video miniatures as row
527 @media screen and (max-width: 1100px) {
528 #video-wrapper {
529 flex-direction: column;
530 justify-content: center;
531
532 my-video-watch-playlist ::ng-deep .playlist {
533 @include playlist-below-player;
534 }
535 }
536
537 .video-bottom {
538 flex-direction: column;
539 }
540
541 my-recommended-videos {
542 @include padding-left(0);
543 }
544 }
545
546 @media screen and (max-width: 600px) {
547 .video-bottom {
548 margin-top: 20px !important;
549 padding-bottom: 20px !important;
550
551 .video-info {
552 padding: 0;
553
554 .video-info-first-row {
555
556 .video-info-name {
557 font-size: 20px;
558 height: auto;
559 }
560 }
561 }
562 }
563
564 .privacy-concerns {
565 width: 100%;
566 }
567 }
568
569 @media screen and (max-width: 450px) {
570 .video-bottom {
571 .action-button .icon-text {
572 display: none !important;
573 }
574
575 .video-info .video-info-first-row {
576 .video-info-name {
577 font-size: 18px;
578 }
579
580 .video-info-date-views {
581 font-size: 14px;
582 }
583
584 .video-actions-rates {
585 margin-top: 10px;
586 }
587 }
588
589 .video-info-description {
590 font-size: 14px !important;
591 }
592 }
593 }
594
595
596 // Special case for iOS, that takes into account the width for fullscreens
597 #video-wrapper ::ng-deep .video-js.vjs-fullscreen {
598 max-width: unset;
599 }