From 5cb5b04b98624138daf8f21b8a30c165c246b898 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:26:59 -0700 Subject: [PATCH 01/12] Gulpfile. --- gulpfile.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 gulpfile.js diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..537726e --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,53 @@ +var gulp = require('gulp'), + connect = require('gulp-connect'), + open = require('gulp-open'), + port = process.env.port || 3001; + +gulp.task('open', function(){ + var options = { + url: 'http://localhost:' + port, + }; + gulp.src('./www/index.html') + .pipe(open('', options)); +}); + +gulp.task('connect', function() { + connect.server({ + root: 'www', + port: port, + livereload: true + }); +}); + +gulp.task('test', function() { + connect.server({ + root: '.', + port: port - 1, + livereload: true + }); + + var options = { + url: 'http://localhost:' + (port - 1), + }; + gulp.src('./test/index.html') + .pipe(open('', options)) +}); + +gulp.task('js', function () { + gulp.src('./www/**/*.js') + .pipe(connect.reload()); +}); + +gulp.task('html', function () { + gulp.src('./www/*.html') + .pipe(connect.reload()); +}); + +gulp.task('watch', function() { + gulp.watch('www/dist/js/*.js', ['js']); + gulp.watch('www/index.html', ['html']); +}); + +gulp.task('default', ['connect', 'watch']); + +gulp.task('serve', ['connect', 'watch', 'open']); \ No newline at end of file From b1e8f5482f5bd0c130b494fba70510a1037c47a0 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:27:17 -0700 Subject: [PATCH 02/12] Updated rules for v2. --- rules.json | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/rules.json b/rules.json index e56e042..337cdf5 100644 --- a/rules.json +++ b/rules.json @@ -6,15 +6,15 @@ // A list of users with their names on the site. "$userid": { // Only the user can write their own entry into this list. - ".write": "$userid == auth.id" + ".write": "$userid == auth.id || $userid == auth.uid" } }, "users": { "$userid": { // The user is allowed to write everything in their bucket. - ".write": "$userid == auth.id", + ".write": "$userid == auth.id || $userid == auth.uid", "following": { - // The following list should only contain actual ids from the "people" list. + // The following list should only contain actual ids from the "people" list. "$followingid": { ".validate": "root.child('people').hasChild($followingid)" } @@ -22,13 +22,13 @@ "followers": { // Anyone can add themself to to this user's followers list. "$followerid": { - ".write": "$followerid == auth.id" + ".write": "$followerid == auth.id || $followerid == auth.uid" } }, "feed": { "$sparkid": { // User A can write in user B's feed, but only if A is following B, and only for sparks for which they are the author. - ".write": "root.child('users/' + $userid + '/following').hasChild(auth.id) && root.child('sparks/' + $sparkid + '/author').val() == auth.id" + ".write": "(root.child('users/' + $userid + '/following').hasChild(auth.id) && root.child('sparks/' + $sparkid + '/author').val() == auth.id) || (root.child('users/' + $userid + '/following').hasChild(auth.uid) && root.child('sparks/' + $sparkid + '/author').val() == auth.uid)" } } } @@ -42,7 +42,7 @@ ".validate": "newData.hasChildren(['author', 'content'])", // A user can attribute a spark only to themselves. "author": { - ".validate": "newData.val() == auth.id" + ".validate": "newData.val() == auth.id || newData.val() == auth.uid" }, "content": { ".validate": "newData.isString()" @@ -52,27 +52,26 @@ "recent-users": { // Users can add themselves to the list of users with recent activity. "$userid": { - ".write": "$userid == auth.id" + ".write": "$userid == auth.id || $userid == auth.uid" } }, "recent-sparks": { // Authors of sparks can add their sparks to this list. "$sparkid": { - ".write": "root.child('sparks/' + $sparkid + '/author').val() == auth.id" + ".write": "root.child('sparks/' + $sparkid + '/author').val() == auth.id || root.child('sparks/' + $sparkid + '/author').val() == auth.uid" } }, "search": { "firstName": { "$searchKey": { - ".write": "auth != null && (root.child('people/' + auth.id + '/firstName').val() + '|' + root.child('people/' + auth.id + '/lastName').val() + '|' + auth.id) == $searchKey && newData.val() == auth.id" + ".write": "auth != null && ((root.child('people/' + auth.id + '/firstName').val() + '|' + root.child('people/' + auth.id + '/lastName').val() + '|' + auth.id) == $searchKey || (root.child('people/' + auth.uid + '/firstName').val() + '|' + root.child('people/' + auth.uid + '/lastName').val() + '|' + auth.uid) == $searchKey) && (newData.val() == auth.id || newData.val() == auth.uid)" } }, "lastName": { "$searchKey": { - ".write": "auth != null && (root.child('people/' + auth.id + '/lastName').val() + '|' + root.child('people/' + auth.id + '/firstName').val() + '|' + auth.id) == $searchKey && newData.val() == auth.id" + ".write": "auth != null && ((root.child('people/' + auth.id + '/lastName').val() + '|' + root.child('people/' + auth.id + '/firstName').val() + '|' + auth.id) == $searchKey || (root.child('people/' + auth.uid + '/lastName').val() + '|' + root.child('people/' + auth.uid + '/firstName').val() + '|' + auth.uid) == $searchKey) && (newData.val() == auth.id || newData.val() == auth.uid)" } } } } -} - +} \ No newline at end of file From 9c1ab14ddcbb1ebd87f263ecc30cc5c11e67b865 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:27:43 -0700 Subject: [PATCH 03/12] Start and build commands. --- package.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..fb3951b --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "firefeed", + "version": "0.1.0", + "description": "Firefeed is a web app that lets users post small messages called sparks to their feed. You can follow other users, and their sparks will appear on your feed.", + "main": "gulpfile.js", + "directories": { + "test": "test" + }, + "scripts": { + "start": "gulp serve", + "build": "gulp" + }, + "repository": { + "type": "git", + "url": "https://github.com/firebase/firefeed.git" + }, + "keywords": [ + "firebase", + "twitter clone" + ], + "author": "Firebase", + "license": "MIT", + "bugs": { + "url": "https://github.com/firebase/firefeed/issues" + }, + "homepage": "https://github.com/firebase/firefeed", + "dependencies": {} +} From 89f0a34acafd3613999983278516063f166789d1 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:29:38 -0700 Subject: [PATCH 04/12] Updated auth.id to auth.uid. Added bind polyfill. --- www/index.html | 14 +++---- www/js/firefeed-ui.js | 18 +++++---- www/js/firefeed.js | 80 ++++++++++++++++++++++++--------------- www/libs/bind-polyfill.js | 30 +++++++++++++++ 4 files changed, 98 insertions(+), 44 deletions(-) create mode 100644 www/libs/bind-polyfill.js diff --git a/www/index.html b/www/index.html index 6945319..47113ce 100644 --- a/www/index.html +++ b/www/index.html @@ -254,7 +254,7 @@

{{fullName}}

{{fullName}}

{{bio}}

- Follow + Follow @@ -272,6 +272,7 @@

{{fullName}}

+ @@ -281,25 +282,24 @@

{{fullName}}

- - + - - + + + diff --git a/www/js/firefeed-ui.js b/www/js/firefeed-ui.js index 404ac8a..69d59c6 100644 --- a/www/js/firefeed-ui.js +++ b/www/js/firefeed-ui.js @@ -8,7 +8,7 @@ function FirefeedUI() { this._limit = 141; this._loggedIn = false; this._spinner = new Spinner(); - this._firefeed = new Firefeed("https://firefeed.firebaseIO.com/"); + this._firefeed = new Firefeed("https://awesome-firebase.firebaseio.com/"); this._unload = null; // Setup page navigation. @@ -20,8 +20,8 @@ function FirefeedUI() { self._pageController(window.History.getState().hash, false); }); - self._firefeed.onLoginStateChange(function(error, user) { - self.onLoginStateChange(error, user); + self._firefeed.onStateChange(function(user) { + self.onLoginStateChange(user); }); } @@ -159,7 +159,7 @@ FirefeedUI.prototype._editableHandler = function(id, value) { return true; }; -FirefeedUI.prototype.onLoginStateChange = function(error, info) { +FirefeedUI.prototype.onLoginStateChange = function(info) { this._spinner.stop(); this._loggedIn = info; $("#header").html(Mustache.to_html($("#tmpl-page-header").html(), {user: this._loggedIn})); @@ -315,12 +315,16 @@ FirefeedUI.prototype.renderTimeline = function(info) { info.id = userid; $(Mustache.to_html($("#tmpl-suggested-user").html(), info)). appendTo("#suggested-users"); - var button = $("#followBtn-" + userid); + + //var button = $("#followBtn-" + userid); + var button = $('.btn-follow'); // Fade out the suggested user if they were followed successfully. button.click(function(e) { + var $button = $(e.target); + var id = $button.data('id'); e.preventDefault(); - button.remove(); - self._firefeed.follow(userid, function(err, done) { + $button.remove(); + self._firefeed.follow(id, function(err, done) { // TODO FIXME: Check for errors! $("#followBox-" + userid).fadeOut(1500); }); diff --git a/www/js/firefeed.js b/www/js/firefeed.js index 89ecfa8..8997f89 100644 --- a/www/js/firefeed.js +++ b/www/js/firefeed.js @@ -14,12 +14,13 @@ function Firefeed(baseURL, newContext) { var self = this; this._name = null; - this._userid = null; + this._facebookId = null; this._firebase = null; this._mainUser = null; this._fullName = null; this._searchHandler = null; this._currentSearch = null; + this._baseURL = baseURL; // Every time we call firebaseRef.on, we need to remember to call .off, // when requested by the caller via unload(). We'll store our handlers @@ -34,9 +35,11 @@ function Firefeed(baseURL, newContext) { ); this._authHandlers = []; - this._firebaseAuthClient = new FirebaseSimpleLogin(this._firebase, function(error, user) { - self._onLoginStateChange(error, user); - }); + this._firebase.onAuth(self._onLoginStateChange.bind(self)); + // this._firebaseAuthClient = new FirebaseSimpleLogin(this._firebase, function(error, user) { + // + // self._onLoginStateChange(error, user); + // }); } Firefeed.prototype = { _validateCallback: function(cb, notInit) { @@ -44,7 +47,7 @@ Firefeed.prototype = { throw new Error("Invalid onComplete callback provided"); } if (!notInit) { - if (!this._userid || !this._firebase) { + if (!this._uid || !this._firebase) { throw new Error("Method called without a preceding login() call"); } } @@ -60,7 +63,10 @@ Firefeed.prototype = { return match && decodeURIComponent(match[1].replace(/\+/g, " ")); }, _getPicURL: function(id, large) { - return "https://graph.facebook.com/" + (id || this._userid) + + if (id) { + id = id.replace('facebook:', ''); + } + return "https://graph.facebook.com/" + (id || this._uid.replace('facebook:', '')) + "/picture/?type=" + (large ? "large" : "square") + "&return_ssl_resources=1"; }, @@ -96,18 +102,19 @@ Firefeed.prototype = { ref: feed, handler: handler, eventType: "child_removed" }); }, - _onLoginStateChange: function(error, user) { + _onLoginStateChange: function(user) { + var self = this; - if (error) { - // An error occurred while authenticating the user. - this.handleLogout(); - } else if (user) { + if (user) { // The user is successfully logged in. this.onLogin(user); } else { // No existing session found - the user is logged out. this.onLogout(); } + }, + onStateChange: function(cb) { + this._firebase.onAuth(cb.bind(this)); } }; @@ -134,9 +141,7 @@ Firefeed.prototype.onLoginStateChange = function(onLoginStateChange) { * @param {string} provider The authentication provider to use. */ Firefeed.prototype.login = function(provider) { - this._firebaseAuthClient.login(provider, { - 'rememberMe': true - }); + this._firebase.authWithOAuthPopup(provider, this.onLogin.bind(this)); }; /** @@ -146,12 +151,12 @@ Firefeed.prototype.login = function(provider) { * permitted, as configured by security rules. */ Firefeed.prototype.logout = function() { - if (this._userid) { + if (this._uid) { // Set presence to offline, reset all instance variables, and return! - var peopleRef = this._firebase.child("people").child(this._userid); + var peopleRef = this._firebase.child("people").child(this._uid); peopleRef.child("presence").set("offline"); } - this._firebaseAuthClient.logout(); + this._firebase.unauth(); }; /** @@ -160,9 +165,21 @@ Firefeed.prototype.logout = function() { * sessions the user using a combination of browser cookies and local storage * so there is no need to do any additional sessioning here. */ + Firefeed.prototype.onLogin = function(user) { var self = this; - this._userid = user.id; + this._uid = user.uid; + this._facebookId = user.facebook.id; + + // adapt model to old scheme + var displayName = user.facebook.displayName.split(' '); + user.first_name = displayName[0]; + user.last_name = displayName[displayName.length - 1]; + user.id = user.facebook.id; + user.name = user.facebook.displayName; + user.location = ''; + user.bio = ''; + user.pic = this._getPicURL(user.id, false); // Populate search index var firstNameKey = [user['first_name'], user['last_name'], user['id']].join('|').toLowerCase(); @@ -170,26 +187,29 @@ Firefeed.prototype.onLogin = function(user) { this._firebase.child('search/firstName').child(firstNameKey).set(user['id']); this._firebase.child('search/lastName').child(lastNameKey).set(user['id']); - this._mainUser = self._firebase.child("users").child(self._userid); + this._mainUser = self._firebase.child("users").child(this._uid); this._fullName = user.name; this._name = user.first_name; - var peopleRef = self._firebase.child("people").child(self._userid); + var peopleRef = self._firebase.child("people").child(this._uid); peopleRef.once("value", function(peopleSnap) { var info = {}; var val = peopleSnap.val(); if (!val) { // If this is a first time login, upload user details. info = { - name: self._name, fullName: self._fullName, - location: "", bio: "", pic: self._getPicURL() + name: self._name, + fullName: self._fullName, + location: "", + bio: "", + pic: self._getPicURL() }; peopleRef.set(info); } else { info = val; } peopleRef.child("presence").set("online"); - info.id = self._userid; + info.id = self._ui; self._user = info; // Notify downstream listeners for new authenticated user state @@ -206,7 +226,7 @@ Firefeed.prototype.onLogin = function(user) { */ Firefeed.prototype.onLogout = function() { this._user = null; - this._userid = null; + this._facebookId = null; this._mainUser = null; this._fullName = null; this._name = null; @@ -367,7 +387,7 @@ Firefeed.prototype.follow = function(user, onComplete) { // Then, we add the current user to the followers list of user just followed. var followUser = self._firebase.child("users").child(user); - followUser.child("followers").child(self._userid).set(true); + followUser.child("followers").child(self._uid).set(true); // Last, we copy all previous sparks generated by the user just followed // to the feed of the current user so they will be displayed. @@ -403,9 +423,8 @@ Firefeed.prototype.post = function(content, onComplete) { // we get a unique ID for the spark that is chronologically ordered. var sparkRef = self._firebase.child("sparks").push(); var sparkRefId = sparkRef.name(); - var spark = { - author: self._userid, + author: self._uid, // uid for v2 security rules by: self._fullName, content: content, timestamp: new Date().getTime() @@ -433,7 +452,8 @@ Firefeed.prototype.post = function(content, onComplete) { // activity which we can use elsewhere to see "active" users. var time = new Date().getTime(); var recentUsersRef = self._firebase.child("recent-users"); - recentUsersRef.child(self._userid).setWithPriority(true, time); + + recentUsersRef.child(self._uid).setWithPriority(true, time); // We'll also add the spark to a separate list of most recent sparks // which can be displayed elsewhere, just like active users above. @@ -500,7 +520,7 @@ Firefeed.prototype.getSuggestedUsers = function(onSuggestedUser) { return true; // Stop enumerating. } var userid = recentUserSnap.name(); - if (userid == self._userid || followerList.indexOf(userid) >= 0) { + if (userid == self._uid || followerList.indexOf(userid) >= 0) { return; // Skip this one. } count++; @@ -520,7 +540,7 @@ Firefeed.prototype.getSuggestedUsers = function(onSuggestedUser) { * @param {Object} value The new value to write. */ Firefeed.prototype.setProfileField = function(field, value) { - var peopleRef = this._firebase.child("people").child(this._userid); + var peopleRef = this._firebase.child("people").child(this._uid); peopleRef.child(field).set(value); }; diff --git a/www/libs/bind-polyfill.js b/www/libs/bind-polyfill.js new file mode 100644 index 0000000..035a393 --- /dev/null +++ b/www/libs/bind-polyfill.js @@ -0,0 +1,30 @@ +(function() { + + // MDN .bind() Polyfill + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill + if (!Function.prototype.bind) { + Function.prototype.bind = function(oThis) { + if (typeof this !== 'function') { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function() {}, + fBound = function() { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; + } + +}()); \ No newline at end of file From 4b701f7227a07a1c1f5aa8dd9c8803ae941c5f99 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:30:19 -0700 Subject: [PATCH 05/12] New test specs --- test/index.html | 9 ++++--- test/spec/helper.js | 48 +++++++++++++++++++++++++++++++++++-- test/spec/initialization.js | 38 ++++++++++++----------------- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/test/index.html b/test/index.html index 61e8e49..14ee2c2 100644 --- a/test/index.html +++ b/test/index.html @@ -10,11 +10,10 @@ - - - - - + + + + diff --git a/test/spec/helper.js b/test/spec/helper.js index 17fd7ee..e38fcbc 100644 --- a/test/spec/helper.js +++ b/test/spec/helper.js @@ -3,10 +3,10 @@ var USER = "jasmine"; var USER2 = "jasmine2"; var TIMEOUT = 1000; -var BASEURL = "https://firefeed.firebaseio-staging.com"; +var BASEURL = "https://awesome-firebase.firebaseio.com"; // Replace $TOP_SECRET with the secret for BASEURL. -var tokenGenerator = new FirebaseTokenGenerator("$TOP_SECRET"); +var tokenGenerator = new FirebaseTokenGenerator('uTZgdJmwpcPqHtxqZ0gpNvqaODY2ELUYyGBfh3rb'); // We create a new context so we can auth independently. var makeAndLoginAs = function(user, cb) { @@ -32,3 +32,47 @@ var makeAndLoginAs = function(user, cb) { cb(ff); }); }; + +var helpers = { + + tokenGenerator: new FirebaseTokenGenerator('uTZgdJmwpcPqHtxqZ0gpNvqaODY2ELUYyGBfh3rb'), + + BASEURL: 'https://awesome-firebase.firebaseio.com', + + userOne: { + id: 1, + facebook: { + displayName: 'David East', + id: 100 + } + }, + + userTwo: { + id: 2, + facebook: { + displayName: 'Kato Wulf', + id: 200 + } + }, + + createFeed: function(params) { + return new Firefeed(this.BASEURL); + }, + setUserToLocalStorage: function(user, token) { + localStorage.clear(); + localStorage.setItem('authToken', token); + localStorage.setItem('userid', user); + localStorage.setItem('name', user); + localStorage.setItem('fullName', user); + }, + createUserToken: function(user) { + return this.tokenGenerator.createToken({id: user}); + }, + authenticate: function(feed, user, cb) { + debugger; + var token = this.createUserToken(user); + this.setUserToLocalStorage(user, token); + feed._firebase.authWithCustomToken(token, cb.bind(feed)); + } +}; + diff --git a/test/spec/initialization.js b/test/spec/initialization.js index 9e2e211..2d48685 100644 --- a/test/spec/initialization.js +++ b/test/spec/initialization.js @@ -2,38 +2,30 @@ describe("Initialization:", function() { var firefeed = null; + beforeEach(function() { + firefeed = helpers.createFeed(); + }); + + afterEach(function() { + firefeed.unload(); + firefeed = null; + }); + it("Constructor", function() { - firefeed = new Firefeed(BASEURL); expect(typeof firefeed).toBe(typeof {}); expect(firefeed._baseURL).toBe(BASEURL); }); it("Login", function() { - var flag = false; - - runs(function() { - makeAndLoginAs(USER, function(ff) { - expect(ff).toNotBe(null); - firefeed = ff; - flag = true; - }); - }); - - waitsFor(function() { - return flag; - }, "Login callback should be called", TIMEOUT); + spyOn(firefeed._firebase, 'authWithOAuthPopup'); + firefeed.login('facebook'); + expect(firefeed._firebase.authWithOAuthPopup).toHaveBeenCalled(); }); it("Logout", function() { + spyOn(firefeed._firebase, 'unauth'); firefeed.logout(); - expect(firefeed._firebase).toBe(null); - expect(firefeed._userid).toBe(null); - expect(firefeed._fullName).toBe(null); - expect(firefeed._name).toBe(null); - expect(firefeed._mainUser).toBe(null); - expect(localStorage.getItem("authToken")).toBe(null); - expect(localStorage.getItem("userid")).toBe(null); - expect(localStorage.getItem("name")).toBe(null); - expect(localStorage.getItem("fullName")).toBe(null); + expect(firefeed._firebase.unauth).toHaveBeenCalled(); }); + }); From 64c1b17c85fd51b9590ec8f0daf9cf539081bf0b Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 14:34:19 -0700 Subject: [PATCH 06/12] URL changes --- test/spec/helper.js | 4 ++-- www/js/firefeed-ui.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spec/helper.js b/test/spec/helper.js index e38fcbc..1cafb75 100644 --- a/test/spec/helper.js +++ b/test/spec/helper.js @@ -3,7 +3,7 @@ var USER = "jasmine"; var USER2 = "jasmine2"; var TIMEOUT = 1000; -var BASEURL = "https://awesome-firebase.firebaseio.com"; +var BASEURL = "https://firefeed-staging.firebaseio.com"; // Replace $TOP_SECRET with the secret for BASEURL. var tokenGenerator = new FirebaseTokenGenerator('uTZgdJmwpcPqHtxqZ0gpNvqaODY2ELUYyGBfh3rb'); @@ -37,7 +37,7 @@ var helpers = { tokenGenerator: new FirebaseTokenGenerator('uTZgdJmwpcPqHtxqZ0gpNvqaODY2ELUYyGBfh3rb'), - BASEURL: 'https://awesome-firebase.firebaseio.com', + BASEURL: 'https://firefeed-staging.firebaseio.com', userOne: { id: 1, diff --git a/www/js/firefeed-ui.js b/www/js/firefeed-ui.js index 69d59c6..c45cfec 100644 --- a/www/js/firefeed-ui.js +++ b/www/js/firefeed-ui.js @@ -8,7 +8,7 @@ function FirefeedUI() { this._limit = 141; this._loggedIn = false; this._spinner = new Spinner(); - this._firefeed = new Firefeed("https://awesome-firebase.firebaseio.com/"); + this._firefeed = new Firefeed("https://firefeed.firebaseio.com/"); this._unload = null; // Setup page navigation. From 2db10666d3203fa87286ada6e8a65697194a84e8 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 15:23:16 -0700 Subject: [PATCH 07/12] Uncommented out code. --- www/js/firefeed.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/www/js/firefeed.js b/www/js/firefeed.js index 8997f89..3d5da28 100644 --- a/www/js/firefeed.js +++ b/www/js/firefeed.js @@ -21,6 +21,7 @@ function Firefeed(baseURL, newContext) { this._searchHandler = null; this._currentSearch = null; this._baseURL = baseURL; + this._loginCount = 0; // Every time we call firebaseRef.on, we need to remember to call .off, // when requested by the caller via unload(). We'll store our handlers @@ -36,10 +37,6 @@ function Firefeed(baseURL, newContext) { this._authHandlers = []; this._firebase.onAuth(self._onLoginStateChange.bind(self)); - // this._firebaseAuthClient = new FirebaseSimpleLogin(this._firebase, function(error, user) { - // - // self._onLoginStateChange(error, user); - // }); } Firefeed.prototype = { _validateCallback: function(cb, notInit) { @@ -167,9 +164,13 @@ Firefeed.prototype.logout = function() { */ Firefeed.prototype.onLogin = function(user) { + this._loginCount = this._loginCount + 1; + console.log(this._loginCount); + console.log(user); + debugger; var self = this; this._uid = user.uid; - this._facebookId = user.facebook.id; + //this._facebookId = user.facebook.id; // adapt model to old scheme var displayName = user.facebook.displayName.split(' '); From 15a3e297cc3b7b06d9c0918bec9a3945368031cf Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 15:24:12 -0700 Subject: [PATCH 08/12] Removing debuggers; --- www/js/firefeed.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/www/js/firefeed.js b/www/js/firefeed.js index 3d5da28..fa693c7 100644 --- a/www/js/firefeed.js +++ b/www/js/firefeed.js @@ -21,7 +21,6 @@ function Firefeed(baseURL, newContext) { this._searchHandler = null; this._currentSearch = null; this._baseURL = baseURL; - this._loginCount = 0; // Every time we call firebaseRef.on, we need to remember to call .off, // when requested by the caller via unload(). We'll store our handlers @@ -164,10 +163,6 @@ Firefeed.prototype.logout = function() { */ Firefeed.prototype.onLogin = function(user) { - this._loginCount = this._loginCount + 1; - console.log(this._loginCount); - console.log(user); - debugger; var self = this; this._uid = user.uid; //this._facebookId = user.facebook.id; From f08168ddc84f2326d3c68488ce6db06753a651e7 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 15:31:00 -0700 Subject: [PATCH 09/12] URL Change. --- www/js/firefeed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/js/firefeed.js b/www/js/firefeed.js index fa693c7..128f044 100644 --- a/www/js/firefeed.js +++ b/www/js/firefeed.js @@ -165,7 +165,7 @@ Firefeed.prototype.logout = function() { Firefeed.prototype.onLogin = function(user) { var self = this; this._uid = user.uid; - //this._facebookId = user.facebook.id; + this._facebookId = user.facebook.id; // adapt model to old scheme var displayName = user.facebook.displayName.split(' '); From 92aa31347c0777659aa7bce8b42fb7c02e4f86f1 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 13 Oct 2014 16:39:31 -0700 Subject: [PATCH 10/12] ui to uid --- www/js/firefeed.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/js/firefeed.js b/www/js/firefeed.js index 128f044..6ec91a6 100644 --- a/www/js/firefeed.js +++ b/www/js/firefeed.js @@ -164,6 +164,8 @@ Firefeed.prototype.logout = function() { Firefeed.prototype.onLogin = function(user) { var self = this; + if (!user) { return; } + this._uid = user.uid; this._facebookId = user.facebook.id; @@ -205,7 +207,7 @@ Firefeed.prototype.onLogin = function(user) { info = val; } peopleRef.child("presence").set("online"); - info.id = self._ui; + info.id = self._uid; self._user = info; // Notify downstream listeners for new authenticated user state From 89c35dde7fdc93cc1a540ee4b14bc0457176a088 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 15 Oct 2014 07:19:18 -0700 Subject: [PATCH 11/12] Rules. Fixed profile follow button. --- rules.json | 18 +++++++++--------- www/index.html | 2 +- www/js/firefeed-ui.js | 10 +++++++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/rules.json b/rules.json index 337cdf5..397560c 100644 --- a/rules.json +++ b/rules.json @@ -6,13 +6,13 @@ // A list of users with their names on the site. "$userid": { // Only the user can write their own entry into this list. - ".write": "$userid == auth.id || $userid == auth.uid" + ".write": "$userid ==auth.uid" } }, "users": { "$userid": { // The user is allowed to write everything in their bucket. - ".write": "$userid == auth.id || $userid == auth.uid", + ".write": "$userid ==auth.uid", "following": { // The following list should only contain actual ids from the "people" list. "$followingid": { @@ -22,13 +22,13 @@ "followers": { // Anyone can add themself to to this user's followers list. "$followerid": { - ".write": "$followerid == auth.id || $followerid == auth.uid" + ".write": "$followerid ==auth.uid" } }, "feed": { "$sparkid": { // User A can write in user B's feed, but only if A is following B, and only for sparks for which they are the author. - ".write": "(root.child('users/' + $userid + '/following').hasChild(auth.id) && root.child('sparks/' + $sparkid + '/author').val() == auth.id) || (root.child('users/' + $userid + '/following').hasChild(auth.uid) && root.child('sparks/' + $sparkid + '/author').val() == auth.uid)" + ".write": "root.child('users/' + $userid + '/following').hasChild(auth.uid) && root.child('sparks/' + $sparkid + '/author').val() ==auth.uid" } } } @@ -42,7 +42,7 @@ ".validate": "newData.hasChildren(['author', 'content'])", // A user can attribute a spark only to themselves. "author": { - ".validate": "newData.val() == auth.id || newData.val() == auth.uid" + ".validate": "newData.val() ==auth.uid" }, "content": { ".validate": "newData.isString()" @@ -52,24 +52,24 @@ "recent-users": { // Users can add themselves to the list of users with recent activity. "$userid": { - ".write": "$userid == auth.id || $userid == auth.uid" + ".write": "$userid ==auth.uid" } }, "recent-sparks": { // Authors of sparks can add their sparks to this list. "$sparkid": { - ".write": "root.child('sparks/' + $sparkid + '/author').val() == auth.id || root.child('sparks/' + $sparkid + '/author').val() == auth.uid" + ".write": "root.child('sparks/' + $sparkid + '/author').val() ==auth.uid" } }, "search": { "firstName": { "$searchKey": { - ".write": "auth != null && ((root.child('people/' + auth.id + '/firstName').val() + '|' + root.child('people/' + auth.id + '/lastName').val() + '|' + auth.id) == $searchKey || (root.child('people/' + auth.uid + '/firstName').val() + '|' + root.child('people/' + auth.uid + '/lastName').val() + '|' + auth.uid) == $searchKey) && (newData.val() == auth.id || newData.val() == auth.uid)" + ".write": "auth != null && (root.child('people/' +auth.uid + '/firstName').val() + '|' + root.child('people/' +auth.uid + '/lastName').val() + '|' +auth.uid) == $searchKey && newData.val() ==auth.uid" } }, "lastName": { "$searchKey": { - ".write": "auth != null && ((root.child('people/' + auth.id + '/lastName').val() + '|' + root.child('people/' + auth.id + '/firstName').val() + '|' + auth.id) == $searchKey || (root.child('people/' + auth.uid + '/lastName').val() + '|' + root.child('people/' + auth.uid + '/firstName').val() + '|' + auth.uid) == $searchKey) && (newData.val() == auth.id || newData.val() == auth.uid)" + ".write": "auth != null && (root.child('people/' +auth.uid + '/lastName').val() + '|' + root.child('people/' +auth.uid + '/firstName').val() + '|' +auth.uid) == $searchKey && newData.val() ==auth.uid" } } } diff --git a/www/index.html b/www/index.html index 47113ce..bfb973d 100644 --- a/www/index.html +++ b/www/index.html @@ -217,7 +217,7 @@

{{fullName}}

{{location}}

{{bio}}

diff --git a/www/js/firefeed-ui.js b/www/js/firefeed-ui.js index c45cfec..9692606 100644 --- a/www/js/firefeed-ui.js +++ b/www/js/firefeed-ui.js @@ -341,6 +341,7 @@ FirefeedUI.prototype.renderTimeline = function(info) { FirefeedUI.prototype.renderProfile = function(uid) { var self = this; + var facebookId = uid.replace('facebook:', ''); $("#header").html(Mustache.to_html($("#tmpl-page-header").html(), {user: self._loggedIn})); // Render profile page body. @@ -363,15 +364,18 @@ FirefeedUI.prototype.renderProfile = function(uid) { info.id = uid; var content = Mustache.to_html($("#tmpl-profile-content").html(), info); $("#profile-content").html(content); - var button = $("#followBtn-" + info.id); + var button = $('.btn-follow'); // Show follow button if logged in. if (self._loggedIn && self._loggedIn.id != info.id) { button.click(function(e) { + var $clickedButton = $(e.target); + var clickedButtonId = $clickedButton.data('id'); e.preventDefault(); - self._firefeed.follow(info.id, function(err, done) { + + self._firefeed.follow(clickedButtonId, function(err, done) { // TODO FIXME: Check for errors! - $("#followBtn-" + info.id).fadeOut(1500); + $clickedButton.fadeOut(1500); }); }); } else { From d70cd7fe67feaccb255e6da2dc3fb4a31fe9db06 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 15 Oct 2014 10:17:01 -0700 Subject: [PATCH 12/12] Dependencies. --- package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fb3951b..bbdaa60 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,9 @@ "url": "https://github.com/firebase/firefeed/issues" }, "homepage": "https://github.com/firebase/firefeed", - "dependencies": {} + "dependencies": { + "gulp": "^3.8.8", + "gulp-connect": "^2.0.6", + "gulp-open": "^0.2.8" + } }