From 2bbb34127fccd187ed690949b6791e49fdd77194 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 1 Dec 2017 16:17:32 +0100 Subject: [PATCH] Add auto scroll to videos list --- client/package.json | 1 + client/src/app/app-routing.module.ts | 2 +- client/src/app/shared/misc/from-now.pipe.ts | 2 +- .../src/app/shared/search/search.component.ts | 33 +--------- client/src/app/shared/shared.module.ts | 7 +-- .../shared/abstract-video-list.html | 14 +++-- .../video-list/shared/abstract-video-list.ts | 63 ++++++++++++++----- .../video-recently-added.component.ts | 1 + .../video-list/video-trending.component.ts | 1 + client/src/app/videos/videos.module.ts | 4 +- client/yarn.lock | 4 ++ 11 files changed, 73 insertions(+), 59 deletions(-) diff --git a/client/package.json b/client/package.json index 310860fec..45f555f29 100644 --- a/client/package.json +++ b/client/package.json @@ -71,6 +71,7 @@ "ngc-webpack": "3.2.2", "ngx-bootstrap": "2.0.0-beta.9", "ngx-chips": "1.5.3", + "ngx-infinite-scroll": "^0.7.0", "ngx-pipes": "^2.0.5", "node-sass": "^4.1.1", "normalize.css": "^7.0.0", diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts index 0f9484344..fe72c9181 100644 --- a/client/src/app/app-routing.module.ts +++ b/client/src/app/app-routing.module.ts @@ -6,7 +6,7 @@ import { PreloadSelectedModulesList } from './core' const routes: Routes = [ { path: '', - redirectTo: '/videos/list', + redirectTo: '/videos/trending', pathMatch: 'full' }, { diff --git a/client/src/app/shared/misc/from-now.pipe.ts b/client/src/app/shared/misc/from-now.pipe.ts index 25e5d6a85..80dab02ba 100644 --- a/client/src/app/shared/misc/from-now.pipe.ts +++ b/client/src/app/shared/misc/from-now.pipe.ts @@ -1,6 +1,6 @@ import { Pipe, PipeTransform } from '@angular/core' -// Thanks: https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts +// Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site @Pipe({name: 'fromNow'}) export class FromNowPipe implements PipeTransform { diff --git a/client/src/app/shared/search/search.component.ts b/client/src/app/shared/search/search.component.ts index 6ef19c97a..f49ecc8ad 100644 --- a/client/src/app/shared/search/search.component.ts +++ b/client/src/app/shared/search/search.component.ts @@ -1,8 +1,6 @@ import { Component, OnInit } from '@angular/core' import { Router } from '@angular/router' - import { Search } from './search.model' -import { SearchField } from './search-field.type' import { SearchService } from './search.service' @Component({ @@ -12,12 +10,6 @@ import { SearchService } from './search.service' }) export class SearchComponent implements OnInit { - fieldChoices = { - name: 'Name', - account: 'Account', - host: 'Host', - tags: 'Tags' - } searchCriteria: Search = { field: 'name', value: '' @@ -40,30 +32,11 @@ export class SearchComponent implements OnInit { ) } - get choiceKeys () { - return Object.keys(this.fieldChoices) - } - - choose ($event: MouseEvent, choice: SearchField) { - $event.preventDefault() - $event.stopPropagation() - - this.searchCriteria.field = choice - - if (this.searchCriteria.value) { - this.doSearch() - } - } - doSearch () { - if (this.router.url.indexOf('/videos/list') === -1) { - this.router.navigate([ '/videos/list' ]) - } + // if (this.router.url.indexOf('/videos/list') === -1) { + // this.router.navigate([ '/videos/list' ]) + // } this.searchService.searchUpdated.next(this.searchCriteria) } - - getStringChoice (choiceKey: SearchField) { - return this.fieldChoices[choiceKey] - } } diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index c7ea6e603..7618748e9 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -6,21 +6,20 @@ import { RouterModule } from '@angular/router' import { BsDropdownModule } from 'ngx-bootstrap/dropdown' import { ModalModule } from 'ngx-bootstrap/modal' -import { PaginationModule } from 'ngx-bootstrap/pagination' import { ProgressbarModule } from 'ngx-bootstrap/progressbar' import { BytesPipe, KeysPipe } from 'ngx-pipes' import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' import { DataTableModule } from 'primeng/components/datatable/datatable' import { AUTH_INTERCEPTOR_PROVIDER } from './auth' +import { FromNowPipe } from './misc/from-now.pipe' import { LoaderComponent } from './misc/loader.component' +import { NumberFormatterPipe } from './misc/number-formatter.pipe' import { RestExtractor, RestService } from './rest' import { SearchComponent, SearchService } from './search' import { UserService } from './users' import { VideoAbuseService } from './video-abuse' import { VideoBlacklistService } from './video-blacklist' -import { NumberFormatterPipe } from './misc/number-formatter.pipe' -import { FromNowPipe } from './misc/from-now.pipe' @NgModule({ imports: [ @@ -32,7 +31,6 @@ import { FromNowPipe } from './misc/from-now.pipe' BsDropdownModule.forRoot(), ModalModule.forRoot(), - PaginationModule.forRoot(), ProgressbarModule.forRoot(), DataTableModule, @@ -57,7 +55,6 @@ import { FromNowPipe } from './misc/from-now.pipe' BsDropdownModule, ModalModule, - PaginationModule, ProgressbarModule, DataTableModule, PrimeSharedModule, diff --git a/client/src/app/videos/video-list/shared/abstract-video-list.html b/client/src/app/videos/video-list/shared/abstract-video-list.html index ab5530e68..69e16319e 100644 --- a/client/src/app/videos/video-list/shared/abstract-video-list.html +++ b/client/src/app/videos/video-list/shared/abstract-video-list.html @@ -2,15 +2,17 @@ {{ titlePage }} -
+
- - diff --git a/client/src/app/videos/video-list/shared/abstract-video-list.ts b/client/src/app/videos/video-list/shared/abstract-video-list.ts index 262ea4e21..44cdc1d9f 100644 --- a/client/src/app/videos/video-list/shared/abstract-video-list.ts +++ b/client/src/app/videos/video-list/shared/abstract-video-list.ts @@ -19,44 +19,77 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { protected notificationsService: NotificationsService protected router: Router protected route: ActivatedRoute - protected subActivatedRoute: Subscription + protected abstract currentRoute: string + abstract titlePage: string + private loadedPages: { [ id: number ]: boolean } = {} + abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}> ngOnInit () { // Subscribe to route changes - this.subActivatedRoute = this.route.params.subscribe(routeParams => { - this.loadRouteParams(routeParams) - - this.getVideos() - }) + const routeParams = this.route.snapshot.params + this.loadRouteParams(routeParams) + this.loadMoreVideos('after') } ngOnDestroy () { this.subActivatedRoute.unsubscribe() } - getVideos () { - this.videos = [] + onNearOfTop () { + if (this.pagination.currentPage > 1) { + this.previousPage() + } + } + + onNearOfBottom () { + if (this.hasMoreVideos()) { + this.nextPage() + } + } + + loadMoreVideos (where: 'before' | 'after') { + if (this.loadedPages[this.pagination.currentPage] === true) return const observable = this.getVideosObservable() observable.subscribe( ({ videos, totalVideos }) => { - this.videos = videos + 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) + } }, error => this.notificationsService.error('Error', error.text) ) } - onPageChanged (event: { page: number }) { - // Be sure the current page is set - this.pagination.currentPage = event.page + protected hasMoreVideos () { + if (!this.pagination.totalItems) return true + + const maxPage = this.pagination.totalItems/this.pagination.itemsPerPage + return maxPage > this.pagination.currentPage + } + + protected previousPage () { + this.pagination.currentPage-- + + this.setNewRouteParams() + this.loadMoreVideos('before') + } + + protected nextPage () { + this.pagination.currentPage++ - this.navigateToNewParams() + this.setNewRouteParams() + this.loadMoreVideos('after') } protected buildRouteParams () { @@ -79,8 +112,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { } } - protected navigateToNewParams () { + protected setNewRouteParams () { const routeParams = this.buildRouteParams() - this.router.navigate([ '/videos/list', routeParams ]) + this.router.navigate([ this.currentRoute, routeParams ]) } } diff --git a/client/src/app/videos/video-list/video-recently-added.component.ts b/client/src/app/videos/video-list/video-recently-added.component.ts index dbba264df..9bf69bd78 100644 --- a/client/src/app/videos/video-list/video-recently-added.component.ts +++ b/client/src/app/videos/video-list/video-recently-added.component.ts @@ -11,6 +11,7 @@ import { AbstractVideoList } from './shared' }) export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage = 'Recently added' + currentRoute = '/videos/recently-added' constructor (protected router: Router, protected route: ActivatedRoute, diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts index b97966c12..a1df68711 100644 --- a/client/src/app/videos/video-list/video-trending.component.ts +++ b/client/src/app/videos/video-list/video-trending.component.ts @@ -11,6 +11,7 @@ import { AbstractVideoList } from './shared' }) export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage = 'Trending' + currentRoute = '/videos/trending' constructor (protected router: Router, protected route: ActivatedRoute, diff --git a/client/src/app/videos/videos.module.ts b/client/src/app/videos/videos.module.ts index 93193000c..f3981d275 100644 --- a/client/src/app/videos/videos.module.ts +++ b/client/src/app/videos/videos.module.ts @@ -1,4 +1,5 @@ import { NgModule } from '@angular/core' +import { InfiniteScrollModule } from 'ngx-infinite-scroll' import { SharedModule } from '../shared' import { VideoService } from './shared' import { MyVideosComponent, VideoMiniatureComponent } from './video-list' @@ -10,7 +11,8 @@ import { VideosComponent } from './videos.component' @NgModule({ imports: [ VideosRoutingModule, - SharedModule + SharedModule, + InfiniteScrollModule ], declarations: [ diff --git a/client/yarn.lock b/client/yarn.lock index fa1802a29..bd6870061 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -4714,6 +4714,10 @@ ngx-chips@1.5.3: dependencies: ng2-material-dropdown "0.7.10" +ngx-infinite-scroll@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-0.7.0.tgz#a390c61c6a05ac14485e1c5bc8b4e6f6bd62fd6a" + ngx-pipes@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/ngx-pipes/-/ngx-pipes-2.0.5.tgz#743b827e350b1e66f5bdae49e90a02fa631d4c54" -- 2.25.1