-import { OnInit } from '@angular/core'
+import { debounceTime } from 'rxjs/operators'
+import { OnDestroy, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
-import { NotificationsService } from 'angular2-notifications'
-import { Observable } from 'rxjs/Observable'
-import { SortField } from './sort-field.type'
-import { VideoPagination } from './video-pagination.model'
+import { fromEvent, Observable, Subscription } from 'rxjs'
+import { AuthService } from '../../core/auth'
+import { ComponentPagination } from '../rest/component-pagination.model'
+import { VideoSortField } from './sort-field.type'
import { Video } from './video.model'
-
-export abstract class AbstractVideoList implements OnInit {
- pagination: VideoPagination = {
+import { ScreenService } from '@app/shared/misc/screen.service'
+import { OwnerDisplayType } from '@app/shared/video/video-miniature.component'
+import { Syndication } from '@app/shared/video/syndication.model'
+import { Notifier, ServerService } from '@app/core'
+import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
+
+export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableForReuseHook {
+ pagination: ComponentPagination = {
currentPage: 1,
itemsPerPage: 25,
totalItems: null
}
- sort: SortField = '-createdAt'
- defaultSort: SortField = '-createdAt'
- videos: Video[] = []
- loadOnInit = true
+ sort: VideoSortField = '-publishedAt'
- protected notificationsService: NotificationsService
- protected router: Router
- protected route: ActivatedRoute
+ categoryOneOf?: number
+ defaultSort: VideoSortField = '-publishedAt'
- protected abstract currentRoute: string
+ syndicationItems: Syndication[] = []
+ loadOnInit = true
+ marginContent = true
+ videos: Video[] = []
+ ownerDisplayType: OwnerDisplayType = 'account'
+ displayModerationBlock = false
+ titleTooltip: string
+
+ disabled = false
+
+ protected abstract notifier: Notifier
+ protected abstract authService: AuthService
+ protected abstract route: ActivatedRoute
+ protected abstract serverService: ServerService
+ protected abstract screenService: ScreenService
+ protected abstract router: Router
abstract titlePage: string
- private loadedPages: { [ id: number ]: boolean } = {}
- abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}>
+ private resizeSubscription: Subscription
+ private angularState: number
+
+ abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number }>
+
+ abstract generateSyndicationList (): void
+
+ get user () {
+ return this.authService.getUser()
+ }
ngOnInit () {
// Subscribe to route changes
- const routeParams = this.route.snapshot.params
+ const routeParams = this.route.snapshot.queryParams
this.loadRouteParams(routeParams)
- if (this.loadOnInit === true) this.loadMoreVideos('after')
+
+ this.resizeSubscription = fromEvent(window, 'resize')
+ .pipe(debounceTime(500))
+ .subscribe(() => this.calcPageSizes())
+
+ this.calcPageSizes()
+ if (this.loadOnInit === true) this.loadMoreVideos()
}
- onNearOfTop () {
- if (this.pagination.currentPage > 1) {
- this.previousPage()
- }
+ ngOnDestroy () {
+ if (this.resizeSubscription) this.resizeSubscription.unsubscribe()
}
- onNearOfBottom () {
- if (this.hasMoreVideos()) {
- this.nextPage()
- }
+ disableForReuse () {
+ this.disabled = true
}
- reloadVideos () {
- this.videos = []
- this.loadedPages = {}
- this.loadMoreVideos('before')
+ enabledForReuse () {
+ this.disabled = false
+ }
+
+ videoById (index: number, video: Video) {
+ return video.id
}
- loadMoreVideos (where: 'before' | 'after') {
- if (this.loadedPages[this.pagination.currentPage] === true) return
+ onNearOfBottom () {
+ if (this.disabled) return
- const observable = this.getVideosObservable()
+ // Last page
+ if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
+
+ this.pagination.currentPage += 1
+
+ this.setScrollRouteParams()
+
+ this.loadMoreVideos()
+ }
+
+ loadMoreVideos () {
+ const observable = this.getVideosObservable(this.pagination.currentPage)
observable.subscribe(
({ videos, totalVideos }) => {
- this.loadedPages[this.pagination.currentPage] = true
this.pagination.totalItems = totalVideos
-
- if (where === 'before') {
- this.videos = videos.concat(this.videos)
- } else {
- this.videos = this.videos.concat(videos)
- }
+ this.videos = this.videos.concat(videos)
},
- error => this.notificationsService.error('Error', error.text)
+
+ error => this.notifier.error(error.message)
)
}
- protected hasMoreVideos () {
- if (!this.pagination.totalItems) return true
-
- const maxPage = this.pagination.totalItems / this.pagination.itemsPerPage
- return maxPage > this.pagination.currentPage
+ reloadVideos () {
+ this.pagination.currentPage = 1
+ this.videos = []
+ this.loadMoreVideos()
}
- protected previousPage () {
- this.pagination.currentPage--
-
- this.setNewRouteParams()
- this.loadMoreVideos('before')
+ toggleModerationDisplay () {
+ throw new Error('toggleModerationDisplay is not implemented')
}
- protected nextPage () {
- this.pagination.currentPage++
-
- this.setNewRouteParams()
- this.loadMoreVideos('after')
+ protected loadRouteParams (routeParams: { [ key: string ]: any }) {
+ this.sort = routeParams[ 'sort' ] as VideoSortField || this.defaultSort
+ this.categoryOneOf = routeParams[ 'categoryOneOf' ]
+ this.angularState = routeParams[ 'a-state' ]
}
- protected buildRouteParams () {
- // There is always a sort and a current page
- const params = {
- sort: this.sort,
- page: this.pagination.currentPage
+ private calcPageSizes () {
+ if (this.screenService.isInMobileView()) {
+ this.pagination.itemsPerPage = 5
}
-
- return params
}
- protected loadRouteParams (routeParams: { [ key: string ]: any }) {
- this.sort = routeParams['sort'] as SortField || this.defaultSort
+ private setScrollRouteParams () {
+ // Already set
+ if (this.angularState) return
+
+ this.angularState = 42
- if (routeParams['page'] !== undefined) {
- this.pagination.currentPage = parseInt(routeParams['page'], 10)
- } else {
- this.pagination.currentPage = 1
+ const queryParams = {
+ 'a-state': this.angularState,
+ categoryOneOf: this.categoryOneOf
}
- }
- protected setNewRouteParams () {
- const routeParams = this.buildRouteParams()
- this.router.navigate([ this.currentRoute, routeParams ])
+ let path = this.router.url
+ if (!path || path === '/') path = this.serverService.getConfig().instance.defaultClientRoute
+
+ this.router.navigate([ path ], { queryParams, replaceUrl: true, queryParamsHandling: 'merge' })
}
}