diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js
index aaa00934cb..0e00b0dc7d 100644
--- a/src/components/structures/MessagePanel.js
+++ b/src/components/structures/MessagePanel.js
@@ -205,6 +205,13 @@ module.exports = React.createClass({
// assume there is no read marker until proven otherwise
var readMarkerVisible = false;
+ // if the readmarker has moved, cancel any active ghost.
+ if (this.currentReadMarkerEventId && this.props.readMarkerEventId &&
+ this.props.readMarkerVisible &&
+ this.currentReadMarkerEventId != this.props.readMarkerEventId) {
+ this.currentGhostEventId = null;
+ }
+
for (i = 0; i < this.props.events.length; i++) {
var mxEv = this.props.events[i];
var wantTile = true;
@@ -336,21 +343,16 @@ module.exports = React.createClass({
);
},
- _getReadMarkerGhostTile: function() {
- // 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;
- };
+ _startAnimation: function(ghostNode) {
+ Velocity(ghostNode, {opacity: '0', width: '10%'},
+ {duration: 600, easing: 'easeInSine',
+ delay: 200});
+ },
+ _getReadMarkerGhostTile: function() {
var hr =
;
// give it a key which depends on the event id. That will ensure that
diff --git a/test/components/structures/MessagePanel-test.js b/test/components/structures/MessagePanel-test.js
index f775388617..9a4996b5da 100644
--- a/test/components/structures/MessagePanel-test.js
+++ b/test/components/structures/MessagePanel-test.js
@@ -130,4 +130,50 @@ describe('MessagePanel', function () {
}, 100);
}, 100);
});
+
+ it('shows only one ghost when the RM moves twice', function() {
+ var parentDiv = document.createElement('div');
+
+ // first render with the RM in one place
+ var mp = ReactDOM.render(
+ , parentDiv);
+
+ var tiles = TestUtils.scryRenderedComponentsWithType(
+ mp, sdk.getComponent('rooms.EventTile'));
+ var tileContainers = tiles.map(function (t) {
+ return ReactDOM.findDOMNode(t).parentNode;
+ });
+
+ // now move the RM
+ mp = ReactDOM.render(
+ , parentDiv);
+
+ // now there should be two RM containers
+ var found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container');
+ expect(found.length).toEqual(2);
+
+ // the first should be the ghost
+ expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(4);
+
+ // the second should be the real RM
+ expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(6);
+
+ // and move the RM again
+ mp = ReactDOM.render(
+ , parentDiv);
+
+ // still two RM containers
+ found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container');
+ expect(found.length).toEqual(2);
+
+ // they should have moved
+ expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(6);
+ expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(8);
+ });
});