Advance read receipts into trailing events without tiles
This changes read receipt sending logic to allow it advance further into events without tiles (such as edits or reactions) that may exist after the last displayed event. By allowing the read receipt to advance past such events, this also marks as read any related notifications. For example, edits trigger notifications by default since they are `m.room.message` events, and with this change, such edit notifications can finally be marked read. Part of https://github.com/vector-im/riot-web/issues/9745
This commit is contained in:
parent
ad84144543
commit
96b213e7cb
3 changed files with 37 additions and 3 deletions
|
@ -648,6 +648,7 @@ const TimelinePanel = React.createClass({
|
|||
|
||||
const lastReadEventIndex = this._getLastDisplayedEventIndex({
|
||||
ignoreOwn: true,
|
||||
allowEventsWithoutTiles: true,
|
||||
});
|
||||
if (lastReadEventIndex === null) {
|
||||
shouldSendRR = false;
|
||||
|
@ -1111,14 +1112,18 @@ const TimelinePanel = React.createClass({
|
|||
const ignoreOwn = opts.ignoreOwn || false;
|
||||
const ignoreEchoes = opts.ignoreEchoes || false;
|
||||
const allowPartial = opts.allowPartial || false;
|
||||
const allowEventsWithoutTiles = opts.allowEventsWithoutTiles || false;
|
||||
|
||||
const messagePanel = this.refs.messagePanel;
|
||||
if (messagePanel === undefined) return null;
|
||||
|
||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||
|
||||
const wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
|
||||
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];
|
||||
|
||||
if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) {
|
||||
|
@ -1136,10 +1141,34 @@ const TimelinePanel = React.createClass({
|
|||
const boundingRect = node.getBoundingClientRect();
|
||||
if ((allowPartial && boundingRect.top < 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;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -819,6 +819,9 @@ module.exports.haveTileForEvent = function(e) {
|
|||
// Only messages have a tile (black-rectangle) if redacted
|
||||
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);
|
||||
if (handler === undefined) return false;
|
||||
if (handler === 'messages.TextualEvent') {
|
||||
|
|
|
@ -45,6 +45,8 @@ export default function shouldHideEvent(ev) {
|
|||
|
||||
// Hide redacted events
|
||||
if (ev.isRedacted() && !isEnabled('showRedactions')) return true;
|
||||
|
||||
// Hide replacement events since they update the original tile
|
||||
if (ev.isRelation("m.replace")) return true;
|
||||
|
||||
const eventDiff = memberEventDiff(ev);
|
||||
|
|
Loading…
Reference in a new issue