github login using firebase
This commit is contained in:
parent
c4cc413d26
commit
7eb7a29ef7
|
@ -3,11 +3,15 @@ module.exports = (grunt) ->
|
|||
pkg: grunt.file.readJSON("package.json")
|
||||
|
||||
apps_c:
|
||||
loader:
|
||||
dest: 'public/js/commonjs.js'
|
||||
|
||||
commonjs:
|
||||
src: [ 'src/**/*.{coffee,mustache}' ]
|
||||
dest: 'build/app.js'
|
||||
src: [ 'src/**/*.{coffee,js,json,mustache}' ]
|
||||
dest: 'public/js/app.js'
|
||||
options:
|
||||
main: 'src/app.coffee'
|
||||
loader: no
|
||||
|
||||
stylus:
|
||||
compile:
|
||||
|
@ -16,22 +20,22 @@ module.exports = (grunt) ->
|
|||
'src/styles/icons.styl'
|
||||
'src/styles/app.styl'
|
||||
]
|
||||
dest: 'build/app.css'
|
||||
dest: 'public/css/app.css'
|
||||
|
||||
concat:
|
||||
scripts:
|
||||
src: [
|
||||
# CommonJS loader.
|
||||
'public/js/commonjs.js'
|
||||
# Vendor dependencies.
|
||||
'vendor/jquery/jquery.js'
|
||||
'vendor/lodash/dist/lodash.js'
|
||||
'vendor/async/lib/async.js'
|
||||
'vendor/ractive/ractive.js'
|
||||
'vendor/firebase/lib/firebase.js'
|
||||
'vendor/firebase/firebase.js'
|
||||
'vendor/firebase-simple-login/firebase-simple-login.js'
|
||||
# Our app.
|
||||
'build/app.js'
|
||||
'public/js/app.js'
|
||||
]
|
||||
dest: 'build/app.bundle.js'
|
||||
dest: 'public/js/app.bundle.js'
|
||||
options:
|
||||
separator: ';' # for minification purposes
|
||||
|
||||
|
@ -40,21 +44,21 @@ module.exports = (grunt) ->
|
|||
# Vendor dependencies.
|
||||
'vendor/normalize-css/normalize.css'
|
||||
# Our style.
|
||||
'build/app.css'
|
||||
'public/css/app.css'
|
||||
]
|
||||
dest: 'build/app.bundle.css'
|
||||
dest: 'public/css/app.bundle.css'
|
||||
|
||||
uglify:
|
||||
scripts:
|
||||
files:
|
||||
'build/app.min.js': 'build/app.js'
|
||||
'build/app.bundle.min.js': 'build/app.bundle.js'
|
||||
'public/js/app.min.js': 'public/js/app.js'
|
||||
'public/js/app.bundle.min.js': 'public/js/app.bundle.js'
|
||||
|
||||
cssmin:
|
||||
combine:
|
||||
files:
|
||||
'build/app.min.css': 'build/app.css'
|
||||
'build/app.bundle.min.css': 'build/app.bundle.css'
|
||||
'public/css/app.min.css': 'public/css/app.css'
|
||||
'public/css/app.bundle.min.css': 'public/css/app.bundle.css'
|
||||
|
||||
grunt.loadNpmTasks('grunt-apps-c')
|
||||
grunt.loadNpmTasks('grunt-contrib-stylus')
|
||||
|
|
3
Makefile
3
Makefile
|
@ -11,4 +11,7 @@ watch:
|
|||
serve:
|
||||
cd public; python -m SimpleHTTPServer 8000
|
||||
|
||||
deploy:
|
||||
firebase deploy
|
||||
|
||||
.PHONY: build
|
|
@ -2,8 +2,6 @@
|
|||
"name": "burnchart",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"async": "0.2.5",
|
||||
"jquery": "2.0.3",
|
||||
"lodash": "2.3.0",
|
||||
"normalize-css": "2.1.3",
|
||||
"ractive": "~0.5.5",
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"firebase": "burnchart",
|
||||
"public": "public",
|
||||
"ignore": [
|
||||
"firebase.json",
|
||||
"**/.*",
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
../build/app.bundle.css
|
|
@ -1 +0,0 @@
|
|||
../build/app.bundle.js
|
|
@ -405,9 +405,9 @@ table {
|
|||
border-spacing: 0;
|
||||
}
|
||||
|
||||
@font-face{font-family:'MuseoSlab500Regular';src:url("fonts/museo-slab-500.eot");src:url("fonts/museo-slab-500.eot?#iefix") format('embedded-opentype'),url("fonts/museo-slab-500.woff") format('woff'),url("fonts/museo-slab-500.ttf") format('truetype'),url("fonts/museo-slab-500.svg#MuseoSlab500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSans500Regular';src:url("fonts/museo-sans-500.eot");src:url("fonts/museo-sans-500.eot?#iefix") format('embedded-opentype'),url("fonts/museo-sans-500.woff") format('woff'),url("fonts/museo-sans-500.ttf") format('truetype'),url("fonts/museo-sans-500.svg#MuseoSans500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'Fontello';src:url("fonts/fontello.eot?74672344");src:url("fonts/fontello.eot?74672344#iefix") format('embedded-opentype'),url("fonts/fontello.woff?74672344") format('woff'),url("fonts/fontello.ttf?74672344") format('truetype'),url("fonts/fontello.svg?74672344#fontello") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSlab500Regular';src:url("../fonts/museo-slab-500.eot");src:url("../fonts/museo-slab-500.eot?#iefix") format('embedded-opentype'),url("../fonts/museo-slab-500.woff") format('woff'),url("../fonts/museo-slab-500.ttf") format('truetype'),url("../fonts/museo-slab-500.svg#MuseoSlab500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSans500Regular';src:url("../fonts/museo-sans-500.eot");src:url("../fonts/museo-sans-500.eot?#iefix") format('embedded-opentype'),url("../fonts/museo-sans-500.woff") format('woff'),url("../fonts/museo-sans-500.ttf") format('truetype'),url("../fonts/museo-sans-500.svg#MuseoSans500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'Fontello';src:url("../fonts/fontello.eot?74672344");src:url("../fonts/fontello.eot?74672344#iefix") format('embedded-opentype'),url("../fonts/fontello.woff?74672344") format('woff'),url("../fonts/fontello.ttf?74672344") format('truetype'),url("../fonts/fontello.svg?74672344#fontello") format('svg');font-weight:normal;font-style:normal}
|
||||
|
||||
.icon{vertical-align:middle;}
|
||||
.icon:before{font-family:"Fontello";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;text-align:center;font-variant:normal;text-transform:none;line-height:1em}
|
||||
|
@ -462,7 +462,7 @@ ul li{display:inline-block}
|
|||
#title .milestone{font-size:16px;font-weight:bold;margin:0 20px}
|
||||
#title .description{display:inline-block;font-family:'MuseoSlab500Regular',serif;color:#b1b6c4}
|
||||
#content{padding:20px;margin-top:20px;}
|
||||
#content #hero{background:url("img/hires/2.jpg") center;-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;-webkit-border-radius:2px;border-radius:2px;margin-bottom:30px;}
|
||||
#content #hero{background:url("../img/hires/2.jpg") center;-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;-webkit-border-radius:2px;border-radius:2px;margin-bottom:30px;}
|
||||
#content #hero .content{-webkit-border-radius:2px;border-radius:2px;color:#fff;padding:30px;background:rgba(0,0,0,0.3);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);}
|
||||
#content #hero .content h2{margin-bottom:20px;margin-left:140px}
|
||||
#content #hero .content p{font-family:'MuseoSlab500Regular',serif;font-size:18px;line-height:24px;margin-left:140px;text-align:justify;text-justify:inter-word}
|
|
@ -1,6 +1,6 @@
|
|||
@font-face{font-family:'MuseoSlab500Regular';src:url("fonts/museo-slab-500.eot");src:url("fonts/museo-slab-500.eot?#iefix") format('embedded-opentype'),url("fonts/museo-slab-500.woff") format('woff'),url("fonts/museo-slab-500.ttf") format('truetype'),url("fonts/museo-slab-500.svg#MuseoSlab500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSans500Regular';src:url("fonts/museo-sans-500.eot");src:url("fonts/museo-sans-500.eot?#iefix") format('embedded-opentype'),url("fonts/museo-sans-500.woff") format('woff'),url("fonts/museo-sans-500.ttf") format('truetype'),url("fonts/museo-sans-500.svg#MuseoSans500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'Fontello';src:url("fonts/fontello.eot?74672344");src:url("fonts/fontello.eot?74672344#iefix") format('embedded-opentype'),url("fonts/fontello.woff?74672344") format('woff'),url("fonts/fontello.ttf?74672344") format('truetype'),url("fonts/fontello.svg?74672344#fontello") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSlab500Regular';src:url("../fonts/museo-slab-500.eot");src:url("../fonts/museo-slab-500.eot?#iefix") format('embedded-opentype'),url("../fonts/museo-slab-500.woff") format('woff'),url("../fonts/museo-slab-500.ttf") format('truetype'),url("../fonts/museo-slab-500.svg#MuseoSlab500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'MuseoSans500Regular';src:url("../fonts/museo-sans-500.eot");src:url("../fonts/museo-sans-500.eot?#iefix") format('embedded-opentype'),url("../fonts/museo-sans-500.woff") format('woff'),url("../fonts/museo-sans-500.ttf") format('truetype'),url("../fonts/museo-sans-500.svg#MuseoSans500Regular") format('svg');font-weight:normal;font-style:normal}
|
||||
@font-face{font-family:'Fontello';src:url("../fonts/fontello.eot?74672344");src:url("../fonts/fontello.eot?74672344#iefix") format('embedded-opentype'),url("../fonts/fontello.woff?74672344") format('woff'),url("../fonts/fontello.ttf?74672344") format('truetype'),url("../fonts/fontello.svg?74672344#fontello") format('svg');font-weight:normal;font-style:normal}
|
||||
|
||||
.icon{vertical-align:middle;}
|
||||
.icon:before{font-family:"Fontello";font-style:normal;font-weight:normal;speak:none;display:inline-block;text-decoration:inherit;text-align:center;font-variant:normal;text-transform:none;line-height:1em}
|
||||
|
@ -55,7 +55,7 @@ ul li{display:inline-block}
|
|||
#title .milestone{font-size:16px;font-weight:bold;margin:0 20px}
|
||||
#title .description{display:inline-block;font-family:'MuseoSlab500Regular',serif;color:#b1b6c4}
|
||||
#content{padding:20px;margin-top:20px;}
|
||||
#content #hero{background:url("img/hires/2.jpg") center;-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;-webkit-border-radius:2px;border-radius:2px;margin-bottom:30px;}
|
||||
#content #hero{background:url("../img/hires/2.jpg") center;-webkit-background-size:cover;-moz-background-size:cover;background-size:cover;-webkit-border-radius:2px;border-radius:2px;margin-bottom:30px;}
|
||||
#content #hero .content{-webkit-border-radius:2px;border-radius:2px;color:#fff;padding:30px;background:rgba(0,0,0,0.3);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);box-shadow:inset 0 1px 2px rgba(0,0,0,0.2);}
|
||||
#content #hero .content h2{margin-bottom:20px;margin-left:140px}
|
||||
#content #hero .content p{font-family:'MuseoSlab500Regular',serif;font-size:18px;line-height:24px;margin-left:140px;text-align:justify;text-justify:inter-word}
|
|
@ -3,15 +3,14 @@
|
|||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="app.bundle.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/app.bundle.css">
|
||||
|
||||
<script src="app.bundle.js"></script>
|
||||
<script src="js/app.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
$(function() {
|
||||
var app = require('burnchart');
|
||||
app.render('body');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,208 +1,3 @@
|
|||
// A standalone CommonJS loader.
|
||||
(function(root) {
|
||||
/**
|
||||
* Require the given path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Object} exports
|
||||
* @api public
|
||||
*/
|
||||
var require = function(path, parent, orig) {
|
||||
var resolved = require.resolve(path);
|
||||
|
||||
// lookup failed
|
||||
if (!resolved) {
|
||||
orig = orig || path;
|
||||
parent = parent || 'root';
|
||||
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
|
||||
err.path = orig;
|
||||
err.parent = parent;
|
||||
err.require = true;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var module = require.modules[resolved];
|
||||
|
||||
// perform real require()
|
||||
// by invoking the module's
|
||||
// registered function
|
||||
if (!module._resolving && !module.exports) {
|
||||
var mod = {};
|
||||
mod.exports = {};
|
||||
mod.client = mod.component = true;
|
||||
module._resolving = true;
|
||||
module.call(this, mod.exports, require.relative(resolved), mod);
|
||||
delete module._resolving;
|
||||
module.exports = mod.exports;
|
||||
}
|
||||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registered modules.
|
||||
*/
|
||||
|
||||
require.modules = {};
|
||||
|
||||
/**
|
||||
* Registered aliases.
|
||||
*/
|
||||
|
||||
require.aliases = {};
|
||||
|
||||
/**
|
||||
* Resolve `path`.
|
||||
*
|
||||
* Lookup:
|
||||
*
|
||||
* - PATH/index.js
|
||||
* - PATH.js
|
||||
* - PATH
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {String} path or null
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.resolve = function(path) {
|
||||
if (path.charAt(0) === '/') path = path.slice(1);
|
||||
|
||||
var paths = [
|
||||
path,
|
||||
path + '.js',
|
||||
path + '.json',
|
||||
path + '/index.js',
|
||||
path + '/index.json'
|
||||
];
|
||||
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
path = paths[i];
|
||||
if (require.modules.hasOwnProperty(path)) return path;
|
||||
if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize `path` relative to the current path.
|
||||
*
|
||||
* @param {String} curr
|
||||
* @param {String} path
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.normalize = function(curr, path) {
|
||||
var segs = [];
|
||||
|
||||
if ('.' != path.charAt(0)) return path;
|
||||
|
||||
curr = curr.split('/');
|
||||
path = path.split('/');
|
||||
|
||||
for (var i = 0; i < path.length; ++i) {
|
||||
if ('..' == path[i]) {
|
||||
curr.pop();
|
||||
} else if ('.' !== path[i] && '' !== path[i]) {
|
||||
segs.push(path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return curr.concat(segs).join('/');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register module at `path` with callback `definition`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} definition
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.register = function(path, definition) {
|
||||
require.modules[path] = definition;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias a module definition.
|
||||
*
|
||||
* @param {String} from
|
||||
* @param {String} to
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.alias = function(from, to) {
|
||||
if (!require.modules.hasOwnProperty(from)) {
|
||||
throw new Error('Failed to alias "' + from + '", it does not exist');
|
||||
}
|
||||
require.aliases[to] = from;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a require function relative to the `parent` path.
|
||||
*
|
||||
* @param {String} parent
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.relative = function(parent) {
|
||||
var p = require.normalize(parent, '..');
|
||||
|
||||
/**
|
||||
* lastIndexOf helper.
|
||||
*/
|
||||
|
||||
function lastIndexOf(arr, obj) {
|
||||
var i = arr.length;
|
||||
while (i--) {
|
||||
if (arr[i] === obj) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The relative require() itself.
|
||||
*/
|
||||
|
||||
var localRequire = function(path) {
|
||||
var resolved = localRequire.resolve(path);
|
||||
return require(resolved, parent, path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve relative to the parent.
|
||||
*/
|
||||
|
||||
localRequire.resolve = function(path) {
|
||||
var c = path.charAt(0);
|
||||
if ('/' == c) return path.slice(1);
|
||||
if ('.' == c) return require.normalize(p, path);
|
||||
|
||||
// resolve deps by returning
|
||||
// the dep in the nearest "deps"
|
||||
// directory
|
||||
var segs = parent.split('/');
|
||||
var i = lastIndexOf(segs, 'deps') + 1;
|
||||
if (!i) i = 0;
|
||||
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
|
||||
return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if module is defined at `path`.
|
||||
*/
|
||||
localRequire.exists = function(path) {
|
||||
return require.modules.hasOwnProperty(localRequire.resolve(path));
|
||||
};
|
||||
|
||||
return localRequire;
|
||||
};
|
||||
|
||||
// Do we already have require loader?
|
||||
root.require = (typeof root.require !== 'undefined') ? root.require : require;
|
||||
|
||||
})(this);
|
||||
// Concat modules and export them as an app.
|
||||
(function(root) {
|
||||
|
||||
|
@ -212,74 +7,100 @@
|
|||
// app.coffee
|
||||
root.require.register('burnchart/src/app.js', function(exports, require, module) {
|
||||
|
||||
var App;
|
||||
var App, firebase;
|
||||
|
||||
firebase = require('./modules/firebase');
|
||||
|
||||
document.title = 'BurnChart: GitHub Burndown Chart as a Service';
|
||||
|
||||
App = Ractive.extend({
|
||||
template: require('./templates/layout'),
|
||||
init: function() {}
|
||||
init: function() {
|
||||
return firebase.login(function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = new App();
|
||||
|
||||
});
|
||||
|
||||
// firebase.coffee
|
||||
root.require.register('burnchart/src/components/firebase.js', function(exports, require, module) {
|
||||
// config.json
|
||||
root.require.register('burnchart/src/models/config.js', function(exports, require, module) {
|
||||
|
||||
var authCb, state, user;
|
||||
module.exports = {
|
||||
"firebase": "burnchart",
|
||||
"provider": "github"
|
||||
};
|
||||
});
|
||||
|
||||
// firebase.coffee
|
||||
root.require.register('burnchart/src/modules/firebase.js', function(exports, require, module) {
|
||||
|
||||
var FB, authCb, config, user;
|
||||
|
||||
config = require('../models/config');
|
||||
|
||||
user = require('./user');
|
||||
|
||||
state = require('../modules/state');
|
||||
|
||||
authCb = function() {};
|
||||
|
||||
module.exports = new can.Map({
|
||||
setClient: function(root, success, error) {
|
||||
var client;
|
||||
client = new Firebase("https://" + root + ".firebaseio.com");
|
||||
state.load('Loading');
|
||||
this.attr('auth', new FirebaseSimpleLogin(client, function(err, obj) {
|
||||
FB = (function() {
|
||||
function FB() {
|
||||
console.log('Init Firebase');
|
||||
this.client = new Firebase("https://" + config.firebase + ".firebaseio.com");
|
||||
this.auth = new FirebaseSimpleLogin(this.client, function(err, obj) {
|
||||
if (err || !obj) {
|
||||
if (!obj) {
|
||||
state.none();
|
||||
}
|
||||
return authCb(err);
|
||||
}
|
||||
user(obj);
|
||||
state.info("" + obj.displayName + " is logged in");
|
||||
return authCb();
|
||||
}));
|
||||
return client;
|
||||
},
|
||||
login: function(cb, provider) {
|
||||
if (provider == null) {
|
||||
provider = 'github';
|
||||
}
|
||||
user.set(obj);
|
||||
return console.log("" + obj.displayName + " is logged in");
|
||||
});
|
||||
}
|
||||
|
||||
FB.prototype.login = function(cb) {
|
||||
if (!this.client) {
|
||||
return cb('Client is not setup');
|
||||
}
|
||||
authCb = cb;
|
||||
state.load('Connecting GitHub account');
|
||||
return this.auth.login(provider, {
|
||||
console.log('Connecting GitHub account');
|
||||
return this.auth.login(config.provider, {
|
||||
'rememberMe': true,
|
||||
'scope': 'public_repo'
|
||||
});
|
||||
},
|
||||
logout: function() {
|
||||
};
|
||||
|
||||
FB.prototype.logout = function() {
|
||||
var _ref;
|
||||
if ((_ref = this.auth) != null) {
|
||||
_ref.logout();
|
||||
_ref.logout;
|
||||
}
|
||||
user({});
|
||||
return state.info('You have logged out');
|
||||
},
|
||||
signup: function(data, cb) {
|
||||
console.log(data);
|
||||
return cb(null);
|
||||
}
|
||||
user.reset();
|
||||
return console.log('You have logged out');
|
||||
};
|
||||
|
||||
return FB;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = new FB();
|
||||
|
||||
});
|
||||
|
||||
// user.coffee
|
||||
root.require.register('burnchart/src/modules/user.js', function(exports, require, module) {
|
||||
|
||||
var user;
|
||||
|
||||
module.exports = user = new Ractive();
|
||||
|
||||
user.render();
|
||||
|
||||
user.observe('*', function() {
|
||||
return console.log('User', arguments);
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,205 @@
|
|||
// A standalone CommonJS loader.
|
||||
(function(root) {
|
||||
/**
|
||||
* Require the given path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Object} exports
|
||||
* @api public
|
||||
*/
|
||||
var require = function(path, parent, orig) {
|
||||
var resolved = require.resolve(path);
|
||||
|
||||
// lookup failed
|
||||
if (!resolved) {
|
||||
orig = orig || path;
|
||||
parent = parent || 'root';
|
||||
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
|
||||
err.path = orig;
|
||||
err.parent = parent;
|
||||
err.require = true;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var module = require.modules[resolved];
|
||||
|
||||
// perform real require()
|
||||
// by invoking the module's
|
||||
// registered function
|
||||
if (!module._resolving && !module.exports) {
|
||||
var mod = {};
|
||||
mod.exports = {};
|
||||
mod.client = mod.component = true;
|
||||
module._resolving = true;
|
||||
module.call(this, mod.exports, require.relative(resolved), mod);
|
||||
delete module._resolving;
|
||||
module.exports = mod.exports;
|
||||
}
|
||||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registered modules.
|
||||
*/
|
||||
|
||||
require.modules = {};
|
||||
|
||||
/**
|
||||
* Registered aliases.
|
||||
*/
|
||||
|
||||
require.aliases = {};
|
||||
|
||||
/**
|
||||
* Resolve `path`.
|
||||
*
|
||||
* Lookup:
|
||||
*
|
||||
* - PATH/index.js
|
||||
* - PATH.js
|
||||
* - PATH
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {String} path or null
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.resolve = function(path) {
|
||||
if (path.charAt(0) === '/') path = path.slice(1);
|
||||
|
||||
var paths = [
|
||||
path,
|
||||
path + '.js',
|
||||
path + '.json',
|
||||
path + '/index.js',
|
||||
path + '/index.json'
|
||||
];
|
||||
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
path = paths[i];
|
||||
if (require.modules.hasOwnProperty(path)) return path;
|
||||
if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize `path` relative to the current path.
|
||||
*
|
||||
* @param {String} curr
|
||||
* @param {String} path
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.normalize = function(curr, path) {
|
||||
var segs = [];
|
||||
|
||||
if ('.' != path.charAt(0)) return path;
|
||||
|
||||
curr = curr.split('/');
|
||||
path = path.split('/');
|
||||
|
||||
for (var i = 0; i < path.length; ++i) {
|
||||
if ('..' == path[i]) {
|
||||
curr.pop();
|
||||
} else if ('.' !== path[i] && '' !== path[i]) {
|
||||
segs.push(path[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return curr.concat(segs).join('/');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register module at `path` with callback `definition`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} definition
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.register = function(path, definition) {
|
||||
require.modules[path] = definition;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias a module definition.
|
||||
*
|
||||
* @param {String} from
|
||||
* @param {String} to
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.alias = function(from, to) {
|
||||
if (!require.modules.hasOwnProperty(from)) {
|
||||
throw new Error('Failed to alias "' + from + '", it does not exist');
|
||||
}
|
||||
require.aliases[to] = from;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a require function relative to the `parent` path.
|
||||
*
|
||||
* @param {String} parent
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
require.relative = function(parent) {
|
||||
var p = require.normalize(parent, '..');
|
||||
|
||||
/**
|
||||
* lastIndexOf helper.
|
||||
*/
|
||||
|
||||
function lastIndexOf(arr, obj) {
|
||||
var i = arr.length;
|
||||
while (i--) {
|
||||
if (arr[i] === obj) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The relative require() itself.
|
||||
*/
|
||||
|
||||
var localRequire = function(path) {
|
||||
var resolved = localRequire.resolve(path);
|
||||
return require(resolved, parent, path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve relative to the parent.
|
||||
*/
|
||||
|
||||
localRequire.resolve = function(path) {
|
||||
var c = path.charAt(0);
|
||||
if ('/' == c) return path.slice(1);
|
||||
if ('.' == c) return require.normalize(p, path);
|
||||
|
||||
// resolve deps by returning
|
||||
// the dep in the nearest "deps"
|
||||
// directory
|
||||
var segs = parent.split('/');
|
||||
var i = lastIndexOf(segs, 'deps') + 1;
|
||||
if (!i) i = 0;
|
||||
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
|
||||
return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if module is defined at `path`.
|
||||
*/
|
||||
localRequire.exists = function(path) {
|
||||
return require.modules.hasOwnProperty(localRequire.resolve(path));
|
||||
};
|
||||
|
||||
return localRequire;
|
||||
};
|
||||
|
||||
// Do we already have require loader?
|
||||
root.require = (typeof root.require !== 'undefined') ? root.require : require;
|
||||
|
||||
})(this);
|
|
@ -1,3 +1,5 @@
|
|||
firebase = require './modules/firebase'
|
||||
|
||||
document.title = 'BurnChart: GitHub Burndown Chart as a Service'
|
||||
|
||||
App = Ractive.extend
|
||||
|
@ -5,5 +7,8 @@ App = Ractive.extend
|
|||
template: require './templates/layout'
|
||||
|
||||
init: ->
|
||||
# Login user.
|
||||
firebase.login (err) ->
|
||||
throw err if err
|
||||
|
||||
module.exports = new App()
|
|
@ -1,3 +1,4 @@
|
|||
{
|
||||
"firebase": "burnchart-app"
|
||||
"firebase": "burnchart",
|
||||
"provider": "github"
|
||||
}
|
|
@ -1,62 +1,43 @@
|
|||
config = require '../models/config'
|
||||
|
||||
user = require './user'
|
||||
state = require '../modules/state'
|
||||
user = require './user'
|
||||
|
||||
# Default "silent" callback for auth.
|
||||
authCb = ->
|
||||
|
||||
# New client.
|
||||
firebase.attr 'client', opts.firebase
|
||||
|
||||
module.exports = new can.Map
|
||||
|
||||
# Ref server.
|
||||
setClient: (root, success, error) ->
|
||||
# Create a new instance pointing to a root.
|
||||
client = new Firebase "https://#{root}.firebaseio.com"
|
||||
|
||||
class FB
|
||||
|
||||
constructor: ->
|
||||
console.log 'Init Firebase'
|
||||
|
||||
# Setup a new client.
|
||||
@client = new Firebase "https://#{config.firebase}.firebaseio.com"
|
||||
|
||||
# Check if we have a user in session.
|
||||
state.load 'Loading'
|
||||
|
||||
@attr 'auth', new FirebaseSimpleLogin client, (err, obj) ->
|
||||
@auth = new FirebaseSimpleLogin @client, (err, obj) ->
|
||||
if err or not obj
|
||||
do state.none unless obj
|
||||
return authCb err
|
||||
|
||||
# Save user in memory.
|
||||
user obj
|
||||
state.info "#{obj.displayName} is logged in"
|
||||
|
||||
# Call back.
|
||||
do authCb
|
||||
|
||||
client
|
||||
# Save user.
|
||||
user.set obj
|
||||
console.log "#{obj.displayName} is logged in"
|
||||
|
||||
# Login a user.
|
||||
login: (cb, provider='github') ->
|
||||
login: (cb) ->
|
||||
return cb 'Client is not setup' unless @client
|
||||
|
||||
# Override the default auth callback.
|
||||
authCb = cb
|
||||
|
||||
# Login.
|
||||
state.load 'Connecting GitHub account'
|
||||
@auth.login provider,
|
||||
# 30 days.
|
||||
console.log 'Connecting GitHub account'
|
||||
@auth.login config.provider,
|
||||
'rememberMe': yes
|
||||
# See: http://developer.github.com/v3/oauth/#scopes
|
||||
# TODO: access private repos as well
|
||||
'scope': 'public_repo'
|
||||
|
||||
# Logout a user.
|
||||
logout: ->
|
||||
do @auth?.logout
|
||||
user {}
|
||||
# TODO: fixme
|
||||
state.info 'You have logged out'
|
||||
@auth?.logout
|
||||
do user.reset
|
||||
console.log 'You have logged out'
|
||||
|
||||
# Signup a new account.
|
||||
signup: (data, cb) ->
|
||||
console.log data
|
||||
cb null
|
||||
module.exports = new FB()
|
|
@ -1,40 +0,0 @@
|
|||
# Timeout in ms.
|
||||
ms = 3e3
|
||||
|
||||
update = (text, type) ->
|
||||
switch type
|
||||
when 'load'
|
||||
text += '<span class="icon spin6"></span>'
|
||||
|
||||
@
|
||||
.attr('text', text)
|
||||
.attr('type', type)
|
||||
|
||||
module.exports = State = new can.Map
|
||||
|
||||
# HTML text.
|
||||
text: null
|
||||
|
||||
# none/load/info/warn
|
||||
type: 'none'
|
||||
|
||||
load: _.partialRight update, 'load'
|
||||
info: _.partialRight update, 'info'
|
||||
warn: _.partialRight update, 'warn'
|
||||
|
||||
none: ->
|
||||
@attr 'type', 'none'
|
||||
|
||||
timeout = null
|
||||
|
||||
# Hide in 3s unless it is an alert or we are loading.
|
||||
State.bind 'type', (ev, newVal, oldVal) ->
|
||||
clearTimeout timeout
|
||||
|
||||
# Skip?
|
||||
return if newVal in [ 'warn', 'load' ]
|
||||
|
||||
# Hide.
|
||||
setTimeout =>
|
||||
@attr 'type', 'none'
|
||||
, ms
|
|
@ -1,7 +1,8 @@
|
|||
# Currently logged-in user.
|
||||
module.exports = user = can.compute({ })
|
||||
user.bind 'change', (ev, obj) ->
|
||||
mixpanel.people.set
|
||||
'$email': obj.email
|
||||
'name': obj.displayName
|
||||
mixpanel.identify obj.username
|
||||
module.exports = user = new Ractive()
|
||||
|
||||
# Init now.
|
||||
do user.render
|
||||
|
||||
user.observe '*', ->
|
||||
console.log 'User', arguments
|
|
@ -124,7 +124,7 @@ ul
|
|||
margin-top: 20px
|
||||
|
||||
#hero
|
||||
background: url('img/hires/2.jpg') center
|
||||
background: url('../img/hires/2.jpg') center
|
||||
background-size: cover
|
||||
border-radius: 2px
|
||||
margin-bottom: 30px
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
@font-face {
|
||||
font-family: 'MuseoSlab500Regular';
|
||||
src: url('fonts/museo-slab-500.eot');
|
||||
src: url('fonts/museo-slab-500.eot?#iefix') format('embedded-opentype'),
|
||||
url('fonts/museo-slab-500.woff') format('woff'),
|
||||
url('fonts/museo-slab-500.ttf') format('truetype'),
|
||||
url('fonts/museo-slab-500.svg#MuseoSlab500Regular') format('svg');
|
||||
src: url('../fonts/museo-slab-500.eot');
|
||||
src: url('../fonts/museo-slab-500.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/museo-slab-500.woff') format('woff'),
|
||||
url('../fonts/museo-slab-500.ttf') format('truetype'),
|
||||
url('../fonts/museo-slab-500.svg#MuseoSlab500Regular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'MuseoSans500Regular';
|
||||
src: url('fonts/museo-sans-500.eot');
|
||||
src: url('fonts/museo-sans-500.eot?#iefix') format('embedded-opentype'),
|
||||
url('fonts/museo-sans-500.woff') format('woff'),
|
||||
url('fonts/museo-sans-500.ttf') format('truetype'),
|
||||
url('fonts/museo-sans-500.svg#MuseoSans500Regular') format('svg');
|
||||
src: url('../fonts/museo-sans-500.eot');
|
||||
src: url('../fonts/museo-sans-500.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/museo-sans-500.woff') format('woff'),
|
||||
url('../fonts/museo-sans-500.ttf') format('truetype'),
|
||||
url('../fonts/museo-sans-500.svg#MuseoSans500Regular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fontello';
|
||||
src: url('fonts/fontello.eot?74672344');
|
||||
src: url('fonts/fontello.eot?74672344#iefix') format('embedded-opentype'),
|
||||
url('fonts/fontello.woff?74672344') format('woff'),
|
||||
url('fonts/fontello.ttf?74672344') format('truetype'),
|
||||
url('fonts/fontello.svg?74672344#fontello') format('svg');
|
||||
src: url('../fonts/fontello.eot?74672344');
|
||||
src: url('../fonts/fontello.eot?74672344#iefix') format('embedded-opentype'),
|
||||
url('../fonts/fontello.woff?74672344') format('woff'),
|
||||
url('../fonts/fontello.ttf?74672344') format('truetype'),
|
||||
url('../fonts/fontello.svg?74672344#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
Loading…
Reference in New Issue