Handle redacted events

matrix-js-sdk now retains redacted events. Filter them out of the timeline.

Also put empty placeholders in the dom so that if we try to scroll to a
redacted event, we don't end up blowing up.
pull/21833/head
Richard van der Hoff 2016-02-16 16:05:27 +00:00
parent 687eae7f43
commit eb91faf554
2 changed files with 31 additions and 8 deletions

View File

@ -114,6 +114,7 @@ module.exports = React.createClass({
this.dispatcherRef = dis.register(this.onAction); this.dispatcherRef = dis.register(this.onAction);
MatrixClientPeg.get().on("Room", this.onRoom); MatrixClientPeg.get().on("Room", this.onRoom);
MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().on("Room.redaction", this.onRoomRedaction);
MatrixClientPeg.get().on("Room.name", this.onRoomName); MatrixClientPeg.get().on("Room.name", this.onRoomName);
MatrixClientPeg.get().on("Room.accountData", this.onRoomAccountData); MatrixClientPeg.get().on("Room.accountData", this.onRoomAccountData);
MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().on("Room.receipt", this.onRoomReceipt);
@ -259,6 +260,7 @@ module.exports = React.createClass({
if (MatrixClientPeg.get()) { if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener("Room", this.onRoom); MatrixClientPeg.get().removeListener("Room", this.onRoom);
MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline); MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
MatrixClientPeg.get().removeListener("Room.redaction", this.onRoomRedaction);
MatrixClientPeg.get().removeListener("Room.name", this.onRoomName); MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
MatrixClientPeg.get().removeListener("Room.accountData", this.onRoomAccountData); MatrixClientPeg.get().removeListener("Room.accountData", this.onRoomAccountData);
MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt); MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt);
@ -377,6 +379,17 @@ module.exports = React.createClass({
} }
}, },
onRoomRedaction: function(ev, room) {
if (this.unmounted) return;
// ignore events for other rooms
if (room.roomId != this.props.roomId) return;
// we could skip an update if the event isn't in our timeline,
// but that's probably an early optimisation.
this.forceUpdate();
},
_calculatePeekRules: function(room) { _calculatePeekRules: function(room) {
var guestAccessEvent = room.currentState.getStateEvents("m.room.guest_access", ""); var guestAccessEvent = room.currentState.getStateEvents("m.room.guest_access", "");
if (guestAccessEvent && guestAccessEvent.getContent().guest_access === "can_join") { if (guestAccessEvent && guestAccessEvent.getContent().guest_access === "can_join") {
@ -969,17 +982,31 @@ module.exports = React.createClass({
var readMarkerIndex; var readMarkerIndex;
for (var i = 0; i < this.state.events.length; i++) { for (var i = 0; i < this.state.events.length; i++) {
var mxEv = this.state.events[i]; var mxEv = this.state.events[i];
var eventId = mxEv.getId();
// we can't use local echoes as scroll tokens, because their event IDs change.
// Local echos have a send "status".
var scrollToken = mxEv.status ? undefined : eventId;
var wantTile = true;
if (!EventTile.haveTileForEvent(mxEv)) { if (!EventTile.haveTileForEvent(mxEv)) {
continue; wantTile = false;
} }
if (this.props.ConferenceHandler && mxEv.getType() === "m.room.member") { else if (this.props.ConferenceHandler && mxEv.getType() === "m.room.member") {
if (this.props.ConferenceHandler.isConferenceUser(mxEv.getSender()) || if (this.props.ConferenceHandler.isConferenceUser(mxEv.getSender()) ||
this.props.ConferenceHandler.isConferenceUser(mxEv.getStateKey())) { this.props.ConferenceHandler.isConferenceUser(mxEv.getStateKey())) {
continue; // suppress conf user join/parts wantTile = false; // suppress conf user join/parts
} }
} }
if (!wantTile) {
// if we aren't showing the event, put in a dummy scroll token anyway, so
// that we can scroll to the right place.
ret.push(<li key={eventId} data-scroll-token={scrollToken}/>);
continue;
}
// now we've decided whether or not to show this message, // now we've decided whether or not to show this message,
// add the read up to marker if appropriate // add the read up to marker if appropriate
// doing this here means we implicitly do not show the marker // doing this here means we implicitly do not show the marker
@ -1028,13 +1055,8 @@ module.exports = React.createClass({
last = true; last = true;
} }
var eventId = mxEv.getId();
var highlight = (eventId == this.props.highlightedEventId); var highlight = (eventId == this.props.highlightedEventId);
// we can't use local echoes as scroll tokens, because their event IDs change.
// Local echos have a send "status".
var scrollToken = mxEv.status ? undefined : eventId;
ret.push( ret.push(
<li key={eventId} <li key={eventId}
ref={this._collectEventNode.bind(this, eventId)} ref={this._collectEventNode.bind(this, eventId)}

View File

@ -65,6 +65,7 @@ module.exports = React.createClass({
statics: { statics: {
haveTileForEvent: function(e) { haveTileForEvent: function(e) {
if (e.isRedacted()) return false;
if (eventTileTypes[e.getType()] == undefined) return false; if (eventTileTypes[e.getType()] == undefined) return false;
if (eventTileTypes[e.getType()] == 'messages.TextualEvent') { if (eventTileTypes[e.getType()] == 'messages.TextualEvent') {
return TextForEvent.textForEvent(e) !== ''; return TextForEvent.textForEvent(e) !== '';