diff --git a/app/javascript/flavours/glitch/actions/announcements.js b/app/javascript/flavours/glitch/actions/announcements.js
index b4e8cee2f2..930493b6a8 100644
--- a/app/javascript/flavours/glitch/actions/announcements.js
+++ b/app/javascript/flavours/glitch/actions/announcements.js
@@ -56,12 +56,27 @@ export const updateAnnouncements = announcement => ({
});
export const addReaction = (announcementId, name) => (dispatch, getState) => {
- dispatch(addReactionRequest(announcementId, name));
+ const announcement = getState().getIn(['announcements', 'items']).find(x => x.get('id') === announcementId);
+
+ let alreadyAdded = false;
+
+ if (announcement) {
+ const reaction = announcement.get('reactions').find(x => x.get('name') === name);
+ if (reaction && reaction.get('me')) {
+ alreadyAdded = true;
+ }
+ }
+
+ if (!alreadyAdded) {
+ dispatch(addReactionRequest(announcementId, name, alreadyAdded));
+ }
api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
- dispatch(addReactionSuccess(announcementId, name));
+ dispatch(addReactionSuccess(announcementId, name, alreadyAdded));
}).catch(err => {
- dispatch(addReactionFail(announcementId, name, err));
+ if (!alreadyAdded) {
+ dispatch(addReactionFail(announcementId, name, err));
+ }
});
};
diff --git a/app/javascript/flavours/glitch/components/column_header.js b/app/javascript/flavours/glitch/components/column_header.js
index dd11624290..be45c9535e 100644
--- a/app/javascript/flavours/glitch/components/column_header.js
+++ b/app/javascript/flavours/glitch/components/column_header.js
@@ -42,6 +42,7 @@ class ColumnHeader extends React.PureComponent {
onMove: PropTypes.func,
onClick: PropTypes.func,
intl: PropTypes.object.isRequired,
+ appendContent: PropTypes.node,
};
state = {
@@ -106,7 +107,7 @@ class ColumnHeader extends React.PureComponent {
}
render () {
- const { intl, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, notifCleaning, notifCleaningActive, placeholder } = this.props;
+ const { intl, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, notifCleaning, notifCleaningActive, placeholder, appendContent } = this.props;
const { collapsed, animating, animatingNCD } = this.state;
let title = this.props.title;
@@ -229,6 +230,8 @@ class ColumnHeader extends React.PureComponent {
{(!collapsed || animating) && collapsedContent}
+
+ {appendContent}
);
diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.js b/app/javascript/flavours/glitch/features/home_timeline/index.js
index 457ac051ce..5e36e5f768 100644
--- a/app/javascript/flavours/glitch/features/home_timeline/index.js
+++ b/app/javascript/flavours/glitch/features/home_timeline/index.js
@@ -142,12 +142,11 @@ class HomeTimeline extends React.PureComponent {
pinned={pinned}
multiColumn={multiColumn}
extraButton={announcementsButton}
+ appendContent={hasAnnouncements && showAnnouncements && }
>
- {hasAnnouncements && showAnnouncements && }
-
({
});
export const addReaction = (announcementId, name) => (dispatch, getState) => {
- dispatch(addReactionRequest(announcementId, name));
+ const announcement = getState().getIn(['announcements', 'items']).find(x => x.get('id') === announcementId);
+
+ let alreadyAdded = false;
+
+ if (announcement) {
+ const reaction = announcement.get('reactions').find(x => x.get('name') === name);
+ if (reaction && reaction.get('me')) {
+ alreadyAdded = true;
+ }
+ }
+
+ if (!alreadyAdded) {
+ dispatch(addReactionRequest(announcementId, name, alreadyAdded));
+ }
api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
- dispatch(addReactionSuccess(announcementId, name));
+ dispatch(addReactionSuccess(announcementId, name, alreadyAdded));
}).catch(err => {
- dispatch(addReactionFail(announcementId, name, err));
+ if (!alreadyAdded) {
+ dispatch(addReactionFail(announcementId, name, err));
+ }
});
};
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index 0038995c8b..ea82f9ef9d 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -33,6 +33,7 @@ class ColumnHeader extends React.PureComponent {
onPin: PropTypes.func,
onMove: PropTypes.func,
onClick: PropTypes.func,
+ appendContent: PropTypes.node,
};
state = {
@@ -81,7 +82,7 @@ class ColumnHeader extends React.PureComponent {
}
render () {
- const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder } = this.props;
+ const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent } = this.props;
const { collapsed, animating } = this.state;
const wrapperClassName = classNames('column-header__wrapper', {
@@ -172,6 +173,8 @@ class ColumnHeader extends React.PureComponent {
{(!collapsed || animating) && collapsedContent}
+
+ {appendContent}
);
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index c7de8c9cbf..2bad22bc1d 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -143,12 +143,11 @@ class HomeTimeline extends React.PureComponent {
pinned={pinned}
multiColumn={multiColumn}
extraButton={announcementsButton}
+ appendContent={hasAnnouncements && showAnnouncements && }
>
- {hasAnnouncements && showAnnouncements && }
-