]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/+videos/+video-watch/video-watch-playlist.component.ts
Merge remote-tracking branch 'weblate/develop' into develop
[github/Chocobozzz/PeerTube.git] / client / src / app / +videos / +video-watch / video-watch-playlist.component.ts
index c60ca46713907f48367d4631a25e29645b4cccb8..0a4d6bfd11c66d2dd6a9e0852a28a182b332e167 100644 (file)
@@ -1,9 +1,10 @@
-import { Component, Input } from '@angular/core'
+
+import { Component, EventEmitter, Input, Output } from '@angular/core'
 import { Router } from '@angular/router'
 import { AuthService, ComponentPagination, LocalStorageService, Notifier, SessionStorageService, UserService } from '@app/core'
 import { VideoPlaylist, VideoPlaylistElement, VideoPlaylistService } from '@app/shared/shared-video-playlist'
 import { peertubeLocalStorage, peertubeSessionStorage } from '@root-helpers/peertube-web-storage'
-import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models'
+import { VideoPlaylistPrivacy } from '@shared/models'
 
 @Component({
   selector: 'my-video-watch-playlist',
@@ -14,9 +15,10 @@ export class VideoWatchPlaylistComponent {
   static LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'auto_play_video_playlist'
   static SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST = 'loop_playlist'
 
-  @Input() video: VideoDetails
   @Input() playlist: VideoPlaylist
 
+  @Output() videoFound = new EventEmitter<string>()
+
   playlistElements: VideoPlaylistElement[] = []
   playlistPagination: ComponentPagination = {
     currentPage: 1,
@@ -29,7 +31,8 @@ export class VideoWatchPlaylistComponent {
   loopPlaylist: boolean
   loopPlaylistSwitchText = ''
   noPlaylistVideos = false
-  currentPlaylistPosition = 1
+
+  currentPlaylistPosition: number
 
   constructor (
     private userService: UserService,
@@ -44,6 +47,7 @@ export class VideoWatchPlaylistComponent {
     this.autoPlayNextVideoPlaylist = this.auth.isLoggedIn()
       ? this.auth.getUser().autoPlayNextVideoPlaylist
       : this.localStorageService.getItem(VideoWatchPlaylistComponent.LOCAL_STORAGE_AUTO_PLAY_NEXT_VIDEO_PLAYLIST) !== 'false'
+
     this.setAutoPlayNextVideoPlaylistSwitchText()
 
     // defaults to false
@@ -51,12 +55,12 @@ export class VideoWatchPlaylistComponent {
     this.setLoopPlaylistSwitchText()
   }
 
-  onPlaylistVideosNearOfBottom () {
+  onPlaylistVideosNearOfBottom (position?: number) {
     // Last page
     if (this.playlistPagination.totalItems <= (this.playlistPagination.currentPage * this.playlistPagination.itemsPerPage)) return
 
     this.playlistPagination.currentPage += 1
-    this.loadPlaylistElements(this.playlist,false)
+    this.loadPlaylistElements(this.playlist, false, position)
   }
 
   onElementRemoved (playlistElement: VideoPlaylistElement) {
@@ -83,26 +87,26 @@ export class VideoWatchPlaylistComponent {
     return this.playlist.privacy.id === VideoPlaylistPrivacy.PUBLIC
   }
 
-  loadPlaylistElements (playlist: VideoPlaylist, redirectToFirst = false) {
+  loadPlaylistElements (playlist: VideoPlaylist, redirectToFirst = false, position?: number) {
     this.videoPlaylist.getPlaylistVideos(playlist.uuid, this.playlistPagination)
         .subscribe(({ total, data }) => {
           this.playlistElements = this.playlistElements.concat(data)
           this.playlistPagination.totalItems = total
 
-          const firstAvailableVideos = this.playlistElements.find(e => !!e.video)
-          if (!firstAvailableVideos) {
+          const firstAvailableVideo = this.playlistElements.find(e => !!e.video)
+          if (!firstAvailableVideo) {
             this.noPlaylistVideos = true
             return
           }
 
-          this.updatePlaylistIndex(this.video)
+          if (position) this.updatePlaylistIndex(position)
 
           if (redirectToFirst) {
             const extras = {
               queryParams: {
-                start: firstAvailableVideos.startTimestamp,
-                stop: firstAvailableVideos.stopTimestamp,
-                videoId: firstAvailableVideos.video.uuid
+                start: firstAvailableVideo.startTimestamp,
+                stop: firstAvailableVideo.stopTimestamp,
+                playlistPosition: firstAvailableVideo.position
               },
               replaceUrl: true
             }
@@ -111,45 +115,71 @@ export class VideoWatchPlaylistComponent {
         })
   }
 
-  updatePlaylistIndex (video: VideoDetails) {
-    if (this.playlistElements.length === 0 || !video) return
+  updatePlaylistIndex (position: number) {
+    if (this.playlistElements.length === 0 || !position) return
+
+    // Handle the reverse index
+    if (position < 0) position = this.playlist.videosLength + position + 1
 
     for (const playlistElement of this.playlistElements) {
-      if (playlistElement.video && playlistElement.video.id === video.id) {
+      // >= if the previous videos were not valid
+      if (playlistElement.video && playlistElement.position >= position) {
         this.currentPlaylistPosition = playlistElement.position
+
+        this.videoFound.emit(playlistElement.video.uuid)
+
+        setTimeout(() => {
+          document.querySelector('.element-' + this.currentPlaylistPosition).scrollIntoView(false)
+        }, 0)
+
         return
       }
     }
 
     // Load more videos to find our video
-    this.onPlaylistVideosNearOfBottom()
+    this.onPlaylistVideosNearOfBottom(position)
   }
 
-  findNextPlaylistVideo (position = this.currentPlaylistPosition): VideoPlaylistElement {
-    if (this.currentPlaylistPosition >= this.playlistPagination.totalItems) {
-      // we have reached the end of the playlist: either loop or stop
-      if (this.loopPlaylist) {
-        this.currentPlaylistPosition = position = 0
-      } else {
-        return
-      }
-    }
+  navigateToPreviousPlaylistVideo () {
+    const previous = this.findPlaylistVideo(this.currentPlaylistPosition - 1, 'previous')
+    if (!previous) return
+
+    const start = previous.startTimestamp
+    const stop = previous.stopTimestamp
+    this.router.navigate([],{ queryParams: { playlistPosition: previous.position, start, stop } })
+  }
 
-    const next = this.playlistElements.find(e => e.position === position)
+  findPlaylistVideo (position: number, type: 'previous' | 'next'): VideoPlaylistElement {
+    if (
+      (type === 'next' && position > this.playlistPagination.totalItems) ||
+      (type === 'previous' && position < 1)
+    ) {
+      // End of the playlist: end the recursion if we're not in the loop mode
+      if (!this.loopPlaylist) return
 
-    if (!next || !next.video) {
-      return this.findNextPlaylistVideo(position + 1)
+      // Loop mode
+      position = type === 'previous'
+        ? this.playlistPagination.totalItems
+        : 1
     }
 
-    return next
+    const found = this.playlistElements.find(e => e.position === position)
+    if (found && found.video) return found
+
+    const newPosition = type === 'previous'
+      ? position - 1
+      : position + 1
+
+    return this.findPlaylistVideo(newPosition, type)
   }
 
   navigateToNextPlaylistVideo () {
-    const next = this.findNextPlaylistVideo(this.currentPlaylistPosition + 1)
+    const next = this.findPlaylistVideo(this.currentPlaylistPosition + 1, 'next')
     if (!next) return
+
     const start = next.startTimestamp
     const stop = next.stopTimestamp
-    this.router.navigate([],{ queryParams: { videoId: next.video.uuid, start, stop } })
+    this.router.navigate([],{ queryParams: { playlistPosition: next.position, start, stop } })
   }
 
   switchAutoPlayNextVideoPlaylist () {