Fix angular 9 build
[oweals/peertube.git] / client / src / app / search / search-filters.component.ts
1 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
2 import { ValidatorFn } from '@angular/forms'
3 import { VideoValidatorsService } from '@app/shared'
4 import { ServerService } from '@app/core'
5 import { I18n } from '@ngx-translate/i18n-polyfill'
6 import { AdvancedSearch } from '@app/search/advanced-search.model'
7 import { ServerConfig, VideoConstant } from '../../../../shared'
8
9 @Component({
10   selector: 'my-search-filters',
11   styleUrls: [ './search-filters.component.scss' ],
12   templateUrl: './search-filters.component.html'
13 })
14 export class SearchFiltersComponent implements OnInit {
15   @Input() advancedSearch: AdvancedSearch = new AdvancedSearch()
16
17   @Output() filtered = new EventEmitter<AdvancedSearch>()
18
19   videoCategories: VideoConstant<number>[] = []
20   videoLicences: VideoConstant<number>[] = []
21   videoLanguages: VideoConstant<string>[] = []
22
23   tagValidators: ValidatorFn[]
24   tagValidatorsMessages: { [ name: string ]: string }
25
26   publishedDateRanges: { id: string, label: string }[] = []
27   sorts: { id: string, label: string }[] = []
28   durationRanges: { id: string, label: string }[] = []
29
30   publishedDateRange: string
31   durationRange: string
32
33   originallyPublishedStartYear: string
34   originallyPublishedEndYear: string
35
36   private serverConfig: ServerConfig
37
38   constructor (
39     private i18n: I18n,
40     private videoValidatorsService: VideoValidatorsService,
41     private serverService: ServerService
42   ) {
43     this.tagValidators = this.videoValidatorsService.VIDEO_TAGS.VALIDATORS
44     this.tagValidatorsMessages = this.videoValidatorsService.VIDEO_TAGS.MESSAGES
45     this.publishedDateRanges = [
46       {
47         id: undefined,
48         label: this.i18n('Any')
49       },
50       {
51         id: 'today',
52         label: this.i18n('Today')
53       },
54       {
55         id: 'last_7days',
56         label: this.i18n('Last 7 days')
57       },
58       {
59         id: 'last_30days',
60         label: this.i18n('Last 30 days')
61       },
62       {
63         id: 'last_365days',
64         label: this.i18n('Last 365 days')
65       }
66     ]
67
68     this.durationRanges = [
69       {
70         id: undefined,
71         label: this.i18n('Any')
72       },
73       {
74         id: 'short',
75         label: this.i18n('Short (< 4 min)')
76       },
77       {
78         id: 'medium',
79         label: this.i18n('Medium (4-10 min)')
80       },
81       {
82         id: 'long',
83         label: this.i18n('Long (> 10 min)')
84       }
85     ]
86
87     this.sorts = [
88       {
89         id: '-match',
90         label: this.i18n('Relevance')
91       },
92       {
93         id: '-publishedAt',
94         label: this.i18n('Publish date')
95       },
96       {
97         id: '-views',
98         label: this.i18n('Views')
99       }
100     ]
101   }
102
103   ngOnInit () {
104     this.serverConfig = this.serverService.getTmpConfig()
105     this.serverService.getConfig()
106         .subscribe(config => this.serverConfig = config)
107
108     this.serverService.getVideoCategories().subscribe(categories => this.videoCategories = categories)
109     this.serverService.getVideoLicences().subscribe(licences => this.videoLicences = licences)
110     this.serverService.getVideoLanguages().subscribe(languages => this.videoLanguages = languages)
111
112     this.loadFromDurationRange()
113     this.loadFromPublishedRange()
114     this.loadOriginallyPublishedAtYears()
115   }
116
117   inputUpdated () {
118     this.updateModelFromDurationRange()
119     this.updateModelFromPublishedRange()
120     this.updateModelFromOriginallyPublishedAtYears()
121   }
122
123   formUpdated () {
124     this.inputUpdated()
125     this.filtered.emit(this.advancedSearch)
126   }
127
128   reset () {
129     this.advancedSearch.reset()
130     this.durationRange = undefined
131     this.publishedDateRange = undefined
132     this.originallyPublishedStartYear = undefined
133     this.originallyPublishedEndYear = undefined
134     this.inputUpdated()
135   }
136
137   resetField (fieldName: string, value?: any) {
138     this.advancedSearch[fieldName] = value
139   }
140
141   resetLocalField (fieldName: string, value?: any) {
142     this[fieldName] = value
143     this.inputUpdated()
144   }
145
146   resetOriginalPublicationYears () {
147     this.originallyPublishedStartYear = this.originallyPublishedEndYear = undefined
148   }
149
150   private loadOriginallyPublishedAtYears () {
151     this.originallyPublishedStartYear = this.advancedSearch.originallyPublishedStartDate
152       ? new Date(this.advancedSearch.originallyPublishedStartDate).getFullYear().toString()
153       : null
154
155     this.originallyPublishedEndYear = this.advancedSearch.originallyPublishedEndDate
156       ? new Date(this.advancedSearch.originallyPublishedEndDate).getFullYear().toString()
157       : null
158   }
159
160   private loadFromDurationRange () {
161     if (this.advancedSearch.durationMin || this.advancedSearch.durationMax) {
162       const fourMinutes = 60 * 4
163       const tenMinutes = 60 * 10
164
165       if (this.advancedSearch.durationMin === fourMinutes && this.advancedSearch.durationMax === tenMinutes) {
166         this.durationRange = 'medium'
167       } else if (this.advancedSearch.durationMax === fourMinutes) {
168         this.durationRange = 'short'
169       } else if (this.advancedSearch.durationMin === tenMinutes) {
170         this.durationRange = 'long'
171       }
172     }
173   }
174
175   private loadFromPublishedRange () {
176     if (this.advancedSearch.startDate) {
177       const date = new Date(this.advancedSearch.startDate)
178       const now = new Date()
179
180       const diff = Math.abs(date.getTime() - now.getTime())
181
182       const dayMS = 1000 * 3600 * 24
183       const numberOfDays = diff / dayMS
184
185       if (numberOfDays >= 365) this.publishedDateRange = 'last_365days'
186       else if (numberOfDays >= 30) this.publishedDateRange = 'last_30days'
187       else if (numberOfDays >= 7) this.publishedDateRange = 'last_7days'
188       else if (numberOfDays >= 0) this.publishedDateRange = 'today'
189     }
190   }
191
192   private updateModelFromOriginallyPublishedAtYears () {
193     const baseDate = new Date()
194     baseDate.setHours(0, 0, 0, 0)
195     baseDate.setMonth(0, 1)
196
197     if (this.originallyPublishedStartYear) {
198       const year = parseInt(this.originallyPublishedStartYear, 10)
199       const start = new Date(baseDate)
200       start.setFullYear(year)
201
202       this.advancedSearch.originallyPublishedStartDate = start.toISOString()
203     } else {
204       this.advancedSearch.originallyPublishedStartDate = null
205     }
206
207     if (this.originallyPublishedEndYear) {
208       const year = parseInt(this.originallyPublishedEndYear, 10)
209       const end = new Date(baseDate)
210       end.setFullYear(year)
211
212       this.advancedSearch.originallyPublishedEndDate = end.toISOString()
213     } else {
214       this.advancedSearch.originallyPublishedEndDate = null
215     }
216   }
217
218   private updateModelFromDurationRange () {
219     if (!this.durationRange) return
220
221     const fourMinutes = 60 * 4
222     const tenMinutes = 60 * 10
223
224     switch (this.durationRange) {
225       case 'short':
226         this.advancedSearch.durationMin = undefined
227         this.advancedSearch.durationMax = fourMinutes
228         break
229
230       case 'medium':
231         this.advancedSearch.durationMin = fourMinutes
232         this.advancedSearch.durationMax = tenMinutes
233         break
234
235       case 'long':
236         this.advancedSearch.durationMin = tenMinutes
237         this.advancedSearch.durationMax = undefined
238         break
239     }
240   }
241
242   private updateModelFromPublishedRange () {
243     if (!this.publishedDateRange) return
244
245     // today
246     const date = new Date()
247     date.setHours(0, 0, 0, 0)
248
249     switch (this.publishedDateRange) {
250       case 'last_7days':
251         date.setDate(date.getDate() - 7)
252         break
253
254       case 'last_30days':
255         date.setDate(date.getDate() - 30)
256         break
257
258       case 'last_365days':
259         date.setDate(date.getDate() - 365)
260         break
261     }
262
263     this.advancedSearch.startDate = date.toISOString()
264   }
265 }