From 322940742b4dca168de6dfed0d1ebf5926dab528 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 22 May 2016 10:43:06 +0200 Subject: [PATCH] Add pagination support to the client --- client/angular/app/app.component.html | 2 +- .../list/video-miniature.component.html | 2 +- .../list/video-miniature.component.scss | 6 ++-- .../list/videos-list.component.html | 14 ++++++-- .../list/videos-list.component.scss | 10 ++++-- .../components/list/videos-list.component.ts | 23 +++++++++---- client/angular/videos/pagination.ts | 5 +++ client/angular/videos/videos.service.ts | 32 ++++++++++++++----- client/package.json | 5 +-- client/systemjs.config.js | 2 ++ client/tsconfig.json | 1 + 11 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 client/angular/videos/pagination.ts diff --git a/client/angular/app/app.component.html b/client/angular/app/app.component.html index 949b375d2..ccbaef947 100644 --- a/client/angular/app/app.component.html +++ b/client/angular/app/app.component.html @@ -5,7 +5,7 @@

PeerTube

-
+
+ - - +
+
There is no video.
+ + + +
+ + diff --git a/client/angular/videos/components/list/videos-list.component.scss b/client/angular/videos/components/list/videos-list.component.scss index ac930978c..05c38b833 100644 --- a/client/angular/videos/components/list/videos-list.component.scss +++ b/client/angular/videos/components/list/videos-list.component.scss @@ -1,8 +1,12 @@ -.loading { - display: inline-block; - margin-top: 100px; +.videos-miniatures { + min-height: 600px; } my-videos-miniature { display: inline-block; } + +pagination { + display: block; + text-align: center; +} diff --git a/client/angular/videos/components/list/videos-list.component.ts b/client/angular/videos/components/list/videos-list.component.ts index 6fc0c1f04..341afdaa6 100644 --- a/client/angular/videos/components/list/videos-list.component.ts +++ b/client/angular/videos/components/list/videos-list.component.ts @@ -1,7 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { ROUTER_DIRECTIVES, RouteParams } from '@angular/router-deprecated'; +import { PAGINATION_DIRECTIVES } from 'ng2-bootstrap/components/pagination'; + import { AuthService } from '../../../users/services/auth.service'; +import { Pagination } from '../../pagination'; import { User } from '../../../users/models/user'; import { VideosService } from '../../videos.service'; import { Video } from '../../video'; @@ -11,21 +14,26 @@ import { VideoMiniatureComponent } from './video-miniature.component'; selector: 'my-videos-list', styleUrls: [ 'app/angular/videos/components/list/videos-list.component.css' ], templateUrl: 'app/angular/videos/components/list/videos-list.component.html', - directives: [ ROUTER_DIRECTIVES, VideoMiniatureComponent ] + directives: [ ROUTER_DIRECTIVES, PAGINATION_DIRECTIVES, VideoMiniatureComponent ] }) export class VideosListComponent implements OnInit { user: User = null; videos: Video[] = []; + pagination: Pagination = { + currentPage: 1, + itemsPerPage: 9, + total: 0 + } private search: string; constructor( private _authService: AuthService, private _videosService: VideosService, - routeParams: RouteParams + private _routeParams: RouteParams ) { - this.search = routeParams.get('search'); + this.search = this._routeParams.get('search'); } ngOnInit() { @@ -40,13 +48,16 @@ export class VideosListComponent implements OnInit { let observable = null; if (this.search !== null) { - observable = this._videosService.searchVideos(this.search); + observable = this._videosService.searchVideos(this.search, this.pagination); } else { - observable = this._videosService.getVideos(); + observable = this._videosService.getVideos(this.pagination); } observable.subscribe( - videos => this.videos = videos, + ({ videos, totalVideos }) => { + this.videos = videos; + this.pagination.total = totalVideos; + }, error => alert(error) ); } diff --git a/client/angular/videos/pagination.ts b/client/angular/videos/pagination.ts new file mode 100644 index 000000000..06f7a7875 --- /dev/null +++ b/client/angular/videos/pagination.ts @@ -0,0 +1,5 @@ +export interface Pagination { + currentPage: number; + itemsPerPage: number; + total: number; +} diff --git a/client/angular/videos/videos.service.ts b/client/angular/videos/videos.service.ts index f4790b511..94ef418eb 100644 --- a/client/angular/videos/videos.service.ts +++ b/client/angular/videos/videos.service.ts @@ -1,7 +1,8 @@ import { Injectable } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { Http, Response, RequestOptions, URLSearchParams } from '@angular/http'; import { Observable } from 'rxjs/Rx'; +import { Pagination } from './pagination'; import { Video } from './video'; import { AuthService } from '../users/services/auth.service'; @@ -11,8 +12,9 @@ export class VideosService { constructor (private http: Http, private _authService: AuthService) {} - getVideos() { - return this.http.get(this._baseVideoUrl) + getVideos(pagination: Pagination) { + const params = { search: this.createPaginationParams(pagination) }; + return this.http.get(this._baseVideoUrl, params) .map(res => res.json()) .map(this.extractVideos) .catch(this.handleError); @@ -31,24 +33,38 @@ export class VideosService { .catch(this.handleError); } - searchVideos(search: string) { - return this.http.get(this._baseVideoUrl + 'search/' + search) + searchVideos(search: string, pagination: Pagination) { + const params = { search: this.createPaginationParams(pagination) }; + return this.http.get(this._baseVideoUrl + 'search/' + encodeURIComponent(search), params) .map(res => res.json()) .map(this.extractVideos) .catch(this.handleError); } - private extractVideos (body: any[]) { + private extractVideos (body: any) { + const videos_json = body.data; + const totalVideos = body.total; const videos = []; - for (const video_json of body) { + for (const video_json of videos_json) { videos.push(new Video(video_json)); } - return videos; + return { videos, totalVideos }; } private handleError (error: Response) { console.error(error); return Observable.throw(error.json().error || 'Server error'); } + + private createPaginationParams(pagination: Pagination) { + const params = new URLSearchParams(); + const start: number = (pagination.currentPage - 1) * pagination.itemsPerPage; + const count: number = pagination.itemsPerPage; + + params.set('start', start.toString()); + params.set('count', count.toString()); + + return params; + } } diff --git a/client/package.json b/client/package.json index b730a1f4a..b77c6e447 100644 --- a/client/package.json +++ b/client/package.json @@ -21,20 +21,21 @@ }, "license": "GPLv3", "dependencies": { - "angular-pipes": "^2.0.0", "@angular/common": "2.0.0-rc.1", "@angular/compiler": "2.0.0-rc.1", "@angular/core": "2.0.0-rc.1", "@angular/http": "2.0.0-rc.1", - "@angular/platform-browser-dynamic": "2.0.0-rc.1", "@angular/platform-browser": "2.0.0-rc.1", + "@angular/platform-browser-dynamic": "2.0.0-rc.1", "@angular/router-deprecated": "2.0.0-rc.1", + "angular-pipes": "^2.0.0", "blueimp-file-upload": "^9.12.1", "bootstrap-sass": "^3.3.6", "es6-promise": "^3.0.2", "es6-shim": "^0.35.0", "jquery": "^2.2.3", "jquery.ui.widget": "^1.10.3", + "ng2-bootstrap": "^1.0.16", "reflect-metadata": "0.1.3", "rxjs": "5.0.0-beta.6", "systemjs": "0.19.27", diff --git a/client/systemjs.config.js b/client/systemjs.config.js index 0ac94ca44..82ca5bb70 100644 --- a/client/systemjs.config.js +++ b/client/systemjs.config.js @@ -2,11 +2,13 @@ var map = { 'app': 'app/angular', 'angular-pipes': 'app/node_modules/angular-pipes', + 'ng2-bootstrap': 'app/node_modules/ng2-bootstrap', 'angular-rxjs.bundle': 'app/bundles/angular-rxjs.bundle.js' } var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, + 'ng2-bootstrap': { defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' } } var packageNames = [ diff --git a/client/tsconfig.json b/client/tsconfig.json index fac9da116..1d002f7b0 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -32,6 +32,7 @@ "angular/videos/components/list/video-miniature.component.ts", "angular/videos/components/list/videos-list.component.ts", "angular/videos/components/watch/videos-watch.component.ts", + "angular/videos/pagination.ts", "angular/videos/video.ts", "angular/videos/videos.service.ts", "typings/globals/es6-shim/index.d.ts",