Set EmojiSelector visibility from props
This commit is contained in:
parent
c29d779bf5
commit
8b505c0488
|
@ -2,22 +2,25 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { ALLOWED_EMOJI } from 'gabsocial/utils/emoji_reacts';
|
||||
import emojify from 'gabsocial/features/emoji/emoji';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default class EmojiSelector extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
onReact: PropTypes.func.isRequired,
|
||||
visible: PropTypes.bool,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
onReact: () => {},
|
||||
visible: false,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { onReact } = this.props;
|
||||
const { onReact, visible } = this.props;
|
||||
|
||||
return (
|
||||
<div className='emoji-react-selector'>
|
||||
<div className={classNames('emoji-react-selector', { 'emoji-react-selector--visible': visible })}>
|
||||
{ALLOWED_EMOJI.map((emoji, i) => (
|
||||
<button
|
||||
key={i}
|
||||
|
|
|
@ -35,6 +35,7 @@ export default class IconButton extends React.PureComponent {
|
|||
animate: false,
|
||||
overlay: false,
|
||||
tabIndex: '0',
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
handleClick = (e) => {
|
||||
|
|
|
@ -77,6 +77,10 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
isStaff: false,
|
||||
}
|
||||
|
||||
state = {
|
||||
emojiSelectorVisible: false,
|
||||
}
|
||||
|
||||
// Avoid checking props that are functions (and whose equality will always
|
||||
// evaluate to false. See react-immutable-pure-component for usage.
|
||||
updateOnProps = [
|
||||
|
@ -102,6 +106,14 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
handleLikeButtonHover = e => {
|
||||
this.setState({ emojiSelectorVisible: true });
|
||||
}
|
||||
|
||||
handleLikeButtonLeave = e => {
|
||||
this.setState({ emojiSelectorVisible: false });
|
||||
}
|
||||
|
||||
handleReactClick = emoji => {
|
||||
return e => {
|
||||
const { me, status } = this.props;
|
||||
|
@ -267,6 +279,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
|
||||
render() {
|
||||
const { status, intl } = this.props;
|
||||
const { emojiSelectorVisible } = this.state;
|
||||
|
||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||
|
||||
|
@ -313,8 +326,12 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
<IconButton className='status__action-bar-button' disabled={!publicStatus} active={status.get('reblogged')} pressed={status.get('reblogged')} title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
|
||||
{reblogCount !== 0 && <Link to={`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/reblogs`} className='detailed-status__link'>{reblogCount}</Link>}
|
||||
</div>
|
||||
<div className='status__action-bar__counter status__action-bar__counter--favourite'>
|
||||
<EmojiSelector onReact={this.handleReactClick} />
|
||||
<div
|
||||
className='status__action-bar__counter status__action-bar__counter--favourite'
|
||||
onMouseEnter={this.handleLikeButtonHover}
|
||||
onMouseLeave={this.handleLikeButtonLeave}
|
||||
>
|
||||
<EmojiSelector onReact={this.handleReactClick} visible={emojiSelectorVisible} />
|
||||
<IconButton
|
||||
className='status__action-bar-button star-icon'
|
||||
animate
|
||||
|
|
|
@ -81,6 +81,10 @@ class ActionBar extends React.PureComponent {
|
|||
isStaff: false,
|
||||
}
|
||||
|
||||
state = {
|
||||
emojiSelectorVisible: false,
|
||||
}
|
||||
|
||||
handleReplyClick = () => {
|
||||
const { me } = this.props;
|
||||
if (me) {
|
||||
|
@ -108,6 +112,20 @@ class ActionBar extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
isMobile = () => window.matchMedia('only screen and (max-width: 895px)').matches;
|
||||
|
||||
handleLikeButtonHover = e => {
|
||||
if (!this.isMobile()) this.setState({ emojiSelectorVisible: true });
|
||||
}
|
||||
|
||||
handleLikeButtonLeave = e => {
|
||||
if (!this.isMobile()) this.setState({ emojiSelectorVisible: false });
|
||||
}
|
||||
|
||||
handleLikeButtonClick = e => {
|
||||
if (this.isMobile()) this.setState({ emojiSelectorVisible: true });
|
||||
}
|
||||
|
||||
handleReactClick = emoji => {
|
||||
return e => {
|
||||
const { me } = this.props;
|
||||
|
@ -185,8 +203,16 @@ class ActionBar extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('click', e => {
|
||||
if (!document.querySelector('.detailed-status__button--favourite').contains(e.target))
|
||||
this.setState({ emojiSelectorVisible: false });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { status, intl, me, isStaff } = this.props;
|
||||
const { emojiSelectorVisible } = this.state;
|
||||
|
||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||
const mutingConversation = status.get('muted');
|
||||
|
@ -265,8 +291,13 @@ class ActionBar extends React.PureComponent {
|
|||
text='Boost'
|
||||
/>
|
||||
</div>
|
||||
<div className='detailed-status__button detailed-status__button--favourite'>
|
||||
<EmojiSelector onReact={this.handleReactClick} />
|
||||
<div
|
||||
className='detailed-status__button detailed-status__button--favourite'
|
||||
onMouseEnter={this.handleLikeButtonHover}
|
||||
onMouseLeave={this.handleLikeButtonLeave}
|
||||
onClick={this.handleLikeButtonClick}
|
||||
>
|
||||
<EmojiSelector onReact={this.handleReactClick} visible={emojiSelectorVisible} />
|
||||
<IconButton
|
||||
className='star-icon'
|
||||
animate
|
||||
|
@ -274,7 +305,7 @@ class ActionBar extends React.PureComponent {
|
|||
title={intl.formatMessage(messages.favourite)}
|
||||
icon='thumbs-up'
|
||||
emoji={meEmojiReact}
|
||||
onClick={this.handleReactClick(meEmojiReact || '👍')}
|
||||
// onClick={this.handleReactClick(meEmojiReact || '👍')}
|
||||
text='Like'
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -66,6 +66,11 @@
|
|||
transition: 0.1s;
|
||||
z-index: 999;
|
||||
|
||||
&--visible {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
&__emoji {
|
||||
display: block;
|
||||
padding: 0;
|
||||
|
@ -90,21 +95,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.detailed-status__button--favourite:hover {
|
||||
.emoji-react-selector {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.status__action-bar__counter--favourite {
|
||||
position: relative;
|
||||
|
||||
&:hover .emoji-react-selector {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
@media(max-width: 455px) {
|
||||
position: static;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue