]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Angular application :first draft
authorChocobozzz <florian.bigard@gmail.com>
Mon, 14 Mar 2016 12:50:19 +0000 (13:50 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Mon, 14 Mar 2016 12:50:19 +0000 (13:50 +0100)
34 files changed:
.gitignore
client/.gitignore
client/angular/app/app.component.html [new file with mode: 0644]
client/angular/app/app.component.scss [new file with mode: 0644]
client/angular/app/app.component.ts [new file with mode: 0644]
client/angular/bootstrap.ts [moved from client/components/bootstrap.ts with 100% similarity]
client/angular/friends/services/friends.service.ts [new file with mode: 0644]
client/angular/videos/components/add/videos-add.component.html [new file with mode: 0644]
client/angular/videos/components/add/videos-add.component.scss [new file with mode: 0644]
client/angular/videos/components/add/videos-add.component.ts [new file with mode: 0644]
client/angular/videos/components/list/videos-list.component.html [new file with mode: 0644]
client/angular/videos/components/list/videos-list.component.scss [new file with mode: 0644]
client/angular/videos/components/list/videos-list.component.ts [new file with mode: 0644]
client/angular/videos/components/watch/videos-watch.component.html [new file with mode: 0644]
client/angular/videos/components/watch/videos-watch.component.scss [moved from client/components/app/app.component.scss with 100% similarity]
client/angular/videos/components/watch/videos-watch.component.ts [new file with mode: 0644]
client/angular/videos/models/video.ts [new file with mode: 0644]
client/angular/videos/services/videos.service.ts [new file with mode: 0644]
client/components/app/app.component.html [deleted file]
client/components/app/app.component.ts [deleted file]
client/components/videos/add/videos-add.component.ts [deleted file]
client/components/videos/list/videos-list.component.ts [deleted file]
client/components/videos/watch/videos-watch.component.ts [deleted file]
client/index.html
client/package.json
client/stylesheets/application.scss
client/stylesheets/bootstrap-variables.scss
client/stylesheets/index.scss
client/typings.json
package.json
server/controllers/api/v1/index.js
server/controllers/api/v1/pods.js
server/controllers/api/v1/remoteVideos.js
server/controllers/api/v1/videos.js

index aaa4db4fbf0903be99c690e0edd79e2377c8b8bb..6c0165c4157cd06d995e751ec7618a49220437ec 100644 (file)
@@ -10,3 +10,4 @@ test5/
 test6/
 public/stylesheets/global.css
 public/stylesheets/vendor
+uploads
index 439f0c025bbfba357de3d079f8357c92b5736202..4bb21ebabb0812c260ee8817aefd7b52f9d217be 100644 (file)
@@ -1,5 +1,5 @@
 typings
-components/**/*.js
-components/**/*.map
+angular/**/*.js
+angular/**/*.map
+angular/**/*.css
 stylesheets/index.css
-components/**/*.css
diff --git a/client/angular/app/app.component.html b/client/angular/app/app.component.html
new file mode 100644 (file)
index 0000000..590efa0
--- /dev/null
@@ -0,0 +1,37 @@
+<div class="container">
+
+  <div class="row">
+
+    <menu class="col-md-2">
+      <div id="panel_get_videos" class="panel_button">
+        <span class="glyphicon glyphicon-list"></span>
+        <a [routerLink]="['VideosList']">Get videos</a>
+      </div>
+
+      <div id="panel_upload_video" class="panel_button">
+        <span class="glyphicon glyphicon-cloud-upload"></span>
+        <a [routerLink]="['VideosAdd']">Upload a video</a>
+      </div>
+
+      <div id="panel_make_friends" class="panel_button">
+        <span class="glyphicon glyphicon-user"></span>
+        <a (click)='makeFriends()'>Make friends</a>
+      </div>
+
+      <div id="panel_quit_friends" class="panel_button">
+        <span class="glyphicon glyphicon-plane"></span>
+        <a (click)='quitFriends()'>Quit friends</a>
+      </div>
+    </menu>
+
+    <div class="col-md-9 router_outler_container">
+      <router-outlet></router-outlet>
+    </div>
+
+  </div>
+
+
+  <footer>
+    PeerTube, CopyLeft 2015-2016
+  </footer>
+</div>
diff --git a/client/angular/app/app.component.scss b/client/angular/app/app.component.scss
new file mode 100644 (file)
index 0000000..03ecba8
--- /dev/null
@@ -0,0 +1,28 @@
+menu {
+  min-height: 300px;
+  height: 100%;
+  margin-right: 20px;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+
+  .panel_button {
+    margin: 8px;
+    cursor: pointer;
+    transition: margin 0.2s;
+
+    &:hover {
+      margin-left: 15px;
+    }
+
+    a {
+      color: #333333;
+    }
+  }
+
+  .glyphicon {
+    margin: 5px;
+  }
+}
+
+footer {
+  margin-top: 30px;
+}
diff --git a/client/angular/app/app.component.ts b/client/angular/app/app.component.ts
new file mode 100644 (file)
index 0000000..3d41183
--- /dev/null
@@ -0,0 +1,63 @@
+import { Component, ElementRef } from 'angular2/core';
+import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
+import {HTTP_PROVIDERS} from 'angular2/http';
+
+import { VideosAddComponent } from '../videos/components/add/videos-add.component';
+import { VideosListComponent } from '../videos/components/list/videos-list.component';
+import { VideosWatchComponent } from '../videos/components/watch/videos-watch.component';
+import { VideosService } from '../videos/services/videos.service';
+import { FriendsService } from '../friends/services/friends.service';
+
+@RouteConfig([
+  {
+    path: '/videos/list',
+    name: 'VideosList',
+    component: VideosListComponent,
+    useAsDefault: true
+  },
+  {
+    path: '/videos/watch/:id',
+    name: 'VideosWatch',
+    component: VideosWatchComponent
+  },
+  {
+    path: '/videos/add',
+    name: 'VideosAdd',
+    component: VideosAddComponent
+  }
+])
+
+@Component({
+    selector: 'my-app',
+    templateUrl: 'app/angular/app/app.component.html',
+    styleUrls: [ 'app/angular/app/app.component.css' ],
+    directives: [ ROUTER_DIRECTIVES ],
+    providers: [ ROUTER_PROVIDERS, HTTP_PROVIDERS, ElementRef, VideosService, FriendsService ]
+})
+
+export class AppComponent {
+  constructor(private _friendsService: FriendsService) {}
+
+  makeFriends() {
+    this._friendsService.makeFriends().subscribe(
+      status => {
+        if (status === 409) {
+          alert('Already made friends!');
+        }
+        else {
+          alert('Made friends!');
+        }
+      },
+      error => alert(error)
+    )
+  }
+
+  quitFriends() {
+    this._friendsService.quitFriends().subscribe(
+      status => {
+          alert('Quit friends!');
+      },
+      error => alert(error)
+    )
+  }
+}
diff --git a/client/angular/friends/services/friends.service.ts b/client/angular/friends/services/friends.service.ts
new file mode 100644 (file)
index 0000000..a34ef0d
--- /dev/null
@@ -0,0 +1,27 @@
+import {Injectable} from 'angular2/core';
+import {Http, Response, Headers, RequestOptions} from 'angular2/http';
+import {Observable} from 'rxjs/Rx';
+
+@Injectable()
+export class FriendsService {
+  private _baseFriendsUrl = '/api/v1/pods/';
+
+  constructor (private http: Http) {}
+
+  makeFriends() {
+    return this.http.get(this._baseFriendsUrl + 'makefriends')
+                    .map(res => <number> res.status)
+                    .catch(this.handleError);
+  }
+
+  quitFriends() {
+    return this.http.get(this._baseFriendsUrl + 'quitfriends')
+                    .map(res => <number> res.status)
+                    .catch(this.handleError);
+  }
+
+  private handleError (error: Response) {
+    console.error(error);
+    return Observable.throw(error.json().error || 'Server error');
+  }
+}
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 (file)
index 0000000..5f28ae6
--- /dev/null
@@ -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 (file)
index 0000000..f418708
--- /dev/null
@@ -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 (file)
index 0000000..97e3bb3
--- /dev/null
@@ -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 (file)
index 0000000..7ecdace
--- /dev/null
@@ -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 (file)
index 0000000..82ddd80
--- /dev/null
@@ -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 (file)
index 0000000..e5af874
--- /dev/null
@@ -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 (file)
index 0000000..e472227
--- /dev/null
@@ -0,0 +1,2 @@
+<div class="embed-responsive embed-responsive-19by9">
+</div>
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 (file)
index 0000000..e3a9738
--- /dev/null
@@ -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 (file)
index 0000000..2f998c4
--- /dev/null
@@ -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 (file)
index 0000000..784eec6
--- /dev/null
@@ -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');
+  }
+}
diff --git a/client/components/app/app.component.html b/client/components/app/app.component.html
deleted file mode 100644 (file)
index 5a841ca..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<div class="container">
-  <div class="row">
-    <menu class="col-md-2">
-      <div id="panel_get_videos" class="panel_button">
-        <a [routerLink]="['VideosList']" class="glyphicon glyphicon-list">Get videos</a>
-      </div>
-
-      <div id="panel_upload_video" class="panel_button">
-        <a [routerLink]="['VideosAdd']" class="glyphicon glyphicon-cloud-upload">Upload a video</a>
-      </div>
-
-      <div id="panel_make_friends" class="panel_button">
-        <a (click)='makeFriends()' class="glyphicon glyphicon-user">Make friends</a>
-      </div>
-
-      <div id="panel_quit_friends" class="panel_button">
-        <a (click)='quitFriends()' class="glyphicon glyphicon-plane">Quit friends</a>
-      </div>
-    </menu>
-
-    <router-outlet class="col-md-9"></router-outlet>
-  </div>
-</div>
diff --git a/client/components/app/app.component.ts b/client/components/app/app.component.ts
deleted file mode 100644 (file)
index e2cebf5..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import {Component} from 'angular2/core';
-import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
-
-import { VideosAddComponent } from '../videos/add/videos-add.component';
-import { VideosListComponent } from '../videos/list/videos-list.component';
-import { VideosWatchComponent } from '../videos/watch/videos-watch.component';
-
-@RouteConfig([
-  {
-    path: '/videos/list',
-    name: 'VideosList',
-    component: VideosListComponent,
-    useAsDefault: true
-  },
-  {
-    path: '/videos/watch/:id',
-    name: 'VideosWatch',
-    component: VideosWatchComponent
-  },
-  {
-    path: '/videos/add',
-    name: 'VideosAdd',
-    component: VideosAddComponent
-  }
-])
-
-@Component({
-    selector: 'my-app',
-    templateUrl: 'app/components/app/app.component.html',
-    styleUrls: [ 'app/components/app/app.component.css' ],
-    directives: [ ROUTER_DIRECTIVES ],
-    providers: [ ROUTER_PROVIDERS ]
-})
-
-export class AppComponent {
-  makeFriends() {
-    alert('make Friends');
-  }
-
-  quitFriends() {
-    alert('quit Friends');
-  }
-}
diff --git a/client/components/videos/add/videos-add.component.ts b/client/components/videos/add/videos-add.component.ts
deleted file mode 100644 (file)
index 0db7c01..0000000
+++ /dev/null
@@ -1 +0,0 @@
-export class VideosAddComponent {}
diff --git a/client/components/videos/list/videos-list.component.ts b/client/components/videos/list/videos-list.component.ts
deleted file mode 100644 (file)
index 54470a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-export class VideosListComponent {}
diff --git a/client/components/videos/watch/videos-watch.component.ts b/client/components/videos/watch/videos-watch.component.ts
deleted file mode 100644 (file)
index 84daef3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-export class VideosWatchComponent {}
index f971b9fdba5d26f752051d042f2703494dec889f..4b273aae4c711012852464ed95b4e334db98ab7d 100644 (file)
@@ -1,34 +1,40 @@
 <html>
   <head>
-    <title>Angular 2 QuickStart</title>
+    <title>PeerTube</title>
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link rel="stylesheet" href="/stylesheets/index.css">
+    <link rel="stylesheet" href="/app/stylesheets/index.css">
 
     <!-- 1. Load libraries -->
     <!-- IE required polyfills, in this exact order -->
-    <script src="app/node_modules/es6-shim/es6-shim.min.js"></script>
-    <script src="app/node_modules/systemjs/dist/system-polyfills.js"></script>
-    <script src="app/node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
+    <script src="/app/node_modules/es6-shim/es6-shim.min.js"></script>
+    <script src="/app/node_modules/systemjs/dist/system-polyfills.js"></script>
+    <script src="/app/node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
+
+    <script src="/app/node_modules/angular2/bundles/angular2-polyfills.js"></script>
+    <script src="/app/node_modules/systemjs/dist/system.src.js"></script>
+    <script src="/app/node_modules/rxjs/bundles/Rx.js"></script>
+    <script src="/app/node_modules/angular2/bundles/angular2.dev.js"></script>
+    <script src="/app/node_modules/angular2/bundles/router.dev.js"></script>
+    <script src="/app/node_modules/angular2/bundles/http.dev.js"></script>
+    <script src="/app/node_modules/jquery/dist/jquery.js"></script>
+    <script src="/app/node_modules/jquery.ui.widget/jquery.ui.widget.js"></script>
+    <script src="/app/node_modules/blueimp-file-upload/js/jquery.fileupload.js"></script>
+    <script src="/app/node_modules/webtorrent/webtorrent.min.js"></script>
 
-    <script src="app/node_modules/angular2/bundles/angular2-polyfills.js"></script>
-    <script src="app/node_modules/systemjs/dist/system.src.js"></script>
-    <script src="app/node_modules/rxjs/bundles/Rx.js"></script>
-    <script src="app/node_modules/angular2/bundles/angular2.dev.js"></script>
-    <script src="app/node_modules/angular2/bundles/router.dev.js"></script>
 
     <!-- 2. Configure SystemJS -->
     <script>
       System.config({
         packages: {
-          app: {
+          '/app': {
             components: {
               format: 'register',
               defaultExtension: 'js'
             }
-          }
+          },
         }
       });
-      System.import('app/components/bootstrap')
+      System.import('/app/angular/bootstrap')
             .then(null, console.error.bind(console));
     </script>
 
index 71f3059142e0ae4d3f6af4fedd8749b2a3e5b804..dbb065974201b0876b625a0d15bb91e1ddd55819 100644 (file)
   },
   "license": "ISC",
   "dependencies": {
-    "angular2": "2.0.0-beta.8",
+    "angular2": "2.0.0-beta.9",
+    "blueimp-file-upload": "^9.12.1",
     "bootstrap-sass": "^3.3.6",
     "es6-promise": "^3.0.2",
     "es6-shim": "^0.33.3",
+    "jquery": "^2.2.1",
+    "jquery.ui.widget": "^1.10.3",
     "reflect-metadata": "0.1.2",
     "rxjs": "5.0.0-beta.2",
     "systemjs": "0.19.22",
+    "webtorrent": "^0.85.1",
     "zone.js": "0.5.15"
   },
   "devDependencies": {
index bf9ec90ab082f2a0216db02ece1e8867519b84f5..d1b309907e271aaa4bea6935742131b3da0f9a98 100644 (file)
@@ -1,6 +1,6 @@
-$icon-font-path: "/stylesheets/vendor/fonts/bootstrap/";
+$icon-font-path: "/app/node_modules/bootstrap-sass/assets/fonts/bootstrap/";
 
 @import "bootstrap-variables";
 @import "_bootstrap";
-@import "base";
-@import "index";
\ No newline at end of file
+@import "base.scss";
+@import "index.scss";
index 5a49649f9cd311022a8e5357ee4bd077337a3c4b..a2472f357efd71db9b598aa195ab89fea2173cec 100644 (file)
 // $line-height-large:         1.3333333 // extra decimals for Win 8.1 Chrome
 // $line-height-small:         1.5
 
-$border-radius-base:        0;
-$border-radius-large:       0;
-$border-radius-small:       0;
+// $border-radius-base:        0;
+// $border-radius-large:       0;
+// $border-radius-small:       0;
 
 //** Global color for active items (e.g., navs or dropdowns).
 // $component-active-color:    #fff
index d13dcfa90eeb115799fbadeb0e0cae99020a16d3..5cba54705c69a1a532e2cabf28b1f1da2a74f591 100644 (file)
@@ -1,88 +1,5 @@
-.span_action {
-  margin: 5px;
-  cursor: pointer;
-}
-
 header div {
   height: 50px;
   line-height: 25px;
   margin-bottom: 50px;
 }
-
-menu {
-  margin-right: 20px;
-  border-right: 1px solid rgba(0, 0, 0, 0.2);
-}
-
-menu .panel_button {
-  margin: 8px;
-  cursor: pointer;
-  transition: margin 0.2s;
-}
-
-menu .panel_button:hover {
-  margin-left: 15px;
-}
-
-menu .glyphicon {
-  margin: 5px;
-}
-
-#ajax_load {
-  min-height: 500px;
-}
-
-.loading {
-  display: inline-block;
-  margin-top: 100px;
-}
-
-.video {
-  margin-bottom: 10px;
-  transition: margin 0.5s ease;
-}
-
-.video:hover {
-  margin-left: 5px;
-}
-
-.video_name {
-  cursor: pointer;
-  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;
-}
-
-.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;
-}
\ No newline at end of file
index f10b7c541627ed0b8679f631f082bd68828cd51a..0e3ed5a01fbb28c8b203a9c9a6ffe2b83d8c4063 100644 (file)
@@ -1,6 +1,9 @@
 {
   "ambientDependencies": {
     "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c",
-    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#bc92442c075929849ec41d28ab618892ba493504"
+    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#bc92442c075929849ec41d28ab618892ba493504",
+    "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#abc2bcfb8524b1e027e6298d3348012b5b06eda5",
+    "parse-torrent": "github:DefinitelyTyped/DefinitelyTyped/parse-torrent/parse-torrent.d.ts#abc2bcfb8524b1e027e6298d3348012b5b06eda5",
+    "webtorrent": "github:DefinitelyTyped/DefinitelyTyped/webtorrent/webtorrent.d.ts#abc2bcfb8524b1e027e6298d3348012b5b06eda5"
   }
 }
index aabd5616f5f7686d48758dae703e43c495e9d4b9..36730aaa075bd06b25e6a6f1ce4be869416fb54c 100644 (file)
   },
   "scripts": {
     "build": "concurrently \"npm run client:sass\" \"npm run client:tsc\"",
+
     "client:clean": "concurrently \"npm run client:tsc:clean\" \"npm run client:sass:clean\"",
+
     "client:sass:index": "npm run client:sass:index:clean && cd client && node-sass --include-path node_modules/bootstrap-sass/assets/stylesheets/ stylesheets/application.scss stylesheets/index.css",
     "client:sass:index:watch": "cd client && node-sass -w --include-path node_modules/bootstrap-sass/assets/stylesheets/ stylesheets/application.scss stylesheets/index.css",
     "client:sass:index:clean": "cd client && rm -f stylesheets/index.css",
-    "client:sass:components": "cd client && node-sass components/ --output components/",
-    "client:sass:components:watch": "cd client && node-sass -w components/ --output components/",
-    "client:sass:components:clean": "cd client && rm -f components/**/*.css",
-    "client:sass": "concurrently \"npm run client:sass:index\" \"npm run client:sass:components\"",
-    "client:sass:watch": "concurrently \"npm run client:sass:index:watch\" \"npm run client:sass:components:watch\"",
-    "client:sass:clean": "concurrently \"npm run client:sass:index:clean\" \"npm run client:sass:components:clean\"",
+
+    "client:sass:angular": "cd client && node-sass angular/ --output angular/",
+    "client:sass:angular:watch": "cd client && node-sass -w angular/ --output angular/",
+    "client:sass:angular:clean": "cd client && rm -f angular/**/*.css",
+
+    "client:sass": "concurrently \"npm run client:sass:index\" \"npm run client:sass:angular\"",
+    "client:sass:watch": "concurrently \"npm run client:sass:index:watch\" \"npm run client:sass:angular:watch\"",
+    "client:sass:clean": "concurrently \"npm run client:sass:index:clean\" \"npm run client:sass:angular:clean\"",
+
     "client:tsc": "cd client && npm run tsc",
     "client:tsc:watch": "cd client && npm run tsc:w",
-    "client:tsc:clean": "cd client && rm -f components/**/*.js components/**/*.js.map",
+    "client:tsc:clean": "cd client && find angular -regextype posix-egrep -regex \".*\\.(js|map)$\" -exec rm -f {} \\;",
+
     "dev": "npm run build && concurrently \"npm run livereload\" \"npm run client:tsc:watch\" \"npm run client:sass:watch\" \"npm start\"",
     "livereload": "livereload ./client",
     "start": "node server",
@@ -47,7 +53,6 @@
     "electron-spawn": "https://github.com/Chocobozzz/electron-spawn",
     "express": "^4.12.4",
     "express-validator": "^2.11.0",
-    "jquery": "^2.1.4",
     "lodash-node": "^3.10.2",
     "mkdirp": "^0.5.1",
     "mongoose": "^4.0.5",
index abbc5eb60420235c66a392d583ec8af4904be89f..b562bc2afa6cd6e1af70b606697de11edc732e88 100644 (file)
@@ -20,5 +20,5 @@ module.exports = router
 // ---------------------------------------------------------------------------
 
 function badRequest (req, res, next) {
-  res.sendStatus(400)
+  res.type('json').status(400).end()
 }
index c93a86ee85fc4d73c6e7127bb03b73b41f0d7249..fa98329147768c2a42fe46116c560e1735c66e9f 100644 (file)
@@ -66,7 +66,7 @@ function makeFriends (req, res, next) {
   friends.makeFriends(function (err) {
     if (err) return next(err)
 
-    res.sendStatus(204)
+    res.type('json').status(204).end()
   })
 }
 
@@ -79,7 +79,7 @@ function removePods (req, res, next) {
       if (err) logger.error('Cannot remove all remote videos of %s.', url)
       else logger.info('%s pod removed.', url)
 
-      res.sendStatus(204)
+      res.type('json').status(204).end()
     })
   })
 }
@@ -88,6 +88,6 @@ function quitFriends (req, res, next) {
   friends.quitFriends(function (err) {
     if (err) return next(err)
 
-    res.sendStatus(204)
+    res.type('json').status(204).end()
   })
 }
index 475a874cf6da408105d8a2978d7203517dd56b17..7622e39f575b648e83951212bf667a104c5b7eac 100644 (file)
@@ -48,6 +48,6 @@ function removeRemoteVideo (req, res, next) {
   videos.removeRemotesOfByMagnetUris(url, magnetUris, function (err) {
     if (err) return next(err)
 
-    res.sendStatus(204)
+    res.type('json').status(204).end()
   })
 }
index 620711925ce1e6ec73cc984a882a49c08d499cb2..9398aabb75fe1b6139054bf76befd1b14e574ae1 100644 (file)
@@ -77,7 +77,7 @@ function addVideo (req, res, next) {
       friends.addVideoToFriends(video_data)
 
       // TODO : include Location of the new video
-      res.sendStatus(201)
+      res.type('json').status(201).end()
     })
   })
 }
@@ -87,7 +87,7 @@ function getVideos (req, res, next) {
     if (err) return next(err)
 
     if (video === null) {
-      return res.sendStatus(404)
+      res.type('json').status(204).end()
     }
 
     res.json(video)
@@ -117,7 +117,7 @@ function removeVideo (req, res, next) {
         }
 
         friends.removeVideoToFriends(params)
-        res.sendStatus(204)
+        res.type('json').status(204).end()
       })
     })
   })