Skip to content

Commit

Permalink
Sat Jun 20 20:04:43 HKT 2015
Browse files Browse the repository at this point in the history
  • Loading branch information
jackhftang committed Jun 20, 2015
0 parents commit a097b98
Show file tree
Hide file tree
Showing 45 changed files with 3,476 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
www
config.js

.idea
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# hike4hk-web
11 changes: 11 additions & 0 deletions config.sample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
address: '127.0.0.1', // for reverse proxy
//address: '0.0.0.0',
port: 3000,
database: {
host: 'localhost',
user: 'test',
password: '',
database: 'test'
}
};
137 changes: 137 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
var fs = require('fs');
var join = require('path').join;
var child = require('child_process');

var gulp = require('gulp');
var gutil = require('gulp-util');
var source = require("vinyl-source-stream");
var changed = require('gulp-changed');
var notify = require('gulp-notify');
var nodemon = require('gulp-nodemon');
var sass = require('gulp-sass');
var browserify = require('browserify');
var browserSync = require('browser-sync');

///////////////////////////////////////////////////////////
// helper

/**
* NOTE:
*
* files are removed in parallel
*
* If there are no error, callback will only be called once.
*
* If there are multiple errors, callback will be called
* exactly as many time as errors occur. (and no final callback)
*
* Sometimes, this behavior maybe useful, but users
* should be aware of this and handle error in callback.
*
*/

function rmfile(dir, file, callback){
var p = join(dir, file);
fs.lstat(p, function(err, stat){
if(err) callback.call(null,err);
else if(stat.isDirectory()) rmdir(p, callback);
else fs.unlink(p, callback)
})
}

function rmdir(dir, callback){
fs.readdir(dir, function(err,files){
if(err) callback.call(null,err);
else if( files.length ){
var i,j;
for(i=j=files.length; i--; ){
rmfile(dir,files[i], function(err){
if(err) callback.call(null, err);
else if(--j === 0 ) fs.rmdir(dir,callback)
})
}
}
else fs.rmdir(dir, callback)
})
}

///////////////////////////////////////////////////////////
// tasks

gulp.task('copyStaticFiles', function(){
gulp.src('./src/static/**')
.pipe(changed('www'))
.pipe(gulp.dest('www'))
});

gulp.task('scss', function () {
gulp.src('./src/scss/index.scss')
.pipe(sass().on('error', gutil.log))
.pipe(gulp.dest('www/css'))
.pipe(notify('scss: <%= file.relative %>'));
});

var b = browserify();
b.transform('reactify'); // use the reactify transform
b.add('./src/jsx/index.jsx');
gulp.task('browserify', function(){
b.bundle()
.on('error', gutil.log)
.pipe(source('index.js'))
.pipe(gulp.dest('www/js'))
.pipe(notify('browserify: <%= file.relative %>'));
});

var reload = browserSync.reload;
gulp.task('browserSync', [], function(){
browserSync({
proxy: 'localhost:3000',
port: 3001
});
});

gulp.task('start', function () {
nodemon({
script: 'index.js',
ext: 'js',
watch: [],
ignore: ['src/jsx/*'],
"execMap": {
"js": "iojs"
}
})
});

gulp.task('build', ['copyStaticFiles', 'scss', 'browserify']);

gulp.task('clean', function(done){
var called = false;
rmdir('./www', function(err){
if(called) return;
called = true;
done(err);
});
});

///////////////////////////////////////////////////////////

gulp.task('default', ['build', 'start', 'browserSync'], function(){

// static
gulp.watch('src/static/**', [ 'copyStaticFiles']);

// scss
gulp.watch('src/scss/**', ['scss']);

// jsx
gulp.watch(['src/jsx/**'], [ 'browserify' ]);

// browser sync
gulp.watch('www/css/**', function(event){
if( event.type === 'deleted' ) reload();
else reload(event.path);
});
gulp.watch(['www/js/**', 'src/routes/api.js']).on('change', reload);

});

84 changes: 84 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
var fs = require('fs');
var join = require('path').join;
var hapi = require('hapi');
var async = require('async');
var SocketIO = require('socket.io');

var Comm = require('./src/lib/Comm.js');

///////////////////////////////////////////////////////////
// helpers

var Config = require(join(__dirname, 'config.js'));
var log = console.log.bind(console);
var Log = require(join(__dirname, 'src/lib/Log.js'));

///////////////////////////////////////////////////////////
// server

var server = new hapi.Server();

server.connection({
address: Config.address || '0.0.0.0',
port: Config.port || 80
});
// set relative path
server.path(join(__dirname, 'www'));

// attach socket.io to web server
var io = SocketIO(server.listener);

///////////////////////////////////////////////////////////
// socket

io.on('connection', function(socket){
Log.i('new connection');

Comm.patch(socket);
});

global.broadcast = function(event){
var len = arguments.length;
var args = Array.prototype.slice.call(arguments,1,len);
io.emit(event, { args: args } )
};

///////////////////////////////////////////////////////////

var registerLout = function(done){
server.register({ register: require('lout') }, function(err) {
done()
});
};

var setRoutes = function(done){
var root = 'src/route';

// api
server.route(Comm.routes);

fs.readdir( join(__dirname, root), function(err,files){
if(err) return done(err);
for(var i=0; i<files.length; i++){
var file = files[i];
if( file.match(/(\.js|\.json)$/) ){
var p = join(__dirname, root, file );
Log.i('setRoutes:', p);
server.route( require(p) );
}
}
done()
})
};

var startServer = function(done){
server.start(function(){
Log.i('listening', server.info.uri);
done()
})
};

async.series([registerLout, setRoutes, startServer]);

///////////////////////////////////////////////////////////

38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "hike4hk-web",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "test"
},
"dependencies": {
"async": "^1.2.1",
"hapi": "^8.6.1",
"joi": "^6.4.3",
"lout": "^6.2.2",
"mysql": "^2.7.0",
"react": "^0.13.3",
"setimmediate": "^1.0.2",
"socket.io": "^1.3.5"
},
"devDependencies": {
"Faker": "^0.7.2",
"browser-sync": "^2.7.10",
"browserify": "^10.2.4",
"gulp": "^3.9.0",
"gulp-changed": "^1.2.1",
"gulp-nodemon": "^2.0.3",
"gulp-notify": "^2.2.0",
"gulp-sass": "^2.0.1",
"gulp-util": "^3.0.5",
"mocha": "^2.2.5",
"reactify": "^1.1.1",
"vinyl-source-stream": "^1.1.0"
},
"scripts": {
"test": "mocha"
},
"author": "",
"license": "GPLv3"
}
25 changes: 25 additions & 0 deletions src/jsx/component/If.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var React = require('React');

module.exports = React.createClass({
mixins: [],
getDefaultProps: function(){
return {
value: true
};
}
,
getInitialState: function(){
return {};
}
,
componentDidMount: function(){
}
,
componentWillUnmount: function(){
}
,
render: function(){
if( this.props.value ) return <div {...this.props} />;
return <noscript />;
}
});
82 changes: 82 additions & 0 deletions src/jsx/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
var React = require('react');
var Frame = require('./partial/Frame.jsx');

window.log = console.log.bind(console);

///////////////////////////////////////////////////////////
/// socket

//var socket = new io();
//
//var models = [
// { name: 'Board', handlers: Board },
// { name: 'State', handlers: State }
//];
//
//// listen broadcast
//(function(){
//
// for(var i=models.length; i--; ){
// var model = models[i];
// for(var key in model.handlers ){
// var handler = model.handlers[key];
// if( handler.callable ) (function(handler){
// var event = [model.name, key].join('.');
// //log('listening', event);
// socket.on( event , function(data){
// handler.apply(null, data.args);
// })
// })(handler);
// }
// }
//
//})();

///////////////////////////////////////////////////////////
/// initialization

// build api
function makeApi(api){
if( Array.isArray(api) ){
var type = api[0];
if( type === 'call' ){
return function(){
socket.emit(api[1], {
args: Array.prototype.slice.call(arguments)
})
}
}
else if( type === 'request' ){
return function(){
var len = arguments.length;
if( len === 0 || typeof arguments[len-1] !== 'function' )
throw new Error('request without callback');
var args = Array.prototype.slice.call(arguments,0,len-1);
var cb = arguments[len-1];
$.ajax({
type: 'POST',
url: api[1],
contentType: 'application/json',
data: JSON.stringify(args)
}).done(function(data){
cb.apply(null, data);
})
}
}
}
else if( typeof api === 'object' ){
var t = {};
for(var key in api ) t[key] = makeApi(api[key]);
return t;
}
}

$.ajax({
type: "GET",
url: '/api.js'
}).done(function(json){
window.api = makeApi(json);

React.render(<Frame />, document.body);
});

Loading

0 comments on commit a097b98

Please sign in to comment.