]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+search/search-filters.component.ts
Add ability to filter by host in search page
[github/Chocobozzz/PeerTube.git] / client / src / app / +search / search-filters.component.ts
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 { HTMLServerConfig, VideoConstant } from '@shared/models'
5
6 type FormOption = { id: string, label: string }
7
8 @Component({
9 selector: 'my-search-filters',
10 styleUrls: [ './search-filters.component.scss' ],
11 templateUrl: './search-filters.component.html'
12 })
13 export class SearchFiltersComponent implements OnInit {
14 @Input() advancedSearch: AdvancedSearch = new AdvancedSearch()
15
16 @Output() filtered = new EventEmitter<AdvancedSearch>()
17
18 videoCategories: VideoConstant<number>[] = []
19 videoLicences: VideoConstant<number>[] = []
20 videoLanguages: VideoConstant<string>[] = []
21
22 publishedDateRanges: FormOption[] = []
23 sorts: FormOption[] = []
24 durationRanges: FormOption[] = []
25 videoType: FormOption[] = []
26
27 publishedDateRange: string
28 durationRange: string
29
30 originallyPublishedStartYear: string
31 originallyPublishedEndYear: string
32
33 private serverConfig: HTMLServerConfig
34
35 constructor (
36 private serverService: ServerService
37 ) {
38 this.publishedDateRanges = [
39 {
40 id: 'today',
41 label: $localize`Today`
42 },
43 {
44 id: 'last_7days',
45 label: $localize`Last 7 days`
46 },
47 {
48 id: 'last_30days',
49 label: $localize`Last 30 days`
50 },
51 {
52 id: 'last_365days',
53 label: $localize`Last 365 days`
54 }
55 ]
56
57 this.videoType = [
58 {
59 id: 'vod',
60 label: $localize`VOD videos`
61 },
62 {
63 id: 'live',
64 label: $localize`Live videos`
65 }
66 ]
67
68 this.durationRanges = [
69 {
70 id: 'short',
71 label: $localize`Short (< 4 min)`
72 },
73 {
74 id: 'medium',
75 label: $localize`Medium (4-10 min)`
76 },
77 {
78 id: 'long',
79 label: $localize`Long (> 10 min)`
80 }
81 ]
82
83 this.sorts = [
84 {
85 id: '-match',
86 label: $localize`Relevance`
87 },
88 {
89 id: '-publishedAt',
90 label: $localize`Publish date`
91 },
92 {
93 id: '-views',
94 label: $localize`Views`
95 }
96 ]
97 }
98
99 ngOnInit () {
100 this.serverConfig = this.serverService.getHTMLConfig()
101
102 this.serverService.getVideoCategories().subscribe(categories => this.videoCategories = categories)
103 this.serverService.getVideoLicences().subscribe(licences => this.videoLicences = licences)
104 this.serverService.getVideoLanguages().subscribe(languages => this.videoLanguages = languages)
105
106 this.loadFromDurationRange()
107 this.loadFromPublishedRange()
108 this.loadOriginallyPublishedAtYears()
109 }
110
111 onDurationOrPublishedUpdated () {
112 this.updateModelFromDurationRange()
113 this.updateModelFromPublishedRange()
114 this.updateModelFromOriginallyPublishedAtYears()
115 }
116
117 formUpdated () {
118 this.onDurationOrPublishedUpdated()
119 this.filtered.emit(this.advancedSearch)
120 }
121
122 reset () {
123 this.advancedSearch.reset()
124
125 this.resetOriginalPublicationYears()
126
127 this.durationRange = undefined
128 this.publishedDateRange = undefined
129
130 this.onDurationOrPublishedUpdated()
131 }
132
133 resetField (fieldName: string, value?: any) {
134 this.advancedSearch[fieldName] = value
135 }
136
137 resetLocalField (fieldName: string, value?: any) {
138 this[fieldName] = value
139 this.onDurationOrPublishedUpdated()
140 }
141
142 resetOriginalPublicationYears () {
143 this.originallyPublishedStartYear = this.originallyPublishedEndYear = undefined
144 }
145
146 isSearchTargetEnabled () {
147 return this.serverConfig.search.searchIndex.enabled && this.serverConfig.search.searchIndex.disableLocalSearch !== true
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 }