diff --git a/package.json b/package.json
index 7762a67..a8b59f9 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
},
"dependencies": {
"deep-diff": "^0.3.3",
+ "firebase": "^2.3.2",
"lesshat": "^3.0.2",
"lodash": "^3.10.1",
"marked": "^0.3.5",
diff --git a/src/js/components/Header.jsx b/src/js/components/Header.jsx
index 20d1ec9..4bf3a04 100644
--- a/src/js/components/Header.jsx
+++ b/src/js/components/Header.jsx
@@ -27,7 +27,7 @@ export default React.createClass({
// Sign-in/out.
let user;
- if (props.user.uid) {
+ if (props.user && 'uid' in props.user) {
user = (
diff --git a/src/js/models/config.js b/src/js/models/config.js
new file mode 100644
index 0000000..ce5e729
--- /dev/null
+++ b/src/js/models/config.js
@@ -0,0 +1,33 @@
+export default {
+ // Firebase app name.
+ "firebase": "burnchart",
+ // Data source provider.
+ "provider": "github",
+ // Fields to keep from GH responses.
+ "fields": {
+ "milestone": [
+ "closed_issues",
+ "created_at",
+ "description",
+ "due_on",
+ "number",
+ "open_issues",
+ "title",
+ "updated_at"
+ ]
+ },
+ // Chart configuration.
+ "chart": {
+ // Days we are not working. Mon = 1
+ "off_days": [ ],
+ // How does a size label look like?
+ "size_label": /^size (\d+)$/,
+ // Process all issues as one size (ONE_SIZE) or use labels (LABELS).
+ "points": 'ONE_SIZE'
+ },
+ // Request pertaining.
+ "request": {
+ // Default timeout of 5s.
+ "timeout": 5e3
+ }
+};
diff --git a/src/js/stores/appStore.js b/src/js/stores/appStore.js
index 6599dc3..91cd926 100644
--- a/src/js/stores/appStore.js
+++ b/src/js/stores/appStore.js
@@ -1,9 +1,15 @@
import _ from 'lodash';
+import Firebase from 'firebase';
import Store from '../core/Store.js';
import actions from '../actions/appActions.js';
+import config from '../models/config.js';
+
+// Setup a new client.
+let client;
+
class AppStore extends Store {
// Initial payload.
@@ -15,7 +21,7 @@ class AppStore extends Store {
user: {}
});
- // Listen to all app actions
+ // Listen to all app actions.
actions.onAny((obj, event) => {
let fn = ('on.' + event).replace(/[.]+(\w|$)/g, (m, p) => {
return p.toUpperCase();
@@ -23,14 +29,38 @@ class AppStore extends Store {
(fn in this) && this[fn](obj);
});
+
+ client = new Firebase("https://" + config.firebase + ".firebaseio.com");
+
+ // When user is already authenticated.
+ client.onAuth((data={}) => actions.emit('firebase.auth', data));
}
onUserSignin() {
- console.log('in');
+ client.authWithOAuthPopup("github", function(err, data) {
+ if (!err) return actions.emit('firebase.auth', data);
+
+ actions.emit('notify', {
+ 'text': err.toString(),
+ 'type': 'alert',
+ 'system': true
+ });
+ }, {
+ 'rememberMe': true,
+ // See https://developer.github.com/v3/oauth/#scopes
+ 'scope': 'repo'
+ });
}
- onUserSignOut() {
- console.log('out');
+ // Sign-out a user.
+ onUserSignout() {
+ this.set('user', {});
+ client.unauth();
+ }
+
+ // Called by Firebase.
+ onFirebaseAuth(data) {
+ this.set('user', data);
}
}