diff --git a/webclient/app.css b/webclient/app.css
index a277bd2a59..4a4ba7b8f4 100755
--- a/webclient/app.css
+++ b/webclient/app.css
@@ -528,8 +528,8 @@ a:active { color: #000; }
}
.bubble .message {
- /* Break lines when encountering CR+LF */
- white-space: pre;
+ /* Wrap words and break lines on CR+LF */
+ white-space: pre-wrap;
}
.bubble .messagePending {
opacity: 0.3
diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js
index 705a5a07f2..4604ff6192 100644
--- a/webclient/components/matrix/event-handler-service.js
+++ b/webclient/components/matrix/event-handler-service.js
@@ -38,6 +38,13 @@ angular.module('eventHandlerService', [])
var TOPIC_EVENT = "TOPIC_EVENT";
var RESET_EVENT = "RESET_EVENT"; // eventHandlerService has been resetted
+ // used for dedupping events - could be expanded in future...
+ // FIXME: means that we leak memory over time (along with lots of the rest
+ // of the app, given we never try to reap memory yet)
+ var eventMap = {};
+
+ $rootScope.presence = {};
+
var initialSyncDeferred;
var reset = function() {
@@ -46,16 +53,13 @@ angular.module('eventHandlerService', [])
$rootScope.events = {
rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
};
- }
- reset();
- // used for dedupping events - could be expanded in future...
- // FIXME: means that we leak memory over time (along with lots of the rest
- // of the app, given we never try to reap memory yet)
- var eventMap = {};
+ $rootScope.presence = {};
+
+ eventMap = {};
+ };
+ reset();
- $rootScope.presence = {};
-
var initRoom = function(room_id) {
if (!(room_id in $rootScope.events.rooms)) {
console.log("Creating new handler entry for " + room_id);
@@ -204,7 +208,7 @@ angular.module('eventHandlerService', [])
var handleCallEvent = function(event, isLiveEvent) {
$rootScope.$broadcast(CALL_EVENT, event, isLiveEvent);
- if (event.type == 'm.call.invite') {
+ if (event.type === 'm.call.invite') {
$rootScope.events.rooms[event.room_id].messages.push(event);
}
};
@@ -231,7 +235,7 @@ angular.module('eventHandlerService', [])
}
}
return index;
- }
+ };
return {
ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
diff --git a/webclient/components/matrix/matrix-call.js b/webclient/components/matrix/matrix-call.js
index 2e3e2b0967..fd21198d24 100644
--- a/webclient/components/matrix/matrix-call.js
+++ b/webclient/components/matrix/matrix-call.js
@@ -47,6 +47,10 @@ angular.module('MatrixCall', [])
this.call_id = "c" + new Date().getTime();
this.state = 'fledgling';
this.didConnect = false;
+
+ // a queue for candidates waiting to go out. We try to amalgamate candidates into a single candidate message where possible
+ this.candidateSendQueue = [];
+ this.candidateSendTries = 0;
}
MatrixCall.prototype.createPeerConnection = function() {
@@ -174,12 +178,7 @@ angular.module('MatrixCall', [])
MatrixCall.prototype.gotLocalIceCandidate = function(event) {
console.log(event);
if (event.candidate) {
- var content = {
- version: 0,
- call_id: this.call_id,
- candidate: event.candidate
- };
- this.sendEventWithRetry('m.call.candidate', content);
+ this.sendCandidate(event.candidate);
}
}
@@ -370,5 +369,53 @@ angular.module('MatrixCall', [])
}, delayMs);
};
+ // Sends candidates with are sent in a special way because we try to amalgamate them into one message
+ MatrixCall.prototype.sendCandidate = function(content) {
+ this.candidateSendQueue.push(content);
+ var self = this;
+ if (this.candidateSendTries == 0) $timeout(function() { self.sendCandidateQueue(); }, 100);
+ };
+
+ MatrixCall.prototype.sendCandidateQueue = function(content) {
+ if (this.candidateSendQueue.length == 0) return;
+
+ var cands = this.candidateSendQueue;
+ this.candidateSendQueue = [];
+ ++this.candidateSendTries;
+ var content = {
+ version: 0,
+ call_id: this.call_id,
+ candidates: cands
+ };
+ var self = this;
+ console.log("Attempting to send "+cands.length+" candidates");
+ matrixService.sendEvent(self.room_id, 'm.call.candidates', undefined, content).then(function() { self.candsSent(); }, function(error) { self.candsSendFailed(cands, error); } );
+ };
+
+ MatrixCall.prototype.candsSent = function() {
+ this.candidateSendTries = 0;
+ this.sendCandidateQueue();
+ };
+
+ MatrixCall.prototype.candsSendFailed = function(cands, error) {
+ for (var i = 0; i < cands.length; ++i) {
+ this.candidateSendQueue.push(cands[i]);
+ }
+
+ if (this.candidateSendTries > 5) {
+ console.log("Failed to send candidates on attempt "+ev.tries+". Giving up for now.");
+ this.candidateSendTries = 0;
+ return;
+ }
+
+ var delayMs = 500 * Math.pow(2, this.candidateSendTries);
+ ++this.candidateSendTries;
+ console.log("Failed to send candidates. Retrying in "+delayMs+"ms");
+ var self = this;
+ $timeout(function() {
+ self.sendCandidateQueue();
+ }, delayMs);
+ };
+
return MatrixCall;
}]);
diff --git a/webclient/components/matrix/matrix-phone-service.js b/webclient/components/matrix/matrix-phone-service.js
index b0dcf19100..2d0732a8da 100644
--- a/webclient/components/matrix/matrix-phone-service.js
+++ b/webclient/components/matrix/matrix-phone-service.js
@@ -77,13 +77,15 @@ angular.module('matrixPhoneService', [])
return;
}
call.receivedAnswer(msg);
- } else if (event.type == 'm.call.candidate') {
+ } else if (event.type == 'm.call.candidates') {
var call = matrixPhoneService.allCalls[msg.call_id];
if (!call) {
- console.log("Got candidate for unknown call ID "+msg.call_id);
+ console.log("Got candidates for unknown call ID "+msg.call_id);
return;
}
- call.gotRemoteIceCandidate(msg.candidate);
+ for (var i = 0; i < msg.candidates.length; ++i) {
+ call.gotRemoteIceCandidate(msg.candidates[i]);
+ }
} else if (event.type == 'm.call.hangup') {
var call = matrixPhoneService.allCalls[msg.call_id];
if (!call) {
diff --git a/webclient/recents/recents.html b/webclient/recents/recents.html
index 3d736b6694..ca7636e36a 100644
--- a/webclient/recents/recents.html
+++ b/webclient/recents/recents.html
@@ -22,7 +22,7 @@
<td colspan="3" class="recentsRoomSummary">
<div ng-show="room.membership === 'invite'">
- {{ room.lastMsg.inviter | mUserDisplayName: room.room_id }} invited you
+ {{ room.inviter | mUserDisplayName: room.room_id }} invited you
</div>
<div ng-hide="room.membership === 'invite'" ng-switch="room.lastMsg.type">
diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js
index 3cc127140b..50d902ae47 100644
--- a/webclient/room/room-controller.js
+++ b/webclient/room/room-controller.js
@@ -220,7 +220,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
};
var paginate = function(numItems) {
- // console.log("paginate " + numItems);
+ //console.log("paginate " + numItems + " and first_pagination is " + $scope.state.first_pagination);
if ($scope.state.paginating || !$scope.room_id) {
return;
}
@@ -260,7 +260,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
}
if ($scope.state.first_pagination) {
- scrollToBottom();
+ scrollToBottom(true);
$scope.state.first_pagination = false;
}
else {
@@ -598,6 +598,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
promise.then(
function(response) {
console.log("Request successfully sent");
+
if (echo) {
// Mark this fake message event with its allocated event_id
// When the true message event will come from the events stream (in handleMessage),
|