-import { bufferTime, catchError, filter, map, share, switchMap, tap } from 'rxjs/operators'
-import { Injectable } from '@angular/core'
-import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
+import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators'
+import { Injectable, NgZone } from '@angular/core'
+import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
import { RestExtractor } from '../rest/rest-extractor.service'
import { HttpClient, HttpParams } from '@angular/common/http'
import { ResultList, VideoPlaylistElementCreate, VideoPlaylistElementUpdate } from '../../../../../shared'
import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model'
import { uniq } from 'lodash-es'
import * as debug from 'debug'
+import { enterZone, leaveZone } from '@app/shared/rxjs/zone'
const logger = debug('peertube:playlists:VideoPlaylistService')
private videoExistsCache: { [ id: number ]: VideoExistInPlaylist[] } = {}
private myAccountPlaylistCache: ResultList<CachedPlaylist> = undefined
+ private myAccountPlaylistCacheRunning: Observable<ResultList<CachedPlaylist>>
private myAccountPlaylistCacheSubject = new Subject<ResultList<CachedPlaylist>>()
constructor (
private authHttp: HttpClient,
private serverService: ServerService,
private restExtractor: RestExtractor,
- private restService: RestService
+ private restService: RestService,
+ private ngZone: NgZone
) {
this.videoExistsInPlaylistObservable = merge(
this.videoExistsInPlaylistNotifier.pipe(
- bufferTime(500),
+ // We leave Angular zone so Protractor does not get stuck
+ bufferTime(500, leaveZone(this.ngZone, asyncScheduler)),
filter(videoIds => videoIds.length !== 0),
map(videoIds => uniq(videoIds)),
+ observeOn(enterZone(this.ngZone, asyncScheduler)),
switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)),
share()
),
}
listMyPlaylistWithCache (user: AuthUser, search?: string) {
- if (!search && this.myAccountPlaylistCache) return of(this.myAccountPlaylistCache)
+ if (!search) {
+ if (this.myAccountPlaylistCacheRunning) return this.myAccountPlaylistCacheRunning
+ if (this.myAccountPlaylistCache) return of(this.myAccountPlaylistCache)
+ }
- return this.listAccountPlaylists(user.account, undefined, '-updatedAt', search)
+ const obs = this.listAccountPlaylists(user.account, undefined, '-updatedAt', search)
.pipe(
tap(result => {
- if (!search) this.myAccountPlaylistCache = result
- })
+ if (!search) {
+ this.myAccountPlaylistCacheRunning = undefined
+ this.myAccountPlaylistCache = result
+ }
+ }),
+ share()
)
+
+ if (!search) this.myAccountPlaylistCacheRunning = obs
+ return obs
}
listAccountPlaylists (
return this.authHttp.post<{ videoPlaylist: { id: number } }>(VideoPlaylistService.BASE_VIDEO_PLAYLIST_URL, data)
.pipe(
tap(res => {
+ if (!this.myAccountPlaylistCache) return
+
this.myAccountPlaylistCache.total++
this.myAccountPlaylistCache.data.push({
.pipe(
map(this.restExtractor.extractDataBool),
tap(() => {
+ if (!this.myAccountPlaylistCache) return
+
const playlist = this.myAccountPlaylistCache.data.find(p => p.id === videoPlaylist.id)
playlist.displayName = body.displayName
.pipe(
map(this.restExtractor.extractDataBool),
tap(() => {
+ if (!this.myAccountPlaylistCache) return
+
this.myAccountPlaylistCache.total--
this.myAccountPlaylistCache.data = this.myAccountPlaylistCache.data
.filter(p => p.id !== videoPlaylist.id)