diff --git a/app/soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json b/app/soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json
new file mode 100644
index 000000000..76c722a45
--- /dev/null
+++ b/app/soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json
@@ -0,0 +1,236 @@
+{
+ "account": {
+ "acct": "alex",
+ "avatar": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
+ "avatar_static": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
+ "bot": false,
+ "created_at": "2020-01-08T01:25:43.000Z",
+ "display_name": "Alex Gleason",
+ "emojis": [],
+ "fields": [
+ {
+ "name": "Website",
+ "value": "https://alexgleason.me"
+ },
+ {
+ "name": "Soapbox",
+ "value": "https://soapbox.pub"
+ },
+ {
+ "name": "Email",
+ "value": "alex@alexgleason.me"
+ },
+ {
+ "name": "Gender identity",
+ "value": "Soyboy"
+ },
+ {
+ "name": "Donate (PayPal)",
+ "value": "https://paypal.me/gleasonator"
+ },
+ {
+ "name": "$BTC",
+ "value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
+ },
+ {
+ "name": "$ETH",
+ "value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
+ },
+ {
+ "name": "$DOGE",
+ "value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
+ },
+ {
+ "name": "$XMR",
+ "value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
+ }
+ ],
+ "followers_count": 2467,
+ "following_count": 1581,
+ "fqn": "alex@gleasonator.com",
+ "header": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
+ "header_static": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
+ "id": "9v5bmRalQvjOy0ECcC",
+ "last_status_at": "2022-03-11T01:33:19",
+ "locked": false,
+ "note": "I create Fediverse software that empowers people online.
I'm vegan btw
Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
+ "pleroma": {
+ "accepts_chat_messages": true,
+ "also_known_as": [
+ "https://mitra.social/users/alex"
+ ],
+ "ap_id": "https://gleasonator.com/users/alex",
+ "background_image": null,
+ "birthday": "1993-07-03",
+ "favicon": "https://gleasonator.com/favicon.png",
+ "hide_favorites": true,
+ "hide_followers": false,
+ "hide_followers_count": false,
+ "hide_follows": false,
+ "hide_follows_count": false,
+ "is_admin": true,
+ "is_confirmed": true,
+ "is_moderator": false,
+ "is_suggested": true,
+ "relationship": {},
+ "skip_thread_containment": false,
+ "tags": []
+ },
+ "source": {
+ "fields": [
+ {
+ "name": "Website",
+ "value": "https://alexgleason.me"
+ },
+ {
+ "name": "Soapbox",
+ "value": "https://soapbox.pub"
+ },
+ {
+ "name": "Email",
+ "value": "alex@alexgleason.me"
+ },
+ {
+ "name": "Gender identity",
+ "value": "Soyboy"
+ },
+ {
+ "name": "Donate (PayPal)",
+ "value": "https://paypal.me/gleasonator"
+ },
+ {
+ "name": "$BTC",
+ "value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
+ },
+ {
+ "name": "$ETH",
+ "value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
+ },
+ {
+ "name": "$DOGE",
+ "value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
+ },
+ {
+ "name": "$XMR",
+ "value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
+ }
+ ],
+ "note": "I create Fediverse software that empowers people online.\r\n\r\nI'm vegan btw\r\n\r\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
+ "pleroma": {
+ "actor_type": "Person",
+ "discoverable": false
+ },
+ "sensitive": false
+ },
+ "statuses_count": 23651,
+ "url": "https://gleasonator.com/users/alex",
+ "username": "alex"
+ },
+ "application": {
+ "name": "Soapbox FE",
+ "website": "https://soapbox.pub/"
+ },
+ "bookmarked": false,
+ "card": null,
+ "content": "
Test poll
", + "created_at": "2022-03-11T01:33:18.000Z", + "emojis": [ + { + "shortcode": "gleason_excited", + "static_url": "https://gleasonator.com/emoji/gleason_emojis/gleason_excited.png", + "url": "https://gleasonator.com/emoji/gleason_emojis/gleason_excited.png", + "visible_in_picker": false + }, + { + "shortcode": "soapbox", + "static_url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png", + "url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png", + "visible_in_picker": false + } + ], + "favourited": false, + "favourites_count": 1, + "id": "AHHue68kB59xtUv7MO", + "in_reply_to_account_id": null, + "in_reply_to_id": null, + "language": null, + "media_attachments": [], + "mentions": [], + "muted": false, + "pinned": false, + "pleroma": { + "content": { + "text/plain": "Test poll" + }, + "conversation_id": "AHHue65YMwbjjbQZO4", + "direct_conversation_id": null, + "emoji_reactions": [], + "expires_at": null, + "in_reply_to_account_acct": null, + "local": true, + "parent_visible": false, + "pinned_at": null, + "quote": null, + "quote_url": null, + "quote_visible": false, + "spoiler_text": { + "text/plain": "" + }, + "thread_muted": false + }, + "poll": { + "emojis": [ + { + "shortcode": "gleason_excited", + "static_url": "https://gleasonator.com/emoji/gleason_emojis/gleason_excited.png", + "url": "https://gleasonator.com/emoji/gleason_emojis/gleason_excited.png", + "visible_in_picker": false + }, + { + "shortcode": "soapbox", + "static_url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png", + "url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png", + "visible_in_picker": false + } + ], + "expired": false, + "expires_at": "2022-03-12T01:33:18.000Z", + "id": "AHHue67gF2JDqCQGhc", + "multiple": false, + "options": [ + { + "title": "Regular emoji 😍 ", + "votes_count": 0 + }, + { + "title": "Custom emoji :gleason_excited: ", + "votes_count": 1 + }, + { + "title": "No emoji", + "votes_count": 0 + }, + { + "title": "🤔 😮 😠 ", + "votes_count": 1 + }, + { + "title": ":soapbox:", + "votes_count": 1 + } + ], + "voters_count": 3, + "votes_count": 3 + }, + "reblog": null, + "reblogged": false, + "reblogs_count": 1, + "replies_count": 1, + "sensitive": false, + "spoiler_text": "", + "tags": [], + "text": null, + "uri": "https://gleasonator.com/objects/46d2ab26-3497-442b-999f-612fe717b0a3", + "url": "https://gleasonator.com/notice/AHHue68kB59xtUv7MO", + "visibility": "public" +} diff --git a/app/soapbox/actions/importer/index.js b/app/soapbox/actions/importer/index.js index 56efcf651..1668ad71e 100644 --- a/app/soapbox/actions/importer/index.js +++ b/app/soapbox/actions/importer/index.js @@ -1,9 +1,6 @@ import { getSettings } from '../settings'; -import { - normalizeAccount, - normalizePoll, -} from './normalizer'; +import { normalizeAccount } from './normalizer'; export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT'; export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT'; @@ -130,7 +127,7 @@ export function importFetchedStatuses(statuses) { } if (status.poll?.id) { - polls.push(normalizePoll(status.poll)); + polls.push(status.poll); } } @@ -144,7 +141,7 @@ export function importFetchedStatuses(statuses) { export function importFetchedPoll(poll) { return dispatch => { - dispatch(importPolls([normalizePoll(poll)])); + dispatch(importPolls([poll])); }; } diff --git a/app/soapbox/actions/importer/normalizer.js b/app/soapbox/actions/importer/normalizer.js index 4de148c0b..a294f4680 100644 --- a/app/soapbox/actions/importer/normalizer.js +++ b/app/soapbox/actions/importer/normalizer.js @@ -41,20 +41,6 @@ export function normalizeAccount(account) { return account; } -export function normalizePoll(poll) { - const normalPoll = { ...poll }; - - const emojiMap = makeEmojiMap(normalPoll); - - normalPoll.options = poll.options.map((option, index) => ({ - ...option, - voted: Boolean(poll.own_votes?.includes(index)), - title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap), - })); - - return normalPoll; -} - export function normalizeChat(chat, normalOldChat) { const normalChat = { ...chat }; const { account, last_message: lastMessage } = chat; diff --git a/app/soapbox/components/poll.js b/app/soapbox/components/poll.js index 57d693003..ee31d25c0 100644 --- a/app/soapbox/components/poll.js +++ b/app/soapbox/components/poll.js @@ -1,5 +1,4 @@ import classNames from 'classnames'; -import escapeTextContentForBrowser from 'escape-html'; import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; @@ -10,7 +9,6 @@ import spring from 'react-motion/lib/spring'; import { openModal } from 'soapbox/actions/modals'; import { vote, fetchPoll } from 'soapbox/actions/polls'; import Icon from 'soapbox/components/icon'; -import emojify from 'soapbox/features/emoji/emoji'; import Motion from 'soapbox/features/ui/util/optional_motion'; import SoapboxPropTypes from 'soapbox/utils/soapbox_prop_types'; @@ -22,11 +20,6 @@ const messages = defineMessages({ votes: { id: 'poll.votes', defaultMessage: '{votes, plural, one {# vote} other {# votes}}' }, }); -const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => { - obj[`:${emoji.get('shortcode')}:`] = emoji.toJS(); - return obj; -}, {}); - export default @injectIntl class Poll extends ImmutablePureComponent { @@ -106,12 +99,7 @@ class Poll extends ImmutablePureComponent { const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') >= other.get('votes_count')); const active = !!this.state.selected[`${optionIndex}`]; const voted = poll.own_votes?.includes(optionIndex); - - let titleEmojified = option.get('title_emojified'); - if (!titleEmojified) { - const emojiMap = makeEmojiMap(poll); - titleEmojified = emojify(escapeTextContentForBrowser(option.get('title')), emojiMap); - } + const titleEmojified = option.get('title_emojified'); return (/g, '\n\n'); - const emojiMap = makeEmojiMap(status); + const emojiMap = makeEmojiMap(status.get('emojis')); return status.merge({ search_index: domParser.parseFromString(searchContent, 'text/html').documentElement.textContent, diff --git a/app/soapbox/utils/normalizers.js b/app/soapbox/utils/normalizers.js index 7d205f21c..d16b2a07c 100644 --- a/app/soapbox/utils/normalizers.js +++ b/app/soapbox/utils/normalizers.js @@ -1,2 +1,7 @@ // Use new value only if old value is undefined export const mergeDefined = (oldVal, newVal) => oldVal === undefined ? newVal : oldVal; + +export const makeEmojiMap = emojis => emojis.reduce((obj, emoji) => { + obj[`:${emoji.shortcode}:`] = emoji; + return obj; +}, {}); diff --git a/package.json b/package.json index dcdca8734..2608b779a 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@sentry/react": "^6.12.0", "@sentry/tracing": "^6.12.0", "@tabler/icons": "^1.53.0", + "@types/escape-html": "^1.0.1", "array-includes": "^3.0.3", "autoprefixer": "^10.0.0", "axios": "^0.21.4", diff --git a/yarn.lock b/yarn.lock index 36ed26b5d..2127e09ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1747,6 +1747,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/escape-html@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-1.0.1.tgz#b19b4646915f0ae2c306bf984dc0a59c5cfc97ba" + integrity sha512-4mI1FuUUZiuT95fSVqvZxp/ssQK9zsa86S43h9x3zPOSU9BBJ+BfDkXwuaU7BfsD+e7U0/cUUfJFk3iW2M4okA== + "@types/eslint-scope@^3.7.0": version "3.7.1" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e"