Hovercard: refactor with HoverRefWrapper
This commit is contained in:
parent
c0051df335
commit
1d90950e59
5 changed files with 62 additions and 42 deletions
50
app/soapbox/components/hover_ref_wrapper.js
Normal file
50
app/soapbox/components/hover_ref_wrapper.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import React, { useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
openProfileHoverCard,
|
||||
closeProfileHoverCard,
|
||||
} from 'soapbox/actions/profile_hover_card';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { debounce } from 'lodash';
|
||||
import { isMobile } from 'soapbox/is_mobile';
|
||||
|
||||
const showProfileHoverCard = debounce((dispatch, ref, accountId) => {
|
||||
dispatch(openProfileHoverCard(ref, accountId));
|
||||
}, 1200);
|
||||
|
||||
const handleMouseEnter = (dispatch, ref, accountId) => {
|
||||
return e => {
|
||||
if (!isMobile(window.innerWidth))
|
||||
showProfileHoverCard(dispatch, ref, accountId);
|
||||
};
|
||||
};
|
||||
|
||||
const handleMouseLeave = (dispatch) => {
|
||||
return e => {
|
||||
showProfileHoverCard.cancel();
|
||||
setTimeout(() => dispatch(closeProfileHoverCard()), 300);
|
||||
};
|
||||
};
|
||||
|
||||
export const HoverRefWrapper = ({ accountId, children }) => {
|
||||
const dispatch = useDispatch();
|
||||
const ref = useRef();
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className='hover-ref-wrapper'
|
||||
onMouseEnter={handleMouseEnter(dispatch, ref, accountId)}
|
||||
onMouseLeave={handleMouseLeave(dispatch)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
HoverRefWrapper.propTypes = {
|
||||
accountId: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default HoverRefWrapper;
|
|
@ -45,7 +45,7 @@ export const ProfileHoverCard = ({ visible }) => {
|
|||
|
||||
const accountId = useSelector(state => state.getIn(['profile_hover_card', 'accountId']));
|
||||
const account = useSelector(state => accountId && getAccount(state, accountId));
|
||||
const targetRef = useSelector(state => state.getIn(['profile_hover_card', 'ref']));
|
||||
const targetRef = useSelector(state => state.getIn(['profile_hover_card', 'ref', 'current']));
|
||||
const badges = account ? getBadges(account) : [];
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -18,9 +18,8 @@ import classNames from 'classnames';
|
|||
import Icon from 'soapbox/components/icon';
|
||||
import PollContainer from 'soapbox/containers/poll_container';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { isMobile } from '../../../app/soapbox/is_mobile';
|
||||
import { debounce } from 'lodash';
|
||||
import { getDomain } from 'soapbox/utils/accounts';
|
||||
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
|
||||
|
||||
// We use the component (and not the container) since we do not want
|
||||
// to use the progress bar to show download progress
|
||||
|
@ -255,20 +254,6 @@ class Status extends ImmutablePureComponent {
|
|||
this.handleToggleMediaVisibility();
|
||||
}
|
||||
|
||||
showProfileHoverCard = debounce(() => {
|
||||
const { onShowProfileHoverCard, status } = this.props;
|
||||
onShowProfileHoverCard(this.profileNode, status.getIn(['account', 'id']));
|
||||
}, 1200);
|
||||
|
||||
handleProfileHover = e => {
|
||||
if (!isMobile(window.innerWidth)) this.showProfileHoverCard();
|
||||
}
|
||||
|
||||
handleProfileLeave = e => {
|
||||
this.showProfileHoverCard.cancel();
|
||||
this.props.onClearProfileHoverCard();
|
||||
}
|
||||
|
||||
_properStatus() {
|
||||
const { status } = this.props;
|
||||
|
||||
|
@ -283,10 +268,6 @@ class Status extends ImmutablePureComponent {
|
|||
this.node = c;
|
||||
}
|
||||
|
||||
setProfileRef = c => {
|
||||
this.profileNode = c;
|
||||
}
|
||||
|
||||
render() {
|
||||
let media = null;
|
||||
let poll = null;
|
||||
|
@ -481,15 +462,17 @@ class Status extends ImmutablePureComponent {
|
|||
<img src={favicon} alt='' title={domain} />
|
||||
</div>}
|
||||
|
||||
<div className='status__profile' ref={this.setProfileRef} onMouseEnter={this.handleProfileHover} onMouseLeave={this.handleProfileLeave}>
|
||||
<div className='status__avatar'>
|
||||
<NavLink to={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='floating-link' />
|
||||
{statusAvatar}
|
||||
<HoverRefWrapper accountId={status.getIn(['account', 'id'])}>
|
||||
<div className='status__profile'>
|
||||
<div className='status__avatar'>
|
||||
<NavLink to={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='floating-link' />
|
||||
{statusAvatar}
|
||||
</div>
|
||||
<NavLink to={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='status__display-name'>
|
||||
<DisplayName account={status.get('account')} others={otherAccounts} />
|
||||
</NavLink>
|
||||
</div>
|
||||
<NavLink to={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='status__display-name'>
|
||||
<DisplayName account={status.get('account')} others={otherAccounts} />
|
||||
</NavLink>
|
||||
</div>
|
||||
</HoverRefWrapper>
|
||||
</div>
|
||||
|
||||
{!group && status.get('group') && (
|
||||
|
|
|
@ -35,10 +35,6 @@ import {
|
|||
groupRemoveStatus,
|
||||
} from '../actions/groups';
|
||||
import { getSettings } from '../actions/settings';
|
||||
import {
|
||||
openProfileHoverCard,
|
||||
closeProfileHoverCard,
|
||||
} from 'soapbox/actions/profile_hover_card';
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
|
@ -210,14 +206,6 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||
dispatch(groupRemoveStatus(groupId, statusId));
|
||||
},
|
||||
|
||||
onShowProfileHoverCard(ref, accountId) {
|
||||
dispatch(openProfileHoverCard(ref, accountId));
|
||||
},
|
||||
|
||||
onClearProfileHoverCard() {
|
||||
setTimeout(() => dispatch(closeProfileHoverCard()), 300);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Status));
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
z-index: 200;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&--visible {
|
||||
opacity: 1;
|
||||
|
|
Loading…
Reference in a new issue