Skip to content

Commit

Permalink
Fix broken playlist api
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocobozzz committed Jul 31, 2019
1 parent 85394ba commit c2fb180
Show file tree
Hide file tree
Showing 45 changed files with 1,496 additions and 929 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
<div *ngIf="getVideosOf(videoChannel)" class="videos">
<div class="no-results" i18n *ngIf="getVideosOf(videoChannel).length === 0">This channel does not have videos.</div>

<my-video-miniature *ngFor="let video of getVideosOf(videoChannel)" [video]="video" [user]="user" [displayVideoActions]="false"></my-video-miniature>
<my-video-miniature
*ngFor="let video of getVideosOf(videoChannel)"
[video]="video" [user]="user" [displayVideoActions]="true"
></my-video-miniature>
</div>

<a class="show-more" i18n [routerLink]="getVideoChannelLink(videoChannel)">
<a *ngIf="getVideosOf(videoChannel).length !== 0" class="show-more" i18n [routerLink]="getVideoChannelLink(videoChannel)">
Show this channel
</a>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
height: 50px;
}
}

my-video-miniature ::ng-deep my-video-actions-dropdown > my-action-dropdown {
// Fix our overflow
position: absolute;
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
class="videos" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"
cdkDropList (cdkDropListDropped)="drop($event)"
>
<div class="video" *ngFor="let video of videos; trackBy: trackByFn" cdkDrag (cdkDragMoved)="onDragMove($event)">
<div class="video" *ngFor="let playlistElement of playlistElements; trackBy: trackByFn" cdkDrag>
<my-video-playlist-element-miniature
[video]="video" [playlist]="playlist" [owned]="true" (elementRemoved)="onElementRemoved($event)"
[position]="video.playlistElement.position"
[playlistElement]="playlistElement" [playlist]="playlist" [owned]="true" (elementRemoved)="onElementRemoved($event)"
[position]="playlistElement.position"
>
</my-video-playlist-element-miniature>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@ 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 { Subject, Subscription } from 'rxjs'
import { 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 { CdkDragDrop, CdkDragMove } from '@angular/cdk/drag-drop'
import { throttleTime } from 'rxjs/operators'
import { CdkDragDrop } from '@angular/cdk/drag-drop'
import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model'

@Component({
selector: 'my-account-video-playlist-elements',
templateUrl: './my-account-video-playlist-elements.component.html',
styleUrls: [ './my-account-video-playlist-elements.component.scss' ]
})
export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestroy {
videos: Video[] = []
playlistElements: VideoPlaylistElement[] = []
playlist: VideoPlaylist

pagination: ComponentPagination = {
Expand All @@ -30,7 +28,6 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro

private videoPlaylistId: string | number
private paramsSub: Subscription
private dragMoveSubject = new Subject<number>()

constructor (
private authService: AuthService,
Expand All @@ -39,7 +36,6 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
private confirmService: ConfirmService,
private route: ActivatedRoute,
private i18n: I18n,
private videoService: VideoService,
private videoPlaylistService: VideoPlaylistService
) {}

Expand All @@ -50,10 +46,6 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro

this.loadPlaylistInfo()
})

this.dragMoveSubject.asObservable()
.pipe(throttleTime(200))
.subscribe(y => this.checkScroll(y))
}

ngOnDestroy () {
Expand All @@ -66,8 +58,8 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro

if (previousIndex === newIndex) return

const oldPosition = this.videos[previousIndex].playlistElement.position
let insertAfter = this.videos[newIndex].playlistElement.position
const oldPosition = this.playlistElements[previousIndex].position
let insertAfter = this.playlistElements[newIndex].position

if (oldPosition > insertAfter) insertAfter--

Expand All @@ -78,42 +70,16 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
err => this.notifier.error(err.message)
)

const video = this.videos[previousIndex]
const element = this.playlistElements[previousIndex]

this.videos.splice(previousIndex, 1)
this.videos.splice(newIndex, 0, video)
this.playlistElements.splice(previousIndex, 1)
this.playlistElements.splice(newIndex, 0, element)

this.reorderClientPositions()
}

onDragMove (event: CdkDragMove<any>) {
this.dragMoveSubject.next(event.pointerPosition.y)
}

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'
// })
// }
}

onElementRemoved (video: Video) {
this.videos = this.videos.filter(v => v.id !== video.id)
onElementRemoved (element: VideoPlaylistElement) {
this.playlistElements = this.playlistElements.filter(v => v.id !== element.id)
this.reorderClientPositions()
}

Expand All @@ -125,14 +91,14 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
this.loadElements()
}

trackByFn (index: number, elem: Video) {
trackByFn (index: number, elem: VideoPlaylistElement) {
return elem.id
}

private loadElements () {
this.videoService.getPlaylistVideos(this.videoPlaylistId, this.pagination)
this.videoPlaylistService.getPlaylistVideos(this.videoPlaylistId, this.pagination)
.subscribe(({ total, data }) => {
this.videos = this.videos.concat(data)
this.playlistElements = this.playlistElements.concat(data)
this.pagination.totalItems = total
})
}
Expand All @@ -147,8 +113,8 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
private reorderClientPositions () {
let i = 1

for (const video of this.videos) {
video.playlistElement.position = i
for (const element of this.playlistElements) {
element.position = i
i++
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
}
displayOptions = false

private playlistElementId: number

constructor (
protected formValidatorService: FormValidatorService,
private authService: AuthService,
Expand Down Expand Up @@ -96,6 +98,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
startTimestamp: existingPlaylist ? existingPlaylist.startTimestamp : undefined,
stopTimestamp: existingPlaylist ? existingPlaylist.stopTimestamp : undefined
})

this.playlistElementId = existingPlaylist ? existingPlaylist.playlistElementId : undefined
}

this.cd.markForCheck()
Expand Down Expand Up @@ -177,7 +181,9 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
}

private removeVideoFromPlaylist (playlist: PlaylistSummary) {
this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, this.video.id)
if (!this.playlistElementId) return

this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, this.playlistElementId)
.subscribe(
() => {
this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,82 @@
</div>

<my-video-thumbnail
[video]="video" [nsfw]="isVideoBlur(video)"
*ngIf="playlistElement.video"
[video]="playlistElement.video" [nsfw]="isVideoBlur(playlistElement.video)"
[routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
></my-video-thumbnail>

<div class="fake-thumbnail" *ngIf="!playlistElement.video"></div>

<div class="video-info">
<a tabindex="-1" class="video-info-name"
[routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
[attr.title]="video.name"
>{{ video.name }}</a>
<ng-container *ngIf="playlistElement.video">
<a tabindex="-1" class="video-info-name"
[routerLink]="buildRouterLink()" [queryParams]="buildRouterQuery()"
[attr.title]="playlistElement.video.name"
>{{ playlistElement.video.name }}</a>

<a *ngIf="accountLink" tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', playlistElement.video.byAccount ]">
{{ playlistElement.video.byAccount }}
</a>
<span *ngIf="!accountLink" tabindex="-1" class="video-info-account">{{ playlistElement.video.byAccount }}</span>

<a *ngIf="accountLink" tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', video.byAccount ]">{{ video.byAccount }}</a>
<span *ngIf="!accountLink" tabindex="-1" class="video-info-account">{{ video.byAccount }}</span>
<span tabindex="-1" class="video-info-timestamp">{{ formatTimestamp(playlistElement) }}</span>
</ng-container>

<span tabindex="-1" class="video-info-timestamp">{{ formatTimestamp(video) }}</span>
<span *ngIf="!playlistElement.video" class="video-info-name">
<ng-container i18n *ngIf="isUnavailable(playlistElement)">Unavailable</ng-container>
<ng-container i18n *ngIf="isPrivate(playlistElement)">Private</ng-container>
<ng-container i18n *ngIf="isDeleted(playlistElement)">Deleted</ng-container>
</span>
</div>
</a>

<div *ngIf="owned" class="more" ngbDropdown #moreDropdown="ngbDropdown" placement="bottom-right" (openChange)="onDropdownOpenChange()"
autoClose="outside">
<div *ngIf="owned" class="more" ngbDropdown #moreDropdown="ngbDropdown" placement="bottom-right"
(openChange)="onDropdownOpenChange()" autoClose="outside"
>
<my-global-icon iconName="more-vertical" ngbDropdownToggle role="button" class="icon-more" (click)="$event.preventDefault()"></my-global-icon>

<div ngbDropdownMenu>
<div class="dropdown-item" (click)="toggleDisplayTimestampsOptions($event, video)">
<my-global-icon iconName="edit"></my-global-icon>
<ng-container i18n>Edit starts/stops at</ng-container>
</div>
<ng-container *ngIf="playlistElement.video">
<div class="dropdown-item" (click)="toggleDisplayTimestampsOptions($event, playlistElement)">
<my-global-icon iconName="edit"></my-global-icon>
<ng-container i18n>Edit starts/stops at</ng-container>
</div>

<div class="timestamp-options" *ngIf="displayTimestampOptions">
<div>
<my-peertube-checkbox
inputName="startAt" [(ngModel)]="timestampOptions.startTimestampEnabled"
i18n-labelText labelText="Start at"
></my-peertube-checkbox>
<div class="timestamp-options" *ngIf="displayTimestampOptions">
<div>
<my-peertube-checkbox
inputName="startAt" [(ngModel)]="timestampOptions.startTimestampEnabled"
i18n-labelText labelText="Start at"
></my-peertube-checkbox>

<my-timestamp-input
[timestamp]="timestampOptions.startTimestamp"
[maxTimestamp]="video.duration"
[disabled]="!timestampOptions.startTimestampEnabled"
[(ngModel)]="timestampOptions.startTimestamp"
></my-timestamp-input>
</div>
<my-timestamp-input
[timestamp]="timestampOptions.startTimestamp"
[maxTimestamp]="playlistElement.video.duration"
[disabled]="!timestampOptions.startTimestampEnabled"
[(ngModel)]="timestampOptions.startTimestamp"
></my-timestamp-input>
</div>

<div>
<my-peertube-checkbox
inputName="stopAt" [(ngModel)]="timestampOptions.stopTimestampEnabled"
i18n-labelText labelText="Stop at"
></my-peertube-checkbox>
<div>
<my-peertube-checkbox
inputName="stopAt" [(ngModel)]="timestampOptions.stopTimestampEnabled"
i18n-labelText labelText="Stop at"
></my-peertube-checkbox>

<my-timestamp-input
[timestamp]="timestampOptions.stopTimestamp"
[maxTimestamp]="video.duration"
[disabled]="!timestampOptions.stopTimestampEnabled"
[(ngModel)]="timestampOptions.stopTimestamp"
></my-timestamp-input>
</div>
<my-timestamp-input
[timestamp]="timestampOptions.stopTimestamp"
[maxTimestamp]="playlistElement.video.duration"
[disabled]="!timestampOptions.stopTimestampEnabled"
[(ngModel)]="timestampOptions.stopTimestamp"
></my-timestamp-input>
</div>

<input type="submit" i18n-value value="Save" (click)="updateTimestamps(video)">
</div>
<input type="submit" i18n-value value="Save" (click)="updateTimestamps(playlistElement)">
</div>
</ng-container>

<span class="dropdown-item" (click)="removeFromPlaylist(video)">
<span class="dropdown-item" (click)="removeFromPlaylist(playlistElement)">
<my-global-icon iconName="delete"></my-global-icon> <ng-container i18n>Delete from {{ playlist?.displayName }}</ng-container>
</span>
</div>
Expand Down
Loading

0 comments on commit c2fb180

Please sign in to comment.