diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js
index b1580b3d8a..3b1354cdef 100644
--- a/webclient/components/matrix/event-handler-service.js
+++ b/webclient/components/matrix/event-handler-service.js
@@ -58,14 +58,29 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
var shouldBing = false;
// case-insensitive name check for user_id OR display_name if they exist
+ var userRegex = "";
var myUserId = matrixService.config().user_id;
if (myUserId) {
- myUserId = myUserId.toLocaleLowerCase();
+ var localpart = getLocalPartFromUserId(myUserId);
+ if (localpart) {
+ localpart = localpart.toLocaleLowerCase();
+ userRegex += "\\b" + localpart + "\\b";
+ }
}
var myDisplayName = matrixService.config().display_name;
if (myDisplayName) {
myDisplayName = myDisplayName.toLocaleLowerCase();
+ if (userRegex.length > 0) {
+ userRegex += "|";
+ }
+ userRegex += "\\b" + myDisplayName + "\\b";
}
+
+ var r = new RegExp(userRegex, 'i');
+ if (content.search(r) >= 0) {
+ shouldBing = true;
+ }
+
if ( (myDisplayName && content.toLocaleLowerCase().indexOf(myDisplayName) != -1) ||
(myUserId && content.toLocaleLowerCase().indexOf(myUserId) != -1) ) {
shouldBing = true;
@@ -84,6 +99,18 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
return shouldBing;
};
+ var getLocalPartFromUserId = function(user_id) {
+ if (!user_id) {
+ return null;
+ }
+ var localpartRegex = /@(.*):\w+/i
+ var results = localpartRegex.exec(user_id);
+ if (results && results.length == 2) {
+ return results[1];
+ }
+ return null;
+ };
+
var initialSyncDeferred;
var reset = function() {
@@ -172,6 +199,17 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
};
var handleMessage = function(event, isLiveEvent) {
+ // Check for empty event content
+ var hasContent = false;
+ for (var prop in event.content) {
+ hasContent = true;
+ break;
+ }
+ if (!hasContent) {
+ // empty json object is a redacted event, so ignore.
+ return;
+ }
+
if (isLiveEvent) {
if (event.user_id === matrixService.config().user_id &&
(event.content.msgtype === "m.text" || event.content.msgtype === "m.emote") ) {
@@ -238,6 +276,12 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
"body": message,
"icon": member ? member.avatar_url : undefined
});
+
+ notification.onclick = function() {
+ console.log("notification.onclick() room=" + event.room_id);
+ $rootScope.goToPage('room/' + (event.room_id));
+ };
+
$timeout(function() {
notification.close();
}, 5 * 1000);
@@ -329,6 +373,31 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
$rootScope.events.rooms[event.room_id].messages.push(event);
}
};
+
+ var handleRedaction = function(event, isLiveEvent) {
+ if (!isLiveEvent) {
+ // we have nothing to remove, so just ignore it.
+ console.log("Received redacted event: "+JSON.stringify(event));
+ return;
+ }
+
+ // we need to remove something possibly: do we know the redacted
+ // event ID?
+ if (eventMap[event.redacts]) {
+ // remove event from list of messages in this room.
+ var eventList = $rootScope.events.rooms[event.room_id].messages;
+ for (var i=0; i<eventList.length; i++) {
+ if (eventList[i].event_id === event.redacts) {
+ console.log("Removing event " + event.redacts);
+ eventList.splice(i, 1);
+ break;
+ }
+ }
+
+ // broadcast the redaction so controllers can nuke this
+ console.log("Redacted an event.");
+ }
+ }
/**
* Get the index of the event in $rootScope.events.rooms[room_id].messages
@@ -491,6 +560,9 @@ function(matrixService, $rootScope, $q, $timeout, mPresence) {
case 'm.room.topic':
handleRoomTopic(event, isLiveEvent, isStateEvent);
break;
+ case 'm.room.redaction':
+ handleRedaction(event, isLiveEvent);
+ break;
default:
console.log("Unable to handle event type " + event.type);
console.log(JSON.stringify(event, undefined, 4));
diff --git a/webclient/components/matrix/matrix-filter.js b/webclient/components/matrix/matrix-filter.js
index e6f2acc5fd..3d64a569a1 100644
--- a/webclient/components/matrix/matrix-filter.js
+++ b/webclient/components/matrix/matrix-filter.js
@@ -47,7 +47,6 @@ angular.module('matrixFilter', [])
else if (room.members && !isPublicRoom) { // Do not rename public room
var user_id = matrixService.config().user_id;
-
// Else, build the name from its users
// Limit the room renaming to 1:1 room
if (2 === Object.keys(room.members).length) {
@@ -65,8 +64,16 @@ angular.module('matrixFilter', [])
var otherUserId;
- if (Object.keys(room.members)[0] && Object.keys(room.members)[0] !== user_id) {
+ if (Object.keys(room.members)[0]) {
otherUserId = Object.keys(room.members)[0];
+ // this could be an invite event (from event stream)
+ if (otherUserId === user_id &&
+ room.members[user_id].content.membership === "invite") {
+ // this is us being invited to this room, so the
+ // *user_id* is the other user ID and not the state
+ // key.
+ otherUserId = room.members[user_id].user_id;
+ }
}
else {
// it's got to be an invite, or failing that a self-chat;
diff --git a/webclient/components/matrix/matrix-service.js b/webclient/components/matrix/matrix-service.js
index a4f0568bce..1840cf46c0 100644
--- a/webclient/components/matrix/matrix-service.js
+++ b/webclient/components/matrix/matrix-service.js
@@ -438,6 +438,14 @@ angular.module('matrixService', [])
return this.sendMessage(room_id, msg_id, content);
},
+ redactEvent: function(room_id, event_id) {
+ var path = "/rooms/$room_id/redact/$event_id";
+ path = path.replace("$room_id", room_id);
+ path = path.replace("$event_id", event_id);
+ var content = {};
+ return doRequest("POST", path, undefined, content);
+ },
+
// get a snapshot of the members in a room.
getMemberList: function(room_id) {
// Like the cmd client, escape room ids
|