Merge pull request #159 from matrix-org/rav/move_ghostmarker_to_messagepanel
Move the ghost-read-marker logic to MessagePanelpull/21833/head
commit
4c149480c9
|
@ -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>
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue