Merge from upstream
[oweals/peertube.git] / client / src / app / search / search-filters.component.ts
1 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
2 import { ActivatedRoute } from '@angular/router'
3 import { RedirectService, ServerService } from '@app/core'
4 import { NotificationsService } from 'angular2-notifications'
5 import { SearchService } from '@app/search/search.service'
6 import { I18n } from '@ngx-translate/i18n-polyfill'
7 import { MetaService } from '@ngx-meta/core'
8 import { AdvancedSearch } from '@app/search/advanced-search.model'
9 import { VideoConstant } from '../../../../shared'
10
11 @Component({
12   selector: 'my-search-filters',
13   styleUrls: [ './search-filters.component.scss' ],
14   templateUrl: './search-filters.component.html'
15 })
16 export class SearchFiltersComponent implements OnInit {
17   @Input() advancedSearch: AdvancedSearch = new AdvancedSearch()
18
19   @Output() filtered = new EventEmitter<AdvancedSearch>()
20
21   videoCategories: VideoConstant<number>[] = []
22   videoLicences: VideoConstant<number>[] = []
23   videoLanguages: VideoConstant<string>[] = []
24
25   publishedDateRanges: { id: string, label: string }[] = []
26   sorts: { id: string, label: string }[] = []
27   durationRanges: { id: string, label: string }[] = []
28
29   publishedDateRange: string
30   durationRange: string
31
32   constructor (
33     private i18n: I18n,
34     private serverService: ServerService
35   ) {
36     this.publishedDateRanges = [
37       {
38         id: 'today',
39         label: this.i18n('Today')
40       },
41       {
42         id: 'last_7days',
43         label: this.i18n('Last 7 days')
44       },
45       {
46         id: 'last_30days',
47         label: this.i18n('Last 30 days')
48       },
49       {
50         id: 'last_365days',
51         label: this.i18n('Last 365 days')
52       }
53     ]
54
55     this.durationRanges = [
56       {
57         id: 'short',
58         label: this.i18n('Short (< 4 min)')
59       },
60       {
61         id: 'long',
62         label: this.i18n('Long (> 10 min)')
63       },
64       {
65         id: 'medium',
66         label: this.i18n('Medium (4-10 min)')
67       }
68     ]
69
70     this.sorts = [
71       {
72         id: '-match',
73         label: this.i18n('Relevance')
74       },
75       {
76         id: '-publishedAt',
77         label: this.i18n('Publish date')
78       },
79       {
80         id: '-views',
81         label: this.i18n('Views')
82       }
83     ]
84   }
85
86   ngOnInit () {
87     this.videoCategories = this.serverService.getVideoCategories()
88     this.videoLicences = this.serverService.getVideoLicences()
89     this.videoLanguages = this.serverService.getVideoLanguages()
90
91     this.loadFromDurationRange()
92     this.loadFromPublishedRange()
93   }
94
95   formUpdated () {
96     this.updateModelFromDurationRange()
97     this.updateModelFromPublishedRange()
98
99     this.filtered.emit(this.advancedSearch)
100   }
101
102   private loadFromDurationRange () {
103     if (this.advancedSearch.durationMin || this.advancedSearch.durationMax) {
104       const fourMinutes = 60 * 4
105       const tenMinutes = 60 * 10
106
107       if (this.advancedSearch.durationMin === fourMinutes && this.advancedSearch.durationMax === tenMinutes) {
108         this.durationRange = 'medium'
109       } else if (this.advancedSearch.durationMax === fourMinutes) {
110         this.durationRange = 'short'
111       } else if (this.advancedSearch.durationMin === tenMinutes) {
112         this.durationRange = 'long'
113       }
114     }
115   }
116
117   private loadFromPublishedRange () {
118     if (this.advancedSearch.startDate) {
119       const date = new Date(this.advancedSearch.startDate)
120       const now = new Date()
121
122       const diff = Math.abs(date.getTime() - now.getTime())
123
124       const dayMS = 1000 * 3600 * 24
125       const numberOfDays = diff / dayMS
126
127       if (numberOfDays >= 365) this.publishedDateRange = 'last_365days'
128       else if (numberOfDays >= 30) this.publishedDateRange = 'last_30days'
129       else if (numberOfDays >= 7) this.publishedDateRange = 'last_7days'
130       else if (numberOfDays >= 0) this.publishedDateRange = 'today'
131     }
132   }
133
134   private updateModelFromDurationRange () {
135     if (!this.durationRange) return
136
137     const fourMinutes = 60 * 4
138     const tenMinutes = 60 * 10
139
140     switch (this.durationRange) {
141       case 'short':
142         this.advancedSearch.durationMin = undefined
143         this.advancedSearch.durationMax = fourMinutes
144         break
145
146       case 'medium':
147         this.advancedSearch.durationMin = fourMinutes
148         this.advancedSearch.durationMax = tenMinutes
149         break
150
151       case 'long':
152         this.advancedSearch.durationMin = tenMinutes
153         this.advancedSearch.durationMax = undefined
154         break
155     }
156   }
157
158   private updateModelFromPublishedRange () {
159     if (!this.publishedDateRange) return
160
161     // today
162     const date = new Date()
163     date.setHours(0, 0, 0, 0)
164
165     switch (this.publishedDateRange) {
166       case 'last_7days':
167         date.setDate(date.getDate() - 7)
168         break
169
170       case 'last_30days':
171         date.setDate(date.getDate() - 30)
172         break
173
174       case 'last_365days':
175         date.setDate(date.getDate() - 365)
176         break
177     }
178
179     this.advancedSearch.startDate = date.toISOString()
180   }
181 }