diff --git a/.gitignore b/.gitignore index 50248f5e5..aaa4db4fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ -*.komodoproject node_modules -.tmp -public/javascripts/bundle.js schemes/ certs/ logs/ diff --git a/Gruntfile.js b/Gruntfile.js index 5aaa13dff..15e75247e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -2,13 +2,11 @@ module.exports = function (grunt) { var paths = { - css: 'public/stylesheets/*.css', - scss: 'public/stylesheets/application.scss', - vendor: 'public/stylesheets/vendor', - js: 'public/javascripts/*.js', + css: 'client/stylesheets/*.css', + scss: 'client/stylesheets/application.scss', + vendor: 'client/stylesheets/vendor', routes: './server/controllers/**/*.js', main: './server.js', - browserified: 'public/javascripts/bundle.js', img: 'public/images/*.{png,jpg,jpeg,gif,webp,svg}', test: 'tests', server: 'server.js' @@ -20,16 +18,6 @@ module.exports = function (grunt) { grunt.initConfig({ paths: paths, pkg: grunt.file.readJSON('package.json'), - browserify: { - dev: { - src: [ paths.js, '!public/javascripts/bundle.js' ], - dest: paths.browserified, - options: { - browserifyOptions: { 'debug': true }, - watch: true - } - } - }, concurrent: { options: { logConcurrentOutput: true @@ -72,22 +60,9 @@ module.exports = function (grunt) { }, dev: { files: { - 'public/stylesheets/global.css': paths.scss + 'client/stylesheets/global.css': paths.scss } } - }, - watch: { - livereload: { - files: [ paths.jade, paths.css, paths.browserified ], - tasks: [ ], - options: { - livereload: true - } - }, - sass: { - files: [ paths.scss ], - tasks: [ 'sass:dev' ] - } } }) @@ -95,10 +70,7 @@ module.exports = function (grunt) { require('load-grunt-tasks')(grunt) // Build client javascript and copy bootstrap dependencies - grunt.registerTask('build', [ 'sass:dev', 'newer:browserify:dev', 'newer:copy:dev' ]) - - // Start in dev mode (reload front end files without refresh) - grunt.registerTask('dev', [ 'sass:dev', 'newer:browserify:dev', 'newer:copy:dev', 'concurrent:dev' ]) + grunt.registerTask('build', [ 'sass:dev', 'newer:copy:dev' ]) // Clean build 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 @@ +typings +app/**/*.js +app/**/*.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 @@ +h1 { + font-size: 80px; +} 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 @@ +

My First Angular 2 App

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 @@ +import {Component} from 'angular2/core'; + +@Component({ + selector: 'my-app', + templateUrl: 'app/app.component.html', + styleUrls: [ 'app/app.component.css' ] +}) +export 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 @@ -;(function () { - 'use strict' - - var $ = require('jquery') - require('blueimp-file-upload') - - var WebTorrent = require('webtorrent') - var client = new WebTorrent({ dht: false }) - - var $content = $('#ajax_load') - - // Webtorrent events - client.on('error', function (err) { - console.error(err) - }) - - client.on('warning', function (err) { - console.warning(err) - }) - - // Events of the panel - $('#panel_get_videos').on('click', function () { - getVideos() - }) - - $('#panel_upload_video').on('click', function () { - uploadVideo() - }) - - $('#panel_make_friends').on('click', function () { - makeFriends() - }) - - $('#panel_quit_friends').on('click', function () { - quitFriends() - }) - - $('#search-video').on('keyup', function (e) { - var search = $(this).val() - - if (search === '') return - - if (e.keyCode === 13) { - $.ajax({ - url: '/api/v1/videos/search/' + search, - type: 'GET', - dataType: 'json', - success: function (videos) { - printVideos(videos) - } - }) - } - }) - - // Join a new network - function makeFriends () { - $.ajax({ - url: '/api/v1/pods/makefriends', - type: 'GET', - dataType: 'json', - statusCode: { - 409: function () { - alert('Already made friends.') - } - }, - success: function () { - alert('Made friends!') - } - }) - } - - function quitFriends () { - $.ajax({ - url: '/api/v1/pods/quitfriends', - type: 'GET', - dataType: 'json', - success: function () { - alert('Quit friends!') - } - }) - } - - function printVideos (videos) { - $content.empty() - - if (videos.length === 0) { - $content.text('There is no videos.') - } - - videos.forEach(function (video) { - var $video = $('
').addClass('video') - - var $video_name = $('').addClass('video_name').text(video.name) - var $video_pod = $('').addClass('video_pod_url').text(video.podUrl) - var $header = $('
').append([ $video_name, $video_pod ]) - - if (video.namePath !== null) { - var $remove = $('').addClass('span_action glyphicon glyphicon-remove') - - // Remove the video - $remove.on('click', function () { - if (!confirm('Are you sure ?')) return - - removeVideo(video) - }) - - $header.append($remove) - } - - var $video_description = $('
').addClass('video_description').text(video.description) - - // Get the video - $video_name.on('click', function () { - getVideo(video) - }) - - if (!video.magnetUri) { - $remove.css('display', 'none') - } - - $video.append([ $header, $video_description ]) - $content.append($video) - }) - } - - // Upload the video, the server will seed it - function uploadVideo () { - // Creating all the elements - var $video_label = $('').attr('for', 'name').text('Video name') - var $video_name = $('').addClass('form-control').attr({ - name: 'name', - id: 'name' - }) - var $video_block = $('
').addClass('form-group').append([ $video_label, $video_name ]) - - var $title = $('

').text('Upload a video') - - var $button_text = $('').text('Select the video...') - var $input_video = $('').attr({ - type: 'file', - name: 'input_video', - id: 'input_video' - }) - var $button = $('
').addClass('btn btn-default btn-file').append([ $button_text, $input_video ]) - - var $description_label = $('').attr('for', 'description').text('Description') - var $description_text = $('').addClass('form-control').attr({ - name: 'description', - id: 'description', - placeholder: 'Description...' - }) - var $description = $('
').addClass('form-group').append([ $description_label, $description_text ]) - - var $bar = $('
').attr('id', 'progress').append($bar) - - var $input_submit = $('').addClass('btn btn-default').attr({ - type: 'button', - value: 'Upload' - }) - - // JQuery plugin - var $form_video = $('
').append([ $video_block, $button, $progress_bar, $description, $input_submit ]) - $form_video.fileupload({ - singleFileUploads: true, - multipart: true, - url: '/api/v1/videos', - autoupload: false, - add: function (e, data) { - var $text = $('').addClass('name_file').text(data['files'][0]['name']) - $text.insertAfter($button) - $input_submit.off('click').on('click', function () { - $bar.css('display', 'block') - data.formData = $form_video.serializeArray() - data.submit() - }) - }, - progressall: function (e, data) { - $bar.attr({ - value: data.loaded, - max: data.total - }) - }, - done: function (e, data) { - // Print all the videos once it's finished - getVideos() - } - }) - - $content.empty() - $content.append([ $title, $form_video ]) - } - - // Print the list of all the videos - function getVideos () { - $.ajax({ - url: '/api/v1/videos/', - dataType: 'json', - type: 'GET', - success: function (videos) { - printVideos(videos) - } - }) - } - - function removeVideo (video) { - $.ajax({ - url: '/api/v1/videos/' + video._id, - type: 'DELETE', - success: function (response, status) { - getVideos() - } - }) - } - - // Get the video: add the torrent file and stream it into a video tag - function getVideo (video) { - var $waiting = $('').addClass('center-block loading').attr('src', '/images/loading.gif') - $content.empty() - $content.append($waiting) - - console.log('Getting ' + video) - client.add(video.magnetUri, function (torrent) { - var $embed = $('
').addClass('embed-responsive embed-responsive-16by9') - - $content.empty() - $content.append($embed) - - // Got torrent metadata! - console.log('Torrent info hash:', torrent.infoHash) - - // Let's say the first file is a webm (vp8) or mp4 (h264) video... - var file = torrent.files[0] - - file.appendTo($embed.get(0), function (err) { - if (err) { - alert('Cannot append the file.') - console.error(err) - } - }) - }) - } - - getVideos() -})() 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 @@ +import {bootstrap} from 'angular2/platform/browser' +import {AppComponent} from './app.component' + +bootstrap(AppComponent); diff --git a/client/app/images/favicon.png b/client/images/favicon.png similarity index 100% rename from client/app/images/favicon.png rename to client/images/favicon.png diff --git a/client/app/images/loading.gif b/client/images/loading.gif similarity index 100% rename from client/app/images/loading.gif rename to client/images/loading.gif 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 @@ + + + Angular 2 QuickStart + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + 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 @@ +{ + "name": "peertube-client", + "version": "0.0.1", + "private": true, + "licence": "GPLv3", + "author": { + "name": "Florian Bigard", + "email": "florian.bigard@gmail.com", + "url": "http://github.com/Chocobozzz" + }, + "repository": { + "type": "git", + "url": "git://github.com/Chocobozzz/PeerTube.git" + }, + "scripts": { + "tsc": "tsc", + "tsc:w": "tsc -w", + "typings": "typings", + "postinstall": "typings install" + }, + "license": "ISC", + "dependencies": { + "angular2": "2.0.0-beta.8", + "systemjs": "0.19.22", + "es6-promise": "^3.0.2", + "es6-shim": "^0.33.3", + "reflect-metadata": "0.1.2", + "rxjs": "5.0.0-beta.2", + "zone.js": "0.5.15" + }, + "devDependencies": { + "concurrently": "^2.0.0", + "lite-server": "^2.1.0", + "typescript": "^1.8.2", + "typings":"^0.6.8" + } +} diff --git a/client/app/stylesheets/application.scss b/client/stylesheets/application.scss similarity index 100% rename from client/app/stylesheets/application.scss rename to client/stylesheets/application.scss diff --git a/client/app/stylesheets/base.scss b/client/stylesheets/base.scss similarity index 100% rename from client/app/stylesheets/base.scss rename to client/stylesheets/base.scss diff --git a/client/app/stylesheets/bootstrap-variables.scss b/client/stylesheets/bootstrap-variables.scss similarity index 100% rename from client/app/stylesheets/bootstrap-variables.scss rename to client/stylesheets/bootstrap-variables.scss diff --git a/client/app/stylesheets/index.scss b/client/stylesheets/index.scss similarity index 100% rename from client/app/stylesheets/index.scss rename to 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 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "system", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": false + }, + "exclude": [ + "node_modules", + "typings/main", + "typings/main.d.ts" + ], + "compileOnSave": false +} 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 @@ +{ + "ambientDependencies": { + "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", + "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#bc92442c075929849ec41d28ab618892ba493504" + } +} 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')({ require('segfault-handler').registerHandler() // Static files -app.use(express.static(path.join(__dirname, '/app'), { maxAge: 0 })) +app.use(express.static(path.join(__dirname, '/client'), { maxAge: 0 })) // API routes var api_route = '/api/' + constants.API_VERSION app.use(api_route, routes.api) -// Views routes -app.use('/', routes.views) +// Client application +app.use('/*', function (req, res, next) { + res.sendFile(path.join(__dirname, 'client/index.html')) +}) // ----------- Tracker ----------- @@ -108,26 +110,10 @@ app.use(function (req, res, next) { next(err) }) -// Prod : no stacktraces leaked to user -if (process.env.NODE_ENV === 'production') { - app.use(function (err, req, res, next) { - logger.error(err) - res.status(err.status || 500) - res.render('error', { - message: err.message, - error: {} - }) - }) -} else { - app.use(function (err, req, res, next) { - logger.error(err) - res.status(err.status || 500) - res.render('error', { - message: err.message, - error: err - }) - }) -} +app.use(function (err, req, res, next) { + logger.error(err) + res.sendStatus(err.status || 500) +}) // ----------- Create the certificates if they don't already exist ----------- peertubeCrypto.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 @@ var constants = require('../initializers/constants') var apiController = require('./api/' + constants.API_VERSION) -var viewsController = require('./views') module.exports = { - api: apiController, - views: viewsController + api: apiController } 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 @@ -'use strict' - -var express = require('express') - -var cacheMiddleware = require('../middlewares').cache - -var router = express.Router() - -router.get(/^\/(index)?$/, cacheMiddleware.cache(), getIndex) -router.get('/partials/:directory/:name', cacheMiddleware.cache(), getPartial) - -// --------------------------------------------------------------------------- - -module.exports = router - -// --------------------------------------------------------------------------- - -function getIndex (req, res) { - res.render('index') -} - -function getPartial (req, res) { - var directory = req.params.directory - var name = req.params.name - - res.render('partials/' + directory + '/' + name) -} 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 @@ var async = require('async') var config = require('config') +// TODO var path = require('path') var webtorrent = require('../lib/webtorrent')