diff options
author | Chocobozzz <me@florianbigard.com> | 2021-08-02 15:29:09 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-08-02 15:40:09 +0200 |
commit | 3da38d6e9f8d600476be276666ac7223aa5f172c (patch) | |
tree | daec25cccb900a0f90fc9d2273099683b42d8551 /client/src/app/shared/shared-search | |
parent | 200eaf5152ca72fe6b05a49caf819e22bd045b37 (diff) | |
download | PeerTube-3da38d6e9f8d600476be276666ac7223aa5f172c.tar.gz PeerTube-3da38d6e9f8d600476be276666ac7223aa5f172c.tar.zst PeerTube-3da38d6e9f8d600476be276666ac7223aa5f172c.zip |
Fetch things in bulk for the homepage
Diffstat (limited to 'client/src/app/shared/shared-search')
4 files changed, 133 insertions, 6 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 | } | ||
diff --git a/client/src/app/shared/shared-search/index.ts b/client/src/app/shared/shared-search/index.ts index f687f6767..0235893c4 100644 --- a/client/src/app/shared/shared-search/index.ts +++ b/client/src/app/shared/shared-search/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './advanced-search.model' | 1 | export * from './advanced-search.model' |
2 | export * from './find-in-bulk.service' | ||
2 | export * from './search.service' | 3 | export * from './search.service' |
3 | export * from './shared-search.module' | 4 | export * from './shared-search.module' |
diff --git a/client/src/app/shared/shared-search/search.service.ts b/client/src/app/shared/shared-search/search.service.ts index a1603da98..fdfab0e0e 100644 --- a/client/src/app/shared/shared-search/search.service.ts +++ b/client/src/app/shared/shared-search/search.service.ts | |||
@@ -32,11 +32,12 @@ export class SearchService { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | searchVideos (parameters: { | 34 | searchVideos (parameters: { |
35 | search: string | 35 | search?: string |
36 | componentPagination?: ComponentPaginationLight | 36 | componentPagination?: ComponentPaginationLight |
37 | advancedSearch?: AdvancedSearch | 37 | advancedSearch?: AdvancedSearch |
38 | uuids?: string[] | ||
38 | }): Observable<ResultList<Video>> { | 39 | }): Observable<ResultList<Video>> { |
39 | const { search, componentPagination, advancedSearch } = parameters | 40 | const { search, uuids, componentPagination, advancedSearch } = parameters |
40 | 41 | ||
41 | const url = SearchService.BASE_SEARCH_URL + 'videos' | 42 | const url = SearchService.BASE_SEARCH_URL + 'videos' |
42 | let pagination: RestPagination | 43 | let pagination: RestPagination |
@@ -49,6 +50,7 @@ export class SearchService { | |||
49 | params = this.restService.addRestGetParams(params, pagination) | 50 | params = this.restService.addRestGetParams(params, pagination) |
50 | 51 | ||
51 | if (search) params = params.append('search', search) | 52 | if (search) params = params.append('search', search) |
53 | if (uuids) params = this.restService.addArrayParams(params, 'uuids', uuids) | ||
52 | 54 | ||
53 | if (advancedSearch) { | 55 | if (advancedSearch) { |
54 | const advancedSearchObject = advancedSearch.toVideosAPIObject() | 56 | const advancedSearchObject = advancedSearch.toVideosAPIObject() |
@@ -64,11 +66,12 @@ export class SearchService { | |||
64 | } | 66 | } |
65 | 67 | ||
66 | searchVideoChannels (parameters: { | 68 | searchVideoChannels (parameters: { |
67 | search: string | 69 | search?: string |
68 | advancedSearch?: AdvancedSearch | 70 | advancedSearch?: AdvancedSearch |
69 | componentPagination?: ComponentPaginationLight | 71 | componentPagination?: ComponentPaginationLight |
72 | handles?: string[] | ||
70 | }): Observable<ResultList<VideoChannel>> { | 73 | }): Observable<ResultList<VideoChannel>> { |
71 | const { search, advancedSearch, componentPagination } = parameters | 74 | const { search, advancedSearch, componentPagination, handles } = parameters |
72 | 75 | ||
73 | const url = SearchService.BASE_SEARCH_URL + 'video-channels' | 76 | const url = SearchService.BASE_SEARCH_URL + 'video-channels' |
74 | 77 | ||
@@ -81,6 +84,7 @@ export class SearchService { | |||
81 | params = this.restService.addRestGetParams(params, pagination) | 84 | params = this.restService.addRestGetParams(params, pagination) |
82 | 85 | ||
83 | if (search) params = params.append('search', search) | 86 | if (search) params = params.append('search', search) |
87 | if (handles) params = this.restService.addArrayParams(params, 'handles', handles) | ||
84 | 88 | ||
85 | if (advancedSearch) { | 89 | if (advancedSearch) { |
86 | const advancedSearchObject = advancedSearch.toChannelAPIObject() | 90 | const advancedSearchObject = advancedSearch.toChannelAPIObject() |
@@ -96,11 +100,12 @@ export class SearchService { | |||
96 | } | 100 | } |
97 | 101 | ||
98 | searchVideoPlaylists (parameters: { | 102 | searchVideoPlaylists (parameters: { |
99 | search: string | 103 | search?: string |
100 | advancedSearch?: AdvancedSearch | 104 | advancedSearch?: AdvancedSearch |
101 | componentPagination?: ComponentPaginationLight | 105 | componentPagination?: ComponentPaginationLight |
106 | uuids?: string[] | ||
102 | }): Observable<ResultList<VideoPlaylist>> { | 107 | }): Observable<ResultList<VideoPlaylist>> { |
103 | const { search, advancedSearch, componentPagination } = parameters | 108 | const { search, advancedSearch, componentPagination, uuids } = parameters |
104 | 109 | ||
105 | const url = SearchService.BASE_SEARCH_URL + 'video-playlists' | 110 | const url = SearchService.BASE_SEARCH_URL + 'video-playlists' |
106 | 111 | ||
@@ -113,6 +118,7 @@ export class SearchService { | |||
113 | params = this.restService.addRestGetParams(params, pagination) | 118 | params = this.restService.addRestGetParams(params, pagination) |
114 | 119 | ||
115 | if (search) params = params.append('search', search) | 120 | if (search) params = params.append('search', search) |
121 | if (uuids) params = this.restService.addArrayParams(params, 'uuids', uuids) | ||
116 | 122 | ||
117 | if (advancedSearch) { | 123 | if (advancedSearch) { |
118 | const advancedSearchObject = advancedSearch.toPlaylistAPIObject() | 124 | const advancedSearchObject = advancedSearch.toPlaylistAPIObject() |
diff --git a/client/src/app/shared/shared-search/shared-search.module.ts b/client/src/app/shared/shared-search/shared-search.module.ts index be4ef5e3f..8b5492400 100644 --- a/client/src/app/shared/shared-search/shared-search.module.ts +++ b/client/src/app/shared/shared-search/shared-search.module.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | import { SharedMainModule } from '../shared-main' | 2 | import { SharedMainModule } from '../shared-main' |
3 | import { SharedVideoPlaylistModule } from '../shared-video-playlist' | 3 | import { SharedVideoPlaylistModule } from '../shared-video-playlist' |
4 | import { FindInBulkService } from './find-in-bulk.service' | ||
4 | import { SearchService } from './search.service' | 5 | import { SearchService } from './search.service' |
5 | 6 | ||
6 | @NgModule({ | 7 | @NgModule({ |
@@ -16,6 +17,7 @@ import { SearchService } from './search.service' | |||
16 | ], | 17 | ], |
17 | 18 | ||
18 | providers: [ | 19 | providers: [ |
20 | FindInBulkService, | ||
19 | SearchService | 21 | SearchService |
20 | ] | 22 | ] |
21 | }) | 23 | }) |