+
{{ video.name }}
+
Published {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views
-
-
-
{{ video.name }}
-
-
- Published {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Support
-
-
-
-
- Share
-
-
-
-
-
+
+
+
+
+
+
+
+ Support
+
+
+
+
+ Share
+
+
+
+
+
-
-
-
-
-
-
-
-
+
-
+
+
+
+
= 250" (click)="showMoreDescription()">
+ Show more
+
+
+
+
+
+ Show less
+
+
+
+
+
+
+ Privacy
+ {{ video.privacy.label }}
+
+
+
+ Originally published
+ {{ video.originallyPublishedAt | date: 'dd MMMM yyyy' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss
index 281b9240b..11406e887 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -4,9 +4,43 @@
@import '_miniature';
$other-videos-width: 260px;
+$player-factor: 1.7; // 16/9
-.root-row {
- flex-direction: column;
+@function getPlayerHeight($width){
+ @return calc(#{$width} / #{$player-factor})
+}
+
+@function getPlayerWidth($height){
+ @return calc(#{$height} * #{$player-factor})
+}
+
+@mixin playlist-below-player {
+ width: 100%;
+ border-bottom: 1px solid $separator-border-color;
+}
+
+.root {
+ margin: 0 -15px;
+
+ &.theater-enabled #video-wrapper {
+ flex-direction: column;
+ justify-content: center;
+
+ #videojs-wrapper {
+ width: 100%;
+ }
+
+ /deep/ .video-js {
+ $height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
+
+ height: $height;
+ width: 100%;
+ }
+
+ .playlist {
+ @include playlist-below-player;
+ }
+ }
}
.blacklisted-label {
@@ -17,7 +51,6 @@ $other-videos-width: 260px;
background-color: #000;
display: flex;
justify-content: center;
- flex-grow: 1;
.remote-server-down {
color: #fff;
@@ -93,14 +126,9 @@ $other-videos-width: 260px;
}
/deep/ .video-js {
- width: calc(66vh * 1.77);
+ width: getPlayerWidth(66vh);
height: 66vh;
- &.vjs-theater-enabled {
- height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
- width: 100%;
- }
-
// VideoJS create an inner video player
video {
outline: 0;
@@ -112,7 +140,7 @@ $other-videos-width: 260px;
.remote-server-down,
/deep/ .video-js {
width: 100vw;
- height: calc(100vw / 1.7); // 16/9
+ height: getPlayerHeight(100vw)
}
}
}
@@ -131,6 +159,7 @@ $other-videos-width: 260px;
}
.video-bottom {
+ display: flex;
margin-top: 40px;
.video-info {
@@ -366,7 +395,7 @@ $other-videos-width: 260px;
/deep/ .other-videos {
padding-left: 15px;
- width: $other-videos-width;
+ flex-basis: $other-videos-width;
.title-page {
margin-top: 0 !important;
@@ -374,14 +403,11 @@ $other-videos-width: 260px;
.video-miniature {
display: flex;
+ width: $other-videos-width;
height: 100%;
margin-bottom: 20px;
flex-wrap: wrap;
- .video-miniature-information {
- flex-grow: 1;
- }
-
.video-thumbnail {
margin-right: 10px
}
@@ -455,12 +481,6 @@ my-video-comments {
}
}
-@media screen and (min-width: map-get($grid-breakpoints, xl)) {
- .video-bottom .video-info {
- max-width: calc(100% - #{$other-videos-width});
- }
-}
-
@media screen and (max-width: 1600px) {
.video-bottom .video-info .video-attributes .video-attribute {
margin-bottom: 5px;
@@ -478,6 +498,37 @@ my-video-comments {
}
}
+@media screen and (max-width: 1100px) {
+ .video-bottom {
+ flex-direction: column;
+
+ /deep/ .other-videos {
+ padding-left: 0 !important;
+
+ /deep/ .video-miniature {
+ flex-direction: row;
+ width: auto;
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 900px) {
+ #video-wrapper {
+ flex-direction: column;
+ justify-content: center;
+
+ #videojs-wrapper {
+ display: flex;
+ justify-content: center;
+ }
+
+ .playlist {
+ @include playlist-below-player;
+ }
+ }
+}
+
@media screen and (max-width: 600px) {
.video-bottom {
margin: 20px 0 0 0;
@@ -495,12 +546,8 @@ my-video-comments {
}
}
- /deep/ .other-videos {
- padding-left: 0 !important;
-
- /deep/ .video-miniature {
- flex-direction: column;
- }
+ /deep/ .other-videos .video-miniature {
+ flex-direction: column;
}
.privacy-concerns {
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index adb728aba..cedbbf985 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -50,6 +50,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
player: any
playerElement: HTMLVideoElement
+ theaterEnabled = false
userRating: UserVideoRateType = null
video: VideoDetails = null
descriptionLoading = false
@@ -572,6 +573,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.zone.runOutsideAngular(async () => {
this.player = await PeertubePlayerManager.initialize(mode, options)
+ this.theaterEnabled = this.player.theaterEnabled
+
this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))
this.player.on('timeupdate', () => {
@@ -589,6 +592,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.zone.run(() => this.navigateToNextPlaylistVideo())
}
})
+
+ this.player.on('theaterChange', (_: any, enabled: boolean) => {
+ this.zone.run(() => this.theaterEnabled = enabled)
+ })
})
this.setVideoDescriptionHTML()
diff --git a/client/src/assets/player/videojs-components/theater-button.ts b/client/src/assets/player/videojs-components/theater-button.ts
index 1e11a9546..bf383cf34 100644
--- a/client/src/assets/player/videojs-components/theater-button.ts
+++ b/client/src/assets/player/videojs-components/theater-button.ts
@@ -16,8 +16,11 @@ class TheaterButton extends Button {
const enabled = getStoredTheater()
if (enabled === true) {
this.player_.addClass(TheaterButton.THEATER_MODE_CLASS)
+
this.handleTheaterChange()
}
+
+ this.player_.theaterEnabled = enabled
}
buildCSSClass () {
@@ -25,13 +28,17 @@ class TheaterButton extends Button {
}
handleTheaterChange () {
- if (this.isTheaterEnabled()) {
+ const theaterEnabled = this.isTheaterEnabled()
+
+ if (theaterEnabled) {
this.controlText('Normal mode')
} else {
this.controlText('Theater mode')
}
- saveTheaterInStore(this.isTheaterEnabled())
+ saveTheaterInStore(theaterEnabled)
+
+ this.player_.trigger('theaterChange', theaterEnabled)
}
handleClick () {
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts
index 6c6d208f5..d573bf024 100644
--- a/server/tests/api/users/user-notifications.ts
+++ b/server/tests/api/users/user-notifications.ts
@@ -216,7 +216,7 @@ describe('Test users notifications', function () {
})
it('Should send a new video notification on a remote scheduled publication', async function () {
- this.timeout(20000)
+ this.timeout(50000)
// In 2 seconds
let updateAt = new Date(new Date().getTime() + 2000)
@@ -238,7 +238,7 @@ describe('Test users notifications', function () {
it('Should not send a notification before the video is published', async function () {
this.timeout(20000)
- let updateAt = new Date(new Date().getTime() + 100000)
+ let updateAt = new Date(new Date().getTime() + 1000000)
const data = {
privacy: VideoPrivacy.PRIVATE,