]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/shared/shared-search/advanced-search.model.ts
Update angular
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-search / advanced-search.model.ts
index 516854a8c210360a6feb67e27346f4b9bf5ebcfc..29fe3e8dc9e7ed3b348cf48d6c23c1f8fb50af68 100644 (file)
@@ -1,4 +1,14 @@
-import { NSFWQuery, SearchTargetType } from '@shared/models'
+import { splitIntoArray } from '@app/helpers'
+import {
+  BooleanBothQuery,
+  BooleanQuery,
+  SearchTargetType,
+  VideoChannelsSearchQuery,
+  VideoPlaylistsSearchQuery,
+  VideosSearchQuery
+} from '@shared/models'
+
+export type AdvancedSearchResultType = 'videos' | 'playlists' | 'channels'
 
 export class AdvancedSearch {
   startDate: string // ISO 8601
@@ -7,7 +17,7 @@ export class AdvancedSearch {
   originallyPublishedStartDate: string // ISO 8601
   originallyPublishedEndDate: string // ISO 8601
 
-  nsfw: NSFWQuery
+  nsfw: BooleanBothQuery
 
   categoryOneOf: string
 
@@ -15,34 +25,47 @@ export class AdvancedSearch {
 
   languageOneOf: string
 
-  tagsOneOf: string
-  tagsAllOf: string
+  tagsOneOf: string[]
+  tagsAllOf: string[]
 
   durationMin: number // seconds
   durationMax: number // seconds
 
+  isLive: BooleanQuery
+
+  host: string
+
   sort: string
 
   searchTarget: SearchTargetType
+  resultType: AdvancedSearchResultType
 
-  // Filters we don't want to count, because they are mandatory
-  private silentFilters = new Set([ 'sort', 'searchTarget' ])
+  excludeAlreadyWatched?: boolean
 
   constructor (options?: {
     startDate?: string
     endDate?: string
     originallyPublishedStartDate?: string
     originallyPublishedEndDate?: string
-    nsfw?: NSFWQuery
+    nsfw?: BooleanBothQuery
     categoryOneOf?: string
     licenceOneOf?: string
     languageOneOf?: string
-    tagsOneOf?: string
-    tagsAllOf?: string
+
+    tagsOneOf?: any
+    tagsAllOf?: any
+
+    isLive?: BooleanQuery
+
+    host?: string
+
     durationMin?: string
     durationMax?: string
     sort?: string
     searchTarget?: SearchTargetType
+    resultType?: AdvancedSearchResultType
+
+    excludeAlreadyWatched?: boolean
   }) {
     if (!options) return
 
@@ -52,16 +75,28 @@ export class AdvancedSearch {
     this.originallyPublishedEndDate = options.originallyPublishedEndDate || undefined
 
     this.nsfw = options.nsfw || undefined
+    this.isLive = options.isLive || undefined
+
     this.categoryOneOf = options.categoryOneOf || undefined
     this.licenceOneOf = options.licenceOneOf || undefined
     this.languageOneOf = options.languageOneOf || undefined
-    this.tagsOneOf = options.tagsOneOf || undefined
-    this.tagsAllOf = options.tagsAllOf || undefined
-    this.durationMin = parseInt(options.durationMin, 10)
-    this.durationMax = parseInt(options.durationMax, 10)
+    this.tagsOneOf = splitIntoArray(options.tagsOneOf)
+    this.tagsAllOf = splitIntoArray(options.tagsAllOf)
+    this.durationMin = options.durationMin ? parseInt(options.durationMin, 10) : undefined
+    this.durationMax = options.durationMax ? parseInt(options.durationMax, 10) : undefined
+
+    this.host = options.host || undefined
 
     this.searchTarget = options.searchTarget || undefined
 
+    this.resultType = options.resultType || undefined
+
+    this.excludeAlreadyWatched = options.excludeAlreadyWatched || undefined
+
+    if (!this.resultType && this.hasVideoFilter()) {
+      this.resultType = 'videos'
+    }
+
     if (isNaN(this.durationMin)) this.durationMin = undefined
     if (isNaN(this.durationMax)) this.durationMax = undefined
 
@@ -69,16 +104,7 @@ export class AdvancedSearch {
   }
 
   containsValues () {
-    const exceptions = new Set([ 'sort', 'searchTarget' ])
-
-    const obj = this.toUrlObject()
-    for (const k of Object.keys(obj)) {
-      if (this.silentFilters.has(k)) continue
-
-      if (obj[k] !== undefined && obj[k] !== '') return true
-    }
-
-    return false
+    return this.size() !== 0
   }
 
   reset () {
@@ -94,6 +120,8 @@ export class AdvancedSearch {
     this.tagsAllOf = undefined
     this.durationMin = undefined
     this.durationMax = undefined
+    this.isLive = undefined
+    this.host = undefined
 
     this.sort = '-match'
   }
@@ -112,26 +140,50 @@ export class AdvancedSearch {
       tagsAllOf: this.tagsAllOf,
       durationMin: this.durationMin,
       durationMax: this.durationMax,
+      isLive: this.isLive,
+      host: this.host,
       sort: this.sort,
-      searchTarget: this.searchTarget
+      searchTarget: this.searchTarget,
+      resultType: this.resultType,
+      excludeAlreadyWatched: this.excludeAlreadyWatched
     }
   }
 
-  toAPIObject () {
+  toVideosAPIObject (): VideosSearchQuery {
+    let isLive: boolean
+    if (this.isLive) isLive = this.isLive === 'true'
+
     return {
       startDate: this.startDate,
       endDate: this.endDate,
       originallyPublishedStartDate: this.originallyPublishedStartDate,
       originallyPublishedEndDate: this.originallyPublishedEndDate,
       nsfw: this.nsfw,
-      categoryOneOf: this.intoArray(this.categoryOneOf),
-      licenceOneOf: this.intoArray(this.licenceOneOf),
-      languageOneOf: this.intoArray(this.languageOneOf),
-      tagsOneOf: this.intoArray(this.tagsOneOf),
-      tagsAllOf: this.intoArray(this.tagsAllOf),
+      categoryOneOf: splitIntoArray(this.categoryOneOf),
+      licenceOneOf: splitIntoArray(this.licenceOneOf),
+      languageOneOf: splitIntoArray(this.languageOneOf),
+      tagsOneOf: this.tagsOneOf,
+      tagsAllOf: this.tagsAllOf,
       durationMin: this.durationMin,
       durationMax: this.durationMax,
+      host: this.host,
+      isLive,
       sort: this.sort,
+      searchTarget: this.searchTarget,
+      excludeAlreadyWatched: this.excludeAlreadyWatched
+    }
+  }
+
+  toPlaylistAPIObject (): VideoPlaylistsSearchQuery {
+    return {
+      host: this.host,
+      searchTarget: this.searchTarget
+    }
+  }
+
+  toChannelAPIObject (): VideoChannelsSearchQuery {
+    return {
+      host: this.host,
       searchTarget: this.searchTarget
     }
   }
@@ -139,22 +191,44 @@ export class AdvancedSearch {
   size () {
     let acc = 0
 
-    const obj = this.toUrlObject()
-    for (const k of Object.keys(obj)) {
-      if (this.silentFilters.has(k)) continue
+    if (this.isValidValue(this.startDate) || this.isValidValue(this.endDate)) acc++
+    if (this.isValidValue(this.originallyPublishedStartDate) || this.isValidValue(this.originallyPublishedEndDate)) acc++
 
-      if (obj[k] !== undefined && obj[k] !== '') acc++
-    }
+    if (this.isValidValue(this.nsfw)) acc++
+    if (this.isValidValue(this.categoryOneOf)) acc++
+    if (this.isValidValue(this.licenceOneOf)) acc++
+    if (this.isValidValue(this.languageOneOf)) acc++
+    if (this.isValidValue(this.tagsOneOf)) acc++
+    if (this.isValidValue(this.tagsAllOf)) acc++
+    if (this.isValidValue(this.durationMin) || this.isValidValue(this.durationMax)) acc++
+    if (this.isValidValue(this.isLive)) acc++
+    if (this.isValidValue(this.host)) acc++
+    if (this.isValidValue(this.resultType)) acc++
 
     return acc
   }
 
-  private intoArray (value: any) {
-    if (!value) return undefined
-    if (Array.isArray(value)) return value
+  private isValidValue (val: any) {
+    if (val === undefined) return false
+    if (val === '') return false
+    if (Array.isArray(val) && val.length === 0) return false
 
-    if (typeof value === 'string') return value.split(',')
+    return true
+  }
 
-    return [ value ]
+  private hasVideoFilter () {
+    return this.startDate !== undefined ||
+      this.endDate !== undefined ||
+      this.originallyPublishedStartDate !== undefined ||
+      this.originallyPublishedEndDate !== undefined ||
+      this.nsfw !== undefined ||
+      this.categoryOneOf !== undefined ||
+      this.licenceOneOf !== undefined ||
+      this.languageOneOf !== undefined ||
+      this.tagsOneOf !== undefined ||
+      this.tagsAllOf !== undefined ||
+      this.durationMin !== undefined ||
+      this.durationMax !== undefined ||
+      this.isLive !== undefined
   }
 }