1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
import { Component, OnDestroy, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { RedirectService } from '@app/core'
import { NotificationsService } from 'angular2-notifications'
import { forkJoin, Subscription } from 'rxjs'
import { SearchService } from '@app/search/search.service'
import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { Video } from '../../../../shared'
import { MetaService } from '@ngx-meta/core'
import { AdvancedSearch } from '@app/search/advanced-search.model'
import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
import { immutableAssign } from '@app/shared/misc/utils'
@Component({
selector: 'my-search',
styleUrls: [ './search.component.scss' ],
templateUrl: './search.component.html'
})
export class SearchComponent implements OnInit, OnDestroy {
videos: Video[] = []
videoChannels: VideoChannel[] = []
pagination: ComponentPagination = {
currentPage: 1,
itemsPerPage: 10, // Only for videos, use another variable for channels
totalItems: null
}
advancedSearch: AdvancedSearch = new AdvancedSearch()
isSearchFilterCollapsed = true
currentSearch: string
private subActivatedRoute: Subscription
private isInitialLoad = true
private channelsPerPage = 2
constructor (
private i18n: I18n,
private route: ActivatedRoute,
private router: Router,
private metaService: MetaService,
private redirectService: RedirectService,
private notificationsService: NotificationsService,
private searchService: SearchService
) { }
ngOnInit () {
this.subActivatedRoute = this.route.queryParams.subscribe(
queryParams => {
const querySearch = queryParams['search']
// New empty search
if (this.currentSearch && !querySearch) return this.redirectService.redirectToHomepage()
// Search updated, reset filters
if (this.currentSearch !== querySearch) {
this.resetPagination()
this.advancedSearch.reset()
this.currentSearch = querySearch
this.updateTitle()
}
this.advancedSearch = new AdvancedSearch(queryParams)
// Don't hide filters if we have some of them AND the user just came on the webpage
this.isSearchFilterCollapsed = this.isInitialLoad === false || !this.advancedSearch.containsValues()
this.isInitialLoad = false
this.search()
},
err => this.notificationsService.error('Error', err.text)
)
}
ngOnDestroy () {
if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
}
search () {
forkJoin([
this.searchService.searchVideos(this.currentSearch, this.pagination, this.advancedSearch),
this.searchService.searchVideoChannels(this.currentSearch, immutableAssign(this.pagination, { itemsPerPage: this.channelsPerPage }))
])
.subscribe(
([ videosResult, videoChannelsResult ]) => {
this.videos = this.videos.concat(videosResult.videos)
this.pagination.totalItems = videosResult.totalVideos + videoChannelsResult.total
this.videoChannels = this.videoChannels.concat(videoChannelsResult.data)
// Focus on channels
if (this.channelsPerPage !== 10 && this.videos.length < this.pagination.itemsPerPage) {
this.resetPagination()
this.channelsPerPage = 10
this.search()
}
},
error => {
this.notificationsService.error(this.i18n('Error'), error.message)
}
)
}
onNearOfBottom () {
// Last page
if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
this.pagination.currentPage += 1
this.search()
}
onFiltered () {
this.resetPagination()
this.updateUrlFromAdvancedSearch()
}
private resetPagination () {
this.pagination.currentPage = 1
this.pagination.totalItems = null
this.channelsPerPage = 2
this.videos = []
this.videoChannels = []
}
private updateTitle () {
this.metaService.setTitle(this.i18n('Search') + ' ' + this.currentSearch)
}
private updateUrlFromAdvancedSearch () {
this.router.navigate([], {
relativeTo: this.route,
queryParams: Object.assign({}, this.advancedSearch.toUrlObject(), { search: this.currentSearch })
})
}
}
|