]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add filter on search results
authorChocobozzz <me@florianbigard.com>
Fri, 10 Dec 2021 10:02:42 +0000 (11:02 +0100)
committerChocobozzz <me@florianbigard.com>
Fri, 10 Dec 2021 10:02:42 +0000 (11:02 +0100)
client/src/app/+search/search-filters.component.html
client/src/app/+search/search-filters.component.ts
client/src/app/+search/search.component.ts
client/src/app/shared/shared-search/advanced-search.model.ts
client/src/app/shared/shared-search/search.service.ts

index 4b87a210209e199048820510aaea8ab92d87141c..c4861e8c4fef9a14c2670f825b568eae78db6593 100644 (file)
         >
       </div>
 
+      <div class="form-group">
+        <div class="radio-label label-container">
+          <label i18n>Result types</label>
+          <button i18n class="reset-button reset-button-small" (click)="resetField('resultType')" *ngIf="advancedSearch.resultType !== undefined">
+            Reset
+          </button>
+        </div>
+
+        <div class="peertube-radio-container">
+          <input type="radio" name="resultType" id="resultTypeVideos" value="videos" [(ngModel)]="advancedSearch.resultType">
+          <label i18n for="resultTypeVideos" class="radio">Videos</label>
+        </div>
+
+        <div class="peertube-radio-container">
+          <input type="radio" name="resultType" id="resultTypeChannels" value="channels" [(ngModel)]="advancedSearch.resultType">
+          <label i18n for="resultTypeChannels" class="radio">Channels</label>
+        </div>
+
+        <div class="peertube-radio-container">
+          <input type="radio" name="resultType" id="resultTypePlaylists" value="playlists" [(ngModel)]="advancedSearch.resultType">
+          <label i18n for="resultTypePlaylists" class="radio">Playlists</label>
+        </div>
+
+      </div>
+
       <div class="form-group" *ngIf="isSearchTargetEnabled()">
         <div class="radio-label label-container">
           <label i18n>Search target</label>
index 5972ba553201408f438d72b7a8f0cdb5b19e1137..aaa4ecc5a8534ece89e4381adf7f130acb86ad0d 100644 (file)
@@ -22,7 +22,6 @@ export class SearchFiltersComponent implements OnInit {
   publishedDateRanges: FormOption[] = []
   sorts: FormOption[] = []
   durationRanges: FormOption[] = []
-  videoType: FormOption[] = []
 
   publishedDateRange: string
   durationRange: string
@@ -54,17 +53,6 @@ export class SearchFiltersComponent implements OnInit {
       }
     ]
 
-    this.videoType = [
-      {
-        id: 'vod',
-        label: $localize`VOD videos`
-      },
-      {
-        id: 'live',
-        label: $localize`Live videos`
-      }
-    ]
-
     this.durationRanges = [
       {
         id: 'short',
index fcf6ebbec77c40202159962b1580d4e2890a4f10..b9ec6dbccf8c431babbf127b851e8ef884d282e3 100644 (file)
@@ -47,10 +47,6 @@ export class SearchComponent implements OnInit, OnDestroy {
   private subActivatedRoute: Subscription
   private isInitialLoad = false // set to false to show the search filters on first arrival
 
-  private channelsPerPage = 2
-  private playlistsPerPage = 2
-  private videosPerPage = 10
-
   private hasMoreResults = true
   private isSearching = false
 
@@ -247,7 +243,6 @@ export class SearchComponent implements OnInit, OnDestroy {
   private resetPagination () {
     this.pagination.currentPage = 1
     this.pagination.totalItems = null
-    this.channelsPerPage = 2
 
     this.results = []
   }
@@ -272,7 +267,7 @@ export class SearchComponent implements OnInit, OnDestroy {
   private getVideosObs () {
     const params = {
       search: this.currentSearch,
-      componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.videosPerPage }),
+      componentPagination: immutableAssign(this.pagination, { itemsPerPage: 10 }),
       advancedSearch: this.advancedSearch
     }
 
@@ -288,7 +283,7 @@ export class SearchComponent implements OnInit, OnDestroy {
   private getVideoChannelObs () {
     const params = {
       search: this.currentSearch,
-      componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.channelsPerPage }),
+      componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildChannelsPerPage() }),
       advancedSearch: this.advancedSearch
     }
 
@@ -304,7 +299,7 @@ export class SearchComponent implements OnInit, OnDestroy {
   private getVideoPlaylistObs () {
     const params = {
       search: this.currentSearch,
-      componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.playlistsPerPage }),
+      componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildPlaylistsPerPage() }),
       advancedSearch: this.advancedSearch
     }
 
@@ -334,4 +329,16 @@ export class SearchComponent implements OnInit, OnDestroy {
 
     return undefined
   }
+
+  private buildChannelsPerPage () {
+    if (this.advancedSearch.resultType === 'channels') return 10
+
+    return 2
+  }
+
+  private buildPlaylistsPerPage () {
+    if (this.advancedSearch.resultType === 'playlists') return 10
+
+    return 2
+  }
 }
index 2675c613547436c2c904d17ddc20673b931e1519..724c4d83498847c08d746e15b68d946d7643de76 100644 (file)
@@ -8,6 +8,8 @@ import {
   VideosSearchQuery
 } from '@shared/models'
 
+export type AdvancedSearchResultType = 'videos' | 'playlists' | 'channels'
+
 export class AdvancedSearch {
   startDate: string // ISO 8601
   endDate: string // ISO 8601
@@ -36,6 +38,7 @@ export class AdvancedSearch {
   sort: string
 
   searchTarget: SearchTargetType
+  resultType: AdvancedSearchResultType
 
   // Filters we don't want to count, because they are mandatory
   private silentFilters = new Set([ 'sort', 'searchTarget' ])
@@ -61,6 +64,7 @@ export class AdvancedSearch {
     durationMax?: string
     sort?: string
     searchTarget?: SearchTargetType
+    resultType?: AdvancedSearchResultType
   }) {
     if (!options) return
 
@@ -84,6 +88,12 @@ export class AdvancedSearch {
 
     this.searchTarget = options.searchTarget || undefined
 
+    this.resultType = options.resultType || undefined
+
+    if (!this.resultType && this.hasVideoFilter()) {
+      this.resultType = 'videos'
+    }
+
     if (isNaN(this.durationMin)) this.durationMin = undefined
     if (isNaN(this.durationMax)) this.durationMax = undefined
 
@@ -137,7 +147,8 @@ export class AdvancedSearch {
       isLive: this.isLive,
       host: this.host,
       sort: this.sort,
-      searchTarget: this.searchTarget
+      searchTarget: this.searchTarget,
+      resultType: this.resultType
     }
   }
 
@@ -199,4 +210,21 @@ export class AdvancedSearch {
 
     return true
   }
+
+  private hasVideoFilter () {
+    return this.startDate !== undefined ||
+      this.endDate !== undefined ||
+      this.originallyPublishedStartDate !== undefined ||
+      this.originallyPublishedEndDate !== undefined ||
+      this.nsfw !== undefined !== undefined ||
+      this.categoryOneOf !== undefined ||
+      this.licenceOneOf !== undefined ||
+      this.languageOneOf !== undefined ||
+      this.tagsOneOf !== undefined ||
+      this.tagsAllOf !== undefined ||
+      this.durationMin !== undefined ||
+      this.durationMax !== undefined ||
+      this.host !== undefined ||
+      this.isLive !== undefined
+  }
 }
index 71350c7337e7c46ee1571074673af4e3129172f9..415bf083c6c813ca0f331c6aa5de5850897c73ac 100644 (file)
@@ -1,4 +1,4 @@
-import { Observable } from 'rxjs'
+import { Observable, of } from 'rxjs'
 import { catchError, map, switchMap } from 'rxjs/operators'
 import { HttpClient, HttpParams } from '@angular/common/http'
 import { Injectable } from '@angular/core'
@@ -39,6 +39,10 @@ export class SearchService {
   }): Observable<ResultList<Video>> {
     const { search, uuids, componentPagination, advancedSearch } = parameters
 
+    if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'videos') {
+      return of({ total: 0, data: [] })
+    }
+
     const url = SearchService.BASE_SEARCH_URL + 'videos'
     let pagination: RestPagination
 
@@ -73,6 +77,10 @@ export class SearchService {
   }): Observable<ResultList<VideoChannel>> {
     const { search, advancedSearch, componentPagination, handles } = parameters
 
+    if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'channels') {
+      return of({ total: 0, data: [] })
+    }
+
     const url = SearchService.BASE_SEARCH_URL + 'video-channels'
 
     let pagination: RestPagination
@@ -107,6 +115,10 @@ export class SearchService {
   }): Observable<ResultList<VideoPlaylist>> {
     const { search, advancedSearch, componentPagination, uuids } = parameters
 
+    if (advancedSearch.resultType !== undefined && advancedSearch.resultType !== 'playlists') {
+      return of({ total: 0, data: [] })
+    }
+
     const url = SearchService.BASE_SEARCH_URL + 'video-playlists'
 
     let pagination: RestPagination