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