Add pagination support to the client

This commit is contained in:
Chocobozzz 2016-05-22 10:43:06 +02:00
parent 46246b5f19
commit 322940742b
11 changed files with 74 additions and 28 deletions

View File

@ -5,7 +5,7 @@
<h4>PeerTube</h4>
</div>
<div class="col-md-8">
<div class="col-md-9">
<input
type="text" id="search_video" name="search_video" class="form-control" placeholder="Search a video..."
#search (keyup.enter)="doSearch(search.value)"

View File

@ -1,4 +1,4 @@
<div class="video-miniature" (mouseenter)="onHover()" (mouseleave)="onBlur()">
<div class="video-miniature col-md-4" (mouseenter)="onHover()" (mouseleave)="onBlur()">
<a
[routerLink]="['VideosWatch', { id: video.id }]" [attr.title]="video.description"
class="video-miniature-thumbnail"

View File

@ -1,8 +1,6 @@
.video-miniature {
width: 200px;
height: 200px;
display: inline-block;
margin-right: 40px;
position: relative;
.video-miniature-thumbnail {
@ -11,7 +9,7 @@
.video-miniature-duration {
position: absolute;
right: 2px;
right: 60px;
bottom: 2px;
display: inline-block;
background-color: rgba(0, 0, 0, 0.8);
@ -24,7 +22,7 @@
.video-miniature-remove {
display: inline-block;
position: absolute;
left: 2px;
left: 16px;
background-color: rgba(0, 0, 0, 0.8);
color: rgba(255, 255, 255, 0.8);
padding: 2px;

View File

@ -1,3 +1,11 @@
<div *ngIf="videos.length === 0">There is no video.</div>
<my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)">
</my-video-miniature>
<div class="videos-miniatures">
<div *ngIf="videos.length === 0">There is no video.</div>
<my-video-miniature *ngFor="let video of videos" [video]="video" [user]="user" (removed)="onRemoved(video)">
</my-video-miniature>
</div>
<pagination
[totalItems]="pagination.total" [itemsPerPage]="pagination.itemsPerPage" [(ngModel)]="pagination.currentPage"
(ngModelChange)="getVideos()"
></pagination>

View File

@ -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;
}

View File

@ -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)
);
}

View File

@ -0,0 +1,5 @@
export interface Pagination {
currentPage: number;
itemsPerPage: number;
total: number;
}

View File

@ -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;
}
}

View File

@ -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",

View File

@ -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 = [

View File

@ -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",