aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/app/videos/shared
diff options
context:
space:
mode:
Diffstat (limited to 'client/app/videos/shared')
-rw-r--r--client/app/videos/shared/index.ts5
-rw-r--r--client/app/videos/shared/loader/index.ts1
-rw-r--r--client/app/videos/shared/loader/loader.component.html3
-rw-r--r--client/app/videos/shared/loader/loader.component.scss26
-rw-r--r--client/app/videos/shared/loader/loader.component.ts11
-rw-r--r--client/app/videos/shared/pagination.model.ts5
-rw-r--r--client/app/videos/shared/sort-field.type.ts3
-rw-r--r--client/app/videos/shared/video.model.ts63
-rw-r--r--client/app/videos/shared/video.service.ts79
9 files changed, 196 insertions, 0 deletions
diff --git a/client/app/videos/shared/index.ts b/client/app/videos/shared/index.ts
new file mode 100644
index 000000000..c535c46fc
--- /dev/null
+++ b/client/app/videos/shared/index.ts
@@ -0,0 +1,5 @@
1export * from './loader/index';
2export * from './pagination.model';
3export * from './sort-field.type';
4export * from './video.model';
5export * from './video.service';
diff --git a/client/app/videos/shared/loader/index.ts b/client/app/videos/shared/loader/index.ts
new file mode 100644
index 000000000..ab22584e4
--- /dev/null
+++ b/client/app/videos/shared/loader/index.ts
@@ -0,0 +1 @@
export * from './loader.component';
diff --git a/client/app/videos/shared/loader/loader.component.html b/client/app/videos/shared/loader/loader.component.html
new file mode 100644
index 000000000..d02296a2d
--- /dev/null
+++ b/client/app/videos/shared/loader/loader.component.html
@@ -0,0 +1,3 @@
1<div id="video-loading" class="col-md-12 text-center" *ngIf="loading">
2 <div class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></div>
3</div>
diff --git a/client/app/videos/shared/loader/loader.component.scss b/client/app/videos/shared/loader/loader.component.scss
new file mode 100644
index 000000000..454195811
--- /dev/null
+++ b/client/app/videos/shared/loader/loader.component.scss
@@ -0,0 +1,26 @@
1div {
2 margin-top: 150px;
3}
4
5// Thanks https://gist.github.com/alexandrevicenzi/680147013e902a4eaa5d
6.glyphicon-refresh-animate {
7 -animation: spin .7s infinite linear;
8 -ms-animation: spin .7s infinite linear;
9 -webkit-animation: spinw .7s infinite linear;
10 -moz-animation: spinm .7s infinite linear;
11}
12
13@keyframes spin {
14 from { transform: scale(1) rotate(0deg);}
15 to { transform: scale(1) rotate(360deg);}
16}
17
18@-webkit-keyframes spinw {
19 from { -webkit-transform: rotate(0deg);}
20 to { -webkit-transform: rotate(360deg);}
21}
22
23@-moz-keyframes spinm {
24 from { -moz-transform: rotate(0deg);}
25 to { -moz-transform: rotate(360deg);}
26}
diff --git a/client/app/videos/shared/loader/loader.component.ts b/client/app/videos/shared/loader/loader.component.ts
new file mode 100644
index 000000000..666d43bc3
--- /dev/null
+++ b/client/app/videos/shared/loader/loader.component.ts
@@ -0,0 +1,11 @@
1import { Component, Input } from '@angular/core';
2
3@Component({
4 selector: 'my-loader',
5 styleUrls: [ 'client/app/videos/shared/loader/loader.component.css' ],
6 templateUrl: 'client/app/videos/shared/loader/loader.component.html'
7})
8
9export class LoaderComponent {
10 @Input() loading: boolean;
11}
diff --git a/client/app/videos/shared/pagination.model.ts b/client/app/videos/shared/pagination.model.ts
new file mode 100644
index 000000000..06f7a7875
--- /dev/null
+++ b/client/app/videos/shared/pagination.model.ts
@@ -0,0 +1,5 @@
1export interface Pagination {
2 currentPage: number;
3 itemsPerPage: number;
4 total: number;
5}
diff --git a/client/app/videos/shared/sort-field.type.ts b/client/app/videos/shared/sort-field.type.ts
new file mode 100644
index 000000000..6e8cc7936
--- /dev/null
+++ b/client/app/videos/shared/sort-field.type.ts
@@ -0,0 +1,3 @@
1export type SortField = "name" | "-name"
2 | "duration" | "-duration"
3 | "createdDate" | "-createdDate";
diff --git a/client/app/videos/shared/video.model.ts b/client/app/videos/shared/video.model.ts
new file mode 100644
index 000000000..eec537c9e
--- /dev/null
+++ b/client/app/videos/shared/video.model.ts
@@ -0,0 +1,63 @@
1export class Video {
2 id: string;
3 name: string;
4 description: string;
5 magnetUri: string;
6 podUrl: string;
7 isLocal: boolean;
8 thumbnailPath: string;
9 author: string;
10 createdDate: Date;
11 by: string;
12 duration: string;
13
14 private static createDurationString(duration: number): string {
15 const minutes = Math.floor(duration / 60);
16 const seconds = duration % 60;
17 const minutes_padding = minutes >= 10 ? '' : '0';
18 const seconds_padding = seconds >= 10 ? '' : '0';
19
20 return minutes_padding + minutes.toString() + ':' + seconds_padding + seconds.toString();
21 }
22
23 private static createByString(author: string, podUrl: string): string {
24 let [ host, port ] = podUrl.replace(/^https?:\/\//, '').split(':');
25
26 if (port === '80' || port === '443') {
27 port = '';
28 } else {
29 port = ':' + port;
30 }
31
32 return author + '@' + host + port;
33 }
34
35 constructor(hash: {
36 id: string,
37 name: string,
38 description: string,
39 magnetUri: string,
40 podUrl: string,
41 isLocal: boolean,
42 thumbnailPath: string,
43 author: string,
44 createdDate: string,
45 duration: number;
46 }) {
47 this.id = hash.id;
48 this.name = hash.name;
49 this.description = hash.description;
50 this.magnetUri = hash.magnetUri;
51 this.podUrl = hash.podUrl;
52 this.isLocal = hash.isLocal;
53 this.thumbnailPath = hash.thumbnailPath;
54 this.author = hash.author;
55 this.createdDate = new Date(hash.createdDate);
56 this.duration = Video.createDurationString(hash.duration);
57 this.by = Video.createByString(hash.author, hash.podUrl);
58 }
59
60 isRemovableBy(user): boolean {
61 return this.isLocal === true && user && this.author === user.username;
62 }
63}
diff --git a/client/app/videos/shared/video.service.ts b/client/app/videos/shared/video.service.ts
new file mode 100644
index 000000000..78789c3cc
--- /dev/null
+++ b/client/app/videos/shared/video.service.ts
@@ -0,0 +1,79 @@
1import { Injectable } from '@angular/core';
2import { Http, Response, URLSearchParams } from '@angular/http';
3import { Observable } from 'rxjs/Rx';
4
5import { Pagination } from './pagination.model';
6import { Search } from '../../shared/index';
7import { SortField } from './sort-field.type';
8import { AuthService } from '../../users/index';
9import { Video } from './video.model';
10
11@Injectable()
12export class VideoService {
13 private _baseVideoUrl = '/api/v1/videos/';
14
15 constructor (private http: Http, private _authService: AuthService) {}
16
17 getVideos(pagination: Pagination, sort: SortField) {
18 const params = this.createPaginationParams(pagination);
19
20 if (sort) params.set('sort', sort);
21
22 return this.http.get(this._baseVideoUrl, { search: params })
23 .map(res => res.json())
24 .map(this.extractVideos)
25 .catch(this.handleError);
26 }
27
28 getVideo(id: string) {
29 return this.http.get(this._baseVideoUrl + id)
30 .map(res => <Video> res.json())
31 .catch(this.handleError);
32 }
33
34 removeVideo(id: string) {
35 const options = this._authService.getAuthRequestOptions();
36 return this.http.delete(this._baseVideoUrl + id, options)
37 .map(res => <number> res.status)
38 .catch(this.handleError);
39 }
40
41 searchVideos(search: Search, pagination: Pagination, sort: SortField) {
42 const params = this.createPaginationParams(pagination);
43
44 if (search.field) params.set('field', search.field);
45 if (sort) params.set('sort', sort);
46
47 return this.http.get(this._baseVideoUrl + 'search/' + encodeURIComponent(search.value), { search: params })
48 .map(res => res.json())
49 .map(this.extractVideos)
50 .catch(this.handleError);
51 }
52
53 private extractVideos (body: any) {
54 const videos_json = body.data;
55 const totalVideos = body.total;
56 const videos = [];
57 for (const video_json of videos_json) {
58 videos.push(new Video(video_json));
59 }
60
61 return { videos, totalVideos };
62 }
63
64 private handleError (error: Response) {
65 console.error(error);
66 return Observable.throw(error.json().error || 'Server error');
67 }
68
69 private createPaginationParams(pagination: Pagination) {
70 const params = new URLSearchParams();
71 const start: number = (pagination.currentPage - 1) * pagination.itemsPerPage;
72 const count: number = pagination.itemsPerPage;
73
74 params.set('start', start.toString());
75 params.set('count', count.toString());
76
77 return params;
78 }
79}