Merge pull request #159 from matrix-org/rav/move_ghostmarker_to_messagepanel

Move the ghost-read-marker logic to MessagePanel
pull/21833/head
Richard van der Hoff 2016-02-17 21:44:24 +00:00
commit 4c149480c9
2 changed files with 39 additions and 15 deletions

View File

@ -17,7 +17,7 @@ limitations under the License.
var React = require('react');
var sdk = require('../../index');
/* stateless UI component which builds the event tiles in the room timeline.
/* (almost) stateless UI component which builds the event tiles in the room timeline.
*/
module.exports = React.createClass({
displayName: 'MessagePanel',
@ -35,10 +35,6 @@ module.exports = React.createClass({
// event after which we should show a read marker
readMarkerEventId: React.PropTypes.string,
// event after which we should show an animating disappearance of a
// read marker
readMarkerGhostEventId: React.PropTypes.string,
// the userid of our user. This is used to suppress the read marker
// for pending messages.
ourUserId: React.PropTypes.string,
@ -63,6 +59,17 @@ module.exports = React.createClass({
onFillRequest: React.PropTypes.func,
},
componentWillMount: function() {
// the event after which we put a visible unread marker on the last
// render cycle; null if readMarkerVisible was false or the RM was
// suppressed (eg because it was at the end of the timeline)
this.currentReadMarkerEventId = null;
// the event after which we are showing a disappearing read marker
// animation
this.currentGhostEventId = null;
},
/* get the DOM node representing the given event */
getNodeForEventId: function(eventId) {
if (!this.eventNodes) {
@ -158,11 +165,16 @@ module.exports = React.createClass({
}
var eventId = mxEv.getId();
if (eventId == this.props.readMarkerGhostEventId) {
ghostIndex = eventsToShow.length;
}
if (eventId == this.props.readMarkerEventId) {
readMarkerIndex = eventsToShow.length;
} else if (eventId == this.currentReadMarkerEventId && !this.currentGhostEventId) {
// there is currently a read-up-to marker at this point, but no
// more. Show an animation of it disappearing.
ghostIndex = eventsToShow.length;
this.currentGhostEventId = eventId;
} else if (eventId == this.currentGhostEventId) {
// if we're showing an animation, continue to show it.
ghostIndex = eventsToShow.length;
}
}
@ -170,6 +182,9 @@ module.exports = React.createClass({
var prevEvent = null; // the last event we showed
// assume there is no read marker until proven otherwise
var readMarkerVisible = false;
for (var i = 0; i < eventsToShow.length; i++) {
var mxEv = eventsToShow[i];
var wantTile = true;
@ -183,6 +198,7 @@ module.exports = React.createClass({
// us sending a message and receiving the synthesized receipt.
if (mxEv.sender && mxEv.sender.userId != this.props.ourUserId) {
ret.push(this._getReadMarkerTile());
readMarkerVisible = true;
}
} else if (i == ghostIndex) {
ret.push(this._getReadMarkerGhostTile());
@ -198,6 +214,7 @@ module.exports = React.createClass({
prevEvent = mxEv;
}
this.currentReadMarkerEventId = readMarkerVisible ? this.props.readMarkerEventId : null;
return ret;
},
@ -259,17 +276,27 @@ module.exports = React.createClass({
},
_getReadMarkerGhostTile: function() {
var hr;
hr = <hr className="mx_RoomView_myReadMarker"
// reset the ghostEventId when the animation finishes, so that
// we can make a new one (and so that we don't run the
// animation code every time we render)
var completeFunc = () => {
this.currentGhostEventId = null;
};
var hr = <hr className="mx_RoomView_myReadMarker"
style={{opacity: 1, width: '99%'}}
ref={function(n) {
Velocity(n, {opacity: '0', width: '10%'},
{duration: 400, easing: 'easeInSine',
delay: 1000});
delay: 1000, complete: completeFunc});
}}
/>;
// give it a key which depends on the event id. That will ensure that
// we get a new DOM node (restarting the animation) when the ghost
// moves to a different event.
return (
<li key="_readuptoghost"
<li key={"_readuptoghost_"+this.currentGhostEventId}
className="mx_RoomView_myReadMarker_container">
{hr}
</li>

View File

@ -82,7 +82,6 @@ module.exports = React.createClass({
timelineLoading: true, // track whether our room timeline is loading
canBackPaginate: true,
readMarkerEventId: this._getCurrentReadReceipt(),
readMarkerGhostEventId: null,
};
},
@ -200,7 +199,6 @@ module.exports = React.createClass({
this.setState({
readMarkerEventId: newReadMarker,
readMarkerGhostEventId: oldReadMarker,
});
},
@ -441,7 +439,6 @@ module.exports = React.createClass({
events={ this.state.events }
highlightedEventId={ this.props.highlightedEventId }
readMarkerEventId={ this.state.readMarkerEventId }
readMarkerGhostEventId={ this.state.readMarkerGhostEventId }
suppressFirstDateSeparator={ this.state.canBackPaginate }
ourUserId={ MatrixClientPeg.get().credentials.userId }
stickyBottom={ stickyBottom }