X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2F%2Bmy-account%2Fmy-account-video-playlists%2Fmy-account-video-playlist-elements.component.ts;h=25d51d2cbdb5de89f0201ae0ff7c982048872c1c;hb=97567dd81f508dd6295ac4d73d849aa2ce0a6549;hp=76aff3d4fc0c3aab8d4f9e772924dfe1daeb4323;hpb=c5a1ae500e68b759f76851552be6dd10631d34f4;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts index 76aff3d4f..25d51d2cb 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts @@ -1,18 +1,17 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core' +import { Component, OnDestroy, OnInit } from '@angular/core' import { Notifier, ServerService } from '@app/core' import { AuthService } from '../../core/auth' import { ConfirmService } from '../../core/confirm' import { ComponentPagination } from '@app/shared/rest/component-pagination.model' import { Video } from '@app/shared/video/video.model' -import { Subscription } from 'rxjs' +import { Subject, Subscription } from 'rxjs' import { ActivatedRoute } from '@angular/router' import { VideoService } from '@app/shared/video/video.service' import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' import { I18n } from '@ngx-translate/i18n-polyfill' -import { secondsToTime } from '../../../assets/player/utils' -import { VideoPlaylistElementUpdate } from '@shared/models' -import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' +import { CdkDragDrop, CdkDragMove } from '@angular/cdk/drag-drop' +import { throttleTime } from 'rxjs/operators' @Component({ selector: 'my-account-video-playlist-elements', @@ -20,28 +19,18 @@ import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' styleUrls: [ './my-account-video-playlist-elements.component.scss' ] }) export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestroy { - @ViewChild('moreDropdown') moreDropdown: NgbDropdown - videos: Video[] = [] playlist: VideoPlaylist pagination: ComponentPagination = { currentPage: 1, - itemsPerPage: 10, + itemsPerPage: 30, totalItems: null } - displayTimestampOptions = false - - timestampOptions: { - startTimestampEnabled: boolean - startTimestamp: number - stopTimestampEnabled: boolean - stopTimestamp: number - } = {} as any - private videoPlaylistId: string | number private paramsSub: Subscription + private dragMoveSubject = new Subject() constructor ( private authService: AuthService, @@ -61,50 +50,69 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro this.loadPlaylistInfo() }) + + this.dragMoveSubject.asObservable() + .pipe(throttleTime(200)) + .subscribe(y => this.checkScroll(y)) } ngOnDestroy () { if (this.paramsSub) this.paramsSub.unsubscribe() } - isVideoBlur (video: Video) { - return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig()) - } + drop (event: CdkDragDrop) { + const previousIndex = event.previousIndex + const newIndex = event.currentIndex - removeFromPlaylist (video: Video) { - this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, video.id) - .subscribe( - () => { - this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName })) + if (previousIndex === newIndex) return - this.videos = this.videos.filter(v => v.id !== video.id) - }, + const oldPosition = this.videos[previousIndex].playlistElement.position + const insertAfter = newIndex === 0 ? 0 : this.videos[newIndex].playlistElement.position - err => this.notifier.error(err.message) - ) + this.videoPlaylistService.reorderPlaylist(this.playlist.id, oldPosition, insertAfter) + .subscribe( + () => { /* nothing to do */ }, - this.moreDropdown.close() - } + err => this.notifier.error(err.message) + ) - updateTimestamps (video: Video) { - const body: VideoPlaylistElementUpdate = {} + const video = this.videos[previousIndex] - body.startTimestamp = this.timestampOptions.startTimestampEnabled ? this.timestampOptions.startTimestamp : null - body.stopTimestamp = this.timestampOptions.stopTimestampEnabled ? this.timestampOptions.stopTimestamp : null + this.videos.splice(previousIndex, 1) + this.videos.splice(newIndex, 0, video) - this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, video.id, body) - .subscribe( - () => { - this.notifier.success(this.i18n('Timestamps updated')) + this.reorderClientPositions() + } - video.playlistElement.startTimestamp = body.startTimestamp - video.playlistElement.stopTimestamp = body.stopTimestamp - }, + onDragMove (event: CdkDragMove) { + this.dragMoveSubject.next(event.pointerPosition.y) + } - err => this.notifier.error(err.message) - ) + checkScroll (pointerY: number) { + // FIXME: Uncomment when https://github.com/angular/material2/issues/14098 is fixed + // FIXME: Remove when https://github.com/angular/material2/issues/13588 is implemented + // if (pointerY < 150) { + // window.scrollBy({ + // left: 0, + // top: -20, + // behavior: 'smooth' + // }) + // + // return + // } + // + // if (window.innerHeight - pointerY <= 50) { + // window.scrollBy({ + // left: 0, + // top: 20, + // behavior: 'smooth' + // }) + // } + } - this.moreDropdown.close() + onElementRemoved (video: Video) { + this.videos = this.videos.filter(v => v.id !== video.id) + this.reorderClientPositions() } onNearOfBottom () { @@ -115,48 +123,8 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro this.loadElements() } - formatTimestamp (video: Video) { - const start = video.playlistElement.startTimestamp - const stop = video.playlistElement.stopTimestamp - - const startFormatted = secondsToTime(start, true, ':') - const stopFormatted = secondsToTime(stop, true, ':') - - if (start === null && stop === null) return '' - - if (start !== null && stop === null) return this.i18n('Starts at ') + startFormatted - if (start === null && stop !== null) return this.i18n('Stops at ') + stopFormatted - - return this.i18n('Starts at ') + startFormatted + this.i18n(' and stops at ') + stopFormatted - } - - onDropdownOpenChange () { - this.displayTimestampOptions = false - } - - toggleDisplayTimestampsOptions (event: Event, video: Video) { - event.preventDefault() - - this.displayTimestampOptions = !this.displayTimestampOptions - - if (this.displayTimestampOptions === true) { - this.timestampOptions = { - startTimestampEnabled: false, - stopTimestampEnabled: false, - startTimestamp: 0, - stopTimestamp: video.duration - } - - if (video.playlistElement.startTimestamp) { - this.timestampOptions.startTimestampEnabled = true - this.timestampOptions.startTimestamp = video.playlistElement.startTimestamp - } - - if (video.playlistElement.stopTimestamp) { - this.timestampOptions.stopTimestampEnabled = true - this.timestampOptions.stopTimestamp = video.playlistElement.stopTimestamp - } - } + trackByFn (index: number, elem: Video) { + return elem.id } private loadElements () { @@ -173,4 +141,13 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro this.playlist = playlist }) } + + private reorderClientPositions () { + let i = 1 + + for (const video of this.videos) { + video.playlistElement.position = i + i++ + } + } }