]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/shared-search/find-in-bulk.service.ts
0383d864805474461fda182c772e5b23dcee76e6
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-search / find-in-bulk.service.ts
1 import * as debug from 'debug'
2 import { Observable, Subject } from 'rxjs'
3 import { map } from 'rxjs/operators'
4 import { Injectable, NgZone } from '@angular/core'
5 import { buildBulkObservable } from '@app/helpers'
6 import { ResultList } from '@shared/models/common'
7 import { Video, VideoChannel } from '../shared-main'
8 import { VideoPlaylist } from '../shared-video-playlist'
9 import { SearchService } from './search.service'
10
11 const logger = debug('peertube:search:FindInBulkService')
12
13 type BulkObservables <P extends number | string, R> = {
14 notifier: Subject<P>
15 result: Observable<R>
16 }
17
18 @Injectable()
19 export class FindInBulkService {
20
21 private getVideoInBulk: BulkObservables<string, ResultList<Video>>
22 private getChannelInBulk: BulkObservables<string, ResultList<VideoChannel>>
23 private getPlaylistInBulk: BulkObservables<string, ResultList<VideoPlaylist>>
24
25 constructor (
26 private searchService: SearchService,
27 private ngZone: NgZone
28 ) {
29 this.getVideoInBulk = this.buildBulkObservableObject(this.getVideosInBulk.bind(this))
30 this.getChannelInBulk = this.buildBulkObservableObject(this.getChannelsInBulk.bind(this))
31 this.getPlaylistInBulk = this.buildBulkObservableObject(this.getPlaylistsInBulk.bind(this))
32 }
33
34 getVideo (uuid: string): Observable<Video> {
35 logger('Schedule video fetch for uuid %s.', uuid)
36
37 return this.getData({
38 observableObject: this.getVideoInBulk,
39 finder: v => v.uuid === uuid,
40 param: uuid
41 })
42 }
43
44 getChannel (handle: string): Observable<VideoChannel> {
45 logger('Schedule channel fetch for handle %s.', handle)
46
47 return this.getData({
48 observableObject: this.getChannelInBulk,
49 finder: c => c.nameWithHost === handle || c.nameWithHostForced === handle,
50 param: handle
51 })
52 }
53
54 getPlaylist (uuid: string): Observable<VideoPlaylist> {
55 logger('Schedule playlist fetch for uuid %s.', uuid)
56
57 return this.getData({
58 observableObject: this.getPlaylistInBulk,
59 finder: p => p.uuid === uuid,
60 param: uuid
61 })
62 }
63
64 private getData <P extends number | string, R> (options: {
65 observableObject: BulkObservables<P, ResultList<R>>
66 param: P
67 finder: (d: R) => boolean
68 }) {
69 const { observableObject, param, finder } = options
70
71 return new Observable<R>(obs => {
72 observableObject.result
73 .pipe(
74 map(({ data }) => data),
75 map(data => data.find(finder))
76 )
77 .subscribe(result => {
78 obs.next(result)
79 obs.complete()
80 })
81
82 observableObject.notifier.next(param)
83 })
84 }
85
86 private getVideosInBulk (uuids: string[]) {
87 logger('Fetching videos %s.', uuids.join(', '))
88
89 return this.searchService.searchVideos({ uuids })
90 }
91
92 private getChannelsInBulk (handles: string[]) {
93 logger('Fetching channels %s.', handles.join(', '))
94
95 return this.searchService.searchVideoChannels({ handles })
96 }
97
98 private getPlaylistsInBulk (uuids: string[]) {
99 logger('Fetching playlists %s.', uuids.join(', '))
100
101 return this.searchService.searchVideoPlaylists({ uuids })
102 }
103
104 private buildBulkObservableObject <T extends number | string, R> (bulkGet: (params: T[]) => Observable<R>) {
105 const notifier = new Subject<T>()
106
107 return {
108 notifier,
109
110 result: buildBulkObservable({
111 time: 500,
112 bulkGet,
113 ngZone: this.ngZone,
114 notifierObservable: notifier.asObservable()
115 })
116 }
117 }
118 }