chuckya/app/javascript/mastodon/features/status/components/action_bar.jsx

334 lines
14 KiB
React
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import IconButton from '../../../components/icon_button';
import ImmutablePropTypes from 'react-immutable-proptypes';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
2016-11-18 23:36:16 +09:00
import { defineMessages, injectIntl } from 'react-intl';
2022-12-01 01:25:36 +09:00
import { me, maxReactions } from '../../../initial_state';
import classNames from 'classnames';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
2022-12-01 01:25:36 +09:00
import EmojiPickerDropdown from '../../compose/containers/emoji_picker_dropdown_container';
2016-11-18 23:36:16 +09:00
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
direct: { id: 'status.direct', defaultMessage: 'Privately mention @{name}' },
2017-03-01 08:53:11 +09:00
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
2016-11-18 23:36:16 +09:00
reply: { id: 'status.reply', defaultMessage: 'Reply' },
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' },
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' },
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
favourite: { id: 'status.favourite', defaultMessage: 'Favourite' },
2022-12-01 01:25:36 +09:00
react: { id: 'status.react', defaultMessage: 'React' },
bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' },
more: { id: 'status.more', defaultMessage: 'More' },
mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
block: { id: 'status.block', defaultMessage: 'Block @{name}' },
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
share: { id: 'status.share', defaultMessage: 'Share' },
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
embed: { id: 'status.embed', defaultMessage: 'Embed' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
2016-11-18 23:36:16 +09:00
});
const mapStateToProps = (state, { status }) => ({
relationship: state.getIn(['relationships', status.getIn(['account', 'id'])]),
});
2018-09-15 00:59:48 +09:00
class ActionBar extends React.PureComponent {
2016-10-10 05:19:15 +09:00
static contextTypes = {
router: PropTypes.object,
identity: PropTypes.object,
};
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
relationship: ImmutablePropTypes.map,
onReply: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired,
onFavourite: PropTypes.func.isRequired,
2022-12-01 01:25:36 +09:00
onReactionAdd: PropTypes.func.isRequired,
onBookmark: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
onDirect: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,
onMute: PropTypes.func,
onUnmute: PropTypes.func,
onBlock: PropTypes.func,
onUnblock: PropTypes.func,
onBlockDomain: PropTypes.func,
onUnblockDomain: PropTypes.func,
onMuteConversation: PropTypes.func,
onReport: PropTypes.func,
onPin: PropTypes.func,
onEmbed: PropTypes.func,
intl: PropTypes.object.isRequired,
};
handleReplyClick = () => {
this.props.onReply(this.props.status);
2023-01-30 09:45:35 +09:00
};
handleReblogClick = (e) => {
this.props.onReblog(this.props.status, e);
2023-01-30 09:45:35 +09:00
};
handleFavouriteClick = () => {
this.props.onFavourite(this.props.status);
2023-01-30 09:45:35 +09:00
};
2022-12-01 01:25:36 +09:00
handleEmojiPick = data => {
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''));
}
Squashed commit of the following: commit 13bca8d5b7344445633ff3c8a162086be8215379 Merge: 1e2782647 ff157b237 Author: Essem <smswessem@gmail.com> Date: Thu Mar 16 11:51:32 2023 -0500 Merge branch 'feat/emoji_reactions' of https://github.com/neatchee/mastodon into feat/emoji_reactions commit ff157b2378a15a786763d7e13ad2de4ff223dc03 Author: neatchee <neatchee@gmail.com> Date: Wed Mar 8 13:27:25 2023 -0800 Remove old .js locale files accidentally restored during rebase commit 52beb88a19626c0b17d0945a43bf8725ceae4b04 Author: Ivan Rodriguez <104603218+IRod22@users.noreply.github.com> Date: Tue Mar 7 23:21:32 2023 -0600 Keep emoji picker within screen bounds Adds the `flip` prop to `<Overlay>`. Fixes #40 commit 7707004cf3d5bacd3ef830ef734dd003b607c2af Author: neatchee <neatchee@gmail.com> Date: Thu Jan 26 11:32:03 2023 -0800 Fix rebase issues commit ce40bbbce1e5e9ab7770f89dd7cffd87d3ceb177 Author: neatchee <neatchee@gmail.com> Date: Thu Jan 26 10:22:15 2023 -0800 Per PR suggestion, split name and domain, and look for emoji ID, for unreact, so remote emoji's can be unreacted commit fc9f34a39fa40b3eda4ccfc0cc8e5c028b9ebe79 Author: fef <owo@fef.moe> Date: Tue Dec 20 17:19:56 2022 +0000 move emoji reaction strings to locales-glitch commit af0f50ca74631e9f2dafde0f0e08417f906c04a0 Author: Jeremy Kescher <jeremy@kescher.at> Date: Sun Dec 18 04:23:42 2022 +0100 Fix status reactions preventing an on_cascade delete commit 2e713c7792438f17ef026f6d79465be25a5fb7db Author: fef <owo@fef.moe> Date: Thu Dec 15 15:27:54 2022 +0000 bypass reaction limit for foreign accounts commit 907e1e490ed9b2373eb18f92af9fda4426274713 Author: fef <owo@fef.moe> Date: Sun Dec 11 13:26:23 2022 +0000 fix 404 when reacting with Keycap Number Sign The Unicode sequence for this emoji starts with an ASCII # character, which the browser's URI parser truncates before sending the request to the backend. commit 9028d3841f7d5d2eb1b06bc210ded055c53fc1d2 Author: fef <owo@fef.moe> Date: Thu Dec 8 09:48:55 2022 +0000 fix status action bar after upstream changes commit 4ce5095d8c187947805ecf21c90ad494440e904a Author: fef <owo@fef.moe> Date: Wed Dec 7 21:52:53 2022 +0100 fix schema after rebase commit 63b9e4392adbb13fe0ce71de4d28419df0f36bb1 Author: fef <owo@fef.moe> Date: Wed Dec 7 12:47:03 2022 +0000 delete reaction notifications when deleting status commit e407cc12b64a664c66717ce06d65342dd8bc609e Author: fef <owo@fef.moe> Date: Wed Dec 7 12:19:36 2022 +0000 support reacting with foreign custom emojis commit b2dbb4dbe4996426a6cdb90e8da27e5096b3e88c Author: fef <owo@fef.moe> Date: Sun Dec 4 12:33:47 2022 +0000 properly disable reactions when not logged in commit ec790f3b1e243e33ccd22685b8e3c017ca7f9273 Author: fef <owo@fef.moe> Date: Sun Dec 4 10:52:02 2022 +0000 serialize custom emoji reactions properly for AP Akkoma and possibly others expect the `tag` field in an EmojiReact activity to be an array, not just a single object, so it's being wrapped into one now. I'm not entirely sure whether this is the idiomatic way of doing it tbh, but it works fine. commit 2637d9b77a6e696face0851328c5bd2e80d1dab2 Author: fef <owo@fef.moe> Date: Sun Dec 4 08:47:24 2022 +0000 also disable reaction buttons in vanilla flavour commit 0b4d5f700b74c0a6c8344321e491082511128f48 Author: fef <owo@fef.moe> Date: Sat Dec 3 16:55:37 2022 +0000 disable reaction button when not signed in commit afd0bb2c05be38477df1a808b32cece5c7e4b416 Author: fef <owo@fef.moe> Date: Sat Dec 3 16:20:29 2022 +0000 fix image for new custom emoji reactions commit b1dcd0eb6ce2f097fab310cdf32cd509426fcfba Author: fef <owo@fef.moe> Date: Sat Dec 3 14:23:55 2022 +0000 run i18n-tasks normalize commit e4e7837bf30082185b2f14e8d60741261f7085f4 Author: fef <owo@fef.moe> Date: Sat Dec 3 11:57:00 2022 +0000 display external custom emoji reactions properly Using an emoji map was completely unnecessary in the first place, because the reaction list from the API response includes URLs for every custom emoji anyway. The reaction list now also contains a boolean field indicating whether it is an external custom emoji, which is required because people should only be able to react with Unicode emojis and local custom ones, not with custom emojis from other servers. commit 6d3e364fa22370ab80f16a311dce15d93976464a Author: fef <owo@fef.moe> Date: Sat Dec 3 10:22:15 2022 +0000 handle incoming custom emoji reactions properly commit 0a47a05905adc3e9d1dc1e7e619891b884b9e512 Author: fef <owo@fef.moe> Date: Sat Dec 3 08:24:23 2022 +0000 support Undo action for EmojiReaction commit b81f4537aced99e427cb30fd54a33c852839e08a Author: fef <owo@fef.moe> Date: Fri Dec 2 17:02:06 2022 +0000 download remote custom emojis from reactions Emoji reactions containing custom emojis from remote instances were assumed to already have been downloaded and stored in the database. This might obviously not be the case. commit ff246bda3731753f58f7e499aae036c331953d0b Author: fef <owo@fef.moe> Date: Fri Dec 2 10:17:59 2022 +0000 fix integer cast bug Gotta love Rails. commit 40a645aab9e8071698051751d88262bb9e10199a Author: fef <owo@fef.moe> Date: Fri Dec 2 09:37:56 2022 +0000 sanitize setting for number of visible reactions This is kind of a hack, but the lack of validation for settings unfortunately makes it necessary. commit 391c6e22f2170f990d30d975c4a5ffb966484c17 Author: Jeremy Kescher <jeremy@kescher.at> Date: Fri Dec 2 08:05:10 2022 +0100 Add reaction limit to instance serializer commit 501ae9e2e1578ef80709ff38910dc46f483c5942 Author: fef <owo@fef.moe> Date: Fri Dec 2 01:52:59 2022 +0000 fix padding on posts without reactions The margins of the elements above and below the main reaction list element overlapped before reactions were added. Adding display: none to empty reaction bars restores this exact look. commit 956edd3ca7cd04a3524addc2c5b6ddc475358734 Author: fef <owo@fef.moe> Date: Fri Dec 2 01:00:08 2022 +0000 rename nop handler to handleNoOp This also adds the comment in action_bar.js to status_action_bar.js, clarifying that a future version could improve this code by modifying EmojiPickerDropdown. commit 2c93f1840f6cc74eef628b370b2c7b8485028cc8 Author: fef <owo@fef.moe> Date: Thu Dec 1 23:30:39 2022 +0100 cleanup JS imports and other minor stuff commit 4a2f91e3de2dfdb53e1a3f09430c6e0eabbf49be Author: fef <owo@fef.moe> Date: Thu Dec 1 04:26:13 2022 +0000 remove unnecessary parameter commit 91d26c871786708f8c2c0188f82318ff2c438127 Author: fef <owo@fef.moe> Date: Thu Dec 1 02:24:08 2022 +0000 change reaction api to match other interactions Status reactions had an API similar to that of announcement reactions, using PUT and DELETE at a single endpoint. I believe that for statuses, it makes more sense to follow the convention of the other interactions and use separate POST endpoints for create and destroy respectively. commit c74e050e3d77920000d7226ae26966d27291e790 Author: fef <owo@fef.moe> Date: Thu Dec 1 01:41:47 2022 +0000 fix reaction deletion bug and clean up controller Turns out the strange error where it would delete the wrong reaction occurred because I forgot to pass the emoji name to the query, which resulted in the database deleting the first reaction it found. Also, this removes the unused set_reaction callback and includes the Authorization module for the status reactions controller. commit e7ed7e37d7995d4bf39ad44c7a738290c81fa9dc Author: fef <owo@fef.moe> Date: Wed Nov 30 19:29:56 2022 +0000 remove outdated comments commit d33f8330c019898f948334453b75fc2802fab9f8 Author: fef <owo@fef.moe> Date: Wed Nov 30 17:09:16 2022 +0000 clean up new imports in vanilla flavour commit 45f803e23f019dbe5246daa3131548acdb99a757 Author: fef <owo@fef.moe> Date: Wed Nov 30 17:25:36 2022 +0100 rebase with upstream commit 8b339e4a2d2632a269dccdba1a60e69b6b38a053 Author: fef <owo@fef.moe> Date: Wed Nov 30 14:59:37 2022 +0000 make number of visible reactions a vanilla setting Reactions will be backported to the vanilla flavour, which requires all related settings to be accessible from the vanilla settings page rather than the glitch specific settings modal. commit 56323209b519a90f9dbf10b1c45a320de4d6aaa5 Author: fef <owo@fef.moe> Date: Wed Nov 30 13:20:20 2022 +0000 make number of displayed reactions a setting This adds an extra item to the local settings for specifying the number of reactions shown in toots. The detailed status view always shows all reactions. commit e96fb97770877749b5c6bca8fe3e6136fffa309a Author: fef <owo@fef.moe> Date: Wed Nov 30 12:01:34 2022 +0000 change default reaction limit to 1 commit 30ae2ad2612bae2abb48c49205bbe71b97435dda Author: fef <owo@fef.moe> Date: Wed Nov 30 09:06:14 2022 +0000 limit number of reactions displayed Too many reactions on a single post quickly get spammy, so they are now sorted by count and only the first MAX_REACTIONS number of different emojis are actually displayed. commit 84fb0f3cc252cabfa374b31f8a34e021a3ad8677 Author: fef <owo@fef.moe> Date: Tue Nov 29 09:07:10 2022 +0000 fix reaction margins and paddings commit 53b685ff1d4589915655da5cafa3a2dd9ee06a51 Author: fef <owo@fef.moe> Date: Tue Nov 29 08:54:35 2022 +0000 cleanup frontend emoji reaction code commit 2b0a474a73a84a3e841ddf44854fa5c2e0681a0f Author: fef <owo@fef.moe> Date: Tue Nov 29 08:15:52 2022 +0000 cleanup backend emoji reaction code commit 3bfd5ceba17c42bee27ff0f10514332caa814332 Author: fef <owo@fef.moe> Date: Tue Nov 29 06:25:43 2022 +0000 fix padding for reaction button commit deabc28e182acc208bffe6fb57430b97c5bc7c6c Author: fef <owo@fef.moe> Date: Tue Nov 29 05:21:53 2022 +0000 handle misskey reactions properly misskey federates emoji reactions as likes. commit 4d47b9929852493b208fdf13dee38e27dde50b8c Author: fef <owo@fef.moe> Date: Tue Nov 29 04:37:44 2022 +0000 move react button to action bar commit 151bcea7d4497086823adc0bca6c674ea78a8d8f Author: fef <owo@fef.moe> Date: Tue Nov 29 04:31:22 2022 +0100 cherry-pick emoji reaction changes commit f150fd0dc8761c2a992875948a2736244e5f7076 Author: fef <owo@fef.moe> Date: Tue Nov 29 00:39:40 2022 +0000 make frontend fetch reaction limit the maximum number of reactions was previously hardcoded to 8. this commit also fixes an incorrect query in StatusReactionValidator where it didn't count per-user reactions but the total amount of different ones. commit 12886aa19ae5be6c7077ff1704b1b4c75c15eae6 Author: fef <owo@fef.moe> Date: Mon Nov 28 23:16:56 2022 +0000 make status reaction count limit configurable commit 25806c568a57e9193b43427df80b60a88143a5eb Author: fef <owo@fef.moe> Date: Mon Nov 28 22:25:12 2022 +0000 remove accidentally created file commit f3784cfef551ad1d9d0df0001b2b480bfc656b14 Author: fef <owo@fef.moe> Date: Mon Nov 28 22:23:13 2022 +0000 federate emoji reactions this is kind of experimental, but it should work in theory. at least i tested it with a remove akkoma instance and it didn't crash. commit d32f3f8c2fb9e8a29e676e54c98d2cac85841728 Author: fef <owo@fef.moe> Date: Fri Nov 25 23:02:40 2022 +0000 show reactions in detailed status view commit 5e9bbb0be253b5b56c6d7b5ee8d843f401995b7c Author: fef <owo@fef.moe> Date: Thu Nov 24 17:30:52 2022 +0000 add frontend for emoji reactions this is still pretty bare bones but hey, it works. commit 85756b572a169857a09d7668ce9f2c856ebefd27 Author: fef <owo@fef.moe> Date: Thu Nov 24 11:50:32 2022 +0000 add backend support for status emoji reactions turns out we can just reuse the code for announcement reactions.
2023-03-17 01:54:49 +09:00
handleEmojiPick = data => {
this.props.onReactionAdd(this.props.status.get('id'), data.native.replace(/:/g, ''));
}
handleBookmarkClick = (e) => {
this.props.onBookmark(this.props.status, e);
2023-01-30 09:45:35 +09:00
};
handleDeleteClick = () => {
this.props.onDelete(this.props.status, this.context.router.history);
2023-01-30 09:45:35 +09:00
};
handleRedraftClick = () => {
this.props.onDelete(this.props.status, this.context.router.history, true);
2023-01-30 09:45:35 +09:00
};
handleEditClick = () => {
this.props.onEdit(this.props.status, this.context.router.history);
2023-01-30 09:45:35 +09:00
};
handleDirectClick = () => {
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
2023-01-30 09:45:35 +09:00
};
handleMentionClick = () => {
this.props.onMention(this.props.status.get('account'), this.context.router.history);
2023-01-30 09:45:35 +09:00
};
handleMuteClick = () => {
const { status, relationship, onMute, onUnmute } = this.props;
const account = status.get('account');
if (relationship && relationship.get('muting')) {
onUnmute(account);
} else {
onMute(account);
}
2023-01-30 09:45:35 +09:00
};
handleBlockClick = () => {
const { status, relationship, onBlock, onUnblock } = this.props;
const account = status.get('account');
if (relationship && relationship.get('blocking')) {
onUnblock(account);
} else {
onBlock(status);
}
2023-01-30 09:45:35 +09:00
};
handleBlockDomain = () => {
const { status, onBlockDomain } = this.props;
const account = status.get('account');
onBlockDomain(account.get('acct').split('@')[1]);
2023-01-30 09:45:35 +09:00
};
handleUnblockDomain = () => {
const { status, onUnblockDomain } = this.props;
const account = status.get('account');
onUnblockDomain(account.get('acct').split('@')[1]);
2023-01-30 09:45:35 +09:00
};
handleConversationMuteClick = () => {
this.props.onMuteConversation(this.props.status);
2023-01-30 09:45:35 +09:00
};
handleReport = () => {
this.props.onReport(this.props.status);
2023-01-30 09:45:35 +09:00
};
handlePinClick = () => {
this.props.onPin(this.props.status);
2023-01-30 09:45:35 +09:00
};
handleShare = () => {
navigator.share({
text: this.props.status.get('search_index'),
url: this.props.status.get('url'),
});
2023-01-30 09:45:35 +09:00
};
handleEmbed = () => {
this.props.onEmbed(this.props.status);
2023-01-30 09:45:35 +09:00
};
handleCopy = () => {
const url = this.props.status.get('url');
navigator.clipboard.writeText(url);
2023-01-30 09:45:35 +09:00
};
handleNoOp = () => {} // hack for reaction add button
2022-12-01 01:25:36 +09:00
Squashed commit of the following: commit 13bca8d5b7344445633ff3c8a162086be8215379 Merge: 1e2782647 ff157b237 Author: Essem <smswessem@gmail.com> Date: Thu Mar 16 11:51:32 2023 -0500 Merge branch 'feat/emoji_reactions' of https://github.com/neatchee/mastodon into feat/emoji_reactions commit ff157b2378a15a786763d7e13ad2de4ff223dc03 Author: neatchee <neatchee@gmail.com> Date: Wed Mar 8 13:27:25 2023 -0800 Remove old .js locale files accidentally restored during rebase commit 52beb88a19626c0b17d0945a43bf8725ceae4b04 Author: Ivan Rodriguez <104603218+IRod22@users.noreply.github.com> Date: Tue Mar 7 23:21:32 2023 -0600 Keep emoji picker within screen bounds Adds the `flip` prop to `<Overlay>`. Fixes #40 commit 7707004cf3d5bacd3ef830ef734dd003b607c2af Author: neatchee <neatchee@gmail.com> Date: Thu Jan 26 11:32:03 2023 -0800 Fix rebase issues commit ce40bbbce1e5e9ab7770f89dd7cffd87d3ceb177 Author: neatchee <neatchee@gmail.com> Date: Thu Jan 26 10:22:15 2023 -0800 Per PR suggestion, split name and domain, and look for emoji ID, for unreact, so remote emoji's can be unreacted commit fc9f34a39fa40b3eda4ccfc0cc8e5c028b9ebe79 Author: fef <owo@fef.moe> Date: Tue Dec 20 17:19:56 2022 +0000 move emoji reaction strings to locales-glitch commit af0f50ca74631e9f2dafde0f0e08417f906c04a0 Author: Jeremy Kescher <jeremy@kescher.at> Date: Sun Dec 18 04:23:42 2022 +0100 Fix status reactions preventing an on_cascade delete commit 2e713c7792438f17ef026f6d79465be25a5fb7db Author: fef <owo@fef.moe> Date: Thu Dec 15 15:27:54 2022 +0000 bypass reaction limit for foreign accounts commit 907e1e490ed9b2373eb18f92af9fda4426274713 Author: fef <owo@fef.moe> Date: Sun Dec 11 13:26:23 2022 +0000 fix 404 when reacting with Keycap Number Sign The Unicode sequence for this emoji starts with an ASCII # character, which the browser's URI parser truncates before sending the request to the backend. commit 9028d3841f7d5d2eb1b06bc210ded055c53fc1d2 Author: fef <owo@fef.moe> Date: Thu Dec 8 09:48:55 2022 +0000 fix status action bar after upstream changes commit 4ce5095d8c187947805ecf21c90ad494440e904a Author: fef <owo@fef.moe> Date: Wed Dec 7 21:52:53 2022 +0100 fix schema after rebase commit 63b9e4392adbb13fe0ce71de4d28419df0f36bb1 Author: fef <owo@fef.moe> Date: Wed Dec 7 12:47:03 2022 +0000 delete reaction notifications when deleting status commit e407cc12b64a664c66717ce06d65342dd8bc609e Author: fef <owo@fef.moe> Date: Wed Dec 7 12:19:36 2022 +0000 support reacting with foreign custom emojis commit b2dbb4dbe4996426a6cdb90e8da27e5096b3e88c Author: fef <owo@fef.moe> Date: Sun Dec 4 12:33:47 2022 +0000 properly disable reactions when not logged in commit ec790f3b1e243e33ccd22685b8e3c017ca7f9273 Author: fef <owo@fef.moe> Date: Sun Dec 4 10:52:02 2022 +0000 serialize custom emoji reactions properly for AP Akkoma and possibly others expect the `tag` field in an EmojiReact activity to be an array, not just a single object, so it's being wrapped into one now. I'm not entirely sure whether this is the idiomatic way of doing it tbh, but it works fine. commit 2637d9b77a6e696face0851328c5bd2e80d1dab2 Author: fef <owo@fef.moe> Date: Sun Dec 4 08:47:24 2022 +0000 also disable reaction buttons in vanilla flavour commit 0b4d5f700b74c0a6c8344321e491082511128f48 Author: fef <owo@fef.moe> Date: Sat Dec 3 16:55:37 2022 +0000 disable reaction button when not signed in commit afd0bb2c05be38477df1a808b32cece5c7e4b416 Author: fef <owo@fef.moe> Date: Sat Dec 3 16:20:29 2022 +0000 fix image for new custom emoji reactions commit b1dcd0eb6ce2f097fab310cdf32cd509426fcfba Author: fef <owo@fef.moe> Date: Sat Dec 3 14:23:55 2022 +0000 run i18n-tasks normalize commit e4e7837bf30082185b2f14e8d60741261f7085f4 Author: fef <owo@fef.moe> Date: Sat Dec 3 11:57:00 2022 +0000 display external custom emoji reactions properly Using an emoji map was completely unnecessary in the first place, because the reaction list from the API response includes URLs for every custom emoji anyway. The reaction list now also contains a boolean field indicating whether it is an external custom emoji, which is required because people should only be able to react with Unicode emojis and local custom ones, not with custom emojis from other servers. commit 6d3e364fa22370ab80f16a311dce15d93976464a Author: fef <owo@fef.moe> Date: Sat Dec 3 10:22:15 2022 +0000 handle incoming custom emoji reactions properly commit 0a47a05905adc3e9d1dc1e7e619891b884b9e512 Author: fef <owo@fef.moe> Date: Sat Dec 3 08:24:23 2022 +0000 support Undo action for EmojiReaction commit b81f4537aced99e427cb30fd54a33c852839e08a Author: fef <owo@fef.moe> Date: Fri Dec 2 17:02:06 2022 +0000 download remote custom emojis from reactions Emoji reactions containing custom emojis from remote instances were assumed to already have been downloaded and stored in the database. This might obviously not be the case. commit ff246bda3731753f58f7e499aae036c331953d0b Author: fef <owo@fef.moe> Date: Fri Dec 2 10:17:59 2022 +0000 fix integer cast bug Gotta love Rails. commit 40a645aab9e8071698051751d88262bb9e10199a Author: fef <owo@fef.moe> Date: Fri Dec 2 09:37:56 2022 +0000 sanitize setting for number of visible reactions This is kind of a hack, but the lack of validation for settings unfortunately makes it necessary. commit 391c6e22f2170f990d30d975c4a5ffb966484c17 Author: Jeremy Kescher <jeremy@kescher.at> Date: Fri Dec 2 08:05:10 2022 +0100 Add reaction limit to instance serializer commit 501ae9e2e1578ef80709ff38910dc46f483c5942 Author: fef <owo@fef.moe> Date: Fri Dec 2 01:52:59 2022 +0000 fix padding on posts without reactions The margins of the elements above and below the main reaction list element overlapped before reactions were added. Adding display: none to empty reaction bars restores this exact look. commit 956edd3ca7cd04a3524addc2c5b6ddc475358734 Author: fef <owo@fef.moe> Date: Fri Dec 2 01:00:08 2022 +0000 rename nop handler to handleNoOp This also adds the comment in action_bar.js to status_action_bar.js, clarifying that a future version could improve this code by modifying EmojiPickerDropdown. commit 2c93f1840f6cc74eef628b370b2c7b8485028cc8 Author: fef <owo@fef.moe> Date: Thu Dec 1 23:30:39 2022 +0100 cleanup JS imports and other minor stuff commit 4a2f91e3de2dfdb53e1a3f09430c6e0eabbf49be Author: fef <owo@fef.moe> Date: Thu Dec 1 04:26:13 2022 +0000 remove unnecessary parameter commit 91d26c871786708f8c2c0188f82318ff2c438127 Author: fef <owo@fef.moe> Date: Thu Dec 1 02:24:08 2022 +0000 change reaction api to match other interactions Status reactions had an API similar to that of announcement reactions, using PUT and DELETE at a single endpoint. I believe that for statuses, it makes more sense to follow the convention of the other interactions and use separate POST endpoints for create and destroy respectively. commit c74e050e3d77920000d7226ae26966d27291e790 Author: fef <owo@fef.moe> Date: Thu Dec 1 01:41:47 2022 +0000 fix reaction deletion bug and clean up controller Turns out the strange error where it would delete the wrong reaction occurred because I forgot to pass the emoji name to the query, which resulted in the database deleting the first reaction it found. Also, this removes the unused set_reaction callback and includes the Authorization module for the status reactions controller. commit e7ed7e37d7995d4bf39ad44c7a738290c81fa9dc Author: fef <owo@fef.moe> Date: Wed Nov 30 19:29:56 2022 +0000 remove outdated comments commit d33f8330c019898f948334453b75fc2802fab9f8 Author: fef <owo@fef.moe> Date: Wed Nov 30 17:09:16 2022 +0000 clean up new imports in vanilla flavour commit 45f803e23f019dbe5246daa3131548acdb99a757 Author: fef <owo@fef.moe> Date: Wed Nov 30 17:25:36 2022 +0100 rebase with upstream commit 8b339e4a2d2632a269dccdba1a60e69b6b38a053 Author: fef <owo@fef.moe> Date: Wed Nov 30 14:59:37 2022 +0000 make number of visible reactions a vanilla setting Reactions will be backported to the vanilla flavour, which requires all related settings to be accessible from the vanilla settings page rather than the glitch specific settings modal. commit 56323209b519a90f9dbf10b1c45a320de4d6aaa5 Author: fef <owo@fef.moe> Date: Wed Nov 30 13:20:20 2022 +0000 make number of displayed reactions a setting This adds an extra item to the local settings for specifying the number of reactions shown in toots. The detailed status view always shows all reactions. commit e96fb97770877749b5c6bca8fe3e6136fffa309a Author: fef <owo@fef.moe> Date: Wed Nov 30 12:01:34 2022 +0000 change default reaction limit to 1 commit 30ae2ad2612bae2abb48c49205bbe71b97435dda Author: fef <owo@fef.moe> Date: Wed Nov 30 09:06:14 2022 +0000 limit number of reactions displayed Too many reactions on a single post quickly get spammy, so they are now sorted by count and only the first MAX_REACTIONS number of different emojis are actually displayed. commit 84fb0f3cc252cabfa374b31f8a34e021a3ad8677 Author: fef <owo@fef.moe> Date: Tue Nov 29 09:07:10 2022 +0000 fix reaction margins and paddings commit 53b685ff1d4589915655da5cafa3a2dd9ee06a51 Author: fef <owo@fef.moe> Date: Tue Nov 29 08:54:35 2022 +0000 cleanup frontend emoji reaction code commit 2b0a474a73a84a3e841ddf44854fa5c2e0681a0f Author: fef <owo@fef.moe> Date: Tue Nov 29 08:15:52 2022 +0000 cleanup backend emoji reaction code commit 3bfd5ceba17c42bee27ff0f10514332caa814332 Author: fef <owo@fef.moe> Date: Tue Nov 29 06:25:43 2022 +0000 fix padding for reaction button commit deabc28e182acc208bffe6fb57430b97c5bc7c6c Author: fef <owo@fef.moe> Date: Tue Nov 29 05:21:53 2022 +0000 handle misskey reactions properly misskey federates emoji reactions as likes. commit 4d47b9929852493b208fdf13dee38e27dde50b8c Author: fef <owo@fef.moe> Date: Tue Nov 29 04:37:44 2022 +0000 move react button to action bar commit 151bcea7d4497086823adc0bca6c674ea78a8d8f Author: fef <owo@fef.moe> Date: Tue Nov 29 04:31:22 2022 +0100 cherry-pick emoji reaction changes commit f150fd0dc8761c2a992875948a2736244e5f7076 Author: fef <owo@fef.moe> Date: Tue Nov 29 00:39:40 2022 +0000 make frontend fetch reaction limit the maximum number of reactions was previously hardcoded to 8. this commit also fixes an incorrect query in StatusReactionValidator where it didn't count per-user reactions but the total amount of different ones. commit 12886aa19ae5be6c7077ff1704b1b4c75c15eae6 Author: fef <owo@fef.moe> Date: Mon Nov 28 23:16:56 2022 +0000 make status reaction count limit configurable commit 25806c568a57e9193b43427df80b60a88143a5eb Author: fef <owo@fef.moe> Date: Mon Nov 28 22:25:12 2022 +0000 remove accidentally created file commit f3784cfef551ad1d9d0df0001b2b480bfc656b14 Author: fef <owo@fef.moe> Date: Mon Nov 28 22:23:13 2022 +0000 federate emoji reactions this is kind of experimental, but it should work in theory. at least i tested it with a remove akkoma instance and it didn't crash. commit d32f3f8c2fb9e8a29e676e54c98d2cac85841728 Author: fef <owo@fef.moe> Date: Fri Nov 25 23:02:40 2022 +0000 show reactions in detailed status view commit 5e9bbb0be253b5b56c6d7b5ee8d843f401995b7c Author: fef <owo@fef.moe> Date: Thu Nov 24 17:30:52 2022 +0000 add frontend for emoji reactions this is still pretty bare bones but hey, it works. commit 85756b572a169857a09d7668ce9f2c856ebefd27 Author: fef <owo@fef.moe> Date: Thu Nov 24 11:50:32 2022 +0000 add backend support for status emoji reactions turns out we can just reuse the code for announcement reactions.
2023-03-17 01:54:49 +09:00
handleNoOp = () => {} // hack for reaction add button
render () {
const { status, relationship, intl } = this.props;
const { signedIn, permissions } = this.context.identity;
2016-10-10 05:19:15 +09:00
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility'));
const mutingConversation = status.get('muted');
const account = status.get('account');
const writtenByMe = status.getIn(['account', 'id']) === me;
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
2016-10-10 05:19:15 +09:00
let menu = [];
if (publicStatus) {
if (isRemote) {
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
}
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
menu.push(null);
}
if (writtenByMe) {
if (pinnableStatus) {
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
menu.push(null);
}
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
2016-11-18 23:36:16 +09:00
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
} else {
2017-03-01 08:53:11 +09:00
menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
menu.push(null);
if (relationship && relationship.get('muting')) {
menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.handleMuteClick });
} else {
menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.handleMuteClick });
}
if (relationship && relationship.get('blocking')) {
menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.handleBlockClick });
} else {
menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.handleBlockClick });
}
2017-03-01 08:53:11 +09:00
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
if (account.get('acct') !== account.get('username')) {
const domain = account.get('acct').split('@')[1];
menu.push(null);
if (relationship && relationship.get('domain_blocking')) {
menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.handleUnblockDomain });
} else {
menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.handleBlockDomain });
}
}
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
menu.push(null);
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
}
if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
const domain = account.get('acct').split('@')[1];
menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
}
}
2016-10-10 05:19:15 +09:00
}
const canReact = signedIn && status.get('reactions').filter(r => r.get('count') > 0 && r.get('me')).size < maxReactions;
2022-12-01 01:25:36 +09:00
const reactButton = (
<IconButton
className='plus-icon'
onClick={this.handleNoOp} // EmojiPickerDropdown handles that
2022-12-01 01:25:36 +09:00
title={intl.formatMessage(messages.react)}
disabled={!canReact}
icon='plus'
/>
);
const shareButton = ('share' in navigator) && publicStatus && (
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShare} /></div>
);
let replyIcon;
if (status.get('in_reply_to_id', null) === null) {
replyIcon = 'reply';
} else {
replyIcon = 'reply-all';
}
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
let reblogTitle;
if (status.get('reblogged')) {
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
} else if (publicStatus) {
reblogTitle = intl.formatMessage(messages.reblog);
} else if (reblogPrivate) {
reblogTitle = intl.formatMessage(messages.reblog_private);
} else {
reblogTitle = intl.formatMessage(messages.cannot_reblog);
}
return (
<div className='detailed-status__action-bar'>
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /></div>
<div className='detailed-status__button' ><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} /></div>
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
<div className='detailed-status__button'>
{
canReact
? <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} button={reactButton} disabled={!canReact} />
: reactButton
}
</div>
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} /></div>
{shareButton}
<div className='detailed-status__action-bar-dropdown'>
<DropdownMenuContainer size={18} icon='ellipsis-h' disabled={!signedIn} status={status} items={menu} direction='left' title={intl.formatMessage(messages.more)} />
</div>
</div>
);
}
}
export default connect(mapStateToProps)(injectIntl(ActionBar));