From eedde4a4a7a3825a6664d9871eaca88e6551d570 Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Fri, 12 Jun 2020 21:51:39 -0400 Subject: [PATCH] Updated DisplayName, Avatar functionality for opening, closing UserInfoPopover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Updated: - DisplayName, Avatar functionality for opening, closing UserInfoPopover • Todo: - Work out issues with closing after certain conditions are met --- app/javascript/gabsocial/components/avatar.js | 32 +++++++++++++-- .../gabsocial/components/display_name.js | 40 ++++++++++++++----- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/app/javascript/gabsocial/components/avatar.js b/app/javascript/gabsocial/components/avatar.js index dedb939a..8c3bfa4f 100644 --- a/app/javascript/gabsocial/components/avatar.js +++ b/app/javascript/gabsocial/components/avatar.js @@ -1,5 +1,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePureComponent from 'react-immutable-pure-component' +import debounce from 'lodash.debounce' import { autoPlayGif } from '../initial_state' import { openPopover, closePopover } from '../actions/popover' import Image from './image' @@ -54,23 +55,48 @@ class Avatar extends ImmutablePureComponent { } } + componentWillUnmount () { + document.removeEventListener('mousemove', this.handleMouseMove, true) + clearTimeout(this.mouseOverTimeout) + } + handleMouseEnter = () => { this.setState({ hovering: true }) if (this.mouseOverTimeout || this.props.noHover) return null + this.mouseOverTimeout = setTimeout(() => { this.props.openUserInfoPopover({ targetRef: this.node, position: 'top', - account: this.props.account, + accountId: this.props.account.get('id'), }) + document.addEventListener('mousemove', this.handleMouseMove, true) }, 650) } - handleMouseLeave = () => { + handleMouseLeave = debounce((e) => { this.setState({ hovering: false }) + this.attemptToHidePopover(e) + }, 250) - if (this.mouseOverTimeout && !this.props.noHover) { + 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 && + !this.props.noHover && + ( + (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() diff --git a/app/javascript/gabsocial/components/display_name.js b/app/javascript/gabsocial/components/display_name.js index 50eb0157..2f58d3f4 100644 --- a/app/javascript/gabsocial/components/display_name.js +++ b/app/javascript/gabsocial/components/display_name.js @@ -1,5 +1,6 @@ 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, @@ -50,19 +51,43 @@ class DisplayName extends ImmutablePureComponent { 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', - account: this.props.account, + accountId: this.props.account.get('id'), }) + document.addEventListener('mousemove', this.handleMouseMove, true) }, 650) } - handleMouseLeave = () => { - if (this.mouseOverTimeout) { + 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() @@ -132,9 +157,6 @@ class DisplayName extends ImmutablePureComponent { !!isComment ? 12 : !!isSmall ? 14 : 15 - const domain = account.get('acct').split('@')[1] - const isRemoteUser = !!domain - let relationshipLabel if (me && account) { const accountId = account.get('id') @@ -146,13 +168,11 @@ class DisplayName extends ImmutablePureComponent { } // { - // /* : todo : audio-mute + // /* : todo : audio-mute, bot // account.getIn(['relationship', 'muting']) // */ // } - - // : todo : remote - // console.log("domain, isRemoteUser:", domain, isRemoteUser) + // bot: { id: 'account.badges.bot', defaultMessage: 'Bot' }, return (