]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/search/search.component.ts
Wait config before loading login/signup
[github/Chocobozzz/PeerTube.git] / client / src / app / search / search.component.ts
CommitLineData
57c36b27 1import { Component, OnDestroy, OnInit } from '@angular/core'
0b18f4aa 2import { ActivatedRoute, Router } from '@angular/router'
3a0fb65c 3import { AuthService, Notifier } from '@app/core'
f37dc0dd 4import { forkJoin, Subscription } from 'rxjs'
57c36b27
C
5import { SearchService } from '@app/search/search.service'
6import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
7import { I18n } from '@ngx-translate/i18n-polyfill'
57c36b27 8import { MetaService } from '@ngx-meta/core'
0b18f4aa 9import { AdvancedSearch } from '@app/search/advanced-search.model'
f37dc0dd
C
10import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
11import { immutableAssign } from '@app/shared/misc/utils'
26fabbd6 12import { Video } from '@app/shared/video/video.model'
57c36b27
C
13
14@Component({
15 selector: 'my-search',
16 styleUrls: [ './search.component.scss' ],
17 templateUrl: './search.component.html'
18})
19export class SearchComponent implements OnInit, OnDestroy {
26fabbd6 20 results: (Video | VideoChannel)[] = []
f37dc0dd 21
57c36b27
C
22 pagination: ComponentPagination = {
23 currentPage: 1,
f37dc0dd 24 itemsPerPage: 10, // Only for videos, use another variable for channels
57c36b27
C
25 totalItems: null
26 }
0b18f4aa
C
27 advancedSearch: AdvancedSearch = new AdvancedSearch()
28 isSearchFilterCollapsed = true
f37dc0dd 29 currentSearch: string
57c36b27
C
30
31 private subActivatedRoute: Subscription
c5d04b4f 32 private isInitialLoad = false // set to false to show the search filters on first arrival
b1ee8526 33 private firstSearch = true
57c36b27 34
f37dc0dd
C
35 private channelsPerPage = 2
36
57c36b27
C
37 constructor (
38 private i18n: I18n,
39 private route: ActivatedRoute,
0b18f4aa 40 private router: Router,
57c36b27 41 private metaService: MetaService,
f8b2c1b4 42 private notifier: Notifier,
26fabbd6 43 private searchService: SearchService,
e2409062 44 private authService: AuthService
57c36b27
C
45 ) { }
46
e2409062
C
47 get user () {
48 return this.authService.getUser()
49 }
50
57c36b27
C
51 ngOnInit () {
52 this.subActivatedRoute = this.route.queryParams.subscribe(
53 queryParams => {
54 const querySearch = queryParams['search']
55
0b18f4aa 56 // Search updated, reset filters
7afea880
C
57 if (this.currentSearch !== querySearch) {
58 this.resetPagination()
59 this.advancedSearch.reset()
60
47879669 61 this.currentSearch = querySearch || undefined
7afea880
C
62 this.updateTitle()
63 }
64
65 this.advancedSearch = new AdvancedSearch(queryParams)
0b18f4aa 66
7afea880
C
67 // Don't hide filters if we have some of them AND the user just came on the webpage
68 this.isSearchFilterCollapsed = this.isInitialLoad === false || !this.advancedSearch.containsValues()
69 this.isInitialLoad = false
57c36b27 70
7afea880 71 this.search()
57c36b27
C
72 },
73
f8b2c1b4 74 err => this.notifier.error(err.text)
57c36b27
C
75 )
76 }
77
78 ngOnDestroy () {
79 if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
80 }
81
26fabbd6
C
82 isVideoChannel (d: VideoChannel | Video): d is VideoChannel {
83 return d instanceof VideoChannel
84 }
85
86 isVideo (v: VideoChannel | Video): v is Video {
87 return v instanceof Video
88 }
89
90 isUserLoggedIn () {
91 return this.authService.isLoggedIn()
92 }
93
57c36b27 94 search () {
f37dc0dd
C
95 forkJoin([
96 this.searchService.searchVideos(this.currentSearch, this.pagination, this.advancedSearch),
97 this.searchService.searchVideoChannels(this.currentSearch, immutableAssign(this.pagination, { itemsPerPage: this.channelsPerPage }))
98 ])
57c36b27 99 .subscribe(
f37dc0dd 100 ([ videosResult, videoChannelsResult ]) => {
26fabbd6
C
101 this.results = this.results
102 .concat(videoChannelsResult.data)
103 .concat(videosResult.videos)
aa55a4da 104 this.pagination.totalItems = videosResult.totalVideos + videoChannelsResult.total
f37dc0dd 105
b1ee8526
C
106 // Focus on channels if there are no enough videos
107 if (this.firstSearch === true && videosResult.videos.length < this.pagination.itemsPerPage) {
aa55a4da 108 this.resetPagination()
b1ee8526 109 this.firstSearch = false
aa55a4da
C
110
111 this.channelsPerPage = 10
112 this.search()
113 }
b1ee8526
C
114
115 this.firstSearch = false
57c36b27
C
116 },
117
f8b2c1b4 118 err => this.notifier.error(err.message)
57c36b27 119 )
f37dc0dd 120
57c36b27
C
121 }
122
123 onNearOfBottom () {
124 // Last page
125 if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
126
127 this.pagination.currentPage += 1
128 this.search()
129 }
130
0b18f4aa 131 onFiltered () {
7afea880 132 this.resetPagination()
0b18f4aa 133
7afea880 134 this.updateUrlFromAdvancedSearch()
0b18f4aa
C
135 }
136
c5d04b4f
RK
137 numberOfFilters () {
138 return this.advancedSearch.size()
139 }
140
3a0fb65c
C
141 removeVideoFromArray (video: Video) {
142 this.results = this.results.filter(r => !this.isVideo(r) || r.id !== video.id)
143 }
144
7afea880 145 private resetPagination () {
57c36b27
C
146 this.pagination.currentPage = 1
147 this.pagination.totalItems = null
aa55a4da 148 this.channelsPerPage = 2
57c36b27 149
26fabbd6 150 this.results = []
57c36b27
C
151 }
152
153 private updateTitle () {
f107470e
C
154 const suffix = this.currentSearch ? ' ' + this.currentSearch : ''
155 this.metaService.setTitle(this.i18n('Search') + suffix)
57c36b27 156 }
0b18f4aa
C
157
158 private updateUrlFromAdvancedSearch () {
47879669 159 const search = this.currentSearch || undefined
c5d04b4f 160
0b18f4aa
C
161 this.router.navigate([], {
162 relativeTo: this.route,
c5d04b4f 163 queryParams: Object.assign({}, this.advancedSearch.toUrlObject(), { search })
0b18f4aa
C
164 })
165 }
57c36b27 166}