Browse Source

Implemented local contact storage.

pull/48/head
Simon Eisenmann 12 years ago
parent
commit
4e31529b3b
  1. 4
      src/styles/components/_buddylist.scss
  2. 1
      static/js/controllers/mediastreamcontroller.js
  3. 11
      static/js/services/appdata.js
  4. 25
      static/js/services/buddylist.js
  5. 41
      static/js/services/buddysession.js
  6. 16
      static/js/services/contactdata.js
  7. 120
      static/js/services/contacts.js
  8. 2
      static/partials/buddy.html

4
src/styles/components/_buddylist.scss

@ -126,10 +126,10 @@
} }
.buddy { .buddy {
&.withSubline .buddy1 { &.withSubline .buddy1, &.contact .buddy1 {
top: 15px; top: 15px;
} }
&.withSubline .buddy2 { &.withSubline .buddy2, &.contact .buddy2 {
display: block; display: block;
} }
&.hovered .buddyactions { &.hovered .buddyactions {

1
static/js/controllers/mediastreamcontroller.js

@ -624,6 +624,7 @@ define(['underscore', 'bigscreen', 'moment', 'sjcl', 'webrtc.adapter'], function
if (userid) { if (userid) {
console.info("Session is now authenticated:", userid); console.info("Session is now authenticated:", userid);
} }
appData.e.triggerHandler("authenticationChanged", [userid]);
}); });
// Apply all layout stuff as classes to our element. // Apply all layout stuff as classes to our element.

11
static/js/services/appdata.js

@ -18,13 +18,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
define([], function() { define(["jquery"], function($) {
// appData.e events
// - authenticationChanged(userid)
// appData // appData
return [function() { return [function() {
var data = { var data = {
data: null data: null,
e: $({})
} }
var appData = { var appData = {
get: function() { get: function() {
@ -33,7 +37,8 @@ define([], function() {
set: function(d) { set: function(d) {
data.data = d; data.data = d;
return d; return d;
} },
e: data.e
} }
return appData; return appData;

25
static/js/services/buddylist.js

@ -67,6 +67,12 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
}; };
BuddyTree.prototype.check = function(id) {
return this.data.hasOwnProperty(id);
};
/** /**
* Returns undefined when no change required. Position result otherwise. * Returns undefined when no change required. Position result otherwise.
*/ */
@ -535,7 +541,10 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
this.updateDisplay(sessionData.Id, scope, sessionData, "status"); this.updateDisplay(sessionData.Id, scope, sessionData, "status");
} else if (scope.contact) { } else if (scope.contact) {
// Use it with userid as id in tree. // Use it with userid as id in tree.
this.tree.add(session.Userid, scope); if (!this.tree.check(session.Userid)) {
this.tree.add(session.Userid, scope);
buddyCount++;
}
} }
if (!noApply) { if (!noApply) {
scope.$apply(); scope.$apply();
@ -567,7 +576,7 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
Buddylist.prototype.onContactAdded = function(contact) { Buddylist.prototype.onContactAdded = function(contact) {
console.log("onContactAdded", contact); //console.log("onContactAdded", contact);
var userid = contact.Userid; var userid = contact.Userid;
var scope = buddyData.get(userid); var scope = buddyData.get(userid);
@ -581,17 +590,23 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
console.log("Injected status into contact", contact); console.log("Injected status into contact", contact);
} }
this.updateDisplay(sessionData.Id, scope, contact, "status"); this.updateDisplay(sessionData.Id, scope, contact, "status");
scope.$apply();
} }
} else { } else {
// TODO(longsleep): Implement rendering of contacts without scope. // Create new scope for contact.
console.log("No scope for contact", userid); scope = this.onJoined({
Id: contact.Userid,
Userid: contact.Userid,
Status: contact.Status
});
scope.contact = contact;
} }
}; };
Buddylist.prototype.onContactRemoved = function(contact) { Buddylist.prototype.onContactRemoved = function(contact) {
console.log("onContactRemoved", contact); //console.log("onContactRemoved", contact);
var userid = contact.Userid; var userid = contact.Userid;
var scope = buddyData.get(userid); var scope = buddyData.get(userid);

41
static/js/services/buddysession.js

@ -30,7 +30,7 @@ define(["underscore"], function(_) {
this.serial = serials++; this.serial = serials++;
this.sessions = {}; this.sessions = {};
this.count = 0; this.count = 0;
//console.log("creating session", this.serial, this); //console.log("creating session", this.serial, data.Id, data.Userid, this);
var id = data.Id; var id = data.Id;
if (data.Id) { if (data.Id) {
var userid = data.Userid || null; var userid = data.Userid || null;
@ -78,7 +78,7 @@ define(["underscore"], function(_) {
} else { } else {
this.Id = null; this.Id = null;
} }
console.log("Use session as default", id, data, this); //console.log("Use session as default", id, data, this);
}; };
BuddySession.prototype.remove = function(id, onEmptyCallback) { BuddySession.prototype.remove = function(id, onEmptyCallback) {
@ -96,9 +96,9 @@ define(["underscore"], function(_) {
if (sessionData) { if (sessionData) {
this.use(sessionData.Id, sessionData); this.use(sessionData.Id, sessionData);
} else { } else {
console.log("Last session removed", sessions); //console.log("Last session removed", sessions);
if (this.Userid) { if (this.Userid) {
console.log("Using userid as session id"); //console.log("Using userid as session id");
this.use(this.Userid); this.use(this.Userid);
} else { } else {
this.use(null); this.use(null);
@ -112,22 +112,29 @@ define(["underscore"], function(_) {
BuddySession.prototype.update = function(id, data, onUseridCallback) { BuddySession.prototype.update = function(id, data, onUseridCallback) {
var sessionData = this.get(id);
if (!sessionData) {
sessionData = this.add(id, data);
}
var userid = data.Userid; var userid = data.Userid;
//console.log("session update", id, userid, this, data);
var sessionData
if (id === userid) {
// Fake updates from userid ids.
sessionData = data;
} else {
sessionData = this.get(id);
if (!sessionData) {
sessionData = this.add(id, data);
}
}
if (userid) { if (userid) {
this.auth(userid, sessionData, onUseridCallback); this.auth(userid, sessionData, onUseridCallback);
} }
if (data !== sessionData) {
if (data.Rev) { if (data.Rev) {
sessionData.Rev = data.Rev; sessionData.Rev = data.Rev;
} }
if (data.Status) {
if (data.Status) { sessionData.Status = data.Status;
sessionData.Status = data.Status; }
} }
if (id === this.Id) { if (id === this.Id) {
@ -142,7 +149,7 @@ define(["underscore"], function(_) {
if (!this.Userid) { if (!this.Userid) {
this.Userid = userid; this.Userid = userid;
console.log("Session now has a user id", this.Id, userid); //console.log("Session now has a user id", this.Id, userid);
} }
// Trigger callback if defined and not triggered before. // Trigger callback if defined and not triggered before.
if (onUseridCallback && !sessionData.auth) { if (onUseridCallback && !sessionData.auth) {

16
static/js/services/contactdata.js

@ -29,7 +29,7 @@ define(['underscore', 'jquery'], function(underscore, $) {
var contactData = { var contactData = {
addByRequest: function(request, status) { addByRequest: function(request, status) {
console.log("addByRequest", request, status); //console.log("addByRequest", request, status);
var userid = request.Userid; var userid = request.Userid;
var token = request.Token; var token = request.Token;
var id; var id;
@ -46,7 +46,19 @@ define(['underscore', 'jquery'], function(underscore, $) {
Token: token, Token: token,
Status: null Status: null
} }
// TODO(longsleep): Trigger this to somewhere. return contact;
},
addByData: function(data) {
//console.log("addByData", data.Userid, data);
var userid = data.Userid;
if (users.hasOwnProperty(userid)) {
id = users[userid]
} else {
id = String(count++);
users[userid] = id;
}
var contact = contacts[id] = data;
contact.Id = id;
return contact; return contact;
}, },
get: function(userid) { get: function(userid) {

120
static/js/services/contacts.js

@ -18,28 +18,142 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
define(['underscore', 'jquery'], function(underscore, $) { define(['underscore', 'jquery', 'modernizr'], function(underscore, $, Modernizr) {
var Database = function(name, version) {
this.ready = false;
this.db = null;
this.name = name;
this.e = $({});
var request = indexedDB.open("mediastream", version);
var that = this;
request.onupgradeneeded = function(event) {
var db = event.target.result;
var transaction = event.target.transaction;
transaction.onerror = _.bind(that.onerror, that);
if (db.objectStoreNames.contains(name)) {
// TODO(longsleep): Database upgrade should keep the data and migrate it.
db.deleteObjectStore("contacts")
console.warn("Removed contacts database with old format.")
}
db.createObjectStore(name, {
// We use id field as our unique identifier.
keyPath: "id"
});
console.log("Created contacts database.")
};
request.onsuccess = _.bind(that.onsuccess, that);
};
Database.prototype.onerror = function(event) {
console.log("IndexDB database error", event);
};
Database.prototype.onsuccess = function(event) {
this.db = event.target.result;
this.ready = true;
console.log("Openend database for contacts", this.db);
this.e.triggerHandler("ready");
};
Database.prototype.put = function(data, successCallback, errorCallback) {
var transaction = this.db.transaction(this.name, "readwrite");
var store = transaction.objectStore(this.name);
var request = store.put(data);
if (!errorCallback) {
errorCallback = _.bind(this.onerror, this);
}
transaction.onerror = request.onerror = errorCallback;
if (successCallback) {
request.onsuccess = successCallback;
}
return request;
};
Database.prototype.delete = function(id, successCallback, errorCallback) {
var transaction = this.db.transaction(this.name, "readwrite");
var store = transaction.objectStore(this.name);
var request = store.delete(id);
if (!errorCallback) {
errorCallback = _.bind(this.onerror, this);
}
transaction.onerror = request.onerror = errorCallback;
if (successCallback) {
request.onsuccess = successCallback;
}
return request;
};
Database.prototype.all = function(iteratorCallback, errorCallback) {
var transaction = this.db.transaction(this.name);
var store = transaction.objectStore(this.name);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(event) {
var result = event.target.result;
if (!!result === false) {
return;
}
//console.log("read data idb", result, event);
iteratorCallback(result.value);
result.continue();
};
if (!errorCallback) {
errorCallback = _.bind(this.onerror, this);
}
transaction.onerror = cursorRequest.onerror = errorCallback;
return cursorRequest;
};
var database;
if (Modernizr.indexeddb) {
database = new Database("contacts", 1);
}
// contacts // contacts
return ["contactData", function(contactData) { return ["appData", "contactData", function(appData, contactData) {
var Contacts = function() { var Contacts = function() {
this.e = $({}); this.e = $({});
this.userid = null;
appData.e.on("authenticationChanged", _.bind(function(event, userid) {
this.userid = userid;
if (database && userid) {
// TODO(longsleep): This needs to be delayed util self has ha userid.
if (database.ready) {
_.defer(_.bind(this.load, this));
} else {
database.e.one("ready", _.bind(this.load, this));
}
}
}, this));
};
Contacts.prototype.load = function() {
console.log("Load contacts from storage", database);
database.all(_.bind(function(data) {
var contact = contactData.addByData(data.contact);
this.e.triggerHandler("contactadded", contact);
}, this));
}; };
Contacts.prototype.add = function(request, status) { Contacts.prototype.add = function(request, status) {
var contact = contactData.addByRequest(request, status); var contact = contactData.addByRequest(request, status);
this.e.triggerHandler("contactadded", contact); this.e.triggerHandler("contactadded", contact);
if (database) {
database.put({
id: contact.Userid,
contact: contact
})
}
}; };
Contacts.prototype.remove = function(userid) { Contacts.prototype.remove = function(userid) {
var contact = contactData.get(userid); var contact = contactData.get(userid);
//console.log("contacts remove", userid, contact); console.log("contacts remove", userid, contact);
if (contact) { if (contact) {
contactData.remove(userid); contactData.remove(userid);
if (database) {
database.delete(userid);
}
this.e.triggerHandler("contactremoved", contact); this.e.triggerHandler("contactremoved", contact);
} }

2
static/partials/buddy.html

@ -1,5 +1,5 @@
<div class="buddy" ng-class="{'contact': contact, 'withSubline': display.subLine}"> <div class="buddy" ng-class="{'contact': contact, 'withSubline': display.subLine}">
<div class="buddyPicture"><i class="fa fa-user fa-3x"/><img ng-show="display.buddyPicture" alt ng-src="{{display.buddyPicture}}" width="46" height="46"/></div> <div class="buddyPicture"><i class="fa fa-user fa-3x"/><img ng-show="display.buddyPicture" alt ng-src="{{display.buddyPicture}}" width="46" height="46"/></div>
<div class="buddy1">{{session.Id|displayName}}</div> <div class="buddy1">{{session.Id|displayName}} {{session.serial}}</div>
<div class="buddy2"><span ng-show="session.Userid"><i class="fa contact"></i><span ng-show="session.count"> ({{session.count}})</span></span> {{display.subLine}}</div> <div class="buddy2"><span ng-show="session.Userid"><i class="fa contact"></i><span ng-show="session.count"> ({{session.count}})</span></span> {{display.subLine}}</div>
</div> </div>

Loading…
Cancel
Save