Prepare Angular routes

pull/10/head
Chocobozzz 2016-03-07 14:48:46 +01:00
parent b9a3e09ad5
commit 6f4e252246
22 changed files with 136 additions and 334 deletions

3
.gitignore vendored
View File

@ -1,7 +1,4 @@
*.komodoproject
node_modules
.tmp
public/javascripts/bundle.js
schemes/
certs/
logs/

View File

@ -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 () {

3
client/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
typings
app/**/*.js
app/**/*.map

View File

@ -0,0 +1,3 @@
h1 {
font-size: 80px;
}

View File

@ -0,0 +1 @@
<h1>My First Angular 2 App</h1>

View File

@ -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 { }

View File

@ -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 = $('<div></div>').addClass('video')
var $video_name = $('<span></span>').addClass('video_name').text(video.name)
var $video_pod = $('<span></span>').addClass('video_pod_url').text(video.podUrl)
var $header = $('<div></div>').append([ $video_name, $video_pod ])
if (video.namePath !== null) {
var $remove = $('<span></span>').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 = $('<div></div>').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 = $('<label></label>').attr('for', 'name').text('Video name')
var $video_name = $('<input></input>').addClass('form-control').attr({
name: 'name',
id: 'name'
})
var $video_block = $('<div></div>').addClass('form-group').append([ $video_label, $video_name ])
var $title = $('<h3></h3>').text('Upload a video')
var $button_text = $('<span></span>').text('Select the video...')
var $input_video = $('<input></input>').attr({
type: 'file',
name: 'input_video',
id: 'input_video'
})
var $button = $('<div></div>').addClass('btn btn-default btn-file').append([ $button_text, $input_video ])
var $description_label = $('<label></label>').attr('for', 'description').text('Description')
var $description_text = $('<textarea></textarea>').addClass('form-control').attr({
name: 'description',
id: 'description',
placeholder: 'Description...'
})
var $description = $('<div></div>').addClass('form-group').append([ $description_label, $description_text ])
var $bar = $('<progress></progress').attr('value', '0').css('display', 'none')
var $progress_bar = $('<div><div>').attr('id', 'progress').append($bar)
var $input_submit = $('<input></input>').addClass('btn btn-default').attr({
type: 'button',
value: 'Upload'
})
// JQuery plugin
var $form_video = $('<form></form>').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 = $('<span></span>').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 = $('<img></img>').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 = $('<div></div>').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()
})()

4
client/app/main.ts Normal file
View File

@ -0,0 +1,4 @@
import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'
bootstrap(AppComponent);

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

40
client/index.html Normal file
View File

@ -0,0 +1,40 @@
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- IE required polyfills, in this exact order -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
<base href="/">
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>

37
client/package.json Normal file
View File

@ -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"
}
}

18
client/tsconfig.json Normal file
View File

@ -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
}

6
client/typings.json Normal file
View File

@ -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"
}
}

View File

@ -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) {

View File

@ -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
}

View File

@ -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)
}

View File

@ -2,6 +2,7 @@
var async = require('async')
var config = require('config')
// TODO
var path = require('path')
var webtorrent = require('../lib/webtorrent')