aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/angular
diff options
context:
space:
mode:
Diffstat (limited to 'client/angular')
-rw-r--r--client/angular/app/app.component.html37
-rw-r--r--client/angular/app/app.component.scss28
-rw-r--r--client/angular/app/app.component.ts63
-rw-r--r--client/angular/bootstrap.ts4
-rw-r--r--client/angular/friends/services/friends.service.ts27
-rw-r--r--client/angular/videos/components/add/videos-add.component.html39
-rw-r--r--client/angular/videos/components/add/videos-add.component.scss25
-rw-r--r--client/angular/videos/components/add/videos-add.component.ts52
-rw-r--r--client/angular/videos/components/list/videos-list.component.html11
-rw-r--r--client/angular/videos/components/list/videos-list.component.scss34
-rw-r--r--client/angular/videos/components/list/videos-list.component.ts39
-rw-r--r--client/angular/videos/components/watch/videos-watch.component.html2
-rw-r--r--client/angular/videos/components/watch/videos-watch.component.scss0
-rw-r--r--client/angular/videos/components/watch/videos-watch.component.ts50
-rw-r--r--client/angular/videos/models/video.ts6
-rw-r--r--client/angular/videos/services/videos.service.ts37
16 files changed, 454 insertions, 0 deletions
diff --git a/client/angular/app/app.component.html b/client/angular/app/app.component.html
new file mode 100644
index 000000000..590efa0d6
--- /dev/null
+++ b/client/angular/app/app.component.html
@@ -0,0 +1,37 @@
1<div class="container">
2
3 <div class="row">
4
5 <menu class="col-md-2">
6 <div id="panel_get_videos" class="panel_button">
7 <span class="glyphicon glyphicon-list"></span>
8 <a [routerLink]="['VideosList']">Get videos</a>
9 </div>
10
11 <div id="panel_upload_video" class="panel_button">
12 <span class="glyphicon glyphicon-cloud-upload"></span>
13 <a [routerLink]="['VideosAdd']">Upload a video</a>
14 </div>
15
16 <div id="panel_make_friends" class="panel_button">
17 <span class="glyphicon glyphicon-user"></span>
18 <a (click)='makeFriends()'>Make friends</a>
19 </div>
20
21 <div id="panel_quit_friends" class="panel_button">
22 <span class="glyphicon glyphicon-plane"></span>
23 <a (click)='quitFriends()'>Quit friends</a>
24 </div>
25 </menu>
26
27 <div class="col-md-9 router_outler_container">
28 <router-outlet></router-outlet>
29 </div>
30
31 </div>
32
33
34 <footer>
35 PeerTube, CopyLeft 2015-2016
36 </footer>
37</div>
diff --git a/client/angular/app/app.component.scss b/client/angular/app/app.component.scss
new file mode 100644
index 000000000..03ecba8f2
--- /dev/null
+++ b/client/angular/app/app.component.scss
@@ -0,0 +1,28 @@
1menu {
2 min-height: 300px;
3 height: 100%;
4 margin-right: 20px;
5 border-right: 1px solid rgba(0, 0, 0, 0.2);
6
7 .panel_button {
8 margin: 8px;
9 cursor: pointer;
10 transition: margin 0.2s;
11
12 &:hover {
13 margin-left: 15px;
14 }
15
16 a {
17 color: #333333;
18 }
19 }
20
21 .glyphicon {
22 margin: 5px;
23 }
24}
25
26footer {
27 margin-top: 30px;
28}
diff --git a/client/angular/app/app.component.ts b/client/angular/app/app.component.ts
new file mode 100644
index 000000000..3d41183f2
--- /dev/null
+++ b/client/angular/app/app.component.ts
@@ -0,0 +1,63 @@
1import { Component, ElementRef } from 'angular2/core';
2import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
3import {HTTP_PROVIDERS} from 'angular2/http';
4
5import { VideosAddComponent } from '../videos/components/add/videos-add.component';
6import { VideosListComponent } from '../videos/components/list/videos-list.component';
7import { VideosWatchComponent } from '../videos/components/watch/videos-watch.component';
8import { VideosService } from '../videos/services/videos.service';
9import { FriendsService } from '../friends/services/friends.service';
10
11@RouteConfig([
12 {
13 path: '/videos/list',
14 name: 'VideosList',
15 component: VideosListComponent,
16 useAsDefault: true
17 },
18 {
19 path: '/videos/watch/:id',
20 name: 'VideosWatch',
21 component: VideosWatchComponent
22 },
23 {
24 path: '/videos/add',
25 name: 'VideosAdd',
26 component: VideosAddComponent
27 }
28])
29
30@Component({
31 selector: 'my-app',
32 templateUrl: 'app/angular/app/app.component.html',
33 styleUrls: [ 'app/angular/app/app.component.css' ],
34 directives: [ ROUTER_DIRECTIVES ],
35 providers: [ ROUTER_PROVIDERS, HTTP_PROVIDERS, ElementRef, VideosService, FriendsService ]
36})
37
38export class AppComponent {
39 constructor(private _friendsService: FriendsService) {}
40
41 makeFriends() {
42 this._friendsService.makeFriends().subscribe(
43 status => {
44 if (status === 409) {
45 alert('Already made friends!');
46 }
47 else {
48 alert('Made friends!');
49 }
50 },
51 error => alert(error)
52 )
53 }
54
55 quitFriends() {
56 this._friendsService.quitFriends().subscribe(
57 status => {
58 alert('Quit friends!');
59 },
60 error => alert(error)
61 )
62 }
63}
diff --git a/client/angular/bootstrap.ts b/client/angular/bootstrap.ts
new file mode 100644
index 000000000..d0f524f4a
--- /dev/null
+++ b/client/angular/bootstrap.ts
@@ -0,0 +1,4 @@
1import { bootstrap } from 'angular2/platform/browser';
2import { AppComponent } from './app/app.component';
3
4bootstrap(AppComponent);
diff --git a/client/angular/friends/services/friends.service.ts b/client/angular/friends/services/friends.service.ts
new file mode 100644
index 000000000..a34ef0d6f
--- /dev/null
+++ b/client/angular/friends/services/friends.service.ts
@@ -0,0 +1,27 @@
1import {Injectable} from 'angular2/core';
2import {Http, Response, Headers, RequestOptions} from 'angular2/http';
3import {Observable} from 'rxjs/Rx';
4
5@Injectable()
6export class FriendsService {
7 private _baseFriendsUrl = '/api/v1/pods/';
8
9 constructor (private http: Http) {}
10
11 makeFriends() {
12 return this.http.get(this._baseFriendsUrl + 'makefriends')
13 .map(res => <number> res.status)
14 .catch(this.handleError);
15 }
16
17 quitFriends() {
18 return this.http.get(this._baseFriendsUrl + 'quitfriends')
19 .map(res => <number> res.status)
20 .catch(this.handleError);
21 }
22
23 private handleError (error: Response) {
24 console.error(error);
25 return Observable.throw(error.json().error || 'Server error');
26 }
27}
diff --git a/client/angular/videos/components/add/videos-add.component.html b/client/angular/videos/components/add/videos-add.component.html
new file mode 100644
index 000000000..5f28ae650
--- /dev/null
+++ b/client/angular/videos/components/add/videos-add.component.html
@@ -0,0 +1,39 @@
1<h3>Upload a video</h3>
2
3<form (ngSubmit)="uploadFile()" #videoForm="ngForm">
4 <div class="form-group">
5 <label for="name">Video name</label>
6 <input
7 type="text" class="form-control" name="name" id="name" required
8 ngControl="name" #name="ngForm"
9 >
10 <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
11 Name is required
12 </div>
13 </div>
14
15 <div class="btn btn-default btn-file">
16 <span>Select the video...</span>
17 <input type="file" name="input_video" id="input_video">
18 </div>
19
20 <span *ngIf="fileToUpload">{{ fileToUpload.name }}</span>
21
22 <div class="form-group">
23 <label for="description">Description</label>
24 <textarea
25 name="description" id="description" class="form-control" placeholder="Description..." required
26 ngControl="description" #description="ngForm"
27 >
28 </textarea>
29 <div [hidden]="description.valid || description.pristine" class="alert alert-danger">
30 A description is required
31 </div>
32 </div>
33
34 <div id="progress" *ngIf="progressBar.max !== 0">
35 <progress [value]="progressBar.value" [max]="progressBar.max"></progress>
36 </div>
37
38 <input type="submit" value="Upload" class="btn btn-default" [disabled]="!videoForm.form.valid || !fileToUpload">
39</form>
diff --git a/client/angular/videos/components/add/videos-add.component.scss b/client/angular/videos/components/add/videos-add.component.scss
new file mode 100644
index 000000000..f4187088b
--- /dev/null
+++ b/client/angular/videos/components/add/videos-add.component.scss
@@ -0,0 +1,25 @@
1.btn-file {
2 position: relative;
3 overflow: hidden;
4}
5
6.btn-file input[type=file] {
7 position: absolute;
8 top: 0;
9 right: 0;
10 min-width: 100%;
11 min-height: 100%;
12 font-size: 100px;
13 text-align: right;
14 filter: alpha(opacity=0);
15 opacity: 0;
16 outline: none;
17 background: white;
18 cursor: inherit;
19 display: block;
20}
21
22.name_file {
23 display: inline-block;
24 margin-left: 10px;
25}
diff --git a/client/angular/videos/components/add/videos-add.component.ts b/client/angular/videos/components/add/videos-add.component.ts
new file mode 100644
index 000000000..97e3bb3b5
--- /dev/null
+++ b/client/angular/videos/components/add/videos-add.component.ts
@@ -0,0 +1,52 @@
1import {Component, ElementRef, Inject, OnInit} from 'angular2/core';
2import {Router} from 'angular2/router';
3import {NgForm} from 'angular2/common';
4
5import {Video} from '../../models/video';
6
7declare var jQuery:any;
8
9@Component({
10 selector: 'my-videos-add',
11 styleUrls: [ 'app/angular/videos/components/add/videos-add.component.css' ],
12 templateUrl: 'app/angular/videos/components/add/videos-add.component.html'
13})
14
15export class VideosAddComponent implements OnInit {
16 fileToUpload: any;
17 progressBar: { value: number; max: number; } = { value: 0, max: 0 };
18
19 private _form: any;
20
21 constructor(private _router: Router, private _elementRef: ElementRef) {}
22
23 ngOnInit() {
24 jQuery(this._elementRef.nativeElement).find('#input_video').fileupload({
25 singleFileUploads: true,
26 multipart: true,
27 url: '/api/v1/videos',
28 autoupload: false,
29
30 add: (e, data) => {
31 this._form = data;
32 this.fileToUpload = data['files'][0];
33 },
34
35 progressall: (e, data) => {
36 this.progressBar.value = data.loaded;
37 this.progressBar.max= data.total;
38 },
39
40 done: (e, data) => {
41 console.log('finished');
42 // Print all the videos once it's finished
43 this._router.navigate(['VideosList']);
44 }
45 });
46 }
47
48 uploadFile() {
49 this._form.formData = jQuery(this._elementRef.nativeElement).find('form').serializeArray();
50 this._form.submit();
51 }
52}
diff --git a/client/angular/videos/components/list/videos-list.component.html b/client/angular/videos/components/list/videos-list.component.html
new file mode 100644
index 000000000..7ecdacee4
--- /dev/null
+++ b/client/angular/videos/components/list/videos-list.component.html
@@ -0,0 +1,11 @@
1<div *ngFor="#video of videos" class="video">
2 <div>
3 <a [routerLink]="['VideosWatch', { id: video._id }]" class="video_name">{{ video.name }}</a>
4 <span class="video_pod_url">{{ video.podUrl }}</span>
5 <span *ngIf="video.namePath !== null" (click)="removeVideo(video._id)" class="video_remove glyphicon glyphicon-remove"></span>
6 </div>
7
8 <div class="video_description">
9 {{ video.description }}
10 </div>
11</div>
diff --git a/client/angular/videos/components/list/videos-list.component.scss b/client/angular/videos/components/list/videos-list.component.scss
new file mode 100644
index 000000000..82ddd80e5
--- /dev/null
+++ b/client/angular/videos/components/list/videos-list.component.scss
@@ -0,0 +1,34 @@
1.video {
2 margin-bottom: 10px;
3 transition: margin 0.5s ease;
4
5 &:hover {
6 margin-left: 5px;
7 }
8
9 a.video_name {
10 color: #333333;
11 margin-right: 5px;
12 }
13
14 .video_pod_url {
15 font-size: small;
16 color: rgba(0, 0, 0, 0.5);
17 }
18
19 .video_description {
20 font-size: small;
21 font-style: italic;
22 margin-left: 7px;
23 }
24
25 .video_remove {
26 margin: 5px;
27 cursor: pointer;
28 }
29}
30
31.loading {
32 display: inline-block;
33 margin-top: 100px;
34}
diff --git a/client/angular/videos/components/list/videos-list.component.ts b/client/angular/videos/components/list/videos-list.component.ts
new file mode 100644
index 000000000..e5af87448
--- /dev/null
+++ b/client/angular/videos/components/list/videos-list.component.ts
@@ -0,0 +1,39 @@
1import {Component, OnInit} from 'angular2/core';
2import {ROUTER_DIRECTIVES} from 'angular2/router';
3
4import {VideosService} from '../../services/videos.service';
5import {Video} from '../../models/video';
6
7@Component({
8 selector: 'my-videos-list',
9 styleUrls: [ 'app/angular/videos/components/list/videos-list.component.css' ],
10 templateUrl: 'app/angular/videos/components/list/videos-list.component.html',
11 directives: [ ROUTER_DIRECTIVES ]
12})
13
14export class VideosListComponent implements OnInit {
15 videos: Video[];
16
17 constructor(
18 private _videosService: VideosService
19 ) { }
20
21 ngOnInit() {
22 this.getVideos();
23 }
24
25 getVideos() {
26 this._videosService.getVideos().subscribe(
27 videos => this.videos = videos,
28 error => alert(error)
29 );
30 }
31
32 removeVideo(id: string) {
33 this._videosService.removeVideo(id).subscribe(
34 status => this.getVideos(),
35 error => alert(error)
36 )
37 }
38
39}
diff --git a/client/angular/videos/components/watch/videos-watch.component.html b/client/angular/videos/components/watch/videos-watch.component.html
new file mode 100644
index 000000000..e47222751
--- /dev/null
+++ b/client/angular/videos/components/watch/videos-watch.component.html
@@ -0,0 +1,2 @@
1<div class="embed-responsive embed-responsive-19by9">
2</div>
diff --git a/client/angular/videos/components/watch/videos-watch.component.scss b/client/angular/videos/components/watch/videos-watch.component.scss
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/client/angular/videos/components/watch/videos-watch.component.scss
diff --git a/client/angular/videos/components/watch/videos-watch.component.ts b/client/angular/videos/components/watch/videos-watch.component.ts
new file mode 100644
index 000000000..e3a973820
--- /dev/null
+++ b/client/angular/videos/components/watch/videos-watch.component.ts
@@ -0,0 +1,50 @@
1/// <reference path='../../../../typings/browser/ambient/webtorrent/webtorrent.d.ts' />
2
3import { Component, OnInit, ElementRef } from 'angular2/core';
4import { RouteParams } from 'angular2/router';
5
6declare var WebTorrent: any;
7
8import { Video } from '../../models/video';
9import { VideosService } from '../../services/videos.service';
10
11@Component({
12 selector: 'my-video-watch',
13 templateUrl: 'app/angular/videos/components/watch/videos-watch.component.html',
14 styleUrls: [ 'app/angular/videos/components/watch/videos-watch.component.css' ]
15})
16
17export class VideosWatchComponent {
18 video: Video;
19
20 private client: any;
21
22 constructor(
23 private _videosService: VideosService,
24 private _routeParams: RouteParams,
25 private _elementRef: ElementRef
26 ) {
27 this.client = new WebTorrent({ dht: false });
28 }
29
30 ngOnInit() {
31 let id = this._routeParams.get('id');
32 this._videosService.getVideo(id).subscribe(
33 video => this.loadVideo(video),
34 error => alert(error)
35 );
36 }
37
38 loadVideo(video: Video) {
39 this.video = video;
40
41 this.client.add(this.video.magnetUri, (torrent) => {
42 torrent.files[0].appendTo(this._elementRef.nativeElement, (err) => {
43 if (err) {
44 alert('Cannot append the file.');
45 console.error(err);
46 }
47 })
48 })
49 }
50}
diff --git a/client/angular/videos/models/video.ts b/client/angular/videos/models/video.ts
new file mode 100644
index 000000000..2f998c49a
--- /dev/null
+++ b/client/angular/videos/models/video.ts
@@ -0,0 +1,6 @@
1export interface Video {
2 _id: string;
3 name: string;
4 description: string;
5 magnetUri: string;
6}
diff --git a/client/angular/videos/services/videos.service.ts b/client/angular/videos/services/videos.service.ts
new file mode 100644
index 000000000..784eec68d
--- /dev/null
+++ b/client/angular/videos/services/videos.service.ts
@@ -0,0 +1,37 @@
1import {Injectable} from 'angular2/core';
2import {Http, Response} from 'angular2/http';
3import {Observable} from 'rxjs/Rx';
4
5import {Video} from '../models/video';
6
7@Injectable()
8export class VideosService {
9 private _baseVideoUrl = '/api/v1/videos/';
10
11 constructor (private http: Http) {}
12
13 getVideos() {
14 return this.http.get(this._baseVideoUrl)
15 .map(res => <Video[]> res.json())
16 .catch(this.handleError);
17 }
18
19 getVideo(id: string) {
20 return this.http.get(this._baseVideoUrl + id)
21 .map(res => <Video> res.json())
22 .catch(this.handleError);
23 }
24
25 removeVideo(id: string) {
26 if (confirm('Are you sure?')) {
27 return this.http.delete(this._baseVideoUrl + id)
28 .map(res => <number> res.status)
29 .catch(this.handleError);
30 }
31 }
32
33 private handleError (error: Response) {
34 console.error(error);
35 return Observable.throw(error.json().error || 'Server error');
36 }
37}