+
()
+
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,18 +115,26 @@ export class VideoWatchPlaylistComponent {
})
}
- updatePlaylistIndex (video: VideoDetails) {
- if (this.playlistElements.length === 0 || !video) return
+ updatePlaylistIndex (position: number) {
+ if (this.playlistElements.length === 0 || !position) return
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 {
@@ -147,9 +159,10 @@ export class VideoWatchPlaylistComponent {
navigateToNextPlaylistVideo () {
const next = this.findNextPlaylistVideo(this.currentPlaylistPosition + 1)
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 () {
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 4279437d2..076c6205f 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.html
+++ b/client/src/app/+videos/+video-watch/video-watch.component.html
@@ -11,7 +11,8 @@
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 4df2c6c5e..7ff860e79 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.component.ts
@@ -53,6 +53,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
video: VideoDetails = null
videoCaptions: VideoCaption[] = []
+ playlistPosition: number
playlist: VideoPlaylist = null
completeDescriptionShown = false
@@ -140,9 +141,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
if (playlistId) this.loadPlaylist(playlistId)
})
- this.queryParamsSub = this.route.queryParams.subscribe(async queryParams => {
- const videoId = queryParams[ 'videoId' ]
- if (videoId) this.loadVideo(videoId)
+ this.queryParamsSub = this.route.queryParams.subscribe(queryParams => {
+ this.playlistPosition = queryParams[ 'playlistPosition' ]
+ this.videoWatchPlaylist.updatePlaylistIndex(this.playlistPosition)
const start = queryParams[ 'start' ]
if (this.player && start) this.player.currentTime(parseInt(start, 10))
@@ -335,6 +336,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
return genericChannelDisplayName.includes(this.video.channel.displayName)
}
+ onPlaylistVideoFound (videoId: string) {
+ this.loadVideo(videoId)
+ }
+
private loadVideo (videoId: string) {
// Video did not change
if (this.video && this.video.uuid === videoId) return
@@ -392,8 +397,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
.subscribe(playlist => {
this.playlist = playlist
- const videoId = this.route.snapshot.queryParams['videoId']
- this.videoWatchPlaylist.loadPlaylistElements(playlist, !videoId)
+ this.videoWatchPlaylist.loadPlaylistElements(playlist, !this.playlistPosition, this.playlistPosition)
})
}
@@ -458,8 +462,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.remoteServerDown = false
this.currentTime = undefined
- this.videoWatchPlaylist.updatePlaylistIndex(video)
-
if (this.isVideoBlur(this.video)) {
const res = await this.confirmService.confirm(
$localize`This video contains mature or explicit content. Are you sure you want to watch it?`,
diff --git a/client/src/app/shared/shared-main/angular/infinite-scroller.directive.ts b/client/src/app/shared/shared-main/angular/infinite-scroller.directive.ts
index f09c3d1fc..d2cf53227 100644
--- a/client/src/app/shared/shared-main/angular/infinite-scroller.directive.ts
+++ b/client/src/app/shared/shared-main/angular/infinite-scroller.directive.ts
@@ -1,6 +1,6 @@
+import { fromEvent, Observable, Subscription } from 'rxjs'
import { distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators'
import { AfterContentChecked, Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
-import { fromEvent, Observable, Subscription } from 'rxjs'
@Directive({
selector: '[myInfiniteScroller]'
@@ -80,7 +80,9 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy, AfterConten
}
private getMaximumScroll () {
- return this.container.scrollHeight - window.innerHeight
+ const elementHeight = this.onItself ? this.container.clientHeight : window.innerHeight
+
+ return this.container.scrollHeight - elementHeight
}
private hasScroll () {
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.ts b/client/src/app/shared/shared-share-modal/video-share.component.ts
index 8d8e8a3a5..f57a50770 100644
--- a/client/src/app/shared/shared-share-modal/video-share.component.ts
+++ b/client/src/app/shared/shared-share-modal/video-share.component.ts
@@ -37,6 +37,7 @@ export class VideoShareComponent {
@Input() video: VideoDetails = null
@Input() videoCaptions: VideoCaption[] = []
@Input() playlist: VideoPlaylist = null
+ @Input() playlistPosition: number = null
activeVideoId: TabId = 'url'
activePlaylistId: TabId = 'url'
@@ -45,8 +46,6 @@ export class VideoShareComponent {
isAdvancedCustomizationCollapsed = true
includeVideoInPlaylist = false
- private playlistPosition: number = null
-
constructor (private modalService: NgbModal) { }
show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
@@ -107,7 +106,7 @@ export class VideoShareComponent {
if (!this.includeVideoInPlaylist) return base
- return base + '?videoId=' + this.video.uuid
+ return base + '?playlistPosition=' + this.playlistPosition
}
notSecure () {
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts
index 5879c4978..7c083ae26 100644
--- a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts
+++ b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts
@@ -78,7 +78,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
if (!this.playlistElement || !this.playlistElement.video) return {}
return {
- videoId: this.playlistElement.video.uuid,
+ playlistPosition: this.playlistElement.position,
start: this.playlistElement.startTimestamp,
stop: this.playlistElement.stopTimestamp,
resume: true