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