]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/shared-video-miniature/video-filters.model.ts
Deprecate filter video query
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-video-miniature / video-filters.model.ts
CommitLineData
dd24f1bb
C
1import { intoArray, toBoolean } from '@app/helpers'
2import { AttributesOnly } from '@shared/core-utils'
2760b454 3import { BooleanBothQuery, NSFWPolicyType, VideoInclude, VideoSortField } from '@shared/models'
dd24f1bb
C
4
5type VideoFiltersKeys = {
6 [ id in keyof AttributesOnly<VideoFilters> ]: any
7}
8
9export type VideoFilterScope = 'local' | 'federated'
10
11export class VideoFilters {
12 sort: VideoSortField
13 nsfw: BooleanBothQuery
14
15 languageOneOf: string[]
16 categoryOneOf: number[]
17
18 scope: VideoFilterScope
19 allVideos: boolean
20
21 live: BooleanBothQuery
22
23 search: string
24
25 private defaultValues = new Map<keyof VideoFilters, any>([
26 [ 'sort', '-publishedAt' ],
27 [ 'nsfw', 'false' ],
28 [ 'languageOneOf', undefined ],
29 [ 'categoryOneOf', undefined ],
30 [ 'scope', 'federated' ],
31 [ 'allVideos', false ],
32 [ 'live', 'both' ]
33 ])
34
35 private activeFilters: { key: string, canRemove: boolean, label: string, value?: string }[] = []
36 private defaultNSFWPolicy: NSFWPolicyType
37
38 private onChangeCallbacks: Array<() => void> = []
39 private oldFormObjectString: string
40
1b206245
C
41 private readonly hiddenFields: string[] = []
42
43 constructor (defaultSort: string, defaultScope: VideoFilterScope, hiddenFields: string[] = []) {
dd24f1bb
C
44 this.setDefaultSort(defaultSort)
45 this.setDefaultScope(defaultScope)
46
1b206245
C
47 this.hiddenFields = hiddenFields
48
dd24f1bb
C
49 this.reset()
50 }
51
52 onChange (cb: () => void) {
53 this.onChangeCallbacks.push(cb)
54 }
55
56 triggerChange () {
57 // Don't run on change if the values did not change
58 const currentFormObjectString = JSON.stringify(this.toFormObject())
59 if (this.oldFormObjectString && currentFormObjectString === this.oldFormObjectString) return
60
61 this.oldFormObjectString = currentFormObjectString
62
63 for (const cb of this.onChangeCallbacks) {
64 cb()
65 }
66 }
67
68 setDefaultScope (scope: VideoFilterScope) {
69 this.defaultValues.set('scope', scope)
70 }
71
72 setDefaultSort (sort: string) {
73 this.defaultValues.set('sort', sort)
74 }
75
76 setNSFWPolicy (nsfwPolicy: NSFWPolicyType) {
77 this.updateDefaultNSFW(nsfwPolicy)
78 }
79
80 reset (specificKey?: string) {
81 for (const [ key, value ] of this.defaultValues) {
82 if (specificKey && specificKey !== key) continue
83
84 // FIXME: typings
85 this[key as any] = value
86 }
87
88 this.buildActiveFilters()
89 }
90
91 load (obj: Partial<AttributesOnly<VideoFilters>>) {
92 if (obj.sort !== undefined) this.sort = obj.sort
93
94 if (obj.nsfw !== undefined) this.nsfw = obj.nsfw
95
96 if (obj.languageOneOf !== undefined) this.languageOneOf = intoArray(obj.languageOneOf)
97 if (obj.categoryOneOf !== undefined) this.categoryOneOf = intoArray(obj.categoryOneOf)
98
99 if (obj.scope !== undefined) this.scope = obj.scope
100 if (obj.allVideos !== undefined) this.allVideos = toBoolean(obj.allVideos)
101
102 if (obj.live !== undefined) this.live = obj.live
103
104 if (obj.search !== undefined) this.search = obj.search
105
106 this.buildActiveFilters()
107 }
108
109 buildActiveFilters () {
110 this.activeFilters = []
111
112 this.activeFilters.push({
113 key: 'nsfw',
114 canRemove: false,
115 label: $localize`Sensitive content`,
116 value: this.getNSFWValue()
117 })
118
119 this.activeFilters.push({
120 key: 'scope',
121 canRemove: false,
122 label: $localize`Scope`,
123 value: this.scope === 'federated'
124 ? $localize`Federated`
125 : $localize`Local`
126 })
127
128 if (this.languageOneOf && this.languageOneOf.length !== 0) {
129 this.activeFilters.push({
130 key: 'languageOneOf',
131 canRemove: true,
132 label: $localize`Languages`,
133 value: this.languageOneOf.map(l => l.toUpperCase()).join(', ')
134 })
135 }
136
137 if (this.categoryOneOf && this.categoryOneOf.length !== 0) {
138 this.activeFilters.push({
139 key: 'categoryOneOf',
140 canRemove: true,
141 label: $localize`Categories`,
142 value: this.categoryOneOf.join(', ')
143 })
144 }
145
146 if (this.allVideos) {
147 this.activeFilters.push({
148 key: 'allVideos',
149 canRemove: true,
150 label: $localize`All videos`
151 })
152 }
153
154 if (this.live === 'true') {
155 this.activeFilters.push({
156 key: 'live',
157 canRemove: true,
158 label: $localize`Live videos`
159 })
160 } else if (this.live === 'false') {
161 this.activeFilters.push({
162 key: 'live',
163 canRemove: true,
164 label: $localize`VOD videos`
165 })
166 }
1b206245
C
167
168 this.activeFilters = this.activeFilters
169 .filter(a => this.hiddenFields.includes(a.key) === false)
dd24f1bb
C
170 }
171
172 getActiveFilters () {
173 return this.activeFilters
174 }
175
176 toFormObject (): VideoFiltersKeys {
177 const result: Partial<VideoFiltersKeys> = {}
178
179 for (const [ key ] of this.defaultValues) {
180 result[key] = this[key]
181 }
182
183 return result as VideoFiltersKeys
184 }
185
186 toUrlObject () {
187 const result: { [ id: string ]: any } = {}
188
189 for (const [ key, defaultValue ] of this.defaultValues) {
190 if (this[key] !== defaultValue) {
191 result[key] = this[key]
192 }
193 }
194
195 return result
196 }
197
198 toVideosAPIObject () {
2760b454
C
199 let isLocal: boolean
200 let include: VideoInclude
201
202 if (this.scope === 'local') {
203 isLocal = true
204 }
205
206 if (this.allVideos) {
207 include = VideoInclude.NOT_PUBLISHED_STATE | VideoInclude.HIDDEN_PRIVACY
dd24f1bb
C
208 }
209
210 let isLive: boolean
211 if (this.live === 'true') isLive = true
212 else if (this.live === 'false') isLive = false
213
214 return {
215 sort: this.sort,
216 nsfw: this.nsfw,
217 languageOneOf: this.languageOneOf,
218 categoryOneOf: this.categoryOneOf,
219 search: this.search,
2760b454
C
220 isLocal,
221 include,
dd24f1bb
C
222 isLive
223 }
224 }
225
226 getNSFWDisplayLabel () {
227 if (this.defaultNSFWPolicy === 'blur') return $localize`Blurred`
228
229 return $localize`Displayed`
230 }
231
232 private getNSFWValue () {
233 if (this.nsfw === 'false') return $localize`hidden`
234 if (this.defaultNSFWPolicy === 'blur') return $localize`blurred`
235
236 return $localize`displayed`
237 }
238
239 private updateDefaultNSFW (nsfwPolicy: NSFWPolicyType) {
240 const nsfw = nsfwPolicy === 'do_not_list'
241 ? 'false'
242 : 'both'
243
244 this.defaultValues.set('nsfw', nsfw)
245 this.defaultNSFWPolicy = nsfwPolicy
246
247 this.reset('nsfw')
248 }
249}