diff --git a/static/js/services/buddydata.js b/static/js/services/buddydata.js
index fc0e110e..212b898d 100644
--- a/static/js/services/buddydata.js
+++ b/static/js/services/buddydata.js
@@ -67,9 +67,20 @@ define(['underscore'], function(underscore) {
} else if (!createInParent && pushed.hasOwnProperty(id)) {
return pushed[id].scope;
} else {
+ var scope;
+ if (userid && scopes.hasOwnProperty(userid)) {
+ scope = scopes[userid];
+ if (createInParent) {
+ scopes[id] = scope;
+ }
+ return scope;
+ }
if (createInParent) {
// If we have a parent we can create a new scope.
- var scope = scopes[id] = createInParent.$new();
+ scope = scopes[id] = createInParent.$new();
+ if (userid) {
+ scopes[userid] = scope;
+ }
scope.buddyIndex = ++count;
if (userid) {
scope.contact = contactData.get(userid);
@@ -107,12 +118,17 @@ define(['underscore'], function(underscore) {
var scope = scopes[id];
if (scope) {
scope.$destroy();
- brain[id] = scope;
+ if (!hard) {
+ brain[id] = scope;
+ }
delete scopes[id];
return scope;
} else {
return null;
}
+ },
+ set: function(id, scope) {
+ scopes[id] = scope;
}
};
return buddyData;
diff --git a/static/js/services/buddylist.js b/static/js/services/buddylist.js
index d2d20718..d4d9dd56 100644
--- a/static/js/services/buddylist.js
+++ b/static/js/services/buddylist.js
@@ -116,7 +116,7 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
};
// buddyList
- return ["$window", "$compile", "playSound", "buddyData", "fastScroll", "mediaStream", function($window, $compile, playSound, buddyData, fastScroll, mediaStream) {
+ return ["$window", "$compile", "playSound", "buddyData", "buddySession", "fastScroll", "mediaStream", function($window, $compile, playSound, buddyData, buddySession, fastScroll, mediaStream) {
var requestAnimationFrame = $window.requestAnimationFrame;
@@ -196,7 +196,7 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
};
- Buddylist.prototype.onBuddyScope = function(scope) {
+ Buddylist.prototype.onBuddyScopeCreated = function(scope) {
scope.element = null;
scope.doDefault = function() {
@@ -217,6 +217,28 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
};
+ Buddylist.prototype.onBuddySessionUserid = function(scope, sourceSession) {
+
+ var targetScope = buddyData.get(sourceSession.Userid);
+ if (targetScope === scope) {
+ // No action.
+ return;
+ }
+ // Merge sessions.
+ targetScope.session.merge(sourceSession);
+ // Cleanup old from tree and DOM.
+ var id = sourceSession.Id;
+ this.tree.remove(id);
+ if (scope.element) {
+ this.lefts[id] = scope.element;
+ scope.element = null;
+ }
+ scope.$destroy();
+ buddyData.set(id, targetScope);
+ delete this.actionElements[id];
+
+ };
+
Buddylist.prototype.soundLoop = function() {
if (this.playSoundLeft) {
@@ -354,22 +376,21 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
//console.log("onStatus", data);
var id = data.Id;
- var scope = buddyData.get(id, this.$scope, _.bind(this.onBuddyScope, this), data.Userid);
+ var scope = buddyData.get(id, this.$scope, _.bind(function(scope) {
+ this.onBuddyScopeCreated(scope);
+ scope.session = buddySession.create(data);
+ }, this), data.Userid);
// Update session.
- if (scope.session.Userid !== data.Userid) {
- scope.session.Userid = data.Userid;
- console.log("onStatus session is now userid", id, data.Userid);
- }
- // Update status.
- if (true) {
- if (data.Rev) {
- scope.session.Rev = data.Rev;
- }
- scope.status = data.Status;
- this.updateBuddyPicture(scope.status);
+ var sessionData = scope.session.update(id, data, _.bind(function(session) {
+ //console.log("Session is now authenticated", session);
+ this.onBuddySessionUserid(scope, session);
+ }, this));
+ if (sessionData) {
+ // onStatus for main session.
+ scope.status = sessionData.Status;
var displayName = scope.displayName;
- if (scope.status.displayName) {
- scope.displayName = scope.status.displayName;
+ if (sessionData.Status.displayName) {
+ scope.displayName = sessionData.Status.displayName;
} else {
scope.displayName = null;
}
@@ -377,8 +398,9 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
var before = this.tree.update(id, scope);
this.queue.push(["status", id, before]);
}
- scope.$apply();
+ this.updateBuddyPicture(sessionData.Status);
}
+ scope.$apply();
};
@@ -386,31 +408,24 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
//console.log("Joined", data);
var id = data.Id;
- var scope = buddyData.get(id, this.$scope, _.bind(this.onBuddyScope, this), data.Userid);
- // Create session.
- scope.session = {
- Id: data.Id,
- Userid: data.Userid,
- Ua: data.Ua,
- Rev: 0
- };
- // Add status.
+ var scope = buddyData.get(id, this.$scope, _.bind(function(scope) {
+ this.onBuddyScopeCreated(scope);
+ scope.session = buddySession.create(data);
+ }, this), data.Userid);
+ // Update session.
buddyCount++;
- if (data.Status) {
- if (true) {
- if (data.Rev) {
- scope.session.Rev = data.Rev;
- }
- scope.status = data.Status;
- scope.displayName = scope.status.displayName;
- this.updateBuddyPicture(scope.status);
+ var sessionData = scope.session.update(id, data);
+ if (sessionData && sessionData.Status) {
+ scope.status = sessionData.Status;
+ scope.displayName = sessionData.Status.displayName;
+ this.updateBuddyPicture(sessionData.Status);
+ if (!scope.element) {
+ var before = this.tree.add(id, scope);
+ this.queue.push(["joined", id, before]);
+ this.playSoundJoined = true;
}
- }
- //console.log("Joined scope", scope, scope.element);
- if (!scope.element) {
- var before = this.tree.add(id, scope);
- this.queue.push(["joined", id, before]);
- this.playSoundJoined = true;
+ } else {
+ scope.$apply();
}
};
@@ -438,9 +453,8 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
Buddylist.prototype.onLeft = function(data) {
- //console.log("Left", session);
+ //console.log("Left", data);
var id = data.Id;
- this.tree.remove(id);
var scope = buddyData.get(id);
if (!scope) {
//console.warn("Trying to remove buddy with no registered scope", session);
@@ -449,12 +463,21 @@ define(['underscore', 'modernizr', 'avltree', 'text!partials/buddy.html', 'text!
if (buddyCount > 0) {
buddyCount--;
}
- if (scope.element) {
- this.lefts[id] = scope.element;
- this.playSoundLeft = true;
+ if (scope.session.remove(id)) {
+ // No session left. Cleanup.
+ this.tree.remove(id);
+ if (scope.element) {
+ this.lefts[id] = scope.element;
+ this.playSoundLeft = true;
+ }
+ buddyData.del(id);
+ if (scope.session.Userid) {
+ buddyData.del(scope.session.Userid);
+ }
+ delete this.actionElements[id];
+ } else {
+ scope.$apply();
}
- buddyData.del(id);
- delete this.actionElements[id];
};
diff --git a/static/js/services/buddysession.js b/static/js/services/buddysession.js
new file mode 100644
index 00000000..cd240f57
--- /dev/null
+++ b/static/js/services/buddysession.js
@@ -0,0 +1,140 @@
+/*
+ * Spreed WebRTC.
+ * Copyright (C) 2013-2014 struktur AG
+ *
+ * This file is part of Spreed WebRTC.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see