Browse Source

Implemented local contact storage.

pull/48/head
Simon Eisenmann 11 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 @@ @@ -126,10 +126,10 @@
}
.buddy {
&.withSubline .buddy1 {
&.withSubline .buddy1, &.contact .buddy1 {
top: 15px;
}
&.withSubline .buddy2 {
&.withSubline .buddy2, &.contact .buddy2 {
display: block;
}
&.hovered .buddyactions {

1
static/js/controllers/mediastreamcontroller.js

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

11
static/js/services/appdata.js

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

25
static/js/services/buddylist.js

@ -67,6 +67,12 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text! @@ -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.
*/
@ -535,7 +541,10 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text! @@ -535,7 +541,10 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
this.updateDisplay(sessionData.Id, scope, sessionData, "status");
} else if (scope.contact) {
// 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) {
scope.$apply();
@ -567,7 +576,7 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text! @@ -567,7 +576,7 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
Buddylist.prototype.onContactAdded = function(contact) {
console.log("onContactAdded", contact);
//console.log("onContactAdded", contact);
var userid = contact.Userid;
var scope = buddyData.get(userid);
@ -581,17 +590,23 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text! @@ -581,17 +590,23 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
console.log("Injected status into contact", contact);
}
this.updateDisplay(sessionData.Id, scope, contact, "status");
scope.$apply();
}
} else {
// TODO(longsleep): Implement rendering of contacts without scope.
console.log("No scope for contact", userid);
// Create new scope for contact.
scope = this.onJoined({
Id: contact.Userid,
Userid: contact.Userid,
Status: contact.Status
});
scope.contact = contact;
}
};
Buddylist.prototype.onContactRemoved = function(contact) {
console.log("onContactRemoved", contact);
//console.log("onContactRemoved", contact);
var userid = contact.Userid;
var scope = buddyData.get(userid);

41
static/js/services/buddysession.js

@ -30,7 +30,7 @@ define(["underscore"], function(_) { @@ -30,7 +30,7 @@ define(["underscore"], function(_) {
this.serial = serials++;
this.sessions = {};
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;
if (data.Id) {
var userid = data.Userid || null;
@ -78,7 +78,7 @@ define(["underscore"], function(_) { @@ -78,7 +78,7 @@ define(["underscore"], function(_) {
} else {
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) {
@ -96,9 +96,9 @@ define(["underscore"], function(_) { @@ -96,9 +96,9 @@ define(["underscore"], function(_) {
if (sessionData) {
this.use(sessionData.Id, sessionData);
} else {
console.log("Last session removed", sessions);
//console.log("Last session removed", sessions);
if (this.Userid) {
console.log("Using userid as session id");
//console.log("Using userid as session id");
this.use(this.Userid);
} else {
this.use(null);
@ -112,22 +112,29 @@ define(["underscore"], function(_) { @@ -112,22 +112,29 @@ define(["underscore"], function(_) {
BuddySession.prototype.update = function(id, data, onUseridCallback) {
var sessionData = this.get(id);
if (!sessionData) {
sessionData = this.add(id, data);
}
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) {
this.auth(userid, sessionData, onUseridCallback);
}
if (data.Rev) {
sessionData.Rev = data.Rev;
}
if (data.Status) {
sessionData.Status = data.Status;
if (data !== sessionData) {
if (data.Rev) {
sessionData.Rev = data.Rev;
}
if (data.Status) {
sessionData.Status = data.Status;
}
}
if (id === this.Id) {
@ -142,7 +149,7 @@ define(["underscore"], function(_) { @@ -142,7 +149,7 @@ define(["underscore"], function(_) {
if (!this.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.
if (onUseridCallback && !sessionData.auth) {

16
static/js/services/contactdata.js

@ -29,7 +29,7 @@ define(['underscore', 'jquery'], function(underscore, $) { @@ -29,7 +29,7 @@ define(['underscore', 'jquery'], function(underscore, $) {
var contactData = {
addByRequest: function(request, status) {
console.log("addByRequest", request, status);
//console.log("addByRequest", request, status);
var userid = request.Userid;
var token = request.Token;
var id;
@ -46,7 +46,19 @@ define(['underscore', 'jquery'], function(underscore, $) { @@ -46,7 +46,19 @@ define(['underscore', 'jquery'], function(underscore, $) {
Token: token,
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;
},
get: function(userid) {

120
static/js/services/contacts.js

@ -18,28 +18,142 @@ @@ -18,28 +18,142 @@
* 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
return ["contactData", function(contactData) {
return ["appData", "contactData", function(appData, contactData) {
var Contacts = function() {
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) {
var contact = contactData.addByRequest(request, status);
this.e.triggerHandler("contactadded", contact);
if (database) {
database.put({
id: contact.Userid,
contact: contact
})
}
};
Contacts.prototype.remove = function(userid) {
var contact = contactData.get(userid);
//console.log("contacts remove", userid, contact);
console.log("contacts remove", userid, contact);
if (contact) {
contactData.remove(userid);
if (database) {
database.delete(userid);
}
this.e.triggerHandler("contactremoved", contact);
}

2
static/partials/buddy.html

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<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="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>

Loading…
Cancel
Save