]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/videos/+video-watch/video-watch-playlist.component.ts
c6b04fd4bf5039390ed674dbfea01c0e3fa7097b
[github/Chocobozzz/PeerTube.git] / client / src / app / videos / +video-watch / video-watch-playlist.component.ts
1 import { Component, Input } from '@angular/core'
2 import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
3 import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
4 import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models'
5 import { Router } from '@angular/router'
6 import { UserService } from '@app/shared'
7 import { AuthService, Notifier } from '@app/core'
8 import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
9 import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model'
10 import { peertubeLocalStorage, peertubeSessionStorage } from '@app/shared/misc/peertube-web-storage'
11 import { I18n } from '@ngx-translate/i18n-polyfill'
12
13 @Component({
14 selector: 'my-video-watch-playlist',
15 templateUrl: './video-watch-playlist.component.html',
16 styleUrls: [ './video-watch-playlist.component.scss' ]
17 })
18 export class VideoWatchPlaylistComponent {
19 static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'auto_play_video_playlist'
20 static SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'loop_playlist'
21
22 @Input() video: VideoDetails
23 @Input() playlist: VideoPlaylist
24
25 playlistElements: VideoPlaylistElement[] = []
26 playlistPagination: ComponentPagination = {
27 currentPage: 1,
28 itemsPerPage: 30,
29 totalItems: null
30 }
31
32 autoPlayNextVideoPlaylist: boolean
33 autoPlayNextVideoPlaylistSwitchText = ''
34 loopPlaylist: boolean
35 loopPlaylistSwitchText = ''
36 noPlaylistVideos = false
37 currentPlaylistPosition = 1
38
39 constructor (
40 private userService: UserService,
41 private auth: AuthService,
42 private notifier: Notifier,
43 private i18n: I18n,
44 private videoPlaylist: VideoPlaylistService,
45 private router: Router
46 ) {
47 this.autoPlayNextVideoPlaylist = this.auth.isLoggedIn()
48 ? this.auth.getUser().autoPlayNextVideoPlaylist
49 : peertubeLocalStorage.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) !== 'false'
50 this.setAutoPlayNextVideoPlaylistSwitchText()
51
52 this.loopPlaylist = peertubeSessionStorage.getItem(VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) === 'true'
53 this.setLoopPlaylistSwitchText()
54 }
55
56 onPlaylistVideosNearOfBottom () {
57 // Last page
58 if (this.playlistPagination.totalItems <= (this.playlistPagination.currentPage * this.playlistPagination.itemsPerPage)) return
59
60 this.playlistPagination.currentPage += 1
61 this.loadPlaylistElements(this.playlist,false)
62 }
63
64 onElementRemoved (playlistElement: VideoPlaylistElement) {
65 this.playlistElements = this.playlistElements.filter(e => e.id !== playlistElement.id)
66
67 this.playlistPagination.totalItems--
68 }
69
70 isPlaylistOwned () {
71 return this.playlist.isLocal === true &&
72 this.auth.isLoggedIn() &&
73 this.playlist.ownerAccount.name === this.auth.getUser().username
74 }
75
76 isUnlistedPlaylist () {
77 return this.playlist.privacy.id === VideoPlaylistPrivacy.UNLISTED
78 }
79
80 isPrivatePlaylist () {
81 return this.playlist.privacy.id === VideoPlaylistPrivacy.PRIVATE
82 }
83
84 isPublicPlaylist () {
85 return this.playlist.privacy.id === VideoPlaylistPrivacy.PUBLIC
86 }
87
88 loadPlaylistElements (playlist: VideoPlaylist, redirectToFirst = false) {
89 this.videoPlaylist.getPlaylistVideos(playlist.uuid, this.playlistPagination)
90 .subscribe(({ total, data }) => {
91 this.playlistElements = this.playlistElements.concat(data)
92 this.playlistPagination.totalItems = total
93
94 const firstAvailableVideos = this.playlistElements.find(e => !!e.video)
95 if (!firstAvailableVideos) {
96 this.noPlaylistVideos = true
97 return
98 }
99
100 this.updatePlaylistIndex(this.video)
101
102 if (redirectToFirst) {
103 const extras = {
104 queryParams: {
105 start: firstAvailableVideos.startTimestamp,
106 stop: firstAvailableVideos.stopTimestamp,
107 videoId: firstAvailableVideos.video.uuid
108 },
109 replaceUrl: true
110 }
111 this.router.navigate([], extras)
112 }
113 })
114 }
115
116 updatePlaylistIndex (video: VideoDetails) {
117 if (this.playlistElements.length === 0 || !video) return
118
119 for (const playlistElement of this.playlistElements) {
120 if (playlistElement.video && playlistElement.video.id === video.id) {
121 this.currentPlaylistPosition = playlistElement.position
122 return
123 }
124 }
125
126 // Load more videos to find our video
127 this.onPlaylistVideosNearOfBottom()
128 }
129
130 navigateToNextPlaylistVideo (_next: VideoPlaylistElement = null) {
131 if (this.currentPlaylistPosition < this.playlistPagination.totalItems) {
132 const next = _next || this.playlistElements.find(e => e.position === this.currentPlaylistPosition + 1)
133
134 if (!next || !next.video) {
135 this.currentPlaylistPosition++
136 this.navigateToNextPlaylistVideo()
137 return
138 }
139
140 const start = next.startTimestamp
141 const stop = next.stopTimestamp
142 this.router.navigate([],{ queryParams: { videoId: next.video.uuid, start, stop } })
143 } else if (this.loopPlaylist) {
144 this.currentPlaylistPosition = 0
145 this.navigateToNextPlaylistVideo(this.playlistElements.find(e => e.position === this.currentPlaylistPosition))
146 }
147 }
148
149 switchAutoPlayNextVideoPlaylist () {
150 this.autoPlayNextVideoPlaylist = !this.autoPlayNextVideoPlaylist
151 this.setAutoPlayNextVideoPlaylistSwitchText()
152
153 peertubeLocalStorage.setItem(
154 VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST,
155 this.autoPlayNextVideoPlaylist.toString()
156 )
157
158 if (this.auth.isLoggedIn()) {
159 const details = {
160 autoPlayNextVideoPlaylist: this.autoPlayNextVideoPlaylist
161 }
162
163 this.userService.updateMyProfile(details).subscribe(
164 () => {
165 this.auth.refreshUserInformation()
166 },
167 err => this.notifier.error(err.message)
168 )
169 }
170 }
171
172 switchLoopPlaylist () {
173 this.loopPlaylist = !this.loopPlaylist
174 this.setLoopPlaylistSwitchText()
175
176 peertubeSessionStorage.setItem(
177 VideoWatchPlaylistComponent.SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST,
178 this.loopPlaylist.toString()
179 )
180 }
181
182 private setAutoPlayNextVideoPlaylistSwitchText () {
183 this.autoPlayNextVideoPlaylistSwitchText = this.autoPlayNextVideoPlaylist
184 ? this.i18n('Stop autoplaying next video')
185 : this.i18n('Autoplay next video')
186 }
187
188 private setLoopPlaylistSwitchText () {
189 this.loopPlaylistSwitchText = this.loopPlaylist
190 ? this.i18n('Stop looping playlist videos')
191 : this.i18n('Loop playlist videos')
192 }
193 }