1
0
Fork 0

Use playlistPosition for playlists instead of videoId

This commit is contained in:
Chocobozzz 2020-08-19 09:21:46 +02:00 committed by Chocobozzz
parent 3c6a44a181
commit d142c7b9c0
7 changed files with 54 additions and 34 deletions

View File

@ -1,4 +1,7 @@
<div *ngIf="playlist && video" class="playlist" myInfiniteScroller [autoInit]="true" [onItself]="true" (nearOfBottom)="onPlaylistVideosNearOfBottom()">
<div
*ngIf="playlist && currentPlaylistPosition" class="playlist"
myInfiniteScroller [autoInit]="true" [onItself]="true" (nearOfBottom)="onPlaylistVideosNearOfBottom()"
>
<div class="playlist-info">
<div class="playlist-display-name">
{{ playlist.displayName }}
@ -36,7 +39,7 @@
</div>
</div>
<div *ngFor="let playlistElement of playlistElements">
<div *ngFor="let playlistElement of playlistElements" [ngClass]="'element-' + playlistElement.position">
<my-video-playlist-element-miniature
[playlistElement]="playlistElement" [playlist]="playlist" [owned]="isPlaylistOwned()" (elementRemoved)="onElementRemoved($event)"
[playing]="currentPlaylistPosition === playlistElement.position" [accountLink]="false" [position]="playlistElement.position"

View 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,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 () {

View File

@ -11,7 +11,8 @@
<my-video-watch-playlist
#videoWatchPlaylist
[video]="video" [playlist]="playlist" class="playlist"
[playlist]="playlist" class="playlist"
(videoFound)="onPlaylistVideoFound($event)"
></my-video-watch-playlist>
</div>

View File

@ -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?`,

View File

@ -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 () {

View File

@ -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 () {

View File

@ -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