Fetch things in bulk for the homepage
This commit is contained in:
parent
200eaf5152
commit
3da38d6e9f
|
@ -44,13 +44,21 @@ export class RestService {
|
||||||
return newParams
|
return newParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addArrayParams (params: HttpParams, name: string, values: (string | number)[]) {
|
||||||
|
for (const v of values) {
|
||||||
|
params = params.append(name, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
addObjectParams (params: HttpParams, object: { [ name: string ]: any }) {
|
addObjectParams (params: HttpParams, object: { [ name: string ]: any }) {
|
||||||
for (const name of Object.keys(object)) {
|
for (const name of Object.keys(object)) {
|
||||||
const value = object[name]
|
const value = object[name]
|
||||||
if (value === undefined || value === null) continue
|
if (value === undefined || value === null) continue
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
for (const v of value) params = params.append(name, v)
|
params = this.addArrayParams(params, name, value)
|
||||||
} else {
|
} else {
|
||||||
params = params.append(name, value)
|
params = params.append(name, value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export * from './locales'
|
export * from './locales'
|
||||||
export * from './constants'
|
export * from './constants'
|
||||||
export * from './i18n-utils'
|
export * from './i18n-utils'
|
||||||
|
export * from './rxjs'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
export * from './zone'
|
export * from './zone'
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { uniq } from 'lodash-es'
|
||||||
|
import { asyncScheduler, Observable } from 'rxjs'
|
||||||
|
import { bufferTime, distinctUntilChanged, filter, map, observeOn, share, switchMap } from 'rxjs/operators'
|
||||||
|
import { NgZone } from '@angular/core'
|
||||||
|
import { enterZone, leaveZone } from './zone'
|
||||||
|
|
||||||
|
function buildBulkObservable <T extends number | string, R> (options: {
|
||||||
|
ngZone: NgZone
|
||||||
|
notifierObservable: Observable<T>
|
||||||
|
time: number
|
||||||
|
bulkGet: (params: T[]) => Observable<R>
|
||||||
|
}) {
|
||||||
|
const { ngZone, notifierObservable, time, bulkGet } = options
|
||||||
|
|
||||||
|
return notifierObservable.pipe(
|
||||||
|
distinctUntilChanged(),
|
||||||
|
// We leave Angular zone so Protractor does not get stuck
|
||||||
|
bufferTime(time, leaveZone(ngZone, asyncScheduler)),
|
||||||
|
filter(params => params.length !== 0),
|
||||||
|
map(params => uniq(params)),
|
||||||
|
observeOn(enterZone(ngZone, asyncScheduler)),
|
||||||
|
switchMap(params => bulkGet(params)),
|
||||||
|
share()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
buildBulkObservable
|
||||||
|
}
|
|
@ -2,8 +2,9 @@ import { from } from 'rxjs'
|
||||||
import { finalize, map, switchMap, tap } from 'rxjs/operators'
|
import { finalize, map, switchMap, tap } from 'rxjs/operators'
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||||
import { MarkdownService, Notifier, UserService } from '@app/core'
|
import { MarkdownService, Notifier, UserService } from '@app/core'
|
||||||
|
import { FindInBulkService } from '@app/shared/shared-search'
|
||||||
import { Video, VideoSortField } from '@shared/models/videos'
|
import { Video, VideoSortField } from '@shared/models/videos'
|
||||||
import { VideoChannel, VideoChannelService, VideoService } from '../../shared-main'
|
import { VideoChannel, VideoService } from '../../shared-main'
|
||||||
import { CustomMarkupComponent } from './shared'
|
import { CustomMarkupComponent } from './shared'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -29,14 +30,14 @@ export class ChannelMiniatureMarkupComponent implements CustomMarkupComponent, O
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private markdown: MarkdownService,
|
private markdown: MarkdownService,
|
||||||
private channelService: VideoChannelService,
|
private findInBulk: FindInBulkService,
|
||||||
private videoService: VideoService,
|
private videoService: VideoService,
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private notifier: Notifier
|
private notifier: Notifier
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.channelService.getVideoChannel(this.name)
|
this.findInBulk.getChannel(this.name)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(channel => this.channel = channel),
|
tap(channel => this.channel = channel),
|
||||||
switchMap(() => from(this.markdown.textMarkdownToHTML(this.channel.description))),
|
switchMap(() => from(this.markdown.textMarkdownToHTML(this.channel.description))),
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { finalize } from 'rxjs/operators'
|
import { finalize } from 'rxjs/operators'
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||||
import { Notifier } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
|
import { FindInBulkService } from '@app/shared/shared-search'
|
||||||
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
||||||
import { VideoPlaylist, VideoPlaylistService } from '../../shared-video-playlist'
|
import { VideoPlaylist } from '../../shared-video-playlist'
|
||||||
import { CustomMarkupComponent } from './shared'
|
import { CustomMarkupComponent } from './shared'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,12 +34,12 @@ export class PlaylistMiniatureMarkupComponent implements CustomMarkupComponent,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private playlistService: VideoPlaylistService,
|
private findInBulkService: FindInBulkService,
|
||||||
private notifier: Notifier
|
private notifier: Notifier
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.playlistService.getVideoPlaylist(this.uuid)
|
this.findInBulkService.getPlaylist(this.uuid)
|
||||||
.pipe(finalize(() => this.loaded.emit(true)))
|
.pipe(finalize(() => this.loaded.emit(true)))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
playlist => this.playlist = playlist,
|
playlist => this.playlist = playlist,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { AuthService, Notifier } from '@app/core'
|
||||||
import { Video, VideoService } from '../../shared-main'
|
import { Video, VideoService } from '../../shared-main'
|
||||||
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
import { MiniatureDisplayOptions } from '../../shared-video-miniature'
|
||||||
import { CustomMarkupComponent } from './shared'
|
import { CustomMarkupComponent } from './shared'
|
||||||
|
import { FindInBulkService } from '@app/shared/shared-search'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Markup component that creates a video miniature only
|
* Markup component that creates a video miniature only
|
||||||
|
@ -35,7 +36,7 @@ export class VideoMiniatureMarkupComponent implements CustomMarkupComponent, OnI
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private auth: AuthService,
|
private auth: AuthService,
|
||||||
private videoService: VideoService,
|
private findInBulk: FindInBulkService,
|
||||||
private notifier: Notifier
|
private notifier: Notifier
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ export class VideoMiniatureMarkupComponent implements CustomMarkupComponent, OnI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.videoService.getVideo({ videoId: this.uuid })
|
this.findInBulk.getVideo(this.uuid)
|
||||||
.pipe(finalize(() => this.loaded.emit(true)))
|
.pipe(finalize(() => this.loaded.emit(true)))
|
||||||
.subscribe(
|
.subscribe(
|
||||||
video => this.video = video,
|
video => this.video = video,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { NgModule } from '@angular/core'
|
||||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||||
import { SharedGlobalIconModule } from '../shared-icons'
|
import { SharedGlobalIconModule } from '../shared-icons'
|
||||||
import { SharedMainModule } from '../shared-main'
|
import { SharedMainModule } from '../shared-main'
|
||||||
|
import { SharedSearchModule } from '../shared-search'
|
||||||
import { SharedVideoMiniatureModule } from '../shared-video-miniature'
|
import { SharedVideoMiniatureModule } from '../shared-video-miniature'
|
||||||
import { SharedVideoPlaylistModule } from '../shared-video-playlist'
|
import { SharedVideoPlaylistModule } from '../shared-video-playlist'
|
||||||
import { CustomMarkupContainerComponent } from './custom-markup-container.component'
|
import { CustomMarkupContainerComponent } from './custom-markup-container.component'
|
||||||
|
@ -26,7 +27,8 @@ import {
|
||||||
SharedGlobalIconModule,
|
SharedGlobalIconModule,
|
||||||
SharedVideoMiniatureModule,
|
SharedVideoMiniatureModule,
|
||||||
SharedVideoPlaylistModule,
|
SharedVideoPlaylistModule,
|
||||||
SharedActorImageModule
|
SharedActorImageModule,
|
||||||
|
SharedSearchModule
|
||||||
],
|
],
|
||||||
|
|
||||||
declarations: [
|
declarations: [
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
import * as debug from 'debug'
|
||||||
|
import { Observable, Subject } from 'rxjs'
|
||||||
|
import { map } from 'rxjs/operators'
|
||||||
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
|
import { buildBulkObservable } from '@app/helpers'
|
||||||
|
import { ResultList } from '@shared/models/common'
|
||||||
|
import { Video, VideoChannel } from '../shared-main'
|
||||||
|
import { VideoPlaylist } from '../shared-video-playlist'
|
||||||
|
import { SearchService } from './search.service'
|
||||||
|
|
||||||
|
const logger = debug('peertube:search:FindInBulkService')
|
||||||
|
|
||||||
|
type BulkObservables <P extends number | string, R> = {
|
||||||
|
notifier: Subject<P>
|
||||||
|
result: Observable<R>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FindInBulkService {
|
||||||
|
|
||||||
|
private getVideoInBulk: BulkObservables<string, ResultList<Video>>
|
||||||
|
private getChannelInBulk: BulkObservables<string, ResultList<VideoChannel>>
|
||||||
|
private getPlaylistInBulk: BulkObservables<string, ResultList<VideoPlaylist>>
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private searchService: SearchService,
|
||||||
|
private ngZone: NgZone
|
||||||
|
) {
|
||||||
|
this.getVideoInBulk = this.buildBulkObservableObject(this.getVideosInBulk.bind(this))
|
||||||
|
this.getChannelInBulk = this.buildBulkObservableObject(this.getChannelsInBulk.bind(this))
|
||||||
|
this.getPlaylistInBulk = this.buildBulkObservableObject(this.getPlaylistsInBulk.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
getVideo (uuid: string): Observable<Video> {
|
||||||
|
logger('Schedule video fetch for uuid %s.', uuid)
|
||||||
|
|
||||||
|
return this.getData({
|
||||||
|
observableObject: this.getVideoInBulk,
|
||||||
|
finder: v => v.uuid === uuid,
|
||||||
|
param: uuid
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getChannel (handle: string): Observable<VideoChannel> {
|
||||||
|
logger('Schedule channel fetch for handle %s.', handle)
|
||||||
|
|
||||||
|
return this.getData({
|
||||||
|
observableObject: this.getChannelInBulk,
|
||||||
|
finder: c => c.nameWithHost === handle || c.nameWithHostForced === handle,
|
||||||
|
param: handle
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlaylist (uuid: string): Observable<VideoPlaylist> {
|
||||||
|
logger('Schedule playlist fetch for uuid %s.', uuid)
|
||||||
|
|
||||||
|
return this.getData({
|
||||||
|
observableObject: this.getPlaylistInBulk,
|
||||||
|
finder: p => p.uuid === uuid,
|
||||||
|
param: uuid
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private getData <P extends number | string, R> (options: {
|
||||||
|
observableObject: BulkObservables<P, ResultList<R>>
|
||||||
|
param: P
|
||||||
|
finder: (d: R) => boolean
|
||||||
|
}) {
|
||||||
|
const { observableObject, param, finder } = options
|
||||||
|
|
||||||
|
return new Observable<R>(obs => {
|
||||||
|
observableObject.result
|
||||||
|
.pipe(
|
||||||
|
map(({ data }) => data),
|
||||||
|
map(data => data.find(finder))
|
||||||
|
)
|
||||||
|
.subscribe(result => {
|
||||||
|
obs.next(result)
|
||||||
|
obs.complete()
|
||||||
|
})
|
||||||
|
|
||||||
|
observableObject.notifier.next(param)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVideosInBulk (uuids: string[]) {
|
||||||
|
logger('Fetching videos %s.', uuids.join(', '))
|
||||||
|
|
||||||
|
return this.searchService.searchVideos({ uuids })
|
||||||
|
}
|
||||||
|
|
||||||
|
private getChannelsInBulk (handles: string[]) {
|
||||||
|
logger('Fetching channels %s.', handles.join(', '))
|
||||||
|
|
||||||
|
return this.searchService.searchVideoChannels({ handles })
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPlaylistsInBulk (uuids: string[]) {
|
||||||
|
logger('Fetching playlists %s.', uuids.join(', '))
|
||||||
|
|
||||||
|
return this.searchService.searchVideoPlaylists({ uuids })
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildBulkObservableObject <T extends number | string, R> (bulkGet: (params: T[]) => Observable<R>) {
|
||||||
|
const notifier = new Subject<T>()
|
||||||
|
|
||||||
|
return {
|
||||||
|
notifier,
|
||||||
|
|
||||||
|
result: buildBulkObservable({
|
||||||
|
time: 500,
|
||||||
|
bulkGet,
|
||||||
|
ngZone: this.ngZone,
|
||||||
|
notifierObservable: notifier.asObservable()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
export * from './advanced-search.model'
|
export * from './advanced-search.model'
|
||||||
|
export * from './find-in-bulk.service'
|
||||||
export * from './search.service'
|
export * from './search.service'
|
||||||
export * from './shared-search.module'
|
export * from './shared-search.module'
|
||||||
|
|
|
@ -32,11 +32,12 @@ export class SearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchVideos (parameters: {
|
searchVideos (parameters: {
|
||||||
search: string
|
search?: string
|
||||||
componentPagination?: ComponentPaginationLight
|
componentPagination?: ComponentPaginationLight
|
||||||
advancedSearch?: AdvancedSearch
|
advancedSearch?: AdvancedSearch
|
||||||
|
uuids?: string[]
|
||||||
}): Observable<ResultList<Video>> {
|
}): Observable<ResultList<Video>> {
|
||||||
const { search, componentPagination, advancedSearch } = parameters
|
const { search, uuids, componentPagination, advancedSearch } = parameters
|
||||||
|
|
||||||
const url = SearchService.BASE_SEARCH_URL + 'videos'
|
const url = SearchService.BASE_SEARCH_URL + 'videos'
|
||||||
let pagination: RestPagination
|
let pagination: RestPagination
|
||||||
|
@ -49,6 +50,7 @@ export class SearchService {
|
||||||
params = this.restService.addRestGetParams(params, pagination)
|
params = this.restService.addRestGetParams(params, pagination)
|
||||||
|
|
||||||
if (search) params = params.append('search', search)
|
if (search) params = params.append('search', search)
|
||||||
|
if (uuids) params = this.restService.addArrayParams(params, 'uuids', uuids)
|
||||||
|
|
||||||
if (advancedSearch) {
|
if (advancedSearch) {
|
||||||
const advancedSearchObject = advancedSearch.toVideosAPIObject()
|
const advancedSearchObject = advancedSearch.toVideosAPIObject()
|
||||||
|
@ -64,11 +66,12 @@ export class SearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchVideoChannels (parameters: {
|
searchVideoChannels (parameters: {
|
||||||
search: string
|
search?: string
|
||||||
advancedSearch?: AdvancedSearch
|
advancedSearch?: AdvancedSearch
|
||||||
componentPagination?: ComponentPaginationLight
|
componentPagination?: ComponentPaginationLight
|
||||||
|
handles?: string[]
|
||||||
}): Observable<ResultList<VideoChannel>> {
|
}): Observable<ResultList<VideoChannel>> {
|
||||||
const { search, advancedSearch, componentPagination } = parameters
|
const { search, advancedSearch, componentPagination, handles } = parameters
|
||||||
|
|
||||||
const url = SearchService.BASE_SEARCH_URL + 'video-channels'
|
const url = SearchService.BASE_SEARCH_URL + 'video-channels'
|
||||||
|
|
||||||
|
@ -81,6 +84,7 @@ export class SearchService {
|
||||||
params = this.restService.addRestGetParams(params, pagination)
|
params = this.restService.addRestGetParams(params, pagination)
|
||||||
|
|
||||||
if (search) params = params.append('search', search)
|
if (search) params = params.append('search', search)
|
||||||
|
if (handles) params = this.restService.addArrayParams(params, 'handles', handles)
|
||||||
|
|
||||||
if (advancedSearch) {
|
if (advancedSearch) {
|
||||||
const advancedSearchObject = advancedSearch.toChannelAPIObject()
|
const advancedSearchObject = advancedSearch.toChannelAPIObject()
|
||||||
|
@ -96,11 +100,12 @@ export class SearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchVideoPlaylists (parameters: {
|
searchVideoPlaylists (parameters: {
|
||||||
search: string
|
search?: string
|
||||||
advancedSearch?: AdvancedSearch
|
advancedSearch?: AdvancedSearch
|
||||||
componentPagination?: ComponentPaginationLight
|
componentPagination?: ComponentPaginationLight
|
||||||
|
uuids?: string[]
|
||||||
}): Observable<ResultList<VideoPlaylist>> {
|
}): Observable<ResultList<VideoPlaylist>> {
|
||||||
const { search, advancedSearch, componentPagination } = parameters
|
const { search, advancedSearch, componentPagination, uuids } = parameters
|
||||||
|
|
||||||
const url = SearchService.BASE_SEARCH_URL + 'video-playlists'
|
const url = SearchService.BASE_SEARCH_URL + 'video-playlists'
|
||||||
|
|
||||||
|
@ -113,6 +118,7 @@ export class SearchService {
|
||||||
params = this.restService.addRestGetParams(params, pagination)
|
params = this.restService.addRestGetParams(params, pagination)
|
||||||
|
|
||||||
if (search) params = params.append('search', search)
|
if (search) params = params.append('search', search)
|
||||||
|
if (uuids) params = this.restService.addArrayParams(params, 'uuids', uuids)
|
||||||
|
|
||||||
if (advancedSearch) {
|
if (advancedSearch) {
|
||||||
const advancedSearchObject = advancedSearch.toPlaylistAPIObject()
|
const advancedSearchObject = advancedSearch.toPlaylistAPIObject()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { SharedMainModule } from '../shared-main'
|
import { SharedMainModule } from '../shared-main'
|
||||||
import { SharedVideoPlaylistModule } from '../shared-video-playlist'
|
import { SharedVideoPlaylistModule } from '../shared-video-playlist'
|
||||||
|
import { FindInBulkService } from './find-in-bulk.service'
|
||||||
import { SearchService } from './search.service'
|
import { SearchService } from './search.service'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -16,6 +17,7 @@ import { SearchService } from './search.service'
|
||||||
],
|
],
|
||||||
|
|
||||||
providers: [
|
providers: [
|
||||||
|
FindInBulkService,
|
||||||
SearchService
|
SearchService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import * as debug from 'debug'
|
import * as debug from 'debug'
|
||||||
import { uniq } from 'lodash-es'
|
import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
||||||
import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
import { catchError, filter, map, switchMap, tap } from 'rxjs/operators'
|
||||||
import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap } from 'rxjs/operators'
|
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { ComponentPaginationLight, RestExtractor, RestService } from '@app/core'
|
import { ComponentPaginationLight, RestExtractor, RestService } from '@app/core'
|
||||||
import { enterZone, leaveZone } from '@app/helpers'
|
import { buildBulkObservable } from '@app/helpers'
|
||||||
import { Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
|
import { Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
|
||||||
import { ResultList, VideoChannel as VideoChannelServer, VideoSortField } from '@shared/models'
|
import { ResultList, VideoChannel as VideoChannelServer, VideoSortField } from '@shared/models'
|
||||||
import { environment } from '../../../environments/environment'
|
import { environment } from '../../../environments/environment'
|
||||||
|
@ -35,15 +34,12 @@ export class UserSubscriptionService {
|
||||||
private ngZone: NgZone
|
private ngZone: NgZone
|
||||||
) {
|
) {
|
||||||
this.existsObservable = merge(
|
this.existsObservable = merge(
|
||||||
this.existsSubject.pipe(
|
buildBulkObservable({
|
||||||
// We leave Angular zone so Protractor does not get stuck
|
time: 500,
|
||||||
bufferTime(500, leaveZone(this.ngZone, asyncScheduler)),
|
ngZone: this.ngZone,
|
||||||
filter(uris => uris.length !== 0),
|
notifierObservable: this.existsSubject,
|
||||||
map(uris => uniq(uris)),
|
bulkGet: this.doSubscriptionsExist.bind(this)
|
||||||
observeOn(enterZone(this.ngZone, asyncScheduler)),
|
}),
|
||||||
switchMap(uris => this.doSubscriptionsExist(uris)),
|
|
||||||
share()
|
|
||||||
),
|
|
||||||
|
|
||||||
this.myAccountSubscriptionCacheSubject
|
this.myAccountSubscriptionCacheSubject
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import * as debug from 'debug'
|
import * as debug from 'debug'
|
||||||
import { uniq } from 'lodash-es'
|
import { merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
||||||
import { asyncScheduler, merge, Observable, of, ReplaySubject, Subject } from 'rxjs'
|
import { catchError, filter, map, share, switchMap, tap } from 'rxjs/operators'
|
||||||
import { bufferTime, catchError, filter, map, observeOn, share, switchMap, tap, distinctUntilChanged } from 'rxjs/operators'
|
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { AuthUser, ComponentPaginationLight, RestExtractor, RestService, ServerService } from '@app/core'
|
import { AuthUser, ComponentPaginationLight, RestExtractor, RestService, ServerService } from '@app/core'
|
||||||
import { enterZone, leaveZone, objectToFormData } from '@app/helpers'
|
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 {
|
import {
|
||||||
ResultList,
|
ResultList,
|
||||||
|
@ -52,16 +51,12 @@ export class VideoPlaylistService {
|
||||||
private ngZone: NgZone
|
private ngZone: NgZone
|
||||||
) {
|
) {
|
||||||
this.videoExistsInPlaylistObservable = merge(
|
this.videoExistsInPlaylistObservable = merge(
|
||||||
this.videoExistsInPlaylistNotifier.pipe(
|
buildBulkObservable({
|
||||||
distinctUntilChanged(),
|
time: 500,
|
||||||
// We leave Angular zone so Protractor does not get stuck
|
ngZone: this.ngZone,
|
||||||
bufferTime(500, leaveZone(this.ngZone, asyncScheduler)),
|
bulkGet: this.doVideosExistInPlaylist.bind(this),
|
||||||
filter(videoIds => videoIds.length !== 0),
|
notifierObservable: this.videoExistsInPlaylistNotifier
|
||||||
map(videoIds => uniq(videoIds)),
|
}),
|
||||||
observeOn(enterZone(this.ngZone, asyncScheduler)),
|
|
||||||
switchMap(videoIds => this.doVideosExistInPlaylist(videoIds)),
|
|
||||||
share()
|
|
||||||
),
|
|
||||||
|
|
||||||
this.videoExistsInPlaylistCacheSubject
|
this.videoExistsInPlaylistCacheSubject
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue