From dc8bc31be517a53e8fbe7100cfe45cd73f596de0 Mon Sep 17 00:00:00 2001
From: Chocobozzz <florian.bigard@gmail.com>
Date: Mon, 14 Mar 2016 13:50:19 +0100
Subject: Angular application :first draft

---
 .../components/add/videos-add.component.html       | 39 ++++++++++++++++
 .../components/add/videos-add.component.scss       | 25 +++++++++++
 .../videos/components/add/videos-add.component.ts  | 52 ++++++++++++++++++++++
 .../components/list/videos-list.component.html     | 11 +++++
 .../components/list/videos-list.component.scss     | 34 ++++++++++++++
 .../components/list/videos-list.component.ts       | 39 ++++++++++++++++
 .../components/watch/videos-watch.component.html   |  2 +
 .../components/watch/videos-watch.component.scss   |  0
 .../components/watch/videos-watch.component.ts     | 50 +++++++++++++++++++++
 client/angular/videos/models/video.ts              |  6 +++
 client/angular/videos/services/videos.service.ts   | 37 +++++++++++++++
 11 files changed, 295 insertions(+)
 create mode 100644 client/angular/videos/components/add/videos-add.component.html
 create mode 100644 client/angular/videos/components/add/videos-add.component.scss
 create mode 100644 client/angular/videos/components/add/videos-add.component.ts
 create mode 100644 client/angular/videos/components/list/videos-list.component.html
 create mode 100644 client/angular/videos/components/list/videos-list.component.scss
 create mode 100644 client/angular/videos/components/list/videos-list.component.ts
 create mode 100644 client/angular/videos/components/watch/videos-watch.component.html
 create mode 100644 client/angular/videos/components/watch/videos-watch.component.scss
 create mode 100644 client/angular/videos/components/watch/videos-watch.component.ts
 create mode 100644 client/angular/videos/models/video.ts
 create mode 100644 client/angular/videos/services/videos.service.ts

(limited to 'client/angular/videos')

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 @@
+<h3>Upload a video</h3>
+
+<form (ngSubmit)="uploadFile()" #videoForm="ngForm">
+  <div class="form-group">
+    <label for="name">Video name</label>
+    <input
+      type="text" class="form-control" name="name" id="name" required
+      ngControl="name"  #name="ngForm"
+    >
+    <div [hidden]="name.valid || name.pristine" class="alert alert-danger">
+      Name is required
+    </div>
+  </div>
+
+  <div class="btn btn-default btn-file">
+    <span>Select the video...</span>
+    <input type="file" name="input_video" id="input_video">
+  </div>
+
+  <span *ngIf="fileToUpload">{{ fileToUpload.name }}</span>
+
+  <div class="form-group">
+    <label for="description">Description</label>
+    <textarea
+      name="description" id="description" class="form-control" placeholder="Description..." required
+      ngControl="description"  #description="ngForm"
+    >
+    </textarea>
+    <div [hidden]="description.valid || description.pristine" class="alert alert-danger">
+        A description is required
+    </div>
+  </div>
+
+  <div id="progress" *ngIf="progressBar.max !== 0">
+    <progress [value]="progressBar.value" [max]="progressBar.max"></progress>
+  </div>
+
+  <input type="submit" value="Upload" class="btn btn-default" [disabled]="!videoForm.form.valid || !fileToUpload">
+</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 @@
+.btn-file {
+  position: relative;
+  overflow: hidden;
+}
+
+.btn-file input[type=file] {
+  position: absolute;
+  top: 0;
+  right: 0;
+  min-width: 100%;
+  min-height: 100%;
+  font-size: 100px;
+  text-align: right;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  outline: none;
+  background: white;
+  cursor: inherit;
+  display: block;
+}
+
+.name_file {
+  display: inline-block;
+  margin-left: 10px;
+}
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 @@
+import {Component, ElementRef, Inject, OnInit} from 'angular2/core';
+import {Router} from 'angular2/router';
+import {NgForm} from 'angular2/common';
+
+import {Video} from '../../models/video';
+
+declare var jQuery:any;
+
+@Component({
+  selector: 'my-videos-add',
+  styleUrls: [ 'app/angular/videos/components/add/videos-add.component.css' ],
+  templateUrl: 'app/angular/videos/components/add/videos-add.component.html'
+})
+
+export class VideosAddComponent implements OnInit {
+  fileToUpload: any;
+  progressBar: { value: number; max: number; } = { value: 0, max: 0 };
+
+  private _form: any;
+
+  constructor(private _router: Router, private _elementRef: ElementRef) {}
+
+  ngOnInit() {
+    jQuery(this._elementRef.nativeElement).find('#input_video').fileupload({
+      singleFileUploads: true,
+      multipart: true,
+      url: '/api/v1/videos',
+      autoupload: false,
+
+      add: (e, data) => {
+        this._form = data;
+        this.fileToUpload = data['files'][0];
+      },
+
+      progressall: (e, data) => {
+        this.progressBar.value = data.loaded;
+        this.progressBar.max= data.total;
+      },
+
+      done: (e, data) => {
+        console.log('finished');
+        // Print all the videos once it's finished
+        this._router.navigate(['VideosList']);
+      }
+    });
+  }
+
+  uploadFile() {
+    this._form.formData = jQuery(this._elementRef.nativeElement).find('form').serializeArray();
+    this._form.submit();
+  }
+}
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 @@
+<div *ngFor="#video of videos" class="video">
+  <div>
+    <a [routerLink]="['VideosWatch', { id: video._id }]" class="video_name">{{ video.name }}</a>
+    <span class="video_pod_url">{{ video.podUrl }}</span>
+    <span *ngIf="video.namePath !== null" (click)="removeVideo(video._id)" class="video_remove glyphicon glyphicon-remove"></span>
+  </div>
+
+  <div class="video_description">
+    {{ video.description }}
+  </div>
+</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 @@
+.video {
+  margin-bottom: 10px;
+  transition: margin 0.5s ease;
+
+  &:hover {
+    margin-left: 5px;
+  }
+
+  a.video_name {
+    color: #333333;
+    margin-right: 5px;
+  }
+
+  .video_pod_url {
+    font-size: small;
+    color: rgba(0, 0, 0, 0.5);
+  }
+
+  .video_description {
+    font-size: small;
+    font-style: italic;
+    margin-left: 7px;
+  }
+
+  .video_remove {
+    margin: 5px;
+    cursor: pointer;
+  }
+}
+
+.loading {
+  display: inline-block;
+  margin-top: 100px;
+}
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 @@
+import {Component, OnInit} from 'angular2/core';
+import {ROUTER_DIRECTIVES} from 'angular2/router';
+
+import {VideosService} from '../../services/videos.service';
+import {Video} from '../../models/video';
+
+@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 ]
+})
+
+export class VideosListComponent implements OnInit {
+  videos: Video[];
+
+  constructor(
+    private _videosService: VideosService
+  ) { }
+
+  ngOnInit() {
+    this.getVideos();
+  }
+
+  getVideos() {
+    this._videosService.getVideos().subscribe(
+      videos => this.videos = videos,
+      error => alert(error)
+    );
+  }
+
+  removeVideo(id: string) {
+    this._videosService.removeVideo(id).subscribe(
+      status => this.getVideos(),
+      error => alert(error)
+    )
+  }
+
+}
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 @@
+<div class="embed-responsive embed-responsive-19by9">
+</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
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 @@
+/// <reference path='../../../../typings/browser/ambient/webtorrent/webtorrent.d.ts' />
+
+import { Component, OnInit, ElementRef } from 'angular2/core';
+import { RouteParams } from 'angular2/router';
+
+declare var WebTorrent: any;
+
+import { Video } from '../../models/video';
+import { VideosService } from '../../services/videos.service';
+
+@Component({
+  selector: 'my-video-watch',
+  templateUrl: 'app/angular/videos/components/watch/videos-watch.component.html',
+  styleUrls: [ 'app/angular/videos/components/watch/videos-watch.component.css' ]
+})
+
+export class VideosWatchComponent {
+  video: Video;
+
+  private client: any;
+
+  constructor(
+    private _videosService: VideosService,
+    private _routeParams: RouteParams,
+    private _elementRef: ElementRef
+  ) {
+    this.client = new WebTorrent({ dht: false });
+  }
+
+  ngOnInit() {
+    let id = this._routeParams.get('id');
+    this._videosService.getVideo(id).subscribe(
+      video => this.loadVideo(video),
+      error => alert(error)
+    );
+  }
+
+  loadVideo(video: Video) {
+    this.video = video;
+
+    this.client.add(this.video.magnetUri, (torrent) => {
+      torrent.files[0].appendTo(this._elementRef.nativeElement, (err) => {
+        if (err) {
+          alert('Cannot append the file.');
+          console.error(err);
+        }
+      })
+    })
+  }
+}
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 @@
+export interface Video {
+  _id: string;
+  name: string;
+  description: string;
+  magnetUri: string;
+}
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 @@
+import {Injectable} from 'angular2/core';
+import {Http, Response} from 'angular2/http';
+import {Observable} from 'rxjs/Rx';
+
+import {Video} from '../models/video';
+
+@Injectable()
+export class VideosService {
+  private _baseVideoUrl = '/api/v1/videos/';
+
+  constructor (private http: Http) {}
+
+  getVideos() {
+    return this.http.get(this._baseVideoUrl)
+                    .map(res => <Video[]> res.json())
+                    .catch(this.handleError);
+  }
+
+  getVideo(id: string) {
+    return this.http.get(this._baseVideoUrl + id)
+                    .map(res => <Video> res.json())
+                    .catch(this.handleError);
+  }
+
+  removeVideo(id: string) {
+    if (confirm('Are you sure?')) {
+      return this.http.delete(this._baseVideoUrl + id)
+                      .map(res => <number> res.status)
+                      .catch(this.handleError);
+    }
+  }
+
+  private handleError (error: Response) {
+    console.error(error);
+    return Observable.throw(error.json().error || 'Server error');
+  }
+}
-- 
cgit v1.2.3