]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/search/search-filters.component.ts
First implem global search
[github/Chocobozzz/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: 'any_published_date',
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: 'any_duration',
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 isSearchTargetEnabled () {
151 return this.serverConfig.search.searchIndex.enabled && this.serverConfig.search.searchIndex.disableLocalSearch !== true
152 }
153
154 private loadOriginallyPublishedAtYears () {
155 this.originallyPublishedStartYear = this.advancedSearch.originallyPublishedStartDate
156 ? new Date(this.advancedSearch.originallyPublishedStartDate).getFullYear().toString()
157 : null
158
159 this.originallyPublishedEndYear = this.advancedSearch.originallyPublishedEndDate
160 ? new Date(this.advancedSearch.originallyPublishedEndDate).getFullYear().toString()
161 : null
162 }
163
164 private loadFromDurationRange () {
165 if (this.advancedSearch.durationMin || this.advancedSearch.durationMax) {
166 const fourMinutes = 60 * 4
167 const tenMinutes = 60 * 10
168
169 if (this.advancedSearch.durationMin === fourMinutes && this.advancedSearch.durationMax === tenMinutes) {
170 this.durationRange = 'medium'
171 } else if (this.advancedSearch.durationMax === fourMinutes) {
172 this.durationRange = 'short'
173 } else if (this.advancedSearch.durationMin === tenMinutes) {
174 this.durationRange = 'long'
175 }
176 }
177 }
178
179 private loadFromPublishedRange () {
180 if (this.advancedSearch.startDate) {
181 const date = new Date(this.advancedSearch.startDate)
182 const now = new Date()
183
184 const diff = Math.abs(date.getTime() - now.getTime())
185
186 const dayMS = 1000 * 3600 * 24
187 const numberOfDays = diff / dayMS
188
189 if (numberOfDays >= 365) this.publishedDateRange = 'last_365days'
190 else if (numberOfDays >= 30) this.publishedDateRange = 'last_30days'
191 else if (numberOfDays >= 7) this.publishedDateRange = 'last_7days'
192 else if (numberOfDays >= 0) this.publishedDateRange = 'today'
193 }
194 }
195
196 private updateModelFromOriginallyPublishedAtYears () {
197 const baseDate = new Date()
198 baseDate.setHours(0, 0, 0, 0)
199 baseDate.setMonth(0, 1)
200
201 if (this.originallyPublishedStartYear) {
202 const year = parseInt(this.originallyPublishedStartYear, 10)
203 const start = new Date(baseDate)
204 start.setFullYear(year)
205
206 this.advancedSearch.originallyPublishedStartDate = start.toISOString()
207 } else {
208 this.advancedSearch.originallyPublishedStartDate = null
209 }
210
211 if (this.originallyPublishedEndYear) {
212 const year = parseInt(this.originallyPublishedEndYear, 10)
213 const end = new Date(baseDate)
214 end.setFullYear(year)
215
216 this.advancedSearch.originallyPublishedEndDate = end.toISOString()
217 } else {
218 this.advancedSearch.originallyPublishedEndDate = null
219 }
220 }
221
222 private updateModelFromDurationRange () {
223 if (!this.durationRange) return
224
225 const fourMinutes = 60 * 4
226 const tenMinutes = 60 * 10
227
228 switch (this.durationRange) {
229 case 'short':
230 this.advancedSearch.durationMin = undefined
231 this.advancedSearch.durationMax = fourMinutes
232 break
233
234 case 'medium':
235 this.advancedSearch.durationMin = fourMinutes
236 this.advancedSearch.durationMax = tenMinutes
237 break
238
239 case 'long':
240 this.advancedSearch.durationMin = tenMinutes
241 this.advancedSearch.durationMax = undefined
242 break
243 }
244 }
245
246 private updateModelFromPublishedRange () {
247 if (!this.publishedDateRange) return
248
249 // today
250 const date = new Date()
251 date.setHours(0, 0, 0, 0)
252
253 switch (this.publishedDateRange) {
254 case 'last_7days':
255 date.setDate(date.getDate() - 7)
256 break
257
258 case 'last_30days':
259 date.setDate(date.getDate() - 30)
260 break
261
262 case 'last_365days':
263 date.setDate(date.getDate() - 365)
264 break
265 }
266
267 this.advancedSearch.startDate = date.toISOString()
268 }
269 }