Merge pull request #739 from matrix-org/luke/visible-redactions

Show message redactions as black event tiles
This commit is contained in:
David Baker 2017-03-09 09:41:31 +00:00 committed by GitHub
commit 676c5c21c1
4 changed files with 34 additions and 19 deletions

View file

@ -116,7 +116,6 @@ function textForRoomNameEvent(ev) {
function textForMessageEvent(ev) { function textForMessageEvent(ev) {
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender(); var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
var message = senderDisplayName + ': ' + ev.getContent().body; var message = senderDisplayName + ': ' + ev.getContent().body;
if (ev.getContent().msgtype === "m.emote") { if (ev.getContent().msgtype === "m.emote") {
message = "* " + senderDisplayName + " " + message; message = "* " + senderDisplayName + " " + message;

View file

@ -295,7 +295,10 @@ module.exports = React.createClass({
var last = (i == lastShownEventIndex); var last = (i == lastShownEventIndex);
// Wrap consecutive member events in a ListSummary, ignore if redacted // Wrap consecutive member events in a ListSummary, ignore if redacted
if (isMembershipChange(mxEv) && EventTile.haveTileForEvent(mxEv)) { if (isMembershipChange(mxEv) &&
EventTile.haveTileForEvent(mxEv) &&
!mxEv.isRedacted()
) {
let ts1 = mxEv.getTs(); let ts1 = mxEv.getTs();
// Ensure that the key of the MemberEventListSummary does not change with new // Ensure that the key of the MemberEventListSummary does not change with new
// member events. This will prevent it from being re-created unnecessarily, and // member events. This will prevent it from being re-created unnecessarily, and
@ -408,7 +411,9 @@ module.exports = React.createClass({
// is this a continuation of the previous message? // is this a continuation of the previous message?
var continuation = false; var continuation = false;
if (prevEvent !== null && prevEvent.sender && mxEv.sender
if (prevEvent !== null
&& !prevEvent.isRedacted() && prevEvent.sender && mxEv.sender
&& mxEv.sender.userId === prevEvent.sender.userId && mxEv.sender.userId === prevEvent.sender.userId
&& mxEv.getType() == prevEvent.getType()) { && mxEv.getType() == prevEvent.getType()) {
continuation = true; continuation = true;
@ -461,6 +466,7 @@ module.exports = React.createClass({
ref={this._collectEventNode.bind(this, eventId)} ref={this._collectEventNode.bind(this, eventId)}
data-scroll-token={scrollToken}> data-scroll-token={scrollToken}>
<EventTile mxEvent={mxEv} continuation={continuation} <EventTile mxEvent={mxEv} continuation={continuation}
isRedacted={mxEv.isRedacted()}
onWidgetLoad={this._onWidgetLoad} onWidgetLoad={this._onWidgetLoad}
readReceipts={readReceipts} readReceipts={readReceipts}
readReceiptMap={this._readReceiptMap} readReceiptMap={this._readReceiptMap}
@ -481,13 +487,17 @@ module.exports = React.createClass({
// here. // here.
return !this.props.suppressFirstDateSeparator; return !this.props.suppressFirstDateSeparator;
} }
const prevEventDate = prevEvent.getDate();
if (!nextEventDate || !prevEventDate) {
return false;
}
// Return early for events that are > 24h apart // Return early for events that are > 24h apart
if (Math.abs(prevEvent.getTs() - nextEventDate.getTime()) > MILLIS_IN_DAY) { if (Math.abs(prevEvent.getTs() - nextEventDate.getTime()) > MILLIS_IN_DAY) {
return true; return true;
} }
// Compare weekdays // Compare weekdays
return prevEvent.getDate().getDay() !== nextEventDate.getDay(); return prevEventDate.getDay() !== nextEventDate.getDay();
}, },
// get a list of read receipts that should be shown next to this event // get a list of read receipts that should be shown next to this event

View file

@ -22,10 +22,10 @@ module.exports = React.createClass({
displayName: 'UnknownBody', displayName: 'UnknownBody',
render: function() { render: function() {
var content = this.props.mxEvent.getContent(); const text = this.props.mxEvent.getContent().body;
return ( return (
<span className="mx_UnknownBody"> <span className="mx_UnknownBody">
{content.body} {text}
</span> </span>
); );
}, },

View file

@ -29,14 +29,6 @@ var dispatcher = require("../../../dispatcher");
var ObjectUtils = require('../../../ObjectUtils'); var ObjectUtils = require('../../../ObjectUtils');
var bounce = false;
try {
if (global.localStorage) {
bounce = global.localStorage.getItem('avatar_bounce') == 'true';
}
} catch (e) {
}
var eventTileTypes = { var eventTileTypes = {
'm.room.message': 'messages.MessageEvent', 'm.room.message': 'messages.MessageEvent',
'm.room.member' : 'messages.TextualEvent', 'm.room.member' : 'messages.TextualEvent',
@ -73,6 +65,12 @@ module.exports = WithMatrixClient(React.createClass({
/* the MatrixEvent to show */ /* the MatrixEvent to show */
mxEvent: React.PropTypes.object.isRequired, mxEvent: React.PropTypes.object.isRequired,
/* true if mxEvent is redacted. This is a prop because using mxEvent.isRedacted()
* might not be enough when deciding shouldComponentUpdate - prevProps.mxEvent
* references the same this.props.mxEvent.
*/
isRedacted: React.PropTypes.bool,
/* true if this is a continuation of the previous event (which has the /* true if this is a continuation of the previous event (which has the
* effect of not showing another avatar/displayname * effect of not showing another avatar/displayname
*/ */
@ -396,6 +394,7 @@ module.exports = WithMatrixClient(React.createClass({
var e2eEnabled = this.props.matrixClient.isRoomEncrypted(this.props.mxEvent.getRoomId()); var e2eEnabled = this.props.matrixClient.isRoomEncrypted(this.props.mxEvent.getRoomId());
var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1); var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
const isRedacted = (eventType === 'm.room.message') && this.props.isRedacted;
var classes = classNames({ var classes = classNames({
mx_EventTile: true, mx_EventTile: true,
@ -412,6 +411,7 @@ module.exports = WithMatrixClient(React.createClass({
mx_EventTile_verified: this.state.verified == true, mx_EventTile_verified: this.state.verified == true,
mx_EventTile_unverified: this.state.verified == false, mx_EventTile_unverified: this.state.verified == false,
mx_EventTile_bad: this.props.mxEvent.getContent().msgtype === 'm.bad.encrypted', mx_EventTile_bad: this.props.mxEvent.getContent().msgtype === 'm.bad.encrypted',
mx_EventTile_redacted: isRedacted,
}); });
var permalink = "https://matrix.to/#/" + this.props.mxEvent.getRoomId() +"/"+ this.props.mxEvent.getId(); var permalink = "https://matrix.to/#/" + this.props.mxEvent.getRoomId() +"/"+ this.props.mxEvent.getId();
@ -421,7 +421,10 @@ module.exports = WithMatrixClient(React.createClass({
let avatarSize; let avatarSize;
let needsSenderProfile; let needsSenderProfile;
if (this.props.tileShape === "notif") { if (isRedacted) {
avatarSize = 0;
needsSenderProfile = false;
} else if (this.props.tileShape === "notif") {
avatarSize = 24; avatarSize = 24;
needsSenderProfile = true; needsSenderProfile = true;
} else if (isInfoMessage) { } else if (isInfoMessage) {
@ -486,6 +489,8 @@ module.exports = WithMatrixClient(React.createClass({
else if (e2eEnabled) { else if (e2eEnabled) {
e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" src="img/e2e-unencrypted.svg" width="12" height="12"/>; e2e = <img onClick={ this.onCryptoClicked } className="mx_EventTile_e2eIcon" src="img/e2e-unencrypted.svg" width="12" height="12"/>;
} }
const timestamp = this.props.mxEvent.isRedacted() ?
null : <MessageTimestamp ts={this.props.mxEvent.getTs()} />;
if (this.props.tileShape === "notif") { if (this.props.tileShape === "notif") {
var room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId()); var room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId());
@ -501,7 +506,7 @@ module.exports = WithMatrixClient(React.createClass({
{ avatar } { avatar }
<a href={ permalink }> <a href={ permalink }>
{ sender } { sender }
<MessageTimestamp ts={this.props.mxEvent.getTs()} /> { timestamp }
</a> </a>
</div> </div>
<div className="mx_EventTile_line" > <div className="mx_EventTile_line" >
@ -530,7 +535,7 @@ module.exports = WithMatrixClient(React.createClass({
<a className="mx_EventTile_senderDetailsLink" href={ permalink }> <a className="mx_EventTile_senderDetailsLink" href={ permalink }>
<div className="mx_EventTile_senderDetails"> <div className="mx_EventTile_senderDetails">
{ sender } { sender }
<MessageTimestamp ts={this.props.mxEvent.getTs()} /> { timestamp }
</div> </div>
</a> </a>
</div> </div>
@ -546,7 +551,7 @@ module.exports = WithMatrixClient(React.createClass({
{ sender } { sender }
<div className="mx_EventTile_line"> <div className="mx_EventTile_line">
<a href={ permalink }> <a href={ permalink }>
<MessageTimestamp ts={this.props.mxEvent.getTs()} /> { timestamp }
</a> </a>
{ e2e } { e2e }
<EventTileType ref="tile" <EventTileType ref="tile"
@ -564,7 +569,8 @@ module.exports = WithMatrixClient(React.createClass({
})); }));
module.exports.haveTileForEvent = function(e) { module.exports.haveTileForEvent = function(e) {
if (e.isRedacted()) return false; // Only messages have a tile (black-rectangle) if redacted
if (e.isRedacted() && e.getType() !== 'm.room.message') 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) !== '';