aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-12-10 11:02:42 +0100
committerChocobozzz <me@florianbigard.com>2021-12-10 11:02:42 +0100
commit8cf43a6524d354fbfa0f0eaf789e8d4756bd25d6 (patch)
tree3f33a5e36a89eedf7e4ebfa4d08336262e9604c2 /client
parent90701ec1d8d27d0072d6b0d2b19362d471484f9a (diff)
downloadPeerTube-8cf43a6524d354fbfa0f0eaf789e8d4756bd25d6.tar.gz
PeerTube-8cf43a6524d354fbfa0f0eaf789e8d4756bd25d6.tar.zst
PeerTube-8cf43a6524d354fbfa0f0eaf789e8d4756bd25d6.zip
Add filter on search results
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+search/search-filters.component.html25
-rw-r--r--client/src/app/+search/search-filters.component.ts12
-rw-r--r--client/src/app/+search/search.component.ts23
-rw-r--r--client/src/app/shared/shared-search/advanced-search.model.ts30
-rw-r--r--client/src/app/shared/shared-search/search.service.ts14
5 files changed, 82 insertions, 22 deletions
diff --git a/client/src/app/+search/search-filters.component.html b/client/src/app/+search/search-filters.component.html
index 4b87a2102..c4861e8c4 100644
--- a/client/src/app/+search/search-filters.component.html
+++ b/client/src/app/+search/search-filters.component.html
@@ -182,6 +182,31 @@
182 > 182 >
183 </div> 183 </div>
184 184
185 <div class="form-group">
186 <div class="radio-label label-container">
187 <label i18n>Result types</label>
188 <button i18n class="reset-button reset-button-small" (click)="resetField('resultType')" *ngIf="advancedSearch.resultType !== undefined">
189 Reset
190 </button>
191 </div>
192
193 <div class="peertube-radio-container">
194 <input type="radio" name="resultType" id="resultTypeVideos" value="videos" [(ngModel)]="advancedSearch.resultType">
195 <label i18n for="resultTypeVideos" class="radio">Videos</label>
196 </div>
197
198 <div class="peertube-radio-container">
199 <input type="radio" name="resultType" id="resultTypeChannels" value="channels" [(ngModel)]="advancedSearch.resultType">
200 <label i18n for="resultTypeChannels" class="radio">Channels</label>
201 </div>
202
203 <div class="peertube-radio-container">
204 <input type="radio" name="resultType" id="resultTypePlaylists" value="playlists" [(ngModel)]="advancedSearch.resultType">
205 <label i18n for="resultTypePlaylists" class="radio">Playlists</label>
206 </div>
207
208 </div>
209
185 <div class="form-group" *ngIf="isSearchTargetEnabled()"> 210 <div class="form-group" *ngIf="isSearchTargetEnabled()">
186 <div class="radio-label label-container"> 211 <div class="radio-label label-container">
187 <label i18n>Search target</label> 212 <label i18n>Search target</label>
diff --git a/client/src/app/+search/search-filters.component.ts b/client/src/app/+search/search-filters.component.ts
index 5972ba553..aaa4ecc5a 100644
--- a/client/src/app/+search/search-filters.component.ts
+++ b/client/src/app/+search/search-filters.component.ts
@@ -22,7 +22,6 @@ export class SearchFiltersComponent implements OnInit {
22 publishedDateRanges: FormOption[] = [] 22 publishedDateRanges: FormOption[] = []
23 sorts: FormOption[] = [] 23 sorts: FormOption[] = []
24 durationRanges: FormOption[] = [] 24 durationRanges: FormOption[] = []
25 videoType: FormOption[] = []
26 25
27 publishedDateRange: string 26 publishedDateRange: string
28 durationRange: string 27 durationRange: string
@@ -54,17 +53,6 @@ export class SearchFiltersComponent implements OnInit {
54 } 53 }
55 ] 54 ]
56 55
57 this.videoType = [
58 {
59 id: 'vod',
60 label: $localize`VOD videos`
61 },
62 {
63 id: 'live',
64 label: $localize`Live videos`
65 }
66 ]
67
68 this.durationRanges = [ 56 this.durationRanges = [
69 { 57 {
70 id: 'short', 58 id: 'short',
diff --git a/client/src/app/+search/search.component.ts b/client/src/app/+search/search.component.ts
index fcf6ebbec..b9ec6dbcc 100644
--- a/client/src/app/+search/search.component.ts
+++ b/client/src/app/+search/search.component.ts
@@ -47,10 +47,6 @@ export class SearchComponent implements OnInit, OnDestroy {
47 private subActivatedRoute: Subscription 47 private subActivatedRoute: Subscription
48 private isInitialLoad = false // set to false to show the search filters on first arrival 48 private isInitialLoad = false // set to false to show the search filters on first arrival
49 49
50 private channelsPerPage = 2
51 private playlistsPerPage = 2
52 private videosPerPage = 10
53
54 private hasMoreResults = true 50 private hasMoreResults = true
55 private isSearching = false 51 private isSearching = false
56 52
@@ -247,7 +243,6 @@ export class SearchComponent implements OnInit, OnDestroy {
247 private resetPagination () { 243 private resetPagination () {
248 this.pagination.currentPage = 1 244 this.pagination.currentPage = 1
249 this.pagination.totalItems = null 245 this.pagination.totalItems = null
250 this.channelsPerPage = 2
251 246
252 this.results = [] 247 this.results = []
253 } 248 }
@@ -272,7 +267,7 @@ export class SearchComponent implements OnInit, OnDestroy {
272 private getVideosObs () { 267 private getVideosObs () {
273 const params = { 268 const params = {
274 search: this.currentSearch, 269 search: this.currentSearch,
275 componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.videosPerPage }), 270 componentPagination: immutableAssign(this.pagination, { itemsPerPage: 10 }),
276 advancedSearch: this.advancedSearch 271 advancedSearch: this.advancedSearch
277 } 272 }
278 273
@@ -288,7 +283,7 @@ export class SearchComponent implements OnInit, OnDestroy {
288 private getVideoChannelObs () { 283 private getVideoChannelObs () {
289 const params = { 284 const params = {
290 search: this.currentSearch, 285 search: this.currentSearch,
291 componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.channelsPerPage }), 286 componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildChannelsPerPage() }),
292 advancedSearch: this.advancedSearch 287 advancedSearch: this.advancedSearch
293 } 288 }
294 289
@@ -304,7 +299,7 @@ export class SearchComponent implements OnInit, OnDestroy {
304 private getVideoPlaylistObs () { 299 private getVideoPlaylistObs () {
305 const params = { 300 const params = {
306 search: this.currentSearch, 301 search: this.currentSearch,
307 componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.playlistsPerPage }), 302 componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildPlaylistsPerPage() }),
308 advancedSearch: this.advancedSearch 303 advancedSearch: this.advancedSearch
309 } 304 }
310 305
@@ -334,4 +329,16 @@ export class SearchComponent implements OnInit, OnDestroy {
334 329
335 return undefined 330 return undefined
336 } 331 }
332
333 private buildChannelsPerPage () {
334 if (this.advancedSearch.resultType === 'channels') return 10
335
336 return 2
337 }
338
339 private buildPlaylistsPerPage () {
340 if (this.advancedSearch.resultType === 'playlists') return 10
341
342 return 2
343 }
337} 344}
diff --git a/client/src/app/shared/shared-search/advanced-search.model.ts b/client/src/app/shared/shared-search/advanced-search.model.ts
index 2675c6135..724c4d834 100644
--- a/client/src/app/shared/shared-search/advanced-search.model.ts
+++ b/client/src/app/shared/shared-search/advanced-search.model.ts
@@ -8,6 +8,8 @@ import {
8 VideosSearchQuery 8 VideosSearchQuery
9} from '@shared/models' 9} from '@shared/models'
10 10
11export type AdvancedSearchResultType = 'videos' | 'playlists' | 'channels'
12
11export class AdvancedSearch { 13export class AdvancedSearch {
12 startDate: string // ISO 8601 14 startDate: string // ISO 8601
13 endDate: string // ISO 8601 15 endDate: string // ISO 8601
@@ -36,6 +38,7 @@ export class AdvancedSearch {
36 sort: string 38 sort: string
37 39
38 searchTarget: SearchTargetType 40 searchTarget: SearchTargetType
41 resultType: AdvancedSearchResultType
39 42
40 // Filters we don't want to count, because they are mandatory 43 // Filters we don't want to count, because they are mandatory
41 private silentFilters = new Set([ 'sort', 'searchTarget' ]) 44 private silentFilters = new Set([ 'sort', 'searchTarget' ])
@@ -61,6 +64,7 @@ export class AdvancedSearch {
61 durationMax?: string 64 durationMax?: string
62 sort?: string 65 sort?: string
63 searchTarget?: SearchTargetType 66 searchTarget?: SearchTargetType
67 resultType?: AdvancedSearchResultType
64 }) { 68 }) {
65 if (!options) return 69 if (!options) return
66 70
@@ -84,6 +88,12 @@ export class AdvancedSearch {
84 88
85 this.searchTarget = options.searchTarget || undefined 89 this.searchTarget = options.searchTarget || undefined
86 90
91 this.resultType = options.resultType || undefined
92
93 if (!this.resultType && this.hasVideoFilter()) {
94 this.resultType = 'videos'
95 }
96
87 if (isNaN(this.durationMin)) this.durationMin = undefined 97 if (isNaN(this.durationMin)) this.durationMin = undefined
88 if (isNaN(this.durationMax)) this.durationMax = undefined 98 if (isNaN(this.durationMax)) this.durationMax = undefined
89 99
@@ -137,7 +147,8 @@ export class AdvancedSearch {
137 isLive: this.isLive, 147 isLive: this.isLive,
138 host: this.host, 148 host: this.host,
139 sort: this.sort, 149 sort: this.sort,
140 searchTarget: this.searchTarget 150 searchTarget: this.searchTarget,
151 resultType: this.resultType
141 } 152 }
142 } 153 }
143 154
@@ -199,4 +210,21 @@ export class AdvancedSearch {
199 210
200 return true 211 return true
201 } 212 }
213
214 private hasVideoFilter () {
215 return this.startDate !== undefined ||
216 this.endDate !== undefined ||
217 this.originallyPublishedStartDate !== undefined ||
218 this.originallyPublishedEndDate !== undefined ||
219 this.nsfw !== undefined !== undefined ||
220 this.categoryOneOf !== undefined ||
221 this.licenceOneOf !== undefined ||
222 this.languageOneOf !== undefined ||
223 this.tagsOneOf !== undefined ||
224 this.tagsAllOf !== undefined ||
225 this.durationMin !== undefined ||
226 this.durationMax !== undefined ||
227 this.host !== undefined ||
228 this.isLive !== undefined
229 }
202} 230}
diff --git a/client/src/app/shared/shared-search/search.service.ts b/client/src/app/shared/shared-search/search.service.ts
index 71350c733..415bf083c 100644
--- a/client/src/app/shared/shared-search/search.service.ts
+++ b/client/src/app/shared/shared-search/search.service.ts
@@ -1,4 +1,4 @@
1import { Observable } from 'rxjs' 1import { Observable, of } from 'rxjs'
2import { catchError, map, switchMap } from 'rxjs/operators' 2import { catchError, map, switchMap } from 'rxjs/operators'
3import { HttpClient, HttpParams } from '@angular/common/http' 3import { HttpClient, HttpParams } from '@angular/common/http'
4import { Injectable } from '@angular/core' 4import { Injectable } from '@angular/core'
@@ -39,6 +39,10 @@ export class SearchService {
39 }): Observable<ResultList<Video>> { 39 }): Observable<ResultList<Video>> {
40 const { search, uuids, componentPagination, advancedSearch } = parameters 40 const { search, uuids, componentPagination, advancedSearch } = parameters
41 41
42 if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'videos') {
43 return of({ total: 0, data: [] })
44 }
45
42 const url = SearchService.BASE_SEARCH_URL + 'videos' 46 const url = SearchService.BASE_SEARCH_URL + 'videos'
43 let pagination: RestPagination 47 let pagination: RestPagination
44 48
@@ -73,6 +77,10 @@ export class SearchService {
73 }): Observable<ResultList<VideoChannel>> { 77 }): Observable<ResultList<VideoChannel>> {
74 const { search, advancedSearch, componentPagination, handles } = parameters 78 const { search, advancedSearch, componentPagination, handles } = parameters
75 79
80 if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'channels') {
81 return of({ total: 0, data: [] })
82 }
83
76 const url = SearchService.BASE_SEARCH_URL + 'video-channels' 84 const url = SearchService.BASE_SEARCH_URL + 'video-channels'
77 85
78 let pagination: RestPagination 86 let pagination: RestPagination
@@ -107,6 +115,10 @@ export class SearchService {
107 }): Observable<ResultList<VideoPlaylist>> { 115 }): Observable<ResultList<VideoPlaylist>> {
108 const { search, advancedSearch, componentPagination, uuids } = parameters 116 const { search, advancedSearch, componentPagination, uuids } = parameters
109 117
118 if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'playlists') {
119 return of({ total: 0, data: [] })
120 }
121
110 const url = SearchService.BASE_SEARCH_URL + 'video-playlists' 122 const url = SearchService.BASE_SEARCH_URL + 'video-playlists'
111 123
112 let pagination: RestPagination 124 let pagination: RestPagination