Merge pull request #3059 from matrix-org/jryans/read-receipts-relations-send-review

Advance read receipts into trailing events without tiles
This commit is contained in:
J. Ryan Stinnett 2019-06-04 14:35:14 +01:00 committed by GitHub
commit bea845a80d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 3 deletions

View file

@ -648,6 +648,7 @@ const TimelinePanel = React.createClass({
const lastReadEventIndex = this._getLastDisplayedEventIndex({ const lastReadEventIndex = this._getLastDisplayedEventIndex({
ignoreOwn: true, ignoreOwn: true,
allowEventsWithoutTiles: true,
}); });
if (lastReadEventIndex === null) { if (lastReadEventIndex === null) {
shouldSendRR = false; shouldSendRR = false;
@ -1111,14 +1112,18 @@ const TimelinePanel = React.createClass({
const ignoreOwn = opts.ignoreOwn || false; const ignoreOwn = opts.ignoreOwn || false;
const ignoreEchoes = opts.ignoreEchoes || false; const ignoreEchoes = opts.ignoreEchoes || false;
const allowPartial = opts.allowPartial || false; const allowPartial = opts.allowPartial || false;
const allowEventsWithoutTiles = opts.allowEventsWithoutTiles || false;
const messagePanel = this.refs.messagePanel; const messagePanel = this.refs.messagePanel;
if (messagePanel === undefined) return null; if (messagePanel === undefined) return null;
const EventTile = sdk.getComponent('rooms.EventTile');
const wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect(); const wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
const myUserId = MatrixClientPeg.get().credentials.userId; const myUserId = MatrixClientPeg.get().credentials.userId;
for (let i = this.state.events.length-1; i >= 0; --i) { let lastDisplayedIndex = null;
for (let i = this.state.events.length - 1; i >= 0; --i) {
const ev = this.state.events[i]; const ev = this.state.events[i];
if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) { if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) {
@ -1136,10 +1141,34 @@ const TimelinePanel = React.createClass({
const boundingRect = node.getBoundingClientRect(); const boundingRect = node.getBoundingClientRect();
if ((allowPartial && boundingRect.top < wrapperRect.bottom) || if ((allowPartial && boundingRect.top < wrapperRect.bottom) ||
(!allowPartial && boundingRect.bottom < wrapperRect.bottom)) { (!allowPartial && boundingRect.bottom < wrapperRect.bottom)) {
return i; lastDisplayedIndex = i;
break;
} }
} }
return null;
if (lastDisplayedIndex === null) {
return null;
}
// If events without tiles are allowed, then we walk forward from the
// the last displayed event and advance the index for any events without
// tiles that immediately follow it.
// XXX: We could track the last event without a tile after the last
// displayed event in the loop above so that we only do a single pass
// through the loop, which would be more efficient. Using two passes is
// easier to reason about, so let's start there and optimise later if
// needed.
if (allowEventsWithoutTiles) {
for (let i = lastDisplayedIndex + 1; i < this.state.events.length; i++) {
const ev = this.state.events[i];
if (EventTile.haveTileForEvent(ev)) {
break;
}
lastDisplayedIndex = i;
}
}
return lastDisplayedIndex;
}, },
/** /**

View file

@ -826,6 +826,9 @@ module.exports.haveTileForEvent = function(e) {
// Only messages have a tile (black-rectangle) if redacted // Only messages have a tile (black-rectangle) if redacted
if (e.isRedacted() && !isMessageEvent(e)) return false; if (e.isRedacted() && !isMessageEvent(e)) return false;
// No tile for replacement events since they update the original tile
if (e.isRelation("m.replace")) return false;
const handler = getHandlerTile(e); const handler = getHandlerTile(e);
if (handler === undefined) return false; if (handler === undefined) return false;
if (handler === 'messages.TextualEvent') { if (handler === 'messages.TextualEvent') {

View file

@ -45,6 +45,8 @@ export default function shouldHideEvent(ev) {
// Hide redacted events // Hide redacted events
if (ev.isRedacted() && !isEnabled('showRedactions')) return true; if (ev.isRedacted() && !isEnabled('showRedactions')) return true;
// Hide replacement events since they update the original tile
if (ev.isRelation("m.replace")) return true; if (ev.isRelation("m.replace")) return true;
const eventDiff = memberEventDiff(ev); const eventDiff = memberEventDiff(ev);