import { React, PropTypes, Utils } from 'mailspring-exports'; import { DropZone, InjectedComponentSet } from 'mailspring-component-kit'; const NUM_TO_DISPLAY_MAX = 999; export default class CollapsedParticipants extends React.Component { static displayName = 'CollapsedParticipants'; static propTypes = { // Arrays of Contact objects. to: PropTypes.array, cc: PropTypes.array, bcc: PropTypes.array, onDrop: PropTypes.func, onDragChange: PropTypes.func, }; static defaultProps = { to: [], cc: [], bcc: [], onDrop: () => {}, onDragChange: () => {}, }; constructor(props = {}) { super(props); this.state = { numToDisplay: NUM_TO_DISPLAY_MAX, numRemaining: 0, numBccRemaining: 0, }; } componentDidMount() { this._setNumHiddenParticipants(); } componentWillReceiveProps(nextProps) { if (!Utils.isEqualReact(nextProps, this.props)) { // Always re-evaluate the hidden participant count when the participant set changes this.setState({ numToDisplay: NUM_TO_DISPLAY_MAX, numRemaining: 0, numBccRemaining: 0, }); } } shouldComponentUpdate(nextProps, nextState) { return !Utils.isEqualReact(nextProps, this.props) || !Utils.isEqualReact(nextState, this.state); } componentDidUpdate() { if (this.state.numToDisplay === NUM_TO_DISPLAY_MAX) { this._setNumHiddenParticipants(); } } _setNumHiddenParticipants() { const $wrap = this._participantsWrapEl; const $regulars = Array.from($wrap.getElementsByClassName('regular-contact')); const $bccs = Array.from($wrap.getElementsByClassName('bcc-contact')); const availableSpace = $wrap.getBoundingClientRect().width; let numRemaining = this.props.to.length + this.props.cc.length; let numBccRemaining = this.props.bcc.length; let numToDisplay = 0; let widthAccumulator = 0; for (const $p of $regulars) { widthAccumulator += $p.getBoundingClientRect().width; if (widthAccumulator >= availableSpace) { break; } numRemaining -= 1; numToDisplay += 1; } for (const $p of $bccs) { widthAccumulator += $p.getBoundingClientRect().width; if (widthAccumulator >= availableSpace) { break; } numBccRemaining -= 1; numToDisplay += 1; } this.setState({ numToDisplay, numRemaining, numBccRemaining }); } _renderNumRemaining() { let str = null; if (this.state.numRemaining === 0 && this.state.numBccRemaining === 0) { return null; } else if (this.state.numRemaining > 0 && this.state.numBccRemaining === 0) { str = `${this.state.numRemaining} more`; } else if (this.state.numRemaining === 0 && this.state.numBccRemaining > 0) { str = `${this.state.numBccRemaining} Bcc`; } else if (this.state.numRemaining > 0 && this.state.numBccRemaining > 0) { str = `${this.state.numRemaining + this.state.numBccRemaining} more (${this.state .numBccRemaining} Bcc)`; } return (
{str}
); } _collapsedContact = contact => { const name = contact.displayName(); const key = contact.email + contact.name; return ( {name} ); }; _collapsedBccContact = (contact, i) => { let name = contact.displayName(); const key = contact.email + contact.name; if (i === 0) { name = `Bcc: ${name}`; } return ( {name} ); }; render() { const contacts = this.props.to.concat(this.props.cc).map(this._collapsedContact); const bcc = this.props.bcc.map(this._collapsedBccContact); let toDisplay = contacts.concat(bcc); toDisplay = toDisplay.splice(0, this.state.numToDisplay); if (toDisplay.length === 0) { toDisplay = 'Recipients'; } return ( true} onDragStateChange={this.props.onDragChange} onDrop={this.props.onDrop} >
{ this._participantsWrapEl = el; }} className="collapsed-composer-participants" > {this._renderNumRemaining()} {toDisplay}
); } }