Add emojiReact popup and call action code
This commit is contained in:
parent
6d48537d54
commit
1901d39871
4 changed files with 73 additions and 1 deletions
|
@ -8,6 +8,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
|
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import { isStaff } from 'gabsocial/utils/accounts';
|
import { isStaff } from 'gabsocial/utils/accounts';
|
||||||
|
import { ALLOWED_EMOJI } from 'gabsocial/utils/emoji_reacts';
|
||||||
|
import emojify from 'gabsocial/features/emoji/emoji';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||||
|
@ -59,6 +61,7 @@ class ActionBar extends React.PureComponent {
|
||||||
onReply: PropTypes.func.isRequired,
|
onReply: PropTypes.func.isRequired,
|
||||||
onReblog: PropTypes.func.isRequired,
|
onReblog: PropTypes.func.isRequired,
|
||||||
onFavourite: PropTypes.func.isRequired,
|
onFavourite: PropTypes.func.isRequired,
|
||||||
|
onEmojiReact: PropTypes.func.isRequired,
|
||||||
onDelete: PropTypes.func.isRequired,
|
onDelete: PropTypes.func.isRequired,
|
||||||
onDirect: PropTypes.func.isRequired,
|
onDirect: PropTypes.func.isRequired,
|
||||||
onMention: PropTypes.func.isRequired,
|
onMention: PropTypes.func.isRequired,
|
||||||
|
@ -105,6 +108,17 @@ class ActionBar extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleReactClick = emoji => {
|
||||||
|
return e => {
|
||||||
|
const { me } = this.props;
|
||||||
|
if (me) {
|
||||||
|
this.props.onEmojiReact(this.props.status, emoji);
|
||||||
|
} else {
|
||||||
|
this.props.onOpenUnauthorizedModal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
handleDeleteClick = () => {
|
handleDeleteClick = () => {
|
||||||
this.props.onDelete(this.props.status, this.context.router.history);
|
this.props.onDelete(this.props.status, this.context.router.history);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +254,16 @@ class ActionBar extends React.PureComponent {
|
||||||
<IconButton disabled={reblog_disabled} active={status.get('reblogged')} title={reblog_disabled ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
|
<IconButton disabled={reblog_disabled} active={status.get('reblogged')} title={reblog_disabled ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
|
||||||
Boost
|
Boost
|
||||||
</div>
|
</div>
|
||||||
<div className='detailed-status__button'>
|
<div className='detailed-status__button detailed-status__button--favourite'>
|
||||||
|
<div className='emoji-react-selector'>
|
||||||
|
{ALLOWED_EMOJI.map(emoji => (
|
||||||
|
<button
|
||||||
|
className='emoji-react-selector__emoji'
|
||||||
|
dangerouslySetInnerHTML={{ __html: emojify(emoji) }}
|
||||||
|
onClick={this.handleReactClick(emoji)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
<IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='thumbs-up' onClick={this.handleFavouriteClick} />
|
<IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='thumbs-up' onClick={this.handleFavouriteClick} />
|
||||||
Like
|
Like
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
pin,
|
pin,
|
||||||
unpin,
|
unpin,
|
||||||
} from '../../actions/interactions';
|
} from '../../actions/interactions';
|
||||||
|
import { emojiReact, unEmojiReact } from '../../actions/emoji_reacts';
|
||||||
import {
|
import {
|
||||||
replyCompose,
|
replyCompose,
|
||||||
mentionCompose,
|
mentionCompose,
|
||||||
|
@ -161,6 +162,20 @@ class Status extends ImmutablePureComponent {
|
||||||
this.setState({ showMedia: !this.state.showMedia });
|
this.setState({ showMedia: !this.state.showMedia });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleEmojiReactClick = (status, emoji) => {
|
||||||
|
if (emoji === '👍') {
|
||||||
|
this.handleFavouriteClick(status); return;
|
||||||
|
}
|
||||||
|
const hasReaction = status.getIn(['pleroma', 'emoji_reactions'])
|
||||||
|
.findIndex(e => e.get('name') === emoji && e.get('me') === true) > -1;
|
||||||
|
|
||||||
|
if (hasReaction) {
|
||||||
|
this.props.dispatch(unEmojiReact(status, emoji));
|
||||||
|
} else {
|
||||||
|
this.props.dispatch(emojiReact(status, emoji));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleFavouriteClick = (status) => {
|
handleFavouriteClick = (status) => {
|
||||||
if (status.get('favourited')) {
|
if (status.get('favourited')) {
|
||||||
this.props.dispatch(unfavourite(status));
|
this.props.dispatch(unfavourite(status));
|
||||||
|
@ -496,6 +511,7 @@ class Status extends ImmutablePureComponent {
|
||||||
status={status}
|
status={status}
|
||||||
onReply={this.handleReplyClick}
|
onReply={this.handleReplyClick}
|
||||||
onFavourite={this.handleFavouriteClick}
|
onFavourite={this.handleFavouriteClick}
|
||||||
|
onEmojiReact={this.handleEmojiReactClick}
|
||||||
onReblog={this.handleReblogClick}
|
onReblog={this.handleReblogClick}
|
||||||
onDelete={this.handleDeleteClick}
|
onDelete={this.handleDeleteClick}
|
||||||
onDirect={this.handleDirectClick}
|
onDirect={this.handleDirectClick}
|
||||||
|
|
|
@ -2790,6 +2790,7 @@ a.status-card.compact:hover {
|
||||||
.detailed-status__button {
|
.detailed-status__button {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-settings__outer {
|
.column-settings__outer {
|
||||||
|
|
|
@ -53,3 +53,35 @@
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emoji-react-selector {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: 0.1s;
|
||||||
|
|
||||||
|
&__emoji {
|
||||||
|
display: block;
|
||||||
|
padding: 0 2px;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-status__button--favourite:hover {
|
||||||
|
.emoji-react-selector {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue