diff --git a/app/gabsocial/features/status/components/action_bar.js b/app/gabsocial/features/status/components/action_bar.js
index e7e2a1c98..8ca178a5c 100644
--- a/app/gabsocial/features/status/components/action_bar.js
+++ b/app/gabsocial/features/status/components/action_bar.js
@@ -8,6 +8,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { defineMessages, injectIntl } from 'react-intl';
import { isStaff } from 'gabsocial/utils/accounts';
+import { ALLOWED_EMOJI } from 'gabsocial/utils/emoji_reacts';
+import emojify from 'gabsocial/features/emoji/emoji';
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -59,6 +61,7 @@ class ActionBar extends React.PureComponent {
onReply: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired,
onFavourite: PropTypes.func.isRequired,
+ onEmojiReact: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onDirect: 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 = () => {
this.props.onDelete(this.props.status, this.context.router.history);
}
@@ -240,7 +254,16 @@ class ActionBar extends React.PureComponent {
Boost
-
+
+
+ {ALLOWED_EMOJI.map(emoji => (
+
+ ))}
+
Like
diff --git a/app/gabsocial/features/status/index.js b/app/gabsocial/features/status/index.js
index 4b9fc2436..ae648d4ce 100644
--- a/app/gabsocial/features/status/index.js
+++ b/app/gabsocial/features/status/index.js
@@ -17,6 +17,7 @@ import {
pin,
unpin,
} from '../../actions/interactions';
+import { emojiReact, unEmojiReact } from '../../actions/emoji_reacts';
import {
replyCompose,
mentionCompose,
@@ -161,6 +162,20 @@ class Status extends ImmutablePureComponent {
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) => {
if (status.get('favourited')) {
this.props.dispatch(unfavourite(status));
@@ -496,6 +511,7 @@ class Status extends ImmutablePureComponent {
status={status}
onReply={this.handleReplyClick}
onFavourite={this.handleFavouriteClick}
+ onEmojiReact={this.handleEmojiReactClick}
onReblog={this.handleReblogClick}
onDelete={this.handleDeleteClick}
onDirect={this.handleDirectClick}
diff --git a/app/styles/gabsocial/components.scss b/app/styles/gabsocial/components.scss
index 2f007f28c..c009a4c0d 100644
--- a/app/styles/gabsocial/components.scss
+++ b/app/styles/gabsocial/components.scss
@@ -2790,6 +2790,7 @@ a.status-card.compact:hover {
.detailed-status__button {
flex: 1 1 auto;
text-align: center;
+ position: relative;
}
.column-settings__outer {
diff --git a/app/styles/gabsocial/components/emoji-reacts.scss b/app/styles/gabsocial/components/emoji-reacts.scss
index 261ce5155..486741d04 100644
--- a/app/styles/gabsocial/components/emoji-reacts.scss
+++ b/app/styles/gabsocial/components/emoji-reacts.scss
@@ -53,3 +53,35 @@
font-size: 12px;
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;
+ }
+}