diff options
Diffstat (limited to 'client/src/app/shared/shared-search/find-in-bulk.service.ts')
-rw-r--r-- | client/src/app/shared/shared-search/find-in-bulk.service.ts | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-search/find-in-bulk.service.ts b/client/src/app/shared/shared-search/find-in-bulk.service.ts new file mode 100644 index 000000000..0383d8648 --- /dev/null +++ b/client/src/app/shared/shared-search/find-in-bulk.service.ts | |||
@@ -0,0 +1,118 @@ | |||
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 | } | ||