aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Gruntfile.js38
-rw-r--r--client/.gitignore3
-rw-r--r--client/app/app.component.css3
-rw-r--r--client/app/app.component.html1
-rw-r--r--client/app/app.component.ts8
-rw-r--r--client/app/javascripts/index.js245
-rw-r--r--client/app/main.ts4
-rw-r--r--client/images/favicon.png (renamed from client/app/images/favicon.png)bin2335 -> 2335 bytes
-rw-r--r--client/images/loading.gif (renamed from client/app/images/loading.gif)bin673 -> 673 bytes
-rw-r--r--client/index.html40
-rw-r--r--client/package.json37
-rw-r--r--client/stylesheets/application.scss (renamed from client/app/stylesheets/application.scss)0
-rw-r--r--client/stylesheets/base.scss (renamed from client/app/stylesheets/base.scss)0
-rw-r--r--client/stylesheets/bootstrap-variables.scss (renamed from client/app/stylesheets/bootstrap-variables.scss)0
-rw-r--r--client/stylesheets/index.scss (renamed from client/app/stylesheets/index.scss)0
-rw-r--r--client/tsconfig.json18
-rw-r--r--client/typings.json6
-rw-r--r--server.js32
-rw-r--r--server/controllers/index.js4
-rw-r--r--server/controllers/views.js27
-rw-r--r--server/lib/videos.js1
22 files changed, 136 insertions, 334 deletions
diff --git a/.gitignore b/.gitignore
index 50248f5e5..aaa4db4fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,4 @@
1*.komodoproject
2node_modules 1node_modules
3.tmp
4public/javascripts/bundle.js
5schemes/ 2schemes/
6certs/ 3certs/
7logs/ 4logs/
diff --git a/Gruntfile.js b/Gruntfile.js
index 5aaa13dff..15e75247e 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -2,13 +2,11 @@
2 2
3module.exports = function (grunt) { 3module.exports = function (grunt) {
4 var paths = { 4 var paths = {
5 css: 'public/stylesheets/*.css', 5 css: 'client/stylesheets/*.css',
6 scss: 'public/stylesheets/application.scss', 6 scss: 'client/stylesheets/application.scss',
7 vendor: 'public/stylesheets/vendor', 7 vendor: 'client/stylesheets/vendor',
8 js: 'public/javascripts/*.js',
9 routes: './server/controllers/**/*.js', 8 routes: './server/controllers/**/*.js',
10 main: './server.js', 9 main: './server.js',
11 browserified: 'public/javascripts/bundle.js',
12 img: 'public/images/*.{png,jpg,jpeg,gif,webp,svg}', 10 img: 'public/images/*.{png,jpg,jpeg,gif,webp,svg}',
13 test: 'tests', 11 test: 'tests',
14 server: 'server.js' 12 server: 'server.js'
@@ -20,16 +18,6 @@ module.exports = function (grunt) {
20 grunt.initConfig({ 18 grunt.initConfig({
21 paths: paths, 19 paths: paths,
22 pkg: grunt.file.readJSON('package.json'), 20 pkg: grunt.file.readJSON('package.json'),
23 browserify: {
24 dev: {
25 src: [ paths.js, '!public/javascripts/bundle.js' ],
26 dest: paths.browserified,
27 options: {
28 browserifyOptions: { 'debug': true },
29 watch: true
30 }
31 }
32 },
33 concurrent: { 21 concurrent: {
34 options: { 22 options: {
35 logConcurrentOutput: true 23 logConcurrentOutput: true
@@ -72,22 +60,9 @@ module.exports = function (grunt) {
72 }, 60 },
73 dev: { 61 dev: {
74 files: { 62 files: {
75 'public/stylesheets/global.css': paths.scss 63 'client/stylesheets/global.css': paths.scss
76 } 64 }
77 } 65 }
78 },
79 watch: {
80 livereload: {
81 files: [ paths.jade, paths.css, paths.browserified ],
82 tasks: [ ],
83 options: {
84 livereload: true
85 }
86 },
87 sass: {
88 files: [ paths.scss ],
89 tasks: [ 'sass:dev' ]
90 }
91 } 66 }
92 }) 67 })
93 68
@@ -95,10 +70,7 @@ module.exports = function (grunt) {
95 require('load-grunt-tasks')(grunt) 70 require('load-grunt-tasks')(grunt)
96 71
97 // Build client javascript and copy bootstrap dependencies 72 // Build client javascript and copy bootstrap dependencies
98 grunt.registerTask('build', [ 'sass:dev', 'newer:browserify:dev', 'newer:copy:dev' ]) 73 grunt.registerTask('build', [ 'sass:dev', 'newer:copy:dev' ])
99
100 // Start in dev mode (reload front end files without refresh)
101 grunt.registerTask('dev', [ 'sass:dev', 'newer:browserify:dev', 'newer:copy:dev', 'concurrent:dev' ])
102 74
103 // Clean build 75 // Clean build
104 grunt.registerTask('clean', [], function () { 76 grunt.registerTask('clean', [], function () {
diff --git a/client/.gitignore b/client/.gitignore
new file mode 100644
index 000000000..ec79762bb
--- /dev/null
+++ b/client/.gitignore
@@ -0,0 +1,3 @@
1typings
2app/**/*.js
3app/**/*.map
diff --git a/client/app/app.component.css b/client/app/app.component.css
new file mode 100644
index 000000000..d627027e4
--- /dev/null
+++ b/client/app/app.component.css
@@ -0,0 +1,3 @@
1h1 {
2 font-size: 80px;
3}
diff --git a/client/app/app.component.html b/client/app/app.component.html
new file mode 100644
index 000000000..4bcdd569c
--- /dev/null
+++ b/client/app/app.component.html
@@ -0,0 +1 @@
<h1>My First Angular 2 App</h1>
diff --git a/client/app/app.component.ts b/client/app/app.component.ts
new file mode 100644
index 000000000..f0ea272af
--- /dev/null
+++ b/client/app/app.component.ts
@@ -0,0 +1,8 @@
1import {Component} from 'angular2/core';
2
3@Component({
4 selector: 'my-app',
5 templateUrl: 'app/app.component.html',
6 styleUrls: [ 'app/app.component.css' ]
7})
8export class AppComponent { }
diff --git a/client/app/javascripts/index.js b/client/app/javascripts/index.js
deleted file mode 100644
index 4910e4540..000000000
--- a/client/app/javascripts/index.js
+++ /dev/null
@@ -1,245 +0,0 @@
1;(function () {
2 'use strict'
3
4 var $ = require('jquery')
5 require('blueimp-file-upload')
6
7 var WebTorrent = require('webtorrent')
8 var client = new WebTorrent({ dht: false })
9
10 var $content = $('#ajax_load')
11
12 // Webtorrent events
13 client.on('error', function (err) {
14 console.error(err)
15 })
16
17 client.on('warning', function (err) {
18 console.warning(err)
19 })
20
21 // Events of the panel
22 $('#panel_get_videos').on('click', function () {
23 getVideos()
24 })
25
26 $('#panel_upload_video').on('click', function () {
27 uploadVideo()
28 })
29
30 $('#panel_make_friends').on('click', function () {
31 makeFriends()
32 })
33
34 $('#panel_quit_friends').on('click', function () {
35 quitFriends()
36 })
37
38 $('#search-video').on('keyup', function (e) {
39 var search = $(this).val()
40
41 if (search === '') return
42
43 if (e.keyCode === 13) {
44 $.ajax({
45 url: '/api/v1/videos/search/' + search,
46 type: 'GET',
47 dataType: 'json',
48 success: function (videos) {
49 printVideos(videos)
50 }
51 })
52 }
53 })
54
55 // Join a new network
56 function makeFriends () {
57 $.ajax({
58 url: '/api/v1/pods/makefriends',
59 type: 'GET',
60 dataType: 'json',
61 statusCode: {
62 409: function () {
63 alert('Already made friends.')
64 }
65 },
66 success: function () {
67 alert('Made friends!')
68 }
69 })
70 }
71
72 function quitFriends () {
73 $.ajax({
74 url: '/api/v1/pods/quitfriends',
75 type: 'GET',
76 dataType: 'json',
77 success: function () {
78 alert('Quit friends!')
79 }
80 })
81 }
82
83 function printVideos (videos) {
84 $content.empty()
85
86 if (videos.length === 0) {
87 $content.text('There is no videos.')
88 }
89
90 videos.forEach(function (video) {
91 var $video = $('<div></div>').addClass('video')
92
93 var $video_name = $('<span></span>').addClass('video_name').text(video.name)
94 var $video_pod = $('<span></span>').addClass('video_pod_url').text(video.podUrl)
95 var $header = $('<div></div>').append([ $video_name, $video_pod ])
96
97 if (video.namePath !== null) {
98 var $remove = $('<span></span>').addClass('span_action glyphicon glyphicon-remove')
99
100 // Remove the video
101 $remove.on('click', function () {
102 if (!confirm('Are you sure ?')) return
103
104 removeVideo(video)
105 })
106
107 $header.append($remove)
108 }
109
110 var $video_description = $('<div></div>').addClass('video_description').text(video.description)
111
112 // Get the video
113 $video_name.on('click', function () {
114 getVideo(video)
115 })
116
117 if (!video.magnetUri) {
118 $remove.css('display', 'none')
119 }
120
121 $video.append([ $header, $video_description ])
122 $content.append($video)
123 })
124 }
125
126 // Upload the video, the server will seed it
127 function uploadVideo () {
128 // Creating all the elements
129 var $video_label = $('<label></label>').attr('for', 'name').text('Video name')
130 var $video_name = $('<input></input>').addClass('form-control').attr({
131 name: 'name',
132 id: 'name'
133 })
134 var $video_block = $('<div></div>').addClass('form-group').append([ $video_label, $video_name ])
135
136 var $title = $('<h3></h3>').text('Upload a video')
137
138 var $button_text = $('<span></span>').text('Select the video...')
139 var $input_video = $('<input></input>').attr({
140 type: 'file',
141 name: 'input_video',
142 id: 'input_video'
143 })
144 var $button = $('<div></div>').addClass('btn btn-default btn-file').append([ $button_text, $input_video ])
145
146 var $description_label = $('<label></label>').attr('for', 'description').text('Description')
147 var $description_text = $('<textarea></textarea>').addClass('form-control').attr({
148 name: 'description',
149 id: 'description',
150 placeholder: 'Description...'
151 })
152 var $description = $('<div></div>').addClass('form-group').append([ $description_label, $description_text ])
153
154 var $bar = $('<progress></progress').attr('value', '0').css('display', 'none')
155 var $progress_bar = $('<div><div>').attr('id', 'progress').append($bar)
156
157 var $input_submit = $('<input></input>').addClass('btn btn-default').attr({
158 type: 'button',
159 value: 'Upload'
160 })
161
162 // JQuery plugin
163 var $form_video = $('<form></form>').append([ $video_block, $button, $progress_bar, $description, $input_submit ])
164 $form_video.fileupload({
165 singleFileUploads: true,
166 multipart: true,
167 url: '/api/v1/videos',
168 autoupload: false,
169 add: function (e, data) {
170 var $text = $('<span></span>').addClass('name_file').text(data['files'][0]['name'])
171 $text.insertAfter($button)
172 $input_submit.off('click').on('click', function () {
173 $bar.css('display', 'block')
174 data.formData = $form_video.serializeArray()
175 data.submit()
176 })
177 },
178 progressall: function (e, data) {
179 $bar.attr({
180 value: data.loaded,
181 max: data.total
182 })
183 },
184 done: function (e, data) {
185 // Print all the videos once it's finished
186 getVideos()
187 }
188 })
189
190 $content.empty()
191 $content.append([ $title, $form_video ])
192 }
193
194 // Print the list of all the videos
195 function getVideos () {
196 $.ajax({
197 url: '/api/v1/videos/',
198 dataType: 'json',
199 type: 'GET',
200 success: function (videos) {
201 printVideos(videos)
202 }
203 })
204 }
205
206 function removeVideo (video) {
207 $.ajax({
208 url: '/api/v1/videos/' + video._id,
209 type: 'DELETE',
210 success: function (response, status) {
211 getVideos()
212 }
213 })
214 }
215
216 // Get the video: add the torrent file and stream it into a video tag
217 function getVideo (video) {
218 var $waiting = $('<img></img>').addClass('center-block loading').attr('src', '/images/loading.gif')
219 $content.empty()
220 $content.append($waiting)
221
222 console.log('Getting ' + video)
223 client.add(video.magnetUri, function (torrent) {
224 var $embed = $('<div></div>').addClass('embed-responsive embed-responsive-16by9')
225
226 $content.empty()
227 $content.append($embed)
228
229 // Got torrent metadata!
230 console.log('Torrent info hash:', torrent.infoHash)
231
232 // Let's say the first file is a webm (vp8) or mp4 (h264) video...
233 var file = torrent.files[0]
234
235 file.appendTo($embed.get(0), function (err) {
236 if (err) {
237 alert('Cannot append the file.')
238 console.error(err)
239 }
240 })
241 })
242 }
243
244 getVideos()
245})()
diff --git a/client/app/main.ts b/client/app/main.ts
new file mode 100644
index 000000000..034c15573
--- /dev/null
+++ b/client/app/main.ts
@@ -0,0 +1,4 @@
1import {bootstrap} from 'angular2/platform/browser'
2import {AppComponent} from './app.component'
3
4bootstrap(AppComponent);
diff --git a/client/app/images/favicon.png b/client/images/favicon.png
index bb57ee6b0..bb57ee6b0 100644
--- a/client/app/images/favicon.png
+++ b/client/images/favicon.png
Binary files differ
diff --git a/client/app/images/loading.gif b/client/images/loading.gif
index f2a1bc0c6..f2a1bc0c6 100644
--- a/client/app/images/loading.gif
+++ b/client/images/loading.gif
Binary files differ
diff --git a/client/index.html b/client/index.html
new file mode 100644
index 000000000..15ccedb74
--- /dev/null
+++ b/client/index.html
@@ -0,0 +1,40 @@
1<html>
2 <head>
3 <title>Angular 2 QuickStart</title>
4 <meta name="viewport" content="width=device-width, initial-scale=1">
5 <link rel="stylesheet" href="styles.css">
6
7 <!-- 1. Load libraries -->
8 <!-- IE required polyfills, in this exact order -->
9 <script src="node_modules/es6-shim/es6-shim.min.js"></script>
10 <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
11 <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
12
13 <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
14 <script src="node_modules/systemjs/dist/system.src.js"></script>
15 <script src="node_modules/rxjs/bundles/Rx.js"></script>
16 <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
17 <script src="node_modules/angular2/bundles/router.dev.js"></script>
18
19 <!-- 2. Configure SystemJS -->
20 <script>
21 System.config({
22 packages: {
23 app: {
24 format: 'register',
25 defaultExtension: 'js'
26 }
27 }
28 });
29 System.import('app/main')
30 .then(null, console.error.bind(console));
31 </script>
32
33 <base href="/">
34 </head>
35
36 <!-- 3. Display the application -->
37 <body>
38 <my-app>Loading...</my-app>
39 </body>
40</html>
diff --git a/client/package.json b/client/package.json
new file mode 100644
index 000000000..171c39edf
--- /dev/null
+++ b/client/package.json
@@ -0,0 +1,37 @@
1{
2 "name": "peertube-client",
3 "version": "0.0.1",
4 "private": true,
5 "licence": "GPLv3",
6 "author": {
7 "name": "Florian Bigard",
8 "email": "florian.bigard@gmail.com",
9 "url": "http://github.com/Chocobozzz"
10 },
11 "repository": {
12 "type": "git",
13 "url": "git://github.com/Chocobozzz/PeerTube.git"
14 },
15 "scripts": {
16 "tsc": "tsc",
17 "tsc:w": "tsc -w",
18 "typings": "typings",
19 "postinstall": "typings install"
20 },
21 "license": "ISC",
22 "dependencies": {
23 "angular2": "2.0.0-beta.8",
24 "systemjs": "0.19.22",
25 "es6-promise": "^3.0.2",
26 "es6-shim": "^0.33.3",
27 "reflect-metadata": "0.1.2",
28 "rxjs": "5.0.0-beta.2",
29 "zone.js": "0.5.15"
30 },
31 "devDependencies": {
32 "concurrently": "^2.0.0",
33 "lite-server": "^2.1.0",
34 "typescript": "^1.8.2",
35 "typings":"^0.6.8"
36 }
37}
diff --git a/client/app/stylesheets/application.scss b/client/stylesheets/application.scss
index bf9ec90ab..bf9ec90ab 100644
--- a/client/app/stylesheets/application.scss
+++ b/client/stylesheets/application.scss
diff --git a/client/app/stylesheets/base.scss b/client/stylesheets/base.scss
index 37bdade1e..37bdade1e 100644
--- a/client/app/stylesheets/base.scss
+++ b/client/stylesheets/base.scss
diff --git a/client/app/stylesheets/bootstrap-variables.scss b/client/stylesheets/bootstrap-variables.scss
index 5a49649f9..5a49649f9 100644
--- a/client/app/stylesheets/bootstrap-variables.scss
+++ b/client/stylesheets/bootstrap-variables.scss
diff --git a/client/app/stylesheets/index.scss b/client/stylesheets/index.scss
index d13dcfa90..d13dcfa90 100644
--- a/client/app/stylesheets/index.scss
+++ b/client/stylesheets/index.scss
diff --git a/client/tsconfig.json b/client/tsconfig.json
new file mode 100644
index 000000000..ca58ddb89
--- /dev/null
+++ b/client/tsconfig.json
@@ -0,0 +1,18 @@
1{
2 "compilerOptions": {
3 "target": "es5",
4 "module": "system",
5 "moduleResolution": "node",
6 "sourceMap": true,
7 "emitDecoratorMetadata": true,
8 "experimentalDecorators": true,
9 "removeComments": false,
10 "noImplicitAny": false
11 },
12 "exclude": [
13 "node_modules",
14 "typings/main",
15 "typings/main.d.ts"
16 ],
17 "compileOnSave": false
18}
diff --git a/client/typings.json b/client/typings.json
new file mode 100644
index 000000000..f10b7c541
--- /dev/null
+++ b/client/typings.json
@@ -0,0 +1,6 @@
1{
2 "ambientDependencies": {
3 "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c",
4 "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#bc92442c075929849ec41d28ab618892ba493504"
5 }
6}
diff --git a/server.js b/server.js
index 5f474a196..72c2e7cd1 100644
--- a/server.js
+++ b/server.js
@@ -67,14 +67,16 @@ app.use(require('connect-livereload')({
67require('segfault-handler').registerHandler() 67require('segfault-handler').registerHandler()
68 68
69// Static files 69// Static files
70app.use(express.static(path.join(__dirname, '/app'), { maxAge: 0 })) 70app.use(express.static(path.join(__dirname, '/client'), { maxAge: 0 }))
71 71
72// API routes 72// API routes
73var api_route = '/api/' + constants.API_VERSION 73var api_route = '/api/' + constants.API_VERSION
74app.use(api_route, routes.api) 74app.use(api_route, routes.api)
75 75
76// Views routes 76// Client application
77app.use('/', routes.views) 77app.use('/*', function (req, res, next) {
78 res.sendFile(path.join(__dirname, 'client/index.html'))
79})
78 80
79// ----------- Tracker ----------- 81// ----------- Tracker -----------
80 82
@@ -108,26 +110,10 @@ app.use(function (req, res, next) {
108 next(err) 110 next(err)
109}) 111})
110 112
111// Prod : no stacktraces leaked to user 113app.use(function (err, req, res, next) {
112if (process.env.NODE_ENV === 'production') { 114 logger.error(err)
113 app.use(function (err, req, res, next) { 115 res.sendStatus(err.status || 500)
114 logger.error(err) 116})
115 res.status(err.status || 500)
116 res.render('error', {
117 message: err.message,
118 error: {}
119 })
120 })
121} else {
122 app.use(function (err, req, res, next) {
123 logger.error(err)
124 res.status(err.status || 500)
125 res.render('error', {
126 message: err.message,
127 error: err
128 })
129 })
130}
131 117
132// ----------- Create the certificates if they don't already exist ----------- 118// ----------- Create the certificates if they don't already exist -----------
133peertubeCrypto.createCertsIfNotExist(function (err) { 119peertubeCrypto.createCertsIfNotExist(function (err) {
diff --git a/server/controllers/index.js b/server/controllers/index.js
index 858f493da..7b0288dbb 100644
--- a/server/controllers/index.js
+++ b/server/controllers/index.js
@@ -3,9 +3,7 @@
3var constants = require('../initializers/constants') 3var constants = require('../initializers/constants')
4 4
5var apiController = require('./api/' + constants.API_VERSION) 5var apiController = require('./api/' + constants.API_VERSION)
6var viewsController = require('./views')
7 6
8module.exports = { 7module.exports = {
9 api: apiController, 8 api: apiController
10 views: viewsController
11} 9}
diff --git a/server/controllers/views.js b/server/controllers/views.js
deleted file mode 100644
index aa9718079..000000000
--- a/server/controllers/views.js
+++ /dev/null
@@ -1,27 +0,0 @@
1'use strict'
2
3var express = require('express')
4
5var cacheMiddleware = require('../middlewares').cache
6
7var router = express.Router()
8
9router.get(/^\/(index)?$/, cacheMiddleware.cache(), getIndex)
10router.get('/partials/:directory/:name', cacheMiddleware.cache(), getPartial)
11
12// ---------------------------------------------------------------------------
13
14module.exports = router
15
16// ---------------------------------------------------------------------------
17
18function getIndex (req, res) {
19 res.render('index')
20}
21
22function getPartial (req, res) {
23 var directory = req.params.directory
24 var name = req.params.name
25
26 res.render('partials/' + directory + '/' + name)
27}
diff --git a/server/lib/videos.js b/server/lib/videos.js
index 2d7d9500d..1e0a83b8b 100644
--- a/server/lib/videos.js
+++ b/server/lib/videos.js
@@ -2,6 +2,7 @@
2 2
3var async = require('async') 3var async = require('async')
4var config = require('config') 4var config = require('config')
5// TODO
5var path = require('path') 6var path = require('path')
6var webtorrent = require('../lib/webtorrent') 7var webtorrent = require('../lib/webtorrent')
7 8