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); + }); });