Merge pull request #244 from matrix-org/rav/no_rm_on_my_events
Move read-marker past our own events when we switch to a room
This commit is contained in:
commit
7fb5736e52
2 changed files with 69 additions and 11 deletions
|
@ -173,15 +173,29 @@ module.exports = React.createClass({
|
||||||
// first figure out which is the last event in the list which we're
|
// first figure out which is the last event in the list which we're
|
||||||
// actually going to show; this allows us to behave slightly
|
// actually going to show; this allows us to behave slightly
|
||||||
// differently for the last event in the list.
|
// differently for the last event in the list.
|
||||||
|
//
|
||||||
|
// we also need to figure out which is the last event we show which isn't
|
||||||
|
// a local echo, to manage the read-marker.
|
||||||
|
var lastShownEventIndex = -1;
|
||||||
|
var lastShownNonLocalEchoIndex = -1;
|
||||||
for (i = this.props.events.length-1; i >= 0; i--) {
|
for (i = this.props.events.length-1; i >= 0; i--) {
|
||||||
var mxEv = this.props.events[i];
|
var mxEv = this.props.events[i];
|
||||||
if (!EventTile.haveTileForEvent(mxEv)) {
|
if (!EventTile.haveTileForEvent(mxEv)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastShownEventIndex < 0) {
|
||||||
|
lastShownEventIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mxEv.status) {
|
||||||
|
// this is a local echo
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastShownNonLocalEchoIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var lastShownEventIndex = i;
|
|
||||||
|
|
||||||
var ret = [];
|
var ret = [];
|
||||||
|
|
||||||
|
@ -213,25 +227,34 @@ module.exports = React.createClass({
|
||||||
ret.push(<li key={eventId} data-scroll-token={eventId}/>);
|
ret.push(<li key={eventId} data-scroll-token={eventId}/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isVisibleReadMarker = false;
|
||||||
|
|
||||||
if (eventId == this.props.readMarkerEventId) {
|
if (eventId == this.props.readMarkerEventId) {
|
||||||
var visible = this.props.readMarkerVisible;
|
var visible = this.props.readMarkerVisible;
|
||||||
|
|
||||||
// if the read marker comes at the end of the timeline, we don't want
|
// if the read marker comes at the end of the timeline (except
|
||||||
// to show it, but we still want to create the <li/> for it so that the
|
// for local echoes, which are excluded from RMs, because they
|
||||||
// algorithms which depend on its position on the screen aren't confused.
|
// don't have useful event ids), we don't want to show it, but
|
||||||
if (i >= lastShownEventIndex) {
|
// we still want to create the <li/> for it so that the
|
||||||
|
// algorithms which depend on its position on the screen aren't
|
||||||
|
// confused.
|
||||||
|
if (i >= lastShownNonLocalEchoIndex) {
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
ret.push(this._getReadMarkerTile(visible));
|
ret.push(this._getReadMarkerTile(visible));
|
||||||
readMarkerVisible = visible;
|
readMarkerVisible = visible;
|
||||||
} else if (eventId == this.currentReadMarkerEventId && !this.currentGhostEventId) {
|
isVisibleReadMarker = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventId == this.currentGhostEventId) {
|
||||||
|
// if we're showing an animation, continue to show it.
|
||||||
|
ret.push(this._getReadMarkerGhostTile());
|
||||||
|
} else if (!isVisibleReadMarker &&
|
||||||
|
eventId == this.currentReadMarkerEventId) {
|
||||||
// there is currently a read-up-to marker at this point, but no
|
// there is currently a read-up-to marker at this point, but no
|
||||||
// more. Show an animation of it disappearing.
|
// more. Show an animation of it disappearing.
|
||||||
ret.push(this._getReadMarkerGhostTile());
|
ret.push(this._getReadMarkerGhostTile());
|
||||||
this.currentGhostEventId = eventId;
|
this.currentGhostEventId = eventId;
|
||||||
} else if (eventId == this.currentGhostEventId) {
|
|
||||||
// if we're showing an animation, continue to show it.
|
|
||||||
ret.push(this._getReadMarkerGhostTile());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -343,8 +343,6 @@ var TimelinePanel = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentIndex = this._indexForEventId(this.state.readMarkerEventId);
|
|
||||||
|
|
||||||
// move the RM to *after* the message at the bottom of the screen. This
|
// move the RM to *after* the message at the bottom of the screen. This
|
||||||
// avoids a problem whereby we never advance the RM if there is a huge
|
// avoids a problem whereby we never advance the RM if there is a huge
|
||||||
// message which doesn't fit on the screen.
|
// message which doesn't fit on the screen.
|
||||||
|
@ -375,6 +373,38 @@ var TimelinePanel = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// advance the read marker past any events we sent ourselves.
|
||||||
|
_advanceReadMarkerPastMyEvents: function() {
|
||||||
|
// we call _timelineWindow.getEvents() rather than using
|
||||||
|
// this.state.events, because react batches the update to the latter, so it
|
||||||
|
// may not have been updated yet.
|
||||||
|
var events = this._timelineWindow.getEvents();
|
||||||
|
|
||||||
|
// first find where the current RM is
|
||||||
|
for (var i = 0; i < events.length; i++) {
|
||||||
|
if (events[i].getId() == this.state.readMarkerEventId)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= events.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now think about advancing it
|
||||||
|
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
|
for (; i < events.length; i++) {
|
||||||
|
var ev = events[i];
|
||||||
|
if (!ev.sender || ev.sender.userId != myUserId) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// i is now the first unread message which we didn't send ourselves.
|
||||||
|
i--;
|
||||||
|
|
||||||
|
var ev = events[i];
|
||||||
|
this._setReadMarker(ev.getId(), ev.getTs());
|
||||||
|
},
|
||||||
|
|
||||||
/* jump down to the bottom of this room, where new events are arriving
|
/* jump down to the bottom of this room, where new events are arriving
|
||||||
*/
|
*/
|
||||||
jumpToLiveTimeline: function() {
|
jumpToLiveTimeline: function() {
|
||||||
|
@ -527,6 +557,11 @@ var TimelinePanel = React.createClass({
|
||||||
var onLoaded = () => {
|
var onLoaded = () => {
|
||||||
this._reloadEvents();
|
this._reloadEvents();
|
||||||
|
|
||||||
|
// If we switched away from the room while there were pending
|
||||||
|
// outgoing events, the read-marker will be before those events.
|
||||||
|
// We need to skip over any which have subsequently been sent.
|
||||||
|
this._advanceReadMarkerPastMyEvents();
|
||||||
|
|
||||||
this.setState({timelineLoading: false}, () => {
|
this.setState({timelineLoading: false}, () => {
|
||||||
// initialise the scroll state of the message panel
|
// initialise the scroll state of the message panel
|
||||||
if (!this.refs.messagePanel) {
|
if (!this.refs.messagePanel) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue