Add filter on search results
This commit is contained in:
parent
90701ec1d8
commit
8cf43a6524
|
@ -182,6 +182,31 @@
|
||||||
>
|
>
|
||||||
</div>
|
</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="form-group" *ngIf="isSearchTargetEnabled()">
|
||||||
<div class="radio-label label-container">
|
<div class="radio-label label-container">
|
||||||
<label i18n>Search target</label>
|
<label i18n>Search target</label>
|
||||||
|
|
|
@ -22,7 +22,6 @@ export class SearchFiltersComponent implements OnInit {
|
||||||
publishedDateRanges: FormOption[] = []
|
publishedDateRanges: FormOption[] = []
|
||||||
sorts: FormOption[] = []
|
sorts: FormOption[] = []
|
||||||
durationRanges: FormOption[] = []
|
durationRanges: FormOption[] = []
|
||||||
videoType: FormOption[] = []
|
|
||||||
|
|
||||||
publishedDateRange: string
|
publishedDateRange: string
|
||||||
durationRange: 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 = [
|
this.durationRanges = [
|
||||||
{
|
{
|
||||||
id: 'short',
|
id: 'short',
|
||||||
|
|
|
@ -47,10 +47,6 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private subActivatedRoute: Subscription
|
private subActivatedRoute: Subscription
|
||||||
private isInitialLoad = false // set to false to show the search filters on first arrival
|
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 hasMoreResults = true
|
||||||
private isSearching = false
|
private isSearching = false
|
||||||
|
|
||||||
|
@ -247,7 +243,6 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private resetPagination () {
|
private resetPagination () {
|
||||||
this.pagination.currentPage = 1
|
this.pagination.currentPage = 1
|
||||||
this.pagination.totalItems = null
|
this.pagination.totalItems = null
|
||||||
this.channelsPerPage = 2
|
|
||||||
|
|
||||||
this.results = []
|
this.results = []
|
||||||
}
|
}
|
||||||
|
@ -272,7 +267,7 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private getVideosObs () {
|
private getVideosObs () {
|
||||||
const params = {
|
const params = {
|
||||||
search: this.currentSearch,
|
search: this.currentSearch,
|
||||||
componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.videosPerPage }),
|
componentPagination: immutableAssign(this.pagination, { itemsPerPage: 10 }),
|
||||||
advancedSearch: this.advancedSearch
|
advancedSearch: this.advancedSearch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +283,7 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private getVideoChannelObs () {
|
private getVideoChannelObs () {
|
||||||
const params = {
|
const params = {
|
||||||
search: this.currentSearch,
|
search: this.currentSearch,
|
||||||
componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.channelsPerPage }),
|
componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildChannelsPerPage() }),
|
||||||
advancedSearch: this.advancedSearch
|
advancedSearch: this.advancedSearch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +299,7 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
private getVideoPlaylistObs () {
|
private getVideoPlaylistObs () {
|
||||||
const params = {
|
const params = {
|
||||||
search: this.currentSearch,
|
search: this.currentSearch,
|
||||||
componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.playlistsPerPage }),
|
componentPagination: immutableAssign(this.pagination, { itemsPerPage: this.buildPlaylistsPerPage() }),
|
||||||
advancedSearch: this.advancedSearch
|
advancedSearch: this.advancedSearch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,4 +329,16 @@ export class SearchComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildChannelsPerPage () {
|
||||||
|
if (this.advancedSearch.resultType === 'channels') return 10
|
||||||
|
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildPlaylistsPerPage () {
|
||||||
|
if (this.advancedSearch.resultType === 'playlists') return 10
|
||||||
|
|
||||||
|
return 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
VideosSearchQuery
|
VideosSearchQuery
|
||||||
} from '@shared/models'
|
} from '@shared/models'
|
||||||
|
|
||||||
|
export type AdvancedSearchResultType = 'videos' | 'playlists' | 'channels'
|
||||||
|
|
||||||
export class AdvancedSearch {
|
export class AdvancedSearch {
|
||||||
startDate: string // ISO 8601
|
startDate: string // ISO 8601
|
||||||
endDate: string // ISO 8601
|
endDate: string // ISO 8601
|
||||||
|
@ -36,6 +38,7 @@ export class AdvancedSearch {
|
||||||
sort: string
|
sort: string
|
||||||
|
|
||||||
searchTarget: SearchTargetType
|
searchTarget: SearchTargetType
|
||||||
|
resultType: AdvancedSearchResultType
|
||||||
|
|
||||||
// Filters we don't want to count, because they are mandatory
|
// Filters we don't want to count, because they are mandatory
|
||||||
private silentFilters = new Set([ 'sort', 'searchTarget' ])
|
private silentFilters = new Set([ 'sort', 'searchTarget' ])
|
||||||
|
@ -61,6 +64,7 @@ export class AdvancedSearch {
|
||||||
durationMax?: string
|
durationMax?: string
|
||||||
sort?: string
|
sort?: string
|
||||||
searchTarget?: SearchTargetType
|
searchTarget?: SearchTargetType
|
||||||
|
resultType?: AdvancedSearchResultType
|
||||||
}) {
|
}) {
|
||||||
if (!options) return
|
if (!options) return
|
||||||
|
|
||||||
|
@ -84,6 +88,12 @@ export class AdvancedSearch {
|
||||||
|
|
||||||
this.searchTarget = options.searchTarget || undefined
|
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.durationMin)) this.durationMin = undefined
|
||||||
if (isNaN(this.durationMax)) this.durationMax = undefined
|
if (isNaN(this.durationMax)) this.durationMax = undefined
|
||||||
|
|
||||||
|
@ -137,7 +147,8 @@ export class AdvancedSearch {
|
||||||
isLive: this.isLive,
|
isLive: this.isLive,
|
||||||
host: this.host,
|
host: this.host,
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
searchTarget: this.searchTarget
|
searchTarget: this.searchTarget,
|
||||||
|
resultType: this.resultType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,4 +210,21 @@ export class AdvancedSearch {
|
||||||
|
|
||||||
return true
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Observable } from 'rxjs'
|
import { Observable, of } from 'rxjs'
|
||||||
import { catchError, map, switchMap } from 'rxjs/operators'
|
import { catchError, map, switchMap } from 'rxjs/operators'
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
@ -39,6 +39,10 @@ export class SearchService {
|
||||||
}): Observable<ResultList<Video>> {
|
}): Observable<ResultList<Video>> {
|
||||||
const { search, uuids, componentPagination, advancedSearch } = parameters
|
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'
|
const url = SearchService.BASE_SEARCH_URL + 'videos'
|
||||||
let pagination: RestPagination
|
let pagination: RestPagination
|
||||||
|
|
||||||
|
@ -73,6 +77,10 @@ export class SearchService {
|
||||||
}): Observable<ResultList<VideoChannel>> {
|
}): Observable<ResultList<VideoChannel>> {
|
||||||
const { search, advancedSearch, componentPagination, handles } = parameters
|
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'
|
const url = SearchService.BASE_SEARCH_URL + 'video-channels'
|
||||||
|
|
||||||
let pagination: RestPagination
|
let pagination: RestPagination
|
||||||
|
@ -107,6 +115,10 @@ export class SearchService {
|
||||||
}): Observable<ResultList<VideoPlaylist>> {
|
}): Observable<ResultList<VideoPlaylist>> {
|
||||||
const { search, advancedSearch, componentPagination, uuids } = parameters
|
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'
|
const url = SearchService.BASE_SEARCH_URL + 'video-playlists'
|
||||||
|
|
||||||
let pagination: RestPagination
|
let pagination: RestPagination
|
||||||
|
|
Loading…
Reference in New Issue
Block a user