import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' import debounce from 'lodash.debounce' import { me } from '../initial_state' import { CX, POPOVER_USER_INFO, } from '../constants' import { openPopover, closePopover } from '../actions/popover' import Icon from './icon' import Text from './text' const mapDispatchToProps = (dispatch) => ({ openUserInfoPopover(props) { dispatch(openPopover(POPOVER_USER_INFO, props)) }, closeUserInfoPopover() { dispatch(closePopover(POPOVER_USER_INFO)) } }) export default @connect(null, mapDispatchToProps) class DisplayName extends ImmutablePureComponent { static propTypes = { account: ImmutablePropTypes.map, openUserInfoPopover: PropTypes.func.isRequired, closeUserInfoPopover: PropTypes.func.isRequired, isLarge: PropTypes.bool, isMultiline: PropTypes.bool, isSmall: PropTypes.bool, noHover: PropTypes.bool, noRelationship: PropTypes.bool, noUsername: PropTypes.bool, isComment: PropTypes.bool, isCentered: PropTypes.bool, } updateOnProps = [ 'account', 'isMultiline', 'isSmall', 'isLarge', 'noHover', 'noRelationship', 'noUsername', 'isComment', 'isCentered', ] mouseOverTimeout = null componentWillUnmount () { document.removeEventListener('mousemove', this.handleMouseMove, true) clearTimeout(this.mouseOverTimeout) } handleMouseEnter = () => { if (this.mouseOverTimeout) return null this.mouseOverTimeout = setTimeout(() => { this.props.openUserInfoPopover({ targetRef: this.node, position: 'top', accountId: this.props.account.get('id'), }) document.addEventListener('mousemove', this.handleMouseMove, true) }, 650) } handleMouseLeave = debounce((e) => { this.attemptToHidePopover(e) }, 250) handleMouseMove = debounce((e) => { this.attemptToHidePopover(e) }, 150) attemptToHidePopover = (e) => { const lastTarget = e.toElement || e.relatedTarget if (!(lastTarget instanceof Element || lastTarget instanceof HTMLDocument)) return const userInfoPopoverEl = document.getElementById('user-info-popover') if (this.mouseOverTimeout && ( (userInfoPopoverEl && lastTarget && !userInfoPopoverEl.contains(lastTarget)) || (!userInfoPopoverEl && lastTarget && this.node && !this.node.contains(lastTarget)) )) { document.removeEventListener('mousemove', this.handleMouseMove, true) clearTimeout(this.mouseOverTimeout) this.mouseOverTimeout = null this.props.closeUserInfoPopover() } } setRef = (n) => { this.node = n } render() { const { account, isMultiline, isLarge, noHover, noUsername, noRelationship, isSmall, isComment, isCentered, } = this.props if (!account) return null const containerClassName = CX({ default: 1, maxWidth100PC: 1, alignItemsCenter: !isMultiline, flexRow: !isMultiline, cursorPointer: !noHover, alignItemsCenter: isCentered, }) const displayNameClasses = CX({ text: 1, overflowWrapBreakWord: 1, whiteSpaceNoWrap: 1, fontWeightBold: 1, colorPrimary: 1, mr2: 1, lineHeight125: !isSmall, fs14PX: isSmall, fs15PX: !isLarge, fs24PX: isLarge && !isSmall, }) const usernameClasses = CX({ text: 1, displayFlex: 1, flexNormal: 1, flexShrink1: 1, overflowWrapBreakWord: 1, textOverflowEllipsis: 1, colorSecondary: 1, fontWeightNormal: 1, lineHeight15: isMultiline, lineHeight125: !isMultiline, ml5: !isMultiline, fs14PX: isSmall, fs15PX: !isLarge, fs16PX: isLarge && !isSmall, }) const iconSize = !!isLarge ? 19 : !!isComment ? 12 : !!isSmall ? 14 : 15 let relationshipLabel if (me && account) { const accountId = account.get('id') const isFollowedBy = (me !== accountId && account.getIn(['relationship', 'followed_by'])) if (isFollowedBy) { relationshipLabel = 'Follows you'//intl.formatMessage(messages.accountFollowsYou) } } // { // /* : todo : audio-mute, bot // account.getIn(['relationship', 'muting']) // */ // } // bot: { id: 'account.badges.bot', defaultMessage: 'Bot' }, return (