aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-05-22 10:43:06 +0200
committerChocobozzz <florian.bigard@gmail.com>2016-05-22 10:44:35 +0200
commit322940742b4dca168de6dfed0d1ebf5926dab528 (patch)
tree7b7fdb77595aa7d6a89d1045ab6012a9e1d68aab
parent46246b5f194caafba4e3a72e9365acd8b35785de (diff)
downloadPeerTube-322940742b4dca168de6dfed0d1ebf5926dab528.tar.gz
PeerTube-322940742b4dca168de6dfed0d1ebf5926dab528.tar.zst
PeerTube-322940742b4dca168de6dfed0d1ebf5926dab528.zip
Add pagination support to the client
-rw-r--r--client/angular/app/app.component.html2
-rw-r--r--client/angular/videos/components/list/video-miniature.component.html2
-rw-r--r--client/angular/videos/components/list/video-miniature.component.scss6
-rw-r--r--client/angular/videos/components/list/videos-list.component.html14
-rw-r--r--client/angular/videos/components/list/videos-list.component.scss10
-rw-r--r--client/angular/videos/components/list/videos-list.component.ts23
-rw-r--r--client/angular/videos/pagination.ts5
-rw-r--r--client/angular/videos/videos.service.ts32
-rw-r--r--client/package.json5
-rw-r--r--client/systemjs.config.js2
-rw-r--r--client/tsconfig.json1
11 files changed, 74 insertions, 28 deletions
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 @@
5 <h4>PeerTube</h4> 5 <h4>PeerTube</h4>
6 </div> 6 </div>
7 7
8 <div class="col-md-8"> 8 <div class="col-md-9">
9 <input 9 <input
10 type="text" id="search_video" name="search_video" class="form-control" placeholder="Search a video..." 10 type="text" id="search_video" name="search_video" class="form-control" placeholder="Search a video..."
11 #search (keyup.enter)="doSearch(search.value)" 11 #search (keyup.enter)="doSearch(search.value)"
diff --git a/client/angular/videos/components/list/video-miniature.component.html b/client/angular/videos/components/list/video-miniature.component.html
index b88a19d5e..244254b5a 100644
--- a/client/angular/videos/components/list/video-miniature.component.html
+++ b/client/angular/videos/components/list/video-miniature.component.html
@@ -1,4 +1,4 @@
1<div class="video-miniature" (mouseenter)="onHover()" (mouseleave)="onBlur()"> 1<div class="video-miniature col-md-4" (mouseenter)="onHover()" (mouseleave)="onBlur()">
2 <a 2 <a
3 [routerLink]="['VideosWatch', { id: video.id }]" [attr.title]="video.description" 3 [routerLink]="['VideosWatch', { id: video.id }]" [attr.title]="video.description"
4 class="video-miniature-thumbnail" 4 class="video-miniature-thumbnail"
diff --git a/client/angular/videos/components/list/video-miniature.component.scss b/client/angular/videos/components/list/video-miniature.component.scss
index dbcd65820..4488abe22 100644
--- a/client/angular/videos/components/list/video-miniature.component.scss
+++ b/client/angular/videos/components/list/video-miniature.component.scss
@@ -1,8 +1,6 @@
1.video-miniature { 1.video-miniature {
2 width: 200px;
3 height: 200px; 2 height: 200px;
4 display: inline-block; 3 display: inline-block;
5 margin-right: 40px;
6 position: relative; 4 position: relative;
7 5
8 .video-miniature-thumbnail { 6 .video-miniature-thumbnail {
@@ -11,7 +9,7 @@
11 9
12 .video-miniature-duration { 10 .video-miniature-duration {
13 position: absolute; 11 position: absolute;
14 right: 2px; 12 right: 60px;
15 bottom: 2px; 13 bottom: 2px;
16 display: inline-block; 14 display: inline-block;
17 background-color: rgba(0, 0, 0, 0.8); 15 background-color: rgba(0, 0, 0, 0.8);
@@ -24,7 +22,7 @@
24 .video-miniature-remove { 22 .video-miniature-remove {
25 display: inline-block; 23 display: inline-block;
26 position: absolute; 24 position: absolute;
27 left: 2px; 25 left: 16px;
28 background-color: rgba(0, 0, 0, 0.8); 26 background-color: rgba(0, 0, 0, 0.8);
29 color: rgba(255, 255, 255, 0.8); 27 color: rgba(255, 255, 255, 0.8);
30 padding: 2px; 28 padding: 2px;
diff --git a/client/angular/videos/components/list/videos-list.component.html b/client/angular/videos/components/list/videos-list.component.html
index 776339d10..39cdf29ba 100644
--- a/client/angular/videos/components/list/videos-list.component.html
+++ b/client/angular/videos/components/list/videos-list.component.html
@@ -1,3 +1,11 @@
1<div *ngIf="videos.length === 0">There is no video.</div> 1<div class="videos-miniatures">
2<my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)"> 2 <div *ngIf="videos.length === 0">There is no video.</div>
3</my-video-miniature> 3
4 <my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)">
5 </my-video-miniature>
6</div>
7
8<pagination
9 [totalItems]="pagination.total" [itemsPerPage]="pagination.itemsPerPage" [(ngModel)]="pagination.currentPage"
10 (ngModelChange)="getVideos()"
11></pagination>
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 @@
1.loading { 1.videos-miniatures {
2 display: inline-block; 2 min-height: 600px;
3 margin-top: 100px;
4} 3}
5 4
6my-videos-miniature { 5my-videos-miniature {
7 display: inline-block; 6 display: inline-block;
8} 7}
8
9pagination {
10 display: block;
11 text-align: center;
12}
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 @@
1import { Component, OnInit } from '@angular/core'; 1import { Component, OnInit } from '@angular/core';
2import { ROUTER_DIRECTIVES, RouteParams } from '@angular/router-deprecated'; 2import { ROUTER_DIRECTIVES, RouteParams } from '@angular/router-deprecated';
3 3
4import { PAGINATION_DIRECTIVES } from 'ng2-bootstrap/components/pagination';
5
4import { AuthService } from '../../../users/services/auth.service'; 6import { AuthService } from '../../../users/services/auth.service';
7import { Pagination } from '../../pagination';
5import { User } from '../../../users/models/user'; 8import { User } from '../../../users/models/user';
6import { VideosService } from '../../videos.service'; 9import { VideosService } from '../../videos.service';
7import { Video } from '../../video'; 10import { Video } from '../../video';
@@ -11,21 +14,26 @@ import { VideoMiniatureComponent } from './video-miniature.component';
11 selector: 'my-videos-list', 14 selector: 'my-videos-list',
12 styleUrls: [ 'app/angular/videos/components/list/videos-list.component.css' ], 15 styleUrls: [ 'app/angular/videos/components/list/videos-list.component.css' ],
13 templateUrl: 'app/angular/videos/components/list/videos-list.component.html', 16 templateUrl: 'app/angular/videos/components/list/videos-list.component.html',
14 directives: [ ROUTER_DIRECTIVES, VideoMiniatureComponent ] 17 directives: [ ROUTER_DIRECTIVES, PAGINATION_DIRECTIVES, VideoMiniatureComponent ]
15}) 18})
16 19
17export class VideosListComponent implements OnInit { 20export class VideosListComponent implements OnInit {
18 user: User = null; 21 user: User = null;
19 videos: Video[] = []; 22 videos: Video[] = [];
23 pagination: Pagination = {
24 currentPage: 1,
25 itemsPerPage: 9,
26 total: 0
27 }
20 28
21 private search: string; 29 private search: string;
22 30
23 constructor( 31 constructor(
24 private _authService: AuthService, 32 private _authService: AuthService,
25 private _videosService: VideosService, 33 private _videosService: VideosService,
26 routeParams: RouteParams 34 private _routeParams: RouteParams
27 ) { 35 ) {
28 this.search = routeParams.get('search'); 36 this.search = this._routeParams.get('search');
29 } 37 }
30 38
31 ngOnInit() { 39 ngOnInit() {
@@ -40,13 +48,16 @@ export class VideosListComponent implements OnInit {
40 let observable = null; 48 let observable = null;
41 49
42 if (this.search !== null) { 50 if (this.search !== null) {
43 observable = this._videosService.searchVideos(this.search); 51 observable = this._videosService.searchVideos(this.search, this.pagination);
44 } else { 52 } else {
45 observable = this._videosService.getVideos(); 53 observable = this._videosService.getVideos(this.pagination);
46 } 54 }
47 55
48 observable.subscribe( 56 observable.subscribe(
49 videos => this.videos = videos, 57 ({ videos, totalVideos }) => {
58 this.videos = videos;
59 this.pagination.total = totalVideos;
60 },
50 error => alert(error) 61 error => alert(error)
51 ); 62 );
52 } 63 }
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 @@
1export interface Pagination {
2 currentPage: number;
3 itemsPerPage: number;
4 total: number;
5}
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 @@
1import { Injectable } from '@angular/core'; 1import { Injectable } from '@angular/core';
2import { Http, Response } from '@angular/http'; 2import { Http, Response, RequestOptions, URLSearchParams } from '@angular/http';
3import { Observable } from 'rxjs/Rx'; 3import { Observable } from 'rxjs/Rx';
4 4
5import { Pagination } from './pagination';
5import { Video } from './video'; 6import { Video } from './video';
6import { AuthService } from '../users/services/auth.service'; 7import { AuthService } from '../users/services/auth.service';
7 8
@@ -11,8 +12,9 @@ export class VideosService {
11 12
12 constructor (private http: Http, private _authService: AuthService) {} 13 constructor (private http: Http, private _authService: AuthService) {}
13 14
14 getVideos() { 15 getVideos(pagination: Pagination) {
15 return this.http.get(this._baseVideoUrl) 16 const params = { search: this.createPaginationParams(pagination) };
17 return this.http.get(this._baseVideoUrl, params)
16 .map(res => res.json()) 18 .map(res => res.json())
17 .map(this.extractVideos) 19 .map(this.extractVideos)
18 .catch(this.handleError); 20 .catch(this.handleError);
@@ -31,24 +33,38 @@ export class VideosService {
31 .catch(this.handleError); 33 .catch(this.handleError);
32 } 34 }
33 35
34 searchVideos(search: string) { 36 searchVideos(search: string, pagination: Pagination) {
35 return this.http.get(this._baseVideoUrl + 'search/' + search) 37 const params = { search: this.createPaginationParams(pagination) };
38 return this.http.get(this._baseVideoUrl + 'search/' + encodeURIComponent(search), params)
36 .map(res => res.json()) 39 .map(res => res.json())
37 .map(this.extractVideos) 40 .map(this.extractVideos)
38 .catch(this.handleError); 41 .catch(this.handleError);
39 } 42 }
40 43
41 private extractVideos (body: any[]) { 44 private extractVideos (body: any) {
45 const videos_json = body.data;
46 const totalVideos = body.total;
42 const videos = []; 47 const videos = [];
43 for (const video_json of body) { 48 for (const video_json of videos_json) {
44 videos.push(new Video(video_json)); 49 videos.push(new Video(video_json));
45 } 50 }
46 51
47 return videos; 52 return { videos, totalVideos };
48 } 53 }
49 54
50 private handleError (error: Response) { 55 private handleError (error: Response) {
51 console.error(error); 56 console.error(error);
52 return Observable.throw(error.json().error || 'Server error'); 57 return Observable.throw(error.json().error || 'Server error');
53 } 58 }
59
60 private createPaginationParams(pagination: Pagination) {
61 const params = new URLSearchParams();
62 const start: number = (pagination.currentPage - 1) * pagination.itemsPerPage;
63 const count: number = pagination.itemsPerPage;
64
65 params.set('start', start.toString());
66 params.set('count', count.toString());
67
68 return params;
69 }
54} 70}
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 @@
21 }, 21 },
22 "license": "GPLv3", 22 "license": "GPLv3",
23 "dependencies": { 23 "dependencies": {
24 "angular-pipes": "^2.0.0",
25 "@angular/common": "2.0.0-rc.1", 24 "@angular/common": "2.0.0-rc.1",
26 "@angular/compiler": "2.0.0-rc.1", 25 "@angular/compiler": "2.0.0-rc.1",
27 "@angular/core": "2.0.0-rc.1", 26 "@angular/core": "2.0.0-rc.1",
28 "@angular/http": "2.0.0-rc.1", 27 "@angular/http": "2.0.0-rc.1",
29 "@angular/platform-browser-dynamic": "2.0.0-rc.1",
30 "@angular/platform-browser": "2.0.0-rc.1", 28 "@angular/platform-browser": "2.0.0-rc.1",
29 "@angular/platform-browser-dynamic": "2.0.0-rc.1",
31 "@angular/router-deprecated": "2.0.0-rc.1", 30 "@angular/router-deprecated": "2.0.0-rc.1",
31 "angular-pipes": "^2.0.0",
32 "blueimp-file-upload": "^9.12.1", 32 "blueimp-file-upload": "^9.12.1",
33 "bootstrap-sass": "^3.3.6", 33 "bootstrap-sass": "^3.3.6",
34 "es6-promise": "^3.0.2", 34 "es6-promise": "^3.0.2",
35 "es6-shim": "^0.35.0", 35 "es6-shim": "^0.35.0",
36 "jquery": "^2.2.3", 36 "jquery": "^2.2.3",
37 "jquery.ui.widget": "^1.10.3", 37 "jquery.ui.widget": "^1.10.3",
38 "ng2-bootstrap": "^1.0.16",
38 "reflect-metadata": "0.1.3", 39 "reflect-metadata": "0.1.3",
39 "rxjs": "5.0.0-beta.6", 40 "rxjs": "5.0.0-beta.6",
40 "systemjs": "0.19.27", 41 "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 @@
2 var map = { 2 var map = {
3 'app': 'app/angular', 3 'app': 'app/angular',
4 'angular-pipes': 'app/node_modules/angular-pipes', 4 'angular-pipes': 'app/node_modules/angular-pipes',
5 'ng2-bootstrap': 'app/node_modules/ng2-bootstrap',
5 'angular-rxjs.bundle': 'app/bundles/angular-rxjs.bundle.js' 6 'angular-rxjs.bundle': 'app/bundles/angular-rxjs.bundle.js'
6 } 7 }
7 8
8 var packages = { 9 var packages = {
9 'app': { main: 'main.js', defaultExtension: 'js' }, 10 'app': { main: 'main.js', defaultExtension: 'js' },
11 'ng2-bootstrap': { defaultExtension: 'js' },
10 'rxjs': { defaultExtension: 'js' } 12 'rxjs': { defaultExtension: 'js' }
11 } 13 }
12 var packageNames = [ 14 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 @@
32 "angular/videos/components/list/video-miniature.component.ts", 32 "angular/videos/components/list/video-miniature.component.ts",
33 "angular/videos/components/list/videos-list.component.ts", 33 "angular/videos/components/list/videos-list.component.ts",
34 "angular/videos/components/watch/videos-watch.component.ts", 34 "angular/videos/components/watch/videos-watch.component.ts",
35 "angular/videos/pagination.ts",
35 "angular/videos/video.ts", 36 "angular/videos/video.ts",
36 "angular/videos/videos.service.ts", 37 "angular/videos/videos.service.ts",
37 "typings/globals/es6-shim/index.d.ts", 38 "typings/globals/es6-shim/index.d.ts",