1 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
2 import { ServerService } from '@app/core'
3 import { AdvancedSearch } from '@app/shared/shared-search'
4 import { ServerConfig, VideoConstant } from '@shared/models'
6 type FormOption = { id: string, label: string }
9 selector: 'my-search-filters',
10 styleUrls: [ './search-filters.component.scss' ],
11 templateUrl: './search-filters.component.html'
13 export class SearchFiltersComponent implements OnInit {
14 @Input() advancedSearch: AdvancedSearch = new AdvancedSearch()
16 @Output() filtered = new EventEmitter<AdvancedSearch>()
18 videoCategories: VideoConstant<number>[] = []
19 videoLicences: VideoConstant<number>[] = []
20 videoLanguages: VideoConstant<string>[] = []
22 publishedDateRanges: FormOption[] = []
23 sorts: FormOption[] = []
24 durationRanges: FormOption[] = []
25 videoType: FormOption[] = []
27 publishedDateRange: string
30 originallyPublishedStartYear: string
31 originallyPublishedEndYear: string
33 private serverConfig: ServerConfig
36 private serverService: ServerService
38 this.publishedDateRanges = [
41 label: $localize`Today`
45 label: $localize`Last 7 days`
49 label: $localize`Last 30 days`
53 label: $localize`Last 365 days`
60 label: $localize`VOD videos`
64 label: $localize`Live videos`
68 this.durationRanges = [
71 label: $localize`Short (< 4 min)`
75 label: $localize`Medium (4-10 min)`
79 label: $localize`Long (> 10 min)`
86 label: $localize`Relevance`
90 label: $localize`Publish date`
94 label: $localize`Views`
100 this.serverConfig = this.serverService.getTmpConfig()
101 this.serverService.getConfig()
102 .subscribe(config => this.serverConfig = config)
104 this.serverService.getVideoCategories().subscribe(categories => this.videoCategories = categories)
105 this.serverService.getVideoLicences().subscribe(licences => this.videoLicences = licences)
106 this.serverService.getVideoLanguages().subscribe(languages => this.videoLanguages = languages)
108 this.loadFromDurationRange()
109 this.loadFromPublishedRange()
110 this.loadOriginallyPublishedAtYears()
114 this.updateModelFromDurationRange()
115 this.updateModelFromPublishedRange()
116 this.updateModelFromOriginallyPublishedAtYears()
120 this.onInputUpdated()
121 this.filtered.emit(this.advancedSearch)
125 this.advancedSearch.reset()
127 this.resetOriginalPublicationYears()
129 this.durationRange = undefined
130 this.publishedDateRange = undefined
132 this.onInputUpdated()
135 resetField (fieldName: string, value?: any) {
136 this.advancedSearch[fieldName] = value
139 resetLocalField (fieldName: string, value?: any) {
140 this[fieldName] = value
141 this.onInputUpdated()
144 resetOriginalPublicationYears () {
145 this.originallyPublishedStartYear = this.originallyPublishedEndYear = undefined
148 isSearchTargetEnabled () {
149 return this.serverConfig.search.searchIndex.enabled && this.serverConfig.search.searchIndex.disableLocalSearch !== true
152 private loadOriginallyPublishedAtYears () {
153 this.originallyPublishedStartYear = this.advancedSearch.originallyPublishedStartDate
154 ? new Date(this.advancedSearch.originallyPublishedStartDate).getFullYear().toString()
157 this.originallyPublishedEndYear = this.advancedSearch.originallyPublishedEndDate
158 ? new Date(this.advancedSearch.originallyPublishedEndDate).getFullYear().toString()
162 private loadFromDurationRange () {
163 if (this.advancedSearch.durationMin || this.advancedSearch.durationMax) {
164 const fourMinutes = 60 * 4
165 const tenMinutes = 60 * 10
167 if (this.advancedSearch.durationMin === fourMinutes && this.advancedSearch.durationMax === tenMinutes) {
168 this.durationRange = 'medium'
169 } else if (this.advancedSearch.durationMax === fourMinutes) {
170 this.durationRange = 'short'
171 } else if (this.advancedSearch.durationMin === tenMinutes) {
172 this.durationRange = 'long'
177 private loadFromPublishedRange () {
178 if (this.advancedSearch.startDate) {
179 const date = new Date(this.advancedSearch.startDate)
180 const now = new Date()
182 const diff = Math.abs(date.getTime() - now.getTime())
184 const dayMS = 1000 * 3600 * 24
185 const numberOfDays = diff / dayMS
187 if (numberOfDays >= 365) this.publishedDateRange = 'last_365days'
188 else if (numberOfDays >= 30) this.publishedDateRange = 'last_30days'
189 else if (numberOfDays >= 7) this.publishedDateRange = 'last_7days'
190 else if (numberOfDays >= 0) this.publishedDateRange = 'today'
194 private updateModelFromOriginallyPublishedAtYears () {
195 const baseDate = new Date()
196 baseDate.setHours(0, 0, 0, 0)
197 baseDate.setMonth(0, 1)
199 if (this.originallyPublishedStartYear) {
200 const year = parseInt(this.originallyPublishedStartYear, 10)
201 const start = new Date(baseDate)
202 start.setFullYear(year)
204 this.advancedSearch.originallyPublishedStartDate = start.toISOString()
206 this.advancedSearch.originallyPublishedStartDate = null
209 if (this.originallyPublishedEndYear) {
210 const year = parseInt(this.originallyPublishedEndYear, 10)
211 const end = new Date(baseDate)
212 end.setFullYear(year)
214 this.advancedSearch.originallyPublishedEndDate = end.toISOString()
216 this.advancedSearch.originallyPublishedEndDate = null
220 private updateModelFromDurationRange () {
221 if (!this.durationRange) return
223 const fourMinutes = 60 * 4
224 const tenMinutes = 60 * 10
226 switch (this.durationRange) {
228 this.advancedSearch.durationMin = undefined
229 this.advancedSearch.durationMax = fourMinutes
233 this.advancedSearch.durationMin = fourMinutes
234 this.advancedSearch.durationMax = tenMinutes
238 this.advancedSearch.durationMin = tenMinutes
239 this.advancedSearch.durationMax = undefined
244 private updateModelFromPublishedRange () {
245 if (!this.publishedDateRange) return
248 const date = new Date()
249 date.setHours(0, 0, 0, 0)
251 switch (this.publishedDateRange) {
253 date.setDate(date.getDate() - 7)
257 date.setDate(date.getDate() - 30)
261 date.setDate(date.getDate() - 365)
265 this.advancedSearch.startDate = date.toISOString()