fix(client/video-miniature): add to playlist

This commit is contained in:
kontrollanten 2022-10-01 16:29:54 +02:00
parent e72bb69350
commit f1a0412391
6 changed files with 59 additions and 28 deletions

View File

@ -88,8 +88,10 @@ export class VideoMiniatureComponent implements OnInit {
channelLinkTitle = '' channelLinkTitle = ''
watchLaterPlaylist: { watchLaterPlaylist: {
displayName: string
id: number id: number
playlistElementId?: number playlistElementId?: number
shortUUID: string
} }
videoRouterLink: string | any[] = [] videoRouterLink: string | any[] = []
@ -245,7 +247,7 @@ export class VideoMiniatureComponent implements OnInit {
addToWatchLater () { addToWatchLater () {
const body = { videoId: this.video.id } const body = { videoId: this.video.id }
this.videoPlaylistService.addVideoInPlaylist(this.watchLaterPlaylist.id, body) this.videoPlaylistService.addVideoInPlaylist(this.watchLaterPlaylist, body)
.subscribe( .subscribe(
res => { res => {
this.watchLaterPlaylist.playlistElementId = res.videoPlaylistElement.id this.watchLaterPlaylist.playlistElementId = res.videoPlaylistElement.id
@ -303,7 +305,9 @@ export class VideoMiniatureComponent implements OnInit {
this.inWatchLaterPlaylist = false this.inWatchLaterPlaylist = false
this.watchLaterPlaylist = { this.watchLaterPlaylist = {
id: watchLaterPlaylist.id id: watchLaterPlaylist.id,
displayName: watchLaterPlaylist.name,
shortUUID: watchLaterPlaylist.shortUUID
} }
if (existsInWatchLater) { if (existsInWatchLater) {

View File

@ -6,6 +6,7 @@ import { AuthService, DisableForReuseHook, Notifier } from '@app/core'
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
import { secondsToTime } from '@shared/core-utils' import { secondsToTime } from '@shared/core-utils'
import { import {
VideoPlaylistSummary,
Video, Video,
VideoExistInPlaylist, VideoExistInPlaylist,
VideoPlaylistCreate, VideoPlaylistCreate,
@ -25,11 +26,8 @@ type PlaylistElement = {
stopTimestamp?: number stopTimestamp?: number
} }
type PlaylistSummary = { type PlaylistSummaryWithElements = VideoPlaylistSummary & {
id: number
displayName: string
optionalRowDisplayed: boolean optionalRowDisplayed: boolean
elements: PlaylistElement[] elements: PlaylistElement[]
} }
@ -49,7 +47,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
videoPlaylistSearch: string videoPlaylistSearch: string
videoPlaylistSearchChanged = new Subject<void>() videoPlaylistSearchChanged = new Subject<void>()
videoPlaylists: PlaylistSummary[] = [] videoPlaylists: PlaylistSummaryWithElements[] = []
private disabled = false private disabled = false
@ -145,7 +143,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
this.isNewPlaylistBlockOpened = true this.isNewPlaylistBlockOpened = true
} }
toggleMainPlaylist (e: Event, playlist: PlaylistSummary) { toggleMainPlaylist (e: Event, playlist: PlaylistSummaryWithElements) {
e.preventDefault() e.preventDefault()
if (this.isPresentMultipleTimes(playlist) || playlist.optionalRowDisplayed) return if (this.isPresentMultipleTimes(playlist) || playlist.optionalRowDisplayed) return
@ -167,7 +165,13 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
this.cd.markForCheck() this.cd.markForCheck()
} }
toggleOptionalPlaylist (e: Event, playlist: PlaylistSummary, element: PlaylistElement, startTimestamp: number, stopTimestamp: number) { toggleOptionalPlaylist (
e: Event,
playlist: PlaylistSummaryWithElements,
element: PlaylistElement,
startTimestamp: number,
stopTimestamp: number
) {
e.preventDefault() e.preventDefault()
if (element.enabled) { if (element.enabled) {
@ -216,23 +220,23 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
this.videoPlaylistSearchChanged.next() this.videoPlaylistSearchChanged.next()
} }
isPrimaryCheckboxChecked (playlist: PlaylistSummary) { isPrimaryCheckboxChecked (playlist: PlaylistSummaryWithElements) {
// Reduce latency when adding a video to a playlist using pendingAddId // Reduce latency when adding a video to a playlist using pendingAddId
return this.pendingAddId === playlist.id || return this.pendingAddId === playlist.id ||
playlist.elements.filter(e => e.enabled).length !== 0 playlist.elements.filter(e => e.enabled).length !== 0
} }
toggleOptionalRow (playlist: PlaylistSummary) { toggleOptionalRow (playlist: PlaylistSummaryWithElements) {
playlist.optionalRowDisplayed = !playlist.optionalRowDisplayed playlist.optionalRowDisplayed = !playlist.optionalRowDisplayed
this.cd.markForCheck() this.cd.markForCheck()
} }
getPrimaryInputName (playlist: PlaylistSummary) { getPrimaryInputName (playlist: PlaylistSummaryWithElements) {
return 'in-playlist-primary-' + playlist.id return 'in-playlist-primary-' + playlist.id
} }
getOptionalInputName (playlist: PlaylistSummary, element?: PlaylistElement) { getOptionalInputName (playlist: PlaylistSummaryWithElements, element?: PlaylistElement) {
const suffix = element const suffix = element
? '-' + element.playlistElementId ? '-' + element.playlistElementId
: '' : ''
@ -240,7 +244,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
return 'in-playlist-optional-' + playlist.id + suffix return 'in-playlist-optional-' + playlist.id + suffix
} }
buildOptionalRowElements (playlist: PlaylistSummary) { buildOptionalRowElements (playlist: PlaylistSummaryWithElements) {
const elements = playlist.elements const elements = playlist.elements
const lastElement = elements.length === 0 const lastElement = elements.length === 0
@ -259,11 +263,11 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
return elements return elements
} }
isPresentMultipleTimes (playlist: PlaylistSummary) { isPresentMultipleTimes (playlist: PlaylistSummaryWithElements) {
return playlist.elements.filter(e => e.enabled === true).length > 1 return playlist.elements.filter(e => e.enabled === true).length > 1
} }
onElementTimestampUpdate (playlist: PlaylistSummary, element: PlaylistElement) { onElementTimestampUpdate (playlist: PlaylistSummaryWithElements, element: PlaylistElement) {
if (!element.playlistElementId || element.enabled === false) return if (!element.playlistElementId || element.enabled === false) return
const body: VideoPlaylistElementUpdate = { const body: VideoPlaylistElementUpdate = {
@ -283,7 +287,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
}) })
} }
private isOptionalRowDisplayed (playlist: PlaylistSummary) { private isOptionalRowDisplayed (playlist: PlaylistSummaryWithElements) {
const elements = playlist.elements.filter(e => e.enabled) const elements = playlist.elements.filter(e => e.enabled)
if (elements.length > 1) return true if (elements.length > 1) return true
@ -302,7 +306,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
return false return false
} }
private removeVideoFromPlaylist (playlist: PlaylistSummary, elementId: number) { private removeVideoFromPlaylist (playlist: PlaylistSummaryWithElements, elementId: number) {
this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, elementId, this.video.id) this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, elementId, this.video.id)
.subscribe({ .subscribe({
next: () => { next: () => {
@ -348,7 +352,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
playlistElementId: e.playlistElementId, playlistElementId: e.playlistElementId,
startTimestamp: e.startTimestamp || 0, startTimestamp: e.startTimestamp || 0,
stopTimestamp: e.stopTimestamp || this.video.duration stopTimestamp: e.stopTimestamp || this.video.duration
})) })),
shortUUID: playlist.shortUUID
} }
const oldPlaylist = oldPlaylists.find(p => p.id === playlist.id) const oldPlaylist = oldPlaylists.find(p => p.id === playlist.id)
@ -364,7 +369,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
this.cd.markForCheck() this.cd.markForCheck()
} }
private addVideoInPlaylist (playlist: PlaylistSummary, element: PlaylistElement) { private addVideoInPlaylist (playlist: PlaylistSummaryWithElements, element: PlaylistElement) {
const body: VideoPlaylistElementCreate = { videoId: this.video.id } const body: VideoPlaylistElementCreate = { videoId: this.video.id }
if (element.startTimestamp) body.startTimestamp = element.startTimestamp if (element.startTimestamp) body.startTimestamp = element.startTimestamp
@ -372,7 +377,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
this.pendingAddId = playlist.id this.pendingAddId = playlist.id
this.videoPlaylistService.addVideoInPlaylist(playlist.id, body) this.videoPlaylistService.addVideoInPlaylist(playlist, body)
.subscribe({ .subscribe({
next: res => { next: res => {
const message = body.startTimestamp || body.stopTimestamp const message = body.startTimestamp || body.stopTimestamp

View File

@ -8,6 +8,7 @@ import { buildBulkObservable, objectToFormData } from '@app/helpers'
import { Account, AccountService, VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { Account, AccountService, VideoChannel, VideoChannelService } from '@app/shared/shared-main'
import { NGX_LOADING_BAR_IGNORED } from '@ngx-loading-bar/http-client' import { NGX_LOADING_BAR_IGNORED } from '@ngx-loading-bar/http-client'
import { import {
VideoPlaylistSummary,
ResultList, ResultList,
VideoExistInPlaylist, VideoExistInPlaylist,
VideoPlaylist as VideoPlaylistServerModel, VideoPlaylist as VideoPlaylistServerModel,
@ -17,7 +18,8 @@ import {
VideoPlaylistElementUpdate, VideoPlaylistElementUpdate,
VideoPlaylistReorder, VideoPlaylistReorder,
VideoPlaylistUpdate, VideoPlaylistUpdate,
VideosExistInPlaylists VideosExistInPlaylists,
VideoPlaylistCreateResult
} from '@shared/models' } from '@shared/models'
import { environment } from '../../../environments/environment' import { environment } from '../../../environments/environment'
import { VideoPlaylistElement } from './video-playlist-element.model' import { VideoPlaylistElement } from './video-playlist-element.model'
@ -25,7 +27,7 @@ import { VideoPlaylist } from './video-playlist.model'
const debugLogger = debug('peertube:playlists:VideoPlaylistService') const debugLogger = debug('peertube:playlists:VideoPlaylistService')
export type CachedPlaylist = VideoPlaylist | { id: number, displayName: string } export type CachedPlaylist = VideoPlaylist | VideoPlaylistSummary
@Injectable() @Injectable()
export class VideoPlaylistService { export class VideoPlaylistService {
@ -139,7 +141,7 @@ export class VideoPlaylistService {
createVideoPlaylist (body: VideoPlaylistCreate) { createVideoPlaylist (body: VideoPlaylistCreate) {
const data = objectToFormData(body) const data = objectToFormData(body)
return this.authHttp.post<{ videoPlaylist: { id: number } }>(VideoPlaylistService.BASE_VIDEO_PLAYLIST_URL, data) return this.authHttp.post<{ videoPlaylist: VideoPlaylistCreateResult }>(VideoPlaylistService.BASE_VIDEO_PLAYLIST_URL, data)
.pipe( .pipe(
tap(res => { tap(res => {
if (!this.myAccountPlaylistCache) return if (!this.myAccountPlaylistCache) return
@ -148,7 +150,8 @@ export class VideoPlaylistService {
this.myAccountPlaylistCache.data.push({ this.myAccountPlaylistCache.data.push({
id: res.videoPlaylist.id, id: res.videoPlaylist.id,
displayName: body.displayName displayName: body.displayName,
shortUUID: res.videoPlaylist.shortUUID
}) })
this.myAccountPlaylistCacheSubject.next(this.myAccountPlaylistCache) this.myAccountPlaylistCacheSubject.next(this.myAccountPlaylistCache)
@ -190,12 +193,23 @@ export class VideoPlaylistService {
) )
} }
addVideoInPlaylist (playlistId: number, body: VideoPlaylistElementCreate) { addVideoInPlaylist (playlist: VideoPlaylistSummary, body: VideoPlaylistElementCreate) {
const url = VideoPlaylistService.BASE_VIDEO_PLAYLIST_URL + playlistId + '/videos' const url = VideoPlaylistService.BASE_VIDEO_PLAYLIST_URL + playlist.id + '/videos'
return this.authHttp.post<{ videoPlaylistElement: { id: number } }>(url, body) return this.authHttp.post<{ videoPlaylistElement: { id: number } }>(url, body)
.pipe( .pipe(
tap(res => { tap(res => {
const existsResult = this.videoExistsCache[body.videoId]
existsResult.push({
playlistElementId: res.videoPlaylistElement.id,
playlistId: playlist.id,
playlistDisplayName: playlist.displayName,
playlistShortUUID: playlist.shortUUID,
startTimestamp: body.startTimestamp,
stopTimestamp: body.stopTimestamp
})
this.runPlaylistCheck(body.videoId) this.runPlaylistCheck(body.videoId)
}), }),
catchError(err => this.restExtractor.handleError(err)) catchError(err => this.restExtractor.handleError(err))

View File

@ -70,6 +70,7 @@ import { VideoImportModel } from '../video/video-import'
import { VideoLiveModel } from '../video/video-live' import { VideoLiveModel } from '../video/video-live'
import { VideoPlaylistModel } from '../video/video-playlist' import { VideoPlaylistModel } from '../video/video-playlist'
import { UserNotificationSettingModel } from './user-notification-setting' import { UserNotificationSettingModel } from './user-notification-setting'
import { uuidToShort } from '@shared/extra-utils'
enum ScopeNames { enum ScopeNames {
FOR_ME_API = 'FOR_ME_API', FOR_ME_API = 'FOR_ME_API',
@ -960,7 +961,7 @@ export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
const formatted = this.toFormattedJSON({ withAdminFlags: true }) const formatted = this.toFormattedJSON({ withAdminFlags: true })
const specialPlaylists = this.Account.VideoPlaylists const specialPlaylists = this.Account.VideoPlaylists
.map(p => ({ id: p.id, name: p.name, type: p.type })) .map(p => ({ id: p.id, name: p.name, shortUUID: uuidToShort(p.uuid), type: p.type }))
return Object.assign(formatted, { specialPlaylists }) return Object.assign(formatted, { specialPlaylists })
} }

View File

@ -67,6 +67,7 @@ export interface User {
export interface MyUserSpecialPlaylist { export interface MyUserSpecialPlaylist {
id: number id: number
name: string name: string
shortUUID: string
type: VideoPlaylistType type: VideoPlaylistType
} }

View File

@ -10,3 +10,9 @@ export type VideoExistInPlaylist = {
startTimestamp?: number startTimestamp?: number
stopTimestamp?: number stopTimestamp?: number
} }
export type VideoPlaylistSummary = {
id: number
displayName: string
shortUUID: string
}