diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 31ef15b6dc..29b2f773dc 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -20,6 +20,7 @@ var dis = require("../../dispatcher"); var sdk = require('../../index'); var MatrixClientPeg = require('../../MatrixClientPeg') +var TruncatedList = require('../views/elements/TruncatedList.js'); /* (almost) stateless UI component which builds the event tiles in the room timeline. */ @@ -286,6 +287,56 @@ module.exports = React.createClass({ var last = (i == lastShownEventIndex); + // Wrap consecutive member events in a TruncatedList + if (mxEv.getType() === 'm.room.member') { + // Prevent message continuations between truncations + prevEvent = null; + + let collapsedEvents = [mxEv]; + i++; + for (;i < this.props.events.length; i++) { + let collapsedMxEv = this.props.events[i]; + + if (collapsedMxEv.getType() !== 'm.room.member') { + i--; + break; + } + collapsedEvents.push(collapsedMxEv); + } + let ePrev = null; + collapsedEvents = collapsedEvents.map( + (e) => { + let ret = this._getTilesForEvent(ePrev, e); + ePrev = e; + return ret; + } + ).reduce((a,b) => a.concat(b)); + + let overflowElement = (overflowCount, totalCount, toggleTruncate, isExpanded) => { + if (isExpanded) { + return ( +
+ collapse ^ +
+ ); + } + else { + return ( +
+ and {overflowCount} more... +
+ ); + } + } + ret.push( + + {collapsedEvents} + + ); + + wantTile = false; + } + if (wantTile) { // make sure we unpack the array returned by _getTilesForEvent, // otherwise react will auto-generate keys and we will end up diff --git a/src/components/views/elements/TruncatedList.js b/src/components/views/elements/TruncatedList.js index 3e174848d3..e49c296515 100644 --- a/src/components/views/elements/TruncatedList.js +++ b/src/components/views/elements/TruncatedList.js @@ -28,10 +28,16 @@ module.exports = React.createClass({ createOverflowElement: React.PropTypes.func }, + getInitialState: function() { + return { + enabled: true, + }; + }, + getDefaultProps: function() { return { truncateAt: 2, - createOverflowElement: function(overflowCount, totalCount) { + createOverflowElement: function(overflowCount, totalCount, toggleTruncate, isExpanded) { return (
And {overflowCount} more...
); @@ -39,6 +45,12 @@ module.exports = React.createClass({ }; }, + toggleTruncate: function() { + this.setState({ + enabled: !this.state.enabled + }); + }, + render: function() { var childsJsx = this.props.children; var overflowJsx; @@ -48,20 +60,26 @@ module.exports = React.createClass({ var childCount = childArray.length; - if (this.props.truncateAt >= 0) { + if (this.state.enabled && this.props.truncateAt >= 0) { var overflowCount = childCount - this.props.truncateAt; if (overflowCount > 1) { overflowJsx = this.props.createOverflowElement( - overflowCount, childCount + overflowCount, childCount, this.toggleTruncate ); - + // cut out the overflow elements childArray.splice(childCount - overflowCount, overflowCount); childsJsx = childArray; // use what is left } } + if (!this.state.enabled) { + overflowJsx = this.props.createOverflowElement( + 0, childCount, this.toggleTruncate, true + ); + } + return (
{childsJsx}