aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2019-12-11 20:20:42 +0100
committerChocobozzz <chocobozzz@cpy.re>2019-12-13 09:13:43 +0100
commitbee29df8a9ba3090be3daa8ff806dd9a26d7a5cf (patch)
tree9e9f6d509ed24f799f82667109498b9561474a4d /client/src
parentd816f3a063febac1cad09ab3a32e5f0d29353627 (diff)
downloadPeerTube-bee29df8a9ba3090be3daa8ff806dd9a26d7a5cf.tar.gz
PeerTube-bee29df8a9ba3090be3daa8ff806dd9a26d7a5cf.tar.zst
PeerTube-bee29df8a9ba3090be3daa8ff806dd9a26d7a5cf.zip
autoplay next video support for playlists
Diffstat (limited to 'client/src')
-rw-r--r--client/src/app/shared/images/global-icon.component.scss8
-rw-r--r--client/src/app/shared/users/user.model.ts1
-rw-r--r--client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss4
-rw-r--r--client/src/app/videos/+video-watch/video-watch-playlist.component.html11
-rw-r--r--client/src/app/videos/+video-watch/video-watch-playlist.component.scss15
-rw-r--r--client/src/app/videos/+video-watch/video-watch-playlist.component.ts48
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html1
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts13
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts4
-rw-r--r--client/src/app/videos/recommendations/recommended-videos.component.html8
-rw-r--r--client/src/app/videos/recommendations/recommended-videos.component.ts4
11 files changed, 100 insertions, 17 deletions
diff --git a/client/src/app/shared/images/global-icon.component.scss b/client/src/app/shared/images/global-icon.component.scss
index 32fb9badb..6795d6628 100644
--- a/client/src/app/shared/images/global-icon.component.scss
+++ b/client/src/app/shared/images/global-icon.component.scss
@@ -1,4 +1,6 @@
1::ng-deep svg { 1::ng-deep {
2 width: inherit; 2 svg {
3 height: inherit; 3 width: inherit;
4 height: inherit;
5 }
4} 6}
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts
index e0b3f1faf..7707d7dda 100644
--- a/client/src/app/shared/users/user.model.ts
+++ b/client/src/app/shared/users/user.model.ts
@@ -17,6 +17,7 @@ export class User implements UserServerModel {
17 17
18 autoPlayVideo: boolean 18 autoPlayVideo: boolean
19 autoPlayNextVideo: boolean 19 autoPlayNextVideo: boolean
20 autoPlayNextVideoPlaylist: boolean
20 webTorrentEnabled: boolean 21 webTorrentEnabled: boolean
21 videosHistoryEnabled: boolean 22 videosHistoryEnabled: boolean
22 videoLanguages: string[] 23 videoLanguages: string[]
diff --git a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
index b55ca0dea..4d9d249d9 100644
--- a/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
+++ b/client/src/app/shared/video-playlist/video-playlist-element-miniature.component.scss
@@ -72,10 +72,6 @@ my-video-thumbnail,
72 72
73 a { 73 a {
74 width: auto; 74 width: auto;
75
76 &:hover {
77 text-decoration: underline !important;
78 }
79 } 75 }
80 76
81 .video-info-account, .video-info-timestamp { 77 .video-info-account, .video-info-timestamp {
diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.html b/client/src/app/videos/+video-watch/video-watch-playlist.component.html
index c89936bd1..c07ba1ed6 100644
--- a/client/src/app/videos/+video-watch/video-watch-playlist.component.html
+++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.html
@@ -14,6 +14,17 @@
14 <span>{{ currentPlaylistPosition }}</span><span>{{ playlistPagination.totalItems }}</span> 14 <span>{{ currentPlaylistPosition }}</span><span>{{ playlistPagination.totalItems }}</span>
15 </div> 15 </div>
16 </div> 16 </div>
17
18 <div class="playlist-controls">
19 <my-global-icon
20 iconName="videos"
21 [class.active]="autoPlayNextVideoPlaylist"
22 (click)="switchAutoPlayNextVideoPlaylist()"
23 [ngbTooltip]="autoPlayNextVideoPlaylistSwitchText"
24 placement="bottom auto"
25 container="body"
26 ></my-global-icon>
27 </div>
17 </div> 28 </div>
18 29
19 <div *ngFor="let playlistElement of playlistElements"> 30 <div *ngFor="let playlistElement of playlistElements">
diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.scss b/client/src/app/videos/+video-watch/video-watch-playlist.component.scss
index 4c24d6b05..ba8d1c3e1 100644
--- a/client/src/app/videos/+video-watch/video-watch-playlist.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.scss
@@ -34,6 +34,21 @@
34 margin: 0 3px; 34 margin: 0 3px;
35 } 35 }
36 } 36 }
37
38 .playlist-controls {
39 display: flex;
40 margin: 10px 0;
41
42 my-global-icon {
43 &:not(.active) {
44 opacity: .5
45 }
46
47 ::ng-deep {
48 cursor: pointer;
49 }
50 }
51 }
37 } 52 }
38 53
39 my-video-playlist-element-miniature { 54 my-video-playlist-element-miniature {
diff --git a/client/src/app/videos/+video-watch/video-watch-playlist.component.ts b/client/src/app/videos/+video-watch/video-watch-playlist.component.ts
index 524055ce2..ed2aeda6e 100644
--- a/client/src/app/videos/+video-watch/video-watch-playlist.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch-playlist.component.ts
@@ -3,9 +3,12 @@ import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
3import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 3import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
4import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models' 4import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models'
5import { Router } from '@angular/router' 5import { Router } from '@angular/router'
6import { AuthService } from '@app/core' 6import { User, UserService } from '@app/shared'
7import { AuthService, Notifier } from '@app/core'
7import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' 8import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
8import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' 9import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model'
10import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
11import { I18n } from '@ngx-translate/i18n-polyfill'
9 12
10@Component({ 13@Component({
11 selector: 'my-video-watch-playlist', 14 selector: 'my-video-watch-playlist',
@@ -13,6 +16,8 @@ import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-
13 styleUrls: [ './video-watch-playlist.component.scss' ] 16 styleUrls: [ './video-watch-playlist.component.scss' ]
14}) 17})
15export class VideoWatchPlaylistComponent { 18export class VideoWatchPlaylistComponent {
19 static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'auto_play_video_playlist'
20
16 @Input() video: VideoDetails 21 @Input() video: VideoDetails
17 @Input() playlist: VideoPlaylist 22 @Input() playlist: VideoPlaylist
18 23
@@ -23,14 +28,24 @@ export class VideoWatchPlaylistComponent {
23 totalItems: null 28 totalItems: null
24 } 29 }
25 30
31 autoPlayNextVideoPlaylist: boolean
32 autoPlayNextVideoPlaylistSwitchText = ''
26 noPlaylistVideos = false 33 noPlaylistVideos = false
27 currentPlaylistPosition = 1 34 currentPlaylistPosition = 1
28 35
29 constructor ( 36 constructor (
37 private userService: UserService,
30 private auth: AuthService, 38 private auth: AuthService,
39 private notifier: Notifier,
40 private i18n: I18n,
31 private videoPlaylist: VideoPlaylistService, 41 private videoPlaylist: VideoPlaylistService,
32 private router: Router 42 private router: Router
33 ) {} 43 ) {
44 this.autoPlayNextVideoPlaylist = this.auth.isLoggedIn()
45 ? this.auth.getUser().autoPlayNextVideoPlaylist
46 : peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) !== 'false'
47 this.setAutoPlayNextVideoPlaylistSwitchText()
48 }
34 49
35 onPlaylistVideosNearOfBottom () { 50 onPlaylistVideosNearOfBottom () {
36 // Last page 51 // Last page
@@ -121,4 +136,33 @@ export class VideoWatchPlaylistComponent {
121 this.router.navigate([],{ queryParams: { videoId: next.video.uuid, start, stop } }) 136 this.router.navigate([],{ queryParams: { videoId: next.video.uuid, start, stop } })
122 } 137 }
123 } 138 }
139
140 switchAutoPlayNextVideoPlaylist () {
141 this.autoPlayNextVideoPlaylist = !this.autoPlayNextVideoPlaylist
142 this.setAutoPlayNextVideoPlaylistSwitchText()
143
144 peertubeLocalStorage.setItem(
145 VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST,
146 this.autoPlayNextVideoPlaylist.toString()
147 )
148
149 if (this.auth.isLoggedIn()) {
150 const details = {
151 autoPlayNextVideoPlaylist: this.autoPlayNextVideoPlaylist
152 }
153
154 this.userService.updateMyProfile(details).subscribe(
155 () => {
156 this.auth.refreshUserInformation()
157 },
158 err => this.notifier.error(err.message)
159 )
160 }
161 }
162
163 private setAutoPlayNextVideoPlaylistSwitchText () {
164 this.autoPlayNextVideoPlaylistSwitchText = this.i18n('{{verb}} autoplay for playlists', {
165 verb: this.autoPlayNextVideoPlaylist ? this.i18n('Disable') : this.i18n('Enable')
166 })
167 }
124} 168}
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index c57b00032..97f3a336e 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -217,6 +217,7 @@
217 <my-recommended-videos 217 <my-recommended-videos
218 [inputRecommendation]="{ uuid: video.uuid, tags: video.tags }" 218 [inputRecommendation]="{ uuid: video.uuid, tags: video.tags }"
219 [user]="user" 219 [user]="user"
220 [playlist]="playlist"
220 (gotRecommendations)="onRecommendations($event)" 221 (gotRecommendations)="onRecommendations($event)"
221 ></my-recommended-videos> 222 ></my-recommended-videos>
222 </div> 223 </div>
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 156a3235a..f13acec40 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -37,6 +37,7 @@ import { PluginService } from '@app/core/plugins/plugin.service'
37import { HooksService } from '@app/core/plugins/hooks.service' 37import { HooksService } from '@app/core/plugins/hooks.service'
38import { PlatformLocation } from '@angular/common' 38import { PlatformLocation } from '@angular/common'
39import { randomInt } from '@shared/core-utils/miscs/miscs' 39import { randomInt } from '@shared/core-utils/miscs/miscs'
40import { RecommendedVideosComponent } from '../recommendations/recommended-videos.component'
40 41
41@Component({ 42@Component({
42 selector: 'my-video-watch', 43 selector: 'my-video-watch',
@@ -436,10 +437,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
436 437
437 this.player.one('ended', () => { 438 this.player.one('ended', () => {
438 if (this.playlist) { 439 if (this.playlist) {
439 this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo()) 440 if (
441 this.user && this.user.autoPlayNextVideoPlaylist ||
442 peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true'
443 ) this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo())
440 } else if ( 444 } else if (
441 this.user && this.user.autoPlayNextVideo || 445 this.user && this.user.autoPlayNextVideo ||
442 peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true' 446 peertubeLocalStorage.getItem(RecommendedVideosComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO) === 'true'
443 ) { 447 ) {
444 this.zone.run(() => this.autoplayNext()) 448 this.zone.run(() => this.autoplayNext())
445 } 449 }
@@ -447,7 +451,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
447 451
448 this.player.one('stopped', () => { 452 this.player.one('stopped', () => {
449 if (this.playlist) { 453 if (this.playlist) {
450 this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo()) 454 if (
455 this.user && this.user.autoPlayNextVideoPlaylist ||
456 peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true'
457 ) this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo())
451 } 458 }
452 }) 459 })
453 460
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts
index f083aca4d..2e45e5674 100644
--- a/client/src/app/videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/videos/+video-watch/video-watch.module.ts
@@ -12,6 +12,7 @@ import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
12import { RecommendationsModule } from '@app/videos/recommendations/recommendations.module' 12import { RecommendationsModule } from '@app/videos/recommendations/recommendations.module'
13import { VideoWatchPlaylistComponent } from '@app/videos/+video-watch/video-watch-playlist.component' 13import { VideoWatchPlaylistComponent } from '@app/videos/+video-watch/video-watch-playlist.component'
14import { QRCodeModule } from 'angularx-qrcode' 14import { QRCodeModule } from 'angularx-qrcode'
15import { InputSwitchModule } from 'primeng/inputswitch'
15 16
16@NgModule({ 17@NgModule({
17 imports: [ 18 imports: [
@@ -19,7 +20,8 @@ import { QRCodeModule } from 'angularx-qrcode'
19 SharedModule, 20 SharedModule,
20 NgbTooltipModule, 21 NgbTooltipModule,
21 QRCodeModule, 22 QRCodeModule,
22 RecommendationsModule 23 RecommendationsModule,
24 InputSwitchModule
23 ], 25 ],
24 26
25 declarations: [ 27 declarations: [
diff --git a/client/src/app/videos/recommendations/recommended-videos.component.html b/client/src/app/videos/recommendations/recommended-videos.component.html
index 5f223078a..c82642c1c 100644
--- a/client/src/app/videos/recommendations/recommended-videos.component.html
+++ b/client/src/app/videos/recommendations/recommended-videos.component.html
@@ -4,15 +4,17 @@
4 <div i18n class="title-page title-page-single"> 4 <div i18n class="title-page title-page-single">
5 Other videos 5 Other videos
6 </div> 6 </div>
7 <div class="d-flex title-page-autoplay"> 7 <div *ngIf="!playlist" class="d-flex title-page-autoplay">
8 <span>Autoplay</span> 8 <span i18n>Autoplay</span>
9 <p-inputSwitch [(ngModel)]="autoPlayNextVideo" (ngModelChange)="switchAutoPlayNextVideo()"></p-inputSwitch> 9 <p-inputSwitch [(ngModel)]="autoPlayNextVideo" (ngModelChange)="switchAutoPlayNextVideo()"></p-inputSwitch>
10 </div> 10 </div>
11 </div> 11 </div>
12 12
13 <div *ngFor="let video of (videos$ | async)"> 13 <div *ngFor="let video of (videos$ | async); let i = index; let length = count">
14 <my-video-miniature [video]="video" [user]="user" (videoBlacklisted)="onVideoRemoved()" (videoRemoved)="onVideoRemoved()"> 14 <my-video-miniature [video]="video" [user]="user" (videoBlacklisted)="onVideoRemoved()" (videoRemoved)="onVideoRemoved()">
15 </my-video-miniature> 15 </my-video-miniature>
16
17 <hr *ngIf="!playlist && i == 0 && length > 1" />
16 </div> 18 </div>
17 </ng-container> 19 </ng-container>
18</div> 20</div>
diff --git a/client/src/app/videos/recommendations/recommended-videos.component.ts b/client/src/app/videos/recommendations/recommended-videos.component.ts
index 4c3cde225..771ae54a2 100644
--- a/client/src/app/videos/recommendations/recommended-videos.component.ts
+++ b/client/src/app/videos/recommendations/recommended-videos.component.ts
@@ -1,6 +1,7 @@
1import { Component, Input, Output, OnChanges, EventEmitter } from '@angular/core' 1import { Component, Input, Output, OnChanges, EventEmitter } from '@angular/core'
2import { Observable } from 'rxjs' 2import { Observable } from 'rxjs'
3import { Video } from '@app/shared/video/video.model' 3import { Video } from '@app/shared/video/video.model'
4import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
4import { RecommendationInfo } from '@app/shared/video/recommendation-info.model' 5import { RecommendationInfo } from '@app/shared/video/recommendation-info.model'
5import { RecommendedVideosStore } from '@app/videos/recommendations/recommended-videos.store' 6import { RecommendedVideosStore } from '@app/videos/recommendations/recommended-videos.store'
6import { User } from '@app/shared' 7import { User } from '@app/shared'
@@ -14,10 +15,11 @@ import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
14 styleUrls: [ './recommended-videos.component.scss' ] 15 styleUrls: [ './recommended-videos.component.scss' ]
15}) 16})
16export class RecommendedVideosComponent implements OnChanges { 17export class RecommendedVideosComponent implements OnChanges {
17 private static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO = 'auto_play_next_video' 18 static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO = 'auto_play_next_video'
18 19
19 @Input() inputRecommendation: RecommendationInfo 20 @Input() inputRecommendation: RecommendationInfo
20 @Input() user: User 21 @Input() user: User
22 @Input() playlist: VideoPlaylist
21 @Output() gotRecommendations = new EventEmitter<Video[]>() 23 @Output() gotRecommendations = new EventEmitter<Video[]>()
22 24
23 readonly hasVideos$: Observable<boolean> 25 readonly hasVideos$: Observable<boolean>