From eecbbb839a508cfbc18eabbb7f3d48a87a6e7769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Mon, 16 May 2022 20:30:42 +0200 Subject: [PATCH 01/13] Use FormattedList for 'Replying to' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../components/status_reply_mentions.js | 33 +++++++++++-------- .../compose/components/reply_mentions.tsx | 17 +++++++--- .../status/components/quoted_status.tsx | 18 ++++++---- app/soapbox/locales/ar.json | 2 -- app/soapbox/locales/ast.json | 2 -- app/soapbox/locales/bg.json | 2 -- app/soapbox/locales/bn.json | 2 -- app/soapbox/locales/br.json | 2 -- app/soapbox/locales/ca.json | 2 -- app/soapbox/locales/co.json | 2 -- app/soapbox/locales/cs.json | 2 -- app/soapbox/locales/cy.json | 2 -- app/soapbox/locales/da.json | 2 -- app/soapbox/locales/de.json | 4 +-- app/soapbox/locales/el.json | 2 -- app/soapbox/locales/en-Shaw.json | 4 +-- app/soapbox/locales/en.json | 2 -- app/soapbox/locales/eo.json | 2 -- app/soapbox/locales/es-AR.json | 2 -- app/soapbox/locales/es.json | 2 -- app/soapbox/locales/et.json | 2 -- app/soapbox/locales/eu.json | 2 -- app/soapbox/locales/fa.json | 2 -- app/soapbox/locales/fi.json | 2 -- app/soapbox/locales/fr.json | 2 -- app/soapbox/locales/ga.json | 2 -- app/soapbox/locales/gl.json | 2 -- app/soapbox/locales/he.json | 4 +-- app/soapbox/locales/hi.json | 2 -- app/soapbox/locales/hr.json | 2 -- app/soapbox/locales/hu.json | 2 -- app/soapbox/locales/hy.json | 2 -- app/soapbox/locales/id.json | 2 -- app/soapbox/locales/io.json | 2 -- app/soapbox/locales/is.json | 4 +-- app/soapbox/locales/it.json | 4 +-- app/soapbox/locales/ja.json | 2 -- app/soapbox/locales/ka.json | 2 -- app/soapbox/locales/kk.json | 2 -- app/soapbox/locales/ko.json | 2 -- app/soapbox/locales/lt.json | 2 -- app/soapbox/locales/lv.json | 2 -- app/soapbox/locales/mk.json | 2 -- app/soapbox/locales/ms.json | 2 -- app/soapbox/locales/nl.json | 2 -- app/soapbox/locales/nn.json | 2 -- app/soapbox/locales/no.json | 2 -- app/soapbox/locales/oc.json | 2 -- app/soapbox/locales/pl.json | 4 +-- app/soapbox/locales/pt-BR.json | 2 -- app/soapbox/locales/pt.json | 2 -- app/soapbox/locales/ro.json | 2 -- app/soapbox/locales/ru.json | 2 -- app/soapbox/locales/sk.json | 2 -- app/soapbox/locales/sl.json | 2 -- app/soapbox/locales/sq.json | 2 -- app/soapbox/locales/sr-Latn.json | 2 -- app/soapbox/locales/sr.json | 2 -- app/soapbox/locales/sv.json | 2 -- app/soapbox/locales/ta.json | 2 -- app/soapbox/locales/te.json | 2 -- app/soapbox/locales/th.json | 2 -- app/soapbox/locales/tr.json | 2 -- app/soapbox/locales/uk.json | 2 -- app/soapbox/locales/zh-CN.json | 2 -- app/soapbox/locales/zh-HK.json | 2 -- app/soapbox/locales/zh-TW.json | 2 -- 67 files changed, 56 insertions(+), 152 deletions(-) diff --git a/app/soapbox/components/status_reply_mentions.js b/app/soapbox/components/status_reply_mentions.js index 76a48d5df..0809d6085 100644 --- a/app/soapbox/components/status_reply_mentions.js +++ b/app/soapbox/components/status_reply_mentions.js @@ -1,8 +1,9 @@ +import { List as ImmutableList } from 'immutable'; import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage, injectIntl } from 'react-intl'; +import { FormattedList, FormattedMessage, injectIntl } from 'react-intl'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; @@ -42,7 +43,7 @@ class StatusReplyMentions extends ImmutablePureComponent { return null; } - const to = status.get('mentions', []); + const to = status.get('mentions', ImmutableList()); // The post is a reply, but it has no mentions. // Rare, but it can happen. @@ -58,23 +59,27 @@ class StatusReplyMentions extends ImmutablePureComponent { } // The typical case with a reply-to and a list of mentions. + const accounts = to.slice(0, 2).map(account => ( + + @{account.get('username')} + + )).toArray(); + + if (to.size > 2) { + accounts.push( + + + , + ); + } + return (
(<> - - @{account.get('username')} - - {' '} - )), - more: to.size > 2 && ( - - - - ), + accounts: , }} />
diff --git a/app/soapbox/features/compose/components/reply_mentions.tsx b/app/soapbox/features/compose/components/reply_mentions.tsx index 2d09134e0..c25c2f3df 100644 --- a/app/soapbox/features/compose/components/reply_mentions.tsx +++ b/app/soapbox/features/compose/components/reply_mentions.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import { FormattedList, FormattedMessage } from 'react-intl'; import { useDispatch } from 'react-redux'; import { openModal } from 'soapbox/actions/modals'; @@ -47,14 +47,23 @@ const ReplyMentions: React.FC = () => { ); } + const accounts = to.slice(0, 2).map((acct: string) => ( + @{acct.split('@')[0]} + )).toArray(); + + if (to.size > 2) { + accounts.push( + , + ); + } + return ( <>@{acct.split('@')[0]}{' '}), - more: to.size > 2 && , + accounts: , }} /> diff --git a/app/soapbox/features/status/components/quoted_status.tsx b/app/soapbox/features/status/components/quoted_status.tsx index aff5940be..c91dd616d 100644 --- a/app/soapbox/features/status/components/quoted_status.tsx +++ b/app/soapbox/features/status/components/quoted_status.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { History } from 'history'; import React from 'react'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl, FormattedMessage, IntlShape } from 'react-intl'; +import { defineMessages, injectIntl, FormattedMessage, IntlShape, FormattedList } from 'react-intl'; import { withRouter } from 'react-router-dom'; import AttachmentThumbs from 'soapbox/components/attachment_thumbs'; @@ -67,10 +67,9 @@ class QuotedStatus extends ImmutablePureComponent {
@@ -84,14 +83,21 @@ class QuotedStatus extends ImmutablePureComponent { } } + const accounts = to.slice(0, 2).map(account => <>@{account.username}).toArray(); + + if (to.size > 2) { + accounts.push( + , + ); + } + return (
`@${account.username} `), - more: to.size > 2 && , + accounts: , }} />
diff --git a/app/soapbox/locales/ar.json b/app/soapbox/locales/ar.json index 5031eb79d..d1e705697 100644 --- a/app/soapbox/locales/ar.json +++ b/app/soapbox/locales/ar.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "إلغاء", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ast.json b/app/soapbox/locales/ast.json index 18f0c07df..ef5c65bd9 100644 --- a/app/soapbox/locales/ast.json +++ b/app/soapbox/locales/ast.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Encaboxar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/bg.json b/app/soapbox/locales/bg.json index b9f8ae1e1..7a62a52f0 100644 --- a/app/soapbox/locales/bg.json +++ b/app/soapbox/locales/bg.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Отказ", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/bn.json b/app/soapbox/locales/bn.json index 54b6a65eb..c030722fa 100644 --- a/app/soapbox/locales/bn.json +++ b/app/soapbox/locales/bn.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "বাতিল করতে", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/br.json b/app/soapbox/locales/br.json index af5a58c8d..1a0d58e9a 100644 --- a/app/soapbox/locales/br.json +++ b/app/soapbox/locales/br.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ca.json b/app/soapbox/locales/ca.json index 0a3b7fa54..e36ad89bc 100644 --- a/app/soapbox/locales/ca.json +++ b/app/soapbox/locales/ca.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel·lar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Bloquejar {target}", "report.block_hint": "També vols bloquejar aquest compte?", diff --git a/app/soapbox/locales/co.json b/app/soapbox/locales/co.json index 390ef9764..79214836a 100644 --- a/app/soapbox/locales/co.json +++ b/app/soapbox/locales/co.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Annullà", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/cs.json b/app/soapbox/locales/cs.json index 96d275865..155e1fa95 100644 --- a/app/soapbox/locales/cs.json +++ b/app/soapbox/locales/cs.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Zrušit", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Zablokovat {target}", "report.block_hint": "Chcete zablokovat tento účet?", diff --git a/app/soapbox/locales/cy.json b/app/soapbox/locales/cy.json index a087fd35c..bfc9c701b 100644 --- a/app/soapbox/locales/cy.json +++ b/app/soapbox/locales/cy.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Canslo", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/da.json b/app/soapbox/locales/da.json index b879b4a51..a935d51cf 100644 --- a/app/soapbox/locales/da.json +++ b/app/soapbox/locales/da.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Annuller", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/de.json b/app/soapbox/locales/de.json index 95bce86fc..67067f2bf 100644 --- a/app/soapbox/locales/de.json +++ b/app/soapbox/locales/de.json @@ -859,8 +859,8 @@ "reply_indicator.cancel": "Abbrechen", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "und {count, plural, one {einen weiteren Nutzer} other {# weitere Nutzer}}", - "reply_mentions.reply": "Antwort an {accounts}{more}", + "reply_mentions.more": "{count, plural, one {einen weiteren Nutzer} other {# weitere Nutzer}}", + "reply_mentions.reply": "Antwort an {accounts}", "reply_mentions.reply_empty": "Antwort auf einen Beitrag", "report.block": "{target} blockieren.", "report.block_hint": "Soll dieses Konto zusammen mit der Meldung auch gleich blockiert werden?", diff --git a/app/soapbox/locales/el.json b/app/soapbox/locales/el.json index 4aba909aa..b601e68e8 100644 --- a/app/soapbox/locales/el.json +++ b/app/soapbox/locales/el.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Άκυρο", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/en-Shaw.json b/app/soapbox/locales/en-Shaw.json index 50f8c36ae..a0c457f11 100644 --- a/app/soapbox/locales/en-Shaw.json +++ b/app/soapbox/locales/en-Shaw.json @@ -859,8 +859,8 @@ "reply_indicator.cancel": "𐑒𐑨𐑯𐑕𐑩𐑤", "reply_mentions.account.add": "𐑨𐑛 𐑑 𐑥𐑧𐑯𐑖𐑩𐑯𐑟", "reply_mentions.account.remove": "𐑮𐑦𐑥𐑵𐑝 𐑓𐑮𐑪𐑥 𐑥𐑧𐑯𐑖𐑩𐑯𐑟", - "reply_mentions.more": "𐑯 {count} 𐑥𐑹", - "reply_mentions.reply": "𐑮𐑦𐑐𐑤𐑲𐑦𐑙 𐑑 {accounts}{more}", + "reply_mentions.more": "{count} 𐑥𐑹", + "reply_mentions.reply": "𐑮𐑦𐑐𐑤𐑲𐑦𐑙 𐑑 {accounts}", "reply_mentions.reply_empty": "𐑮𐑦𐑐𐑤𐑲𐑦𐑙 𐑑 𐑐𐑴𐑕𐑑", "report.block": "𐑚𐑤𐑪𐑒 {target}", "report.block_hint": "𐑛𐑵 𐑿 𐑷𐑤𐑕𐑴 𐑢𐑪𐑯𐑑 𐑑 𐑚𐑤𐑪𐑒 𐑞𐑦𐑕 𐑩𐑒𐑬𐑯𐑑?", diff --git a/app/soapbox/locales/en.json b/app/soapbox/locales/en.json index a7c1d1ce1..e6267ac94 100644 --- a/app/soapbox/locales/en.json +++ b/app/soapbox/locales/en.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/eo.json b/app/soapbox/locales/eo.json index 879fdde3b..4c3bd6166 100644 --- a/app/soapbox/locales/eo.json +++ b/app/soapbox/locales/eo.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Nuligi", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/es-AR.json b/app/soapbox/locales/es-AR.json index e1fa60e68..eb56879a0 100644 --- a/app/soapbox/locales/es-AR.json +++ b/app/soapbox/locales/es-AR.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancelar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/es.json b/app/soapbox/locales/es.json index 2e0ab4ec9..c4a3e99cb 100644 --- a/app/soapbox/locales/es.json +++ b/app/soapbox/locales/es.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancelar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/et.json b/app/soapbox/locales/et.json index 5a4eb43c6..636be30e0 100644 --- a/app/soapbox/locales/et.json +++ b/app/soapbox/locales/et.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Tühista", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/eu.json b/app/soapbox/locales/eu.json index 3a3881aca..a16e4332b 100644 --- a/app/soapbox/locales/eu.json +++ b/app/soapbox/locales/eu.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Utzi", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/fa.json b/app/soapbox/locales/fa.json index 863046301..b9e9da44d 100644 --- a/app/soapbox/locales/fa.json +++ b/app/soapbox/locales/fa.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "لغو", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/fi.json b/app/soapbox/locales/fi.json index 2a29e6c20..d806c2fc6 100644 --- a/app/soapbox/locales/fi.json +++ b/app/soapbox/locales/fi.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Peruuta", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/fr.json b/app/soapbox/locales/fr.json index 743341596..373c89021 100644 --- a/app/soapbox/locales/fr.json +++ b/app/soapbox/locales/fr.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Annuler", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ga.json b/app/soapbox/locales/ga.json index 5e6cb3a8b..eec9f2971 100644 --- a/app/soapbox/locales/ga.json +++ b/app/soapbox/locales/ga.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/gl.json b/app/soapbox/locales/gl.json index a5a04c57c..3ea35cb9f 100644 --- a/app/soapbox/locales/gl.json +++ b/app/soapbox/locales/gl.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancelar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/he.json b/app/soapbox/locales/he.json index 69ae4d20a..21717e89f 100644 --- a/app/soapbox/locales/he.json +++ b/app/soapbox/locales/he.json @@ -859,8 +859,8 @@ "reply_indicator.cancel": "ביטול", "reply_mentions.account.add": "הוסף לאזכורים", "reply_mentions.account.remove": "הסר מהאזכורים", - "reply_mentions.more": "ו-{count} עוד", - "reply_mentions.reply": "משיב ל-{accounts}{more}", + "reply_mentions.more": "{count} עוד", + "reply_mentions.reply": "משיב ל-{accounts}", "reply_mentions.reply_empty": "משיב לפוסט", "report.block": "חסום {target}", "report.block_hint": "האם גם אתה רוצה לחסום את החשבון הזה?", diff --git a/app/soapbox/locales/hi.json b/app/soapbox/locales/hi.json index 2080a931a..292d6a033 100644 --- a/app/soapbox/locales/hi.json +++ b/app/soapbox/locales/hi.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/hr.json b/app/soapbox/locales/hr.json index e78476954..ca5451121 100644 --- a/app/soapbox/locales/hr.json +++ b/app/soapbox/locales/hr.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Otkaži", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/hu.json b/app/soapbox/locales/hu.json index 031c6c0a7..0d5b56411 100644 --- a/app/soapbox/locales/hu.json +++ b/app/soapbox/locales/hu.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Mégsem", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/hy.json b/app/soapbox/locales/hy.json index e023bb148..c2638e2d4 100644 --- a/app/soapbox/locales/hy.json +++ b/app/soapbox/locales/hy.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Չեղարկել", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/id.json b/app/soapbox/locales/id.json index 92bd85bdd..904f73cc5 100644 --- a/app/soapbox/locales/id.json +++ b/app/soapbox/locales/id.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Batal", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/io.json b/app/soapbox/locales/io.json index 0a5bffb3c..f85f36a5a 100644 --- a/app/soapbox/locales/io.json +++ b/app/soapbox/locales/io.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Nihiligar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/is.json b/app/soapbox/locales/is.json index e3eea2422..49e906eb5 100644 --- a/app/soapbox/locales/is.json +++ b/app/soapbox/locales/is.json @@ -788,8 +788,8 @@ "reply_indicator.cancel": "Hætta við", "reply_mentions.account.add": "Bæta við í tilvísanirnar", "reply_mentions.account.remove": "Fjarlægja úr tilvísunum", - "reply_mentions.more": "og {count} fleirum", - "reply_mentions.reply": "Að svara {accounts}{more}", + "reply_mentions.more": "{count} fleirum", + "reply_mentions.reply": "Að svara {accounts}", "reply_mentions.reply_empty": "Að svara færslu", "report.block": "Loka á {target}", "report.block_hint": "Viltu líka loka á þennan reikning?", diff --git a/app/soapbox/locales/it.json b/app/soapbox/locales/it.json index 57e54f718..e565fb5d6 100644 --- a/app/soapbox/locales/it.json +++ b/app/soapbox/locales/it.json @@ -859,8 +859,8 @@ "reply_indicator.cancel": "Annulla", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "e ancora {count}", - "reply_mentions.reply": "Risponde a {accounts}{more}", + "reply_mentions.more": "ancora {count}", + "reply_mentions.reply": "Risponde a {accounts}", "reply_mentions.reply_empty": "Rispondendo al contenuto", "report.block": "Blocca {target}", "report.block_hint": "Vuoi anche bloccare questa persona?", diff --git a/app/soapbox/locales/ja.json b/app/soapbox/locales/ja.json index ea90e3e07..931c89326 100644 --- a/app/soapbox/locales/ja.json +++ b/app/soapbox/locales/ja.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "キャンセル", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "{target}さんをブロック", "report.block_hint": "このアカウントをブロックしますか?", diff --git a/app/soapbox/locales/ka.json b/app/soapbox/locales/ka.json index 05f781c9b..950b4e69c 100644 --- a/app/soapbox/locales/ka.json +++ b/app/soapbox/locales/ka.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "უარყოფა", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/kk.json b/app/soapbox/locales/kk.json index 0bf4c7faf..40f4f25ac 100644 --- a/app/soapbox/locales/kk.json +++ b/app/soapbox/locales/kk.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Қайтып алу", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ko.json b/app/soapbox/locales/ko.json index 6e56a125d..55bc1e1bb 100644 --- a/app/soapbox/locales/ko.json +++ b/app/soapbox/locales/ko.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "취소", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/lt.json b/app/soapbox/locales/lt.json index a369a6ec5..44b913afb 100644 --- a/app/soapbox/locales/lt.json +++ b/app/soapbox/locales/lt.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/lv.json b/app/soapbox/locales/lv.json index a8fb3a793..c97bca375 100644 --- a/app/soapbox/locales/lv.json +++ b/app/soapbox/locales/lv.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/mk.json b/app/soapbox/locales/mk.json index 501a56cd9..c760d08e0 100644 --- a/app/soapbox/locales/mk.json +++ b/app/soapbox/locales/mk.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ms.json b/app/soapbox/locales/ms.json index 880fd2938..eaafcd52f 100644 --- a/app/soapbox/locales/ms.json +++ b/app/soapbox/locales/ms.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/nl.json b/app/soapbox/locales/nl.json index 1c1c00c3f..47795ef3d 100644 --- a/app/soapbox/locales/nl.json +++ b/app/soapbox/locales/nl.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Annuleren", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/nn.json b/app/soapbox/locales/nn.json index 41a2b7f85..26e4c3134 100644 --- a/app/soapbox/locales/nn.json +++ b/app/soapbox/locales/nn.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancel", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/no.json b/app/soapbox/locales/no.json index 77ac02363..fe86be051 100644 --- a/app/soapbox/locales/no.json +++ b/app/soapbox/locales/no.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Avbryt", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/oc.json b/app/soapbox/locales/oc.json index c952d6eea..64b471abc 100644 --- a/app/soapbox/locales/oc.json +++ b/app/soapbox/locales/oc.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Anullar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/pl.json b/app/soapbox/locales/pl.json index e9a38c69c..d5c8b15e5 100644 --- a/app/soapbox/locales/pl.json +++ b/app/soapbox/locales/pl.json @@ -876,8 +876,8 @@ "reply_indicator.cancel": "Anuluj", "reply_mentions.account.add": "Dodaj do wspomnianych", "reply_mentions.account.remove": "Usuń z wspomnianych", - "reply_mentions.more": "i {count} więcej", - "reply_mentions.reply": "W odpowiedzi do {accounts}{more}", + "reply_mentions.more": "{count} więcej", + "reply_mentions.reply": "W odpowiedzi do {accounts}", "reply_mentions.reply_empty": "W odpowiedzi na wpis", "report.block": "Zablokuj {target}", "report.block_hint": "Czy chcesz też zablokować to konto?", diff --git a/app/soapbox/locales/pt-BR.json b/app/soapbox/locales/pt-BR.json index 79701f4e8..f0b0a19df 100644 --- a/app/soapbox/locales/pt-BR.json +++ b/app/soapbox/locales/pt-BR.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancelar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/pt.json b/app/soapbox/locales/pt.json index 6eadee36d..4cc86daad 100644 --- a/app/soapbox/locales/pt.json +++ b/app/soapbox/locales/pt.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Cancelar", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Bloquear {target}", "report.block_hint": "Desejas também bloquear esta conta?", diff --git a/app/soapbox/locales/ro.json b/app/soapbox/locales/ro.json index 46c068630..2f49f24ce 100644 --- a/app/soapbox/locales/ro.json +++ b/app/soapbox/locales/ro.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Anulează", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ru.json b/app/soapbox/locales/ru.json index 76e4c0eb2..b4d0b3e2d 100644 --- a/app/soapbox/locales/ru.json +++ b/app/soapbox/locales/ru.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Отмена", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sk.json b/app/soapbox/locales/sk.json index 368c8d9b4..7a81a02c4 100644 --- a/app/soapbox/locales/sk.json +++ b/app/soapbox/locales/sk.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Zrušiť", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sl.json b/app/soapbox/locales/sl.json index 5a5e08eaf..d1710325d 100644 --- a/app/soapbox/locales/sl.json +++ b/app/soapbox/locales/sl.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Prekliči", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sq.json b/app/soapbox/locales/sq.json index ca6dc72cb..1c0a23d21 100644 --- a/app/soapbox/locales/sq.json +++ b/app/soapbox/locales/sq.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Anuloje", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sr-Latn.json b/app/soapbox/locales/sr-Latn.json index f04b9bef5..ccf0c8ef1 100644 --- a/app/soapbox/locales/sr-Latn.json +++ b/app/soapbox/locales/sr-Latn.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Poništi", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sr.json b/app/soapbox/locales/sr.json index efe2c4aa6..140a2738c 100644 --- a/app/soapbox/locales/sr.json +++ b/app/soapbox/locales/sr.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Поништи", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/sv.json b/app/soapbox/locales/sv.json index dd56ef574..a57d57e8f 100644 --- a/app/soapbox/locales/sv.json +++ b/app/soapbox/locales/sv.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Ångra", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/ta.json b/app/soapbox/locales/ta.json index 189eda2bb..69c44f84f 100644 --- a/app/soapbox/locales/ta.json +++ b/app/soapbox/locales/ta.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "எதிராணை", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/te.json b/app/soapbox/locales/te.json index 04f5c1931..6b34989f9 100644 --- a/app/soapbox/locales/te.json +++ b/app/soapbox/locales/te.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "రద్దు చెయ్యి", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/th.json b/app/soapbox/locales/th.json index 72d984068..c509dd4a3 100644 --- a/app/soapbox/locales/th.json +++ b/app/soapbox/locales/th.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "ยกเลิก", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/tr.json b/app/soapbox/locales/tr.json index 133b7c649..45c7c02b0 100644 --- a/app/soapbox/locales/tr.json +++ b/app/soapbox/locales/tr.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "İptal", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/uk.json b/app/soapbox/locales/uk.json index f88236624..bf601a95b 100644 --- a/app/soapbox/locales/uk.json +++ b/app/soapbox/locales/uk.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "Відмінити", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/zh-CN.json b/app/soapbox/locales/zh-CN.json index 25d9a28f7..0ec6a2e0f 100644 --- a/app/soapbox/locales/zh-CN.json +++ b/app/soapbox/locales/zh-CN.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "取消", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "屏蔽帐号 {target}", "report.block_hint": "你是否也要屏蔽这个帐号呢?", diff --git a/app/soapbox/locales/zh-HK.json b/app/soapbox/locales/zh-HK.json index b4143a647..b163f6675 100644 --- a/app/soapbox/locales/zh-HK.json +++ b/app/soapbox/locales/zh-HK.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "取消", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", diff --git a/app/soapbox/locales/zh-TW.json b/app/soapbox/locales/zh-TW.json index 44db7da27..5eade39d5 100644 --- a/app/soapbox/locales/zh-TW.json +++ b/app/soapbox/locales/zh-TW.json @@ -859,8 +859,6 @@ "reply_indicator.cancel": "取消", "reply_mentions.account.add": "Add to mentions", "reply_mentions.account.remove": "Remove from mentions", - "reply_mentions.more": "and {count} more", - "reply_mentions.reply": "Replying to {accounts}{more}", "reply_mentions.reply_empty": "Replying to post", "report.block": "Block {target}", "report.block_hint": "Do you also want to block this account?", From e21ec04be614597611e1938890d2829db17343d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 17 May 2022 13:05:01 +0200 Subject: [PATCH 02/13] Add 'Remove from followers' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/accounts.js | 40 +++++++++++++++++++ .../features/account/components/header.js | 9 +++++ .../account_timeline/components/header.js | 6 +++ .../containers/header_container.js | 17 ++++++++ app/soapbox/reducers/relationships.js | 2 + app/soapbox/utils/features.ts | 9 +++++ 6 files changed, 83 insertions(+) diff --git a/app/soapbox/actions/accounts.js b/app/soapbox/actions/accounts.js index 1005af838..4df56417e 100644 --- a/app/soapbox/actions/accounts.js +++ b/app/soapbox/actions/accounts.js @@ -57,6 +57,10 @@ export const ACCOUNT_UNPIN_REQUEST = 'ACCOUNT_UNPIN_REQUEST'; export const ACCOUNT_UNPIN_SUCCESS = 'ACCOUNT_UNPIN_SUCCESS'; export const ACCOUNT_UNPIN_FAIL = 'ACCOUNT_UNPIN_FAIL'; +export const ACCOUNT_REMOVE_FROM_FOLLOWERS_REQUEST = 'ACCOUNT_REMOVE_FROM_FOLLOWERS_REQUEST'; +export const ACCOUNT_REMOVE_FROM_FOLLOWERS_SUCCESS = 'ACCOUNT_REMOVE_FROM_FOLLOWERS_SUCCESS'; +export const ACCOUNT_REMOVE_FROM_FOLLOWERS_FAIL = 'ACCOUNT_REMOVE_FROM_FOLLOWERS_FAIL'; + export const PINNED_ACCOUNTS_FETCH_REQUEST = 'PINNED_ACCOUNTS_FETCH_REQUEST'; export const PINNED_ACCOUNTS_FETCH_SUCCESS = 'PINNED_ACCOUNTS_FETCH_SUCCESS'; export const PINNED_ACCOUNTS_FETCH_FAIL = 'PINNED_ACCOUNTS_FETCH_FAIL'; @@ -520,6 +524,42 @@ export function unsubscribeAccountFail(error) { }; } + +export function removeFromFollowers(id) { + return (dispatch, getState) => { + if (!isLoggedIn(getState)) return; + + dispatch(muteAccountRequest(id)); + + api(getState).post(`/api/v1/accounts/${id}/remove_from_followers`).then(response => { + dispatch(removeFromFollowersSuccess(response.data)); + }).catch(error => { + dispatch(removeFromFollowersFail(id, error)); + }); + }; +} + +export function removeFromFollowersRequest(id) { + return { + type: ACCOUNT_REMOVE_FROM_FOLLOWERS_REQUEST, + id, + }; +} + +export function removeFromFollowersSuccess(relationship) { + return { + type: ACCOUNT_REMOVE_FROM_FOLLOWERS_SUCCESS, + relationship, + }; +} + +export function removeFromFollowersFail(error) { + return { + type: ACCOUNT_REMOVE_FROM_FOLLOWERS_FAIL, + error, + }; +} + export function fetchFollowers(id) { return (dispatch, getState) => { dispatch(fetchFollowersRequest(id)); diff --git a/app/soapbox/features/account/components/header.js b/app/soapbox/features/account/components/header.js index 47c1172c7..7a65b0bef 100644 --- a/app/soapbox/features/account/components/header.js +++ b/app/soapbox/features/account/components/header.js @@ -48,6 +48,7 @@ const messages = defineMessages({ mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, + removeFromFollowers: { id: 'account.remove_from_followers', defaultMessage: 'Remove this follower' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, deactivateUser: { id: 'admin.users.actions.deactivate_user', defaultMessage: 'Deactivate @{name}' }, @@ -283,6 +284,14 @@ class Header extends ImmutablePureComponent { }); } + if (features.removeFromFollowers && account.getIn(['relationship', 'followed_by'])) { + menu.push({ + text: intl.formatMessage(messages.removeFromFollowers), + action: this.props.onRemoveFromFollowers, + icon: require('@tabler/icons/icons/user-x.svg'), + }); + } + if (account.getIn(['relationship', 'muting'])) { menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), diff --git a/app/soapbox/features/account_timeline/components/header.js b/app/soapbox/features/account_timeline/components/header.js index b969e0b61..bba6bbcd5 100644 --- a/app/soapbox/features/account_timeline/components/header.js +++ b/app/soapbox/features/account_timeline/components/header.js @@ -25,6 +25,7 @@ class Header extends ImmutablePureComponent { onUnblockDomain: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, + onRemoveFromFollowers: PropTypes.func.isRequired, username: PropTypes.string, history: PropTypes.object, }; @@ -141,6 +142,10 @@ class Header extends ImmutablePureComponent { this.props.onShowNote(this.props.account); } + handleRemoveFromFollowers = () => { + this.props.onRemoveFromFollowers(this.props.account); + } + render() { const { account } = this.props; const moved = (account) ? account.get('moved') : false; @@ -177,6 +182,7 @@ class Header extends ImmutablePureComponent { onSuggestUser={this.handleSuggestUser} onUnsuggestUser={this.handleUnsuggestUser} onShowNote={this.handleShowNote} + onRemoveFromFollowers={this.handleRemoveFromFollowers} username={this.props.username} /> diff --git a/app/soapbox/features/account_timeline/containers/header_container.js b/app/soapbox/features/account_timeline/containers/header_container.js index 43ceceb2f..baf0ccb17 100644 --- a/app/soapbox/features/account_timeline/containers/header_container.js +++ b/app/soapbox/features/account_timeline/containers/header_container.js @@ -13,6 +13,7 @@ import { unpinAccount, subscribeAccount, unsubscribeAccount, + removeFromFollowers, } from 'soapbox/actions/accounts'; import { verifyUser, @@ -56,6 +57,7 @@ const messages = defineMessages({ demotedToUser: { id: 'admin.users.actions.demote_to_user_message', defaultMessage: '@{acct} was demoted to a regular user' }, userSuggested: { id: 'admin.users.user_suggested_message', defaultMessage: '@{acct} was suggested' }, userUnsuggested: { id: 'admin.users.user_unsuggested_message', defaultMessage: '@{acct} was unsuggested' }, + removeFromFollowersConfirm: { id: 'confirmations.remove_from_followers.confirm', defaultMessage: 'Remove' }, }); const makeMapStateToProps = () => { @@ -269,6 +271,21 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ onShowNote(account) { dispatch(initAccountNoteModal(account)); }, + + onRemoveFromFollowers(account) { + dispatch((_, getState) => { + const unfollowModal = getSettings(getState()).get('unfollowModal'); + if (unfollowModal) { + dispatch(openModal('CONFIRM', { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.removeFromFollowersConfirm), + onConfirm: () => dispatch(removeFromFollowers(account.get('id'))), + })); + } else { + dispatch(removeFromFollowers(account.get('id'))); + } + }); + }, }); export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header)); diff --git a/app/soapbox/reducers/relationships.js b/app/soapbox/reducers/relationships.js index c63ee978e..80754842c 100644 --- a/app/soapbox/reducers/relationships.js +++ b/app/soapbox/reducers/relationships.js @@ -19,6 +19,7 @@ import { ACCOUNT_UNSUBSCRIBE_SUCCESS, ACCOUNT_PIN_SUCCESS, ACCOUNT_UNPIN_SUCCESS, + ACCOUNT_REMOVE_FROM_FOLLOWERS_SUCCESS, RELATIONSHIPS_FETCH_SUCCESS, } from '../actions/accounts'; import { @@ -108,6 +109,7 @@ export default function relationships(state = initialState, action) { case ACCOUNT_PIN_SUCCESS: case ACCOUNT_UNPIN_SUCCESS: case ACCOUNT_NOTE_SUBMIT_SUCCESS: + case ACCOUNT_REMOVE_FROM_FOLLOWERS_SUCCESS: return normalizeRelationship(state, action.relationship); case RELATIONSHIPS_FETCH_SUCCESS: return normalizeRelationships(state, action.relationships); diff --git a/app/soapbox/utils/features.ts b/app/soapbox/utils/features.ts index 1e4d76266..7819b2554 100644 --- a/app/soapbox/utils/features.ts +++ b/app/soapbox/utils/features.ts @@ -420,6 +420,15 @@ const getInstanceFeatures = (instance: Instance) => { */ remoteInteractionsAPI: v.software === PLEROMA && gte(v.version, '2.4.50'), + /** + * Ability to remove an account from your followers. + * @see POST /api/v1/accounts/:id/remove_from_followers + */ + removeFromFollowers: any([ + v.software === MASTODON && gte(v.compatVersion, '3.5.0'), + v.software === PLEROMA && v.build === SOAPBOX && gte(v.version, '2.4.50'), + ]), + reportMultipleStatuses: any([ v.software === MASTODON, v.software === PLEROMA, From 93187c8eed8dce89e56d07129ac2b6c7cab4feeb Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 18 May 2022 14:38:49 -0500 Subject: [PATCH 03/13] SoapboxMount: display a spinner while API requests are loading --- app/soapbox/components/ui/spinner/spinner.css | 2 +- app/soapbox/components/ui/spinner/spinner.tsx | 6 ++--- app/soapbox/containers/soapbox.tsx | 24 +++++++++++++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/soapbox/components/ui/spinner/spinner.css b/app/soapbox/components/ui/spinner/spinner.css index 177f9dad5..f048ee7fc 100644 --- a/app/soapbox/components/ui/spinner/spinner.css +++ b/app/soapbox/components/ui/spinner/spinner.css @@ -1,9 +1,9 @@ - /** * iOS style loading spinner. * Adapted from: https://loading.io/css/ * With some help scaling it: https://signalvnoise.com/posts/2577-loading-spinner-animation-using-css-and-webkit */ + .spinner { @apply inline-block relative w-20 h-20; } diff --git a/app/soapbox/components/ui/spinner/spinner.tsx b/app/soapbox/components/ui/spinner/spinner.tsx index c4b77a120..98c3eaae7 100644 --- a/app/soapbox/components/ui/spinner/spinner.tsx +++ b/app/soapbox/components/ui/spinner/spinner.tsx @@ -6,7 +6,7 @@ import Text from '../text/text'; import './spinner.css'; -interface ILoadingIndicator { +interface ISpinner { /** Width and height of the spinner in pixels. */ size?: number, /** Whether to display "Loading..." beneath the spinner. */ @@ -14,7 +14,7 @@ interface ILoadingIndicator { } /** Spinning loading placeholder. */ -const LoadingIndicator = ({ size = 30, withText = true }: ILoadingIndicator) => ( +const Spinner = ({ size = 30, withText = true }: ISpinner) => (
{Array.from(Array(12).keys()).map(i => ( @@ -30,4 +30,4 @@ const LoadingIndicator = ({ size = 30, withText = true }: ILoadingIndicator) => ); -export default LoadingIndicator; +export default Spinner; diff --git a/app/soapbox/containers/soapbox.tsx b/app/soapbox/containers/soapbox.tsx index cde450e65..d8ffd97d5 100644 --- a/app/soapbox/containers/soapbox.tsx +++ b/app/soapbox/containers/soapbox.tsx @@ -14,6 +14,7 @@ import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox'; import { fetchVerificationConfig } from 'soapbox/actions/verification'; import * as BuildConfig from 'soapbox/build_config'; import Helmet from 'soapbox/components/helmet'; +import { Spinner } from 'soapbox/components/ui'; import AuthLayout from 'soapbox/features/auth_layout'; import OnboardingWizard from 'soapbox/features/onboarding/onboarding-wizard'; import PublicLayout from 'soapbox/features/public_layout'; @@ -115,10 +116,25 @@ const SoapboxMount = () => { return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey); }; - if (me === null) return null; - if (me && !account) return null; - if (!isLoaded) return null; - if (localeLoading) return null; + /** Whether to display a loading indicator. */ + const showLoading = [ + me === null, + me && !account, + !isLoaded, + localeLoading, + ].some(Boolean); + + if (showLoading) { + return ( +
+ + {themeCss && } + + + +
+ ); + } const waitlisted = account && !account.source.get('approved', true); From 48290ab5404ae8eadad214f533750f2c78fb1da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 19 May 2022 15:22:15 +0200 Subject: [PATCH 04/13] Convert import/export data to TypeScript, use FileInput component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/export_data.js | 104 ---------------- app/soapbox/actions/export_data.ts | 113 ++++++++++++++++++ .../{import_data.js => import_data.ts} | 38 ++++-- app/soapbox/actions/snackbar.js | 28 ----- app/soapbox/actions/snackbar.ts | 39 ++++++ app/soapbox/components/ui/form/form.tsx | 2 + .../export_data/components/csv_exporter.js | 54 --------- .../export_data/components/csv_exporter.tsx | 47 ++++++++ .../export_data/{index.js => index.tsx} | 41 ++----- .../import_data/components/csv_importer.js | 71 ----------- .../import_data/components/csv_importer.tsx | 66 ++++++++++ .../import_data/{index.js => index.tsx} | 42 +++---- 12 files changed, 319 insertions(+), 326 deletions(-) delete mode 100644 app/soapbox/actions/export_data.js create mode 100644 app/soapbox/actions/export_data.ts rename app/soapbox/actions/{import_data.js => import_data.ts} (65%) delete mode 100644 app/soapbox/actions/snackbar.js create mode 100644 app/soapbox/actions/snackbar.ts delete mode 100644 app/soapbox/features/export_data/components/csv_exporter.js create mode 100644 app/soapbox/features/export_data/components/csv_exporter.tsx rename app/soapbox/features/export_data/{index.js => index.tsx} (60%) delete mode 100644 app/soapbox/features/import_data/components/csv_importer.js create mode 100644 app/soapbox/features/import_data/components/csv_importer.tsx rename app/soapbox/features/import_data/{index.js => index.tsx} (61%) diff --git a/app/soapbox/actions/export_data.js b/app/soapbox/actions/export_data.js deleted file mode 100644 index 12e0bd58b..000000000 --- a/app/soapbox/actions/export_data.js +++ /dev/null @@ -1,104 +0,0 @@ -import { defineMessages } from 'react-intl'; - -import snackbar from 'soapbox/actions/snackbar'; - -import api, { getLinks } from '../api'; - -export const EXPORT_FOLLOWS_REQUEST = 'EXPORT_FOLLOWS_REQUEST'; -export const EXPORT_FOLLOWS_SUCCESS = 'EXPORT_FOLLOWS_SUCCESS'; -export const EXPORT_FOLLOWS_FAIL = 'EXPORT_FOLLOWS_FAIL'; - -export const EXPORT_BLOCKS_REQUEST = 'EXPORT_BLOCKS_REQUEST'; -export const EXPORT_BLOCKS_SUCCESS = 'EXPORT_BLOCKS_SUCCESS'; -export const EXPORT_BLOCKS_FAIL = 'EXPORT_BLOCKS_FAIL'; - -export const EXPORT_MUTES_REQUEST = 'EXPORT_MUTES_REQUEST'; -export const EXPORT_MUTES_SUCCESS = 'EXPORT_MUTES_SUCCESS'; -export const EXPORT_MUTES_FAIL = 'EXPORT_MUTES_FAIL'; - -const messages = defineMessages({ - blocksSuccess: { id: 'export_data.success.blocks', defaultMessage: 'Blocks exported successfully' }, - followersSuccess: { id: 'export_data.success.followers', defaultMessage: 'Followers exported successfully' }, - mutesSuccess: { id: 'export_data.success.mutes', defaultMessage: 'Mutes exported successfully' }, -}); - -function fileExport(content, fileName) { - const fileToDownload = document.createElement('a'); - - fileToDownload.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(content)); - fileToDownload.setAttribute('download', fileName); - fileToDownload.style.display = 'none'; - document.body.appendChild(fileToDownload); - fileToDownload.click(); - document.body.removeChild(fileToDownload); -} - -function listAccounts(state) { - return async apiResponse => { - const followings = apiResponse.data; - let accounts = []; - let next = getLinks(apiResponse).refs.find(link => link.rel === 'next'); - while (next) { - apiResponse = await api(state).get(next.uri); - next = getLinks(apiResponse).refs.find(link => link.rel === 'next'); - Array.prototype.push.apply(followings, apiResponse.data); - } - - accounts = followings.map(account => account.fqn); - return [... new Set(accounts)]; - }; -} - -export function exportFollows(intl) { - return (dispatch, getState) => { - dispatch({ type: EXPORT_FOLLOWS_REQUEST }); - const me = getState().get('me'); - return api(getState) - .get(`/api/v1/accounts/${me}/following?limit=40`) - .then(listAccounts(getState)) - .then((followings) => { - followings = followings.map(fqn => fqn + ',true'); - followings.unshift('Account address,Show boosts'); - fileExport(followings.join('\n'), 'export_followings.csv'); - - dispatch(snackbar.success(intl.formatMessage(messages.followersSuccess))); - dispatch({ type: EXPORT_FOLLOWS_SUCCESS }); - }).catch(error => { - dispatch({ type: EXPORT_FOLLOWS_FAIL, error }); - }); - }; -} - -export function exportBlocks(intl) { - return (dispatch, getState) => { - dispatch({ type: EXPORT_BLOCKS_REQUEST }); - return api(getState) - .get('/api/v1/blocks?limit=40') - .then(listAccounts(getState)) - .then((blocks) => { - fileExport(blocks.join('\n'), 'export_block.csv'); - - dispatch(snackbar.success(intl.formatMessage(messages.blocksSuccess))); - dispatch({ type: EXPORT_BLOCKS_SUCCESS }); - }).catch(error => { - dispatch({ type: EXPORT_BLOCKS_FAIL, error }); - }); - }; -} - -export function exportMutes(intl) { - return (dispatch, getState) => { - dispatch({ type: EXPORT_MUTES_REQUEST }); - return api(getState) - .get('/api/v1/mutes?limit=40') - .then(listAccounts(getState)) - .then((mutes) => { - fileExport(mutes.join('\n'), 'export_mutes.csv'); - - dispatch(snackbar.success(intl.formatMessage(messages.mutesSuccess))); - dispatch({ type: EXPORT_MUTES_SUCCESS }); - }).catch(error => { - dispatch({ type: EXPORT_MUTES_FAIL, error }); - }); - }; -} diff --git a/app/soapbox/actions/export_data.ts b/app/soapbox/actions/export_data.ts new file mode 100644 index 000000000..de81215dd --- /dev/null +++ b/app/soapbox/actions/export_data.ts @@ -0,0 +1,113 @@ +import { defineMessages } from 'react-intl'; + +import api, { getLinks } from '../api'; + +import snackbar from './snackbar'; + +import type { SnackbarAction } from './snackbar'; +import type { AxiosResponse } from 'axios'; +import type { RootState } from 'soapbox/store'; + +export const EXPORT_FOLLOWS_REQUEST = 'EXPORT_FOLLOWS_REQUEST'; +export const EXPORT_FOLLOWS_SUCCESS = 'EXPORT_FOLLOWS_SUCCESS'; +export const EXPORT_FOLLOWS_FAIL = 'EXPORT_FOLLOWS_FAIL'; + +export const EXPORT_BLOCKS_REQUEST = 'EXPORT_BLOCKS_REQUEST'; +export const EXPORT_BLOCKS_SUCCESS = 'EXPORT_BLOCKS_SUCCESS'; +export const EXPORT_BLOCKS_FAIL = 'EXPORT_BLOCKS_FAIL'; + +export const EXPORT_MUTES_REQUEST = 'EXPORT_MUTES_REQUEST'; +export const EXPORT_MUTES_SUCCESS = 'EXPORT_MUTES_SUCCESS'; +export const EXPORT_MUTES_FAIL = 'EXPORT_MUTES_FAIL'; + +const messages = defineMessages({ + blocksSuccess: { id: 'export_data.success.blocks', defaultMessage: 'Blocks exported successfully' }, + followersSuccess: { id: 'export_data.success.followers', defaultMessage: 'Followers exported successfully' }, + mutesSuccess: { id: 'export_data.success.mutes', defaultMessage: 'Mutes exported successfully' }, +}); + +type ExportDataActions = { + type: typeof EXPORT_FOLLOWS_REQUEST + | typeof EXPORT_FOLLOWS_SUCCESS + | typeof EXPORT_FOLLOWS_FAIL + | typeof EXPORT_BLOCKS_REQUEST + | typeof EXPORT_BLOCKS_SUCCESS + | typeof EXPORT_BLOCKS_FAIL + | typeof EXPORT_MUTES_REQUEST + | typeof EXPORT_MUTES_SUCCESS + | typeof EXPORT_MUTES_FAIL, + error?: any, +} | SnackbarAction + +function fileExport(content: string, fileName: string) { + const fileToDownload = document.createElement('a'); + + fileToDownload.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(content)); + fileToDownload.setAttribute('download', fileName); + fileToDownload.style.display = 'none'; + document.body.appendChild(fileToDownload); + fileToDownload.click(); + document.body.removeChild(fileToDownload); +} + +const listAccounts = (getState: () => RootState) => async(apiResponse: AxiosResponse) => { + const followings = apiResponse.data; + let accounts = []; + let next = getLinks(apiResponse).refs.find(link => link.rel === 'next'); + while (next) { + apiResponse = await api(getState).get(next.uri); + next = getLinks(apiResponse).refs.find(link => link.rel === 'next'); + Array.prototype.push.apply(followings, apiResponse.data); + } + + accounts = followings.map((account: { fqn: string }) => account.fqn); + return Array.from(new Set(accounts)); +}; + +export const exportFollows = () => (dispatch: React.Dispatch, getState: () => RootState) => { + dispatch({ type: EXPORT_FOLLOWS_REQUEST }); + const me = getState().me; + return api(getState) + .get(`/api/v1/accounts/${me}/following?limit=40`) + .then(listAccounts(getState)) + .then((followings) => { + followings = followings.map(fqn => fqn + ',true'); + followings.unshift('Account address,Show boosts'); + fileExport(followings.join('\n'), 'export_followings.csv'); + + dispatch(snackbar.success(messages.followersSuccess)); + dispatch({ type: EXPORT_FOLLOWS_SUCCESS }); + }).catch(error => { + dispatch({ type: EXPORT_FOLLOWS_FAIL, error }); + }); +}; + +export const exportBlocks = () => (dispatch: React.Dispatch, getState: () => RootState) => { + dispatch({ type: EXPORT_BLOCKS_REQUEST }); + return api(getState) + .get('/api/v1/blocks?limit=40') + .then(listAccounts(getState)) + .then((blocks) => { + fileExport(blocks.join('\n'), 'export_block.csv'); + + dispatch(snackbar.success(messages.blocksSuccess)); + dispatch({ type: EXPORT_BLOCKS_SUCCESS }); + }).catch(error => { + dispatch({ type: EXPORT_BLOCKS_FAIL, error }); + }); +}; + +export const exportMutes = () => (dispatch: React.Dispatch, getState: () => RootState) => { + dispatch({ type: EXPORT_MUTES_REQUEST }); + return api(getState) + .get('/api/v1/mutes?limit=40') + .then(listAccounts(getState)) + .then((mutes) => { + fileExport(mutes.join('\n'), 'export_mutes.csv'); + + dispatch(snackbar.success(messages.mutesSuccess)); + dispatch({ type: EXPORT_MUTES_SUCCESS }); + }).catch(error => { + dispatch({ type: EXPORT_MUTES_FAIL, error }); + }); +}; diff --git a/app/soapbox/actions/import_data.js b/app/soapbox/actions/import_data.ts similarity index 65% rename from app/soapbox/actions/import_data.js rename to app/soapbox/actions/import_data.ts index 7bde21a4a..43de9f85c 100644 --- a/app/soapbox/actions/import_data.js +++ b/app/soapbox/actions/import_data.ts @@ -4,6 +4,9 @@ import snackbar from 'soapbox/actions/snackbar'; import api from '../api'; +import type { SnackbarAction } from './snackbar'; +import type { RootState } from 'soapbox/store'; + export const IMPORT_FOLLOWS_REQUEST = 'IMPORT_FOLLOWS_REQUEST'; export const IMPORT_FOLLOWS_SUCCESS = 'IMPORT_FOLLOWS_SUCCESS'; export const IMPORT_FOLLOWS_FAIL = 'IMPORT_FOLLOWS_FAIL'; @@ -16,50 +19,61 @@ export const IMPORT_MUTES_REQUEST = 'IMPORT_MUTES_REQUEST'; export const IMPORT_MUTES_SUCCESS = 'IMPORT_MUTES_SUCCESS'; export const IMPORT_MUTES_FAIL = 'IMPORT_MUTES_FAIL'; +type ImportDataActions = { + type: typeof IMPORT_FOLLOWS_REQUEST + | typeof IMPORT_FOLLOWS_SUCCESS + | typeof IMPORT_FOLLOWS_FAIL + | typeof IMPORT_BLOCKS_REQUEST + | typeof IMPORT_BLOCKS_SUCCESS + | typeof IMPORT_BLOCKS_FAIL + | typeof IMPORT_MUTES_REQUEST + | typeof IMPORT_MUTES_SUCCESS + | typeof IMPORT_MUTES_FAIL, + error?: any, + config?: string +} | SnackbarAction + const messages = defineMessages({ blocksSuccess: { id: 'import_data.success.blocks', defaultMessage: 'Blocks imported successfully' }, followersSuccess: { id: 'import_data.success.followers', defaultMessage: 'Followers imported successfully' }, mutesSuccess: { id: 'import_data.success.mutes', defaultMessage: 'Mutes imported successfully' }, }); -export function importFollows(intl, params) { - return (dispatch, getState) => { +export const importFollows = (params: FormData) => + (dispatch: React.Dispatch, getState: () => RootState) => { dispatch({ type: IMPORT_FOLLOWS_REQUEST }); return api(getState) .post('/api/pleroma/follow_import', params) .then(response => { - dispatch(snackbar.success(intl.formatMessage(messages.followersSuccess))); + dispatch(snackbar.success(messages.followersSuccess)); dispatch({ type: IMPORT_FOLLOWS_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_FOLLOWS_FAIL, error }); }); }; -} -export function importBlocks(intl, params) { - return (dispatch, getState) => { +export const importBlocks = (params: FormData) => + (dispatch: React.Dispatch, getState: () => RootState) => { dispatch({ type: IMPORT_BLOCKS_REQUEST }); return api(getState) .post('/api/pleroma/blocks_import', params) .then(response => { - dispatch(snackbar.success(intl.formatMessage(messages.blocksSuccess))); + dispatch(snackbar.success(messages.blocksSuccess)); dispatch({ type: IMPORT_BLOCKS_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_BLOCKS_FAIL, error }); }); }; -} -export function importMutes(intl, params) { - return (dispatch, getState) => { +export const importMutes = (params: FormData) => + (dispatch: React.Dispatch, getState: () => RootState) => { dispatch({ type: IMPORT_MUTES_REQUEST }); return api(getState) .post('/api/pleroma/mutes_import', params) .then(response => { - dispatch(snackbar.success(intl.formatMessage(messages.mutesSuccess))); + dispatch(snackbar.success(messages.mutesSuccess)); dispatch({ type: IMPORT_MUTES_SUCCESS, config: response.data }); }).catch(error => { dispatch({ type: IMPORT_MUTES_FAIL, error }); }); }; -} diff --git a/app/soapbox/actions/snackbar.js b/app/soapbox/actions/snackbar.js deleted file mode 100644 index 47fd11137..000000000 --- a/app/soapbox/actions/snackbar.js +++ /dev/null @@ -1,28 +0,0 @@ -import { ALERT_SHOW } from './alerts'; - -export const show = (severity, message, actionLabel, actionLink) => ({ - type: ALERT_SHOW, - message, - actionLabel, - actionLink, - severity, -}); - -export function info(message, actionLabel, actionLink) { - return show('info', message, actionLabel, actionLink); -} - -export function success(message, actionLabel, actionLink) { - return show('success', message, actionLabel, actionLink); -} - -export function error(message, actionLabel, actionLink) { - return show('error', message, actionLabel, actionLink); -} - -export default { - info, - success, - error, - show, -}; diff --git a/app/soapbox/actions/snackbar.ts b/app/soapbox/actions/snackbar.ts new file mode 100644 index 000000000..d1cda0d94 --- /dev/null +++ b/app/soapbox/actions/snackbar.ts @@ -0,0 +1,39 @@ +import { ALERT_SHOW } from './alerts'; + +import type { MessageDescriptor } from 'react-intl'; + +type SnackbarActionSeverity = 'info' | 'success' | 'error' + +type SnackbarMessage = string | MessageDescriptor + +export type SnackbarAction = { + type: typeof ALERT_SHOW + message: SnackbarMessage + actionLabel?: string + actionLink?: string + severity: SnackbarActionSeverity +} + +export const show = (severity: SnackbarActionSeverity, message: SnackbarMessage, actionLabel?: string, actionLink?: string): SnackbarAction => ({ + type: ALERT_SHOW, + message, + actionLabel, + actionLink, + severity, +}); + +export const info = (message: SnackbarMessage, actionLabel?: string, actionLink?: string) => + show('info', message, actionLabel, actionLink); + +export const success = (message: SnackbarMessage, actionLabel?: string, actionLink?: string) => + show('success', message, actionLabel, actionLink); + +export const error = (message: SnackbarMessage, actionLabel?: string, actionLink?: string) => + show('error', message, actionLabel, actionLink); + +export default { + info, + success, + error, + show, +}; diff --git a/app/soapbox/components/ui/form/form.tsx b/app/soapbox/components/ui/form/form.tsx index 59ca180b1..3b02634fa 100644 --- a/app/soapbox/components/ui/form/form.tsx +++ b/app/soapbox/components/ui/form/form.tsx @@ -5,6 +5,8 @@ interface IForm { onSubmit?: (event: React.FormEvent) => void, /** Class name override for the
element. */ className?: string, + /** Prevent the form from being submitted. */ + disabled?: boolean, } /** Form element with custom styles. */ diff --git a/app/soapbox/features/export_data/components/csv_exporter.js b/app/soapbox/features/export_data/components/csv_exporter.js deleted file mode 100644 index bd47b83fb..000000000 --- a/app/soapbox/features/export_data/components/csv_exporter.js +++ /dev/null @@ -1,54 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; - -import { Button, Form, FormActions, Text } from 'soapbox/components/ui'; - -export default @connect() -@injectIntl -class CSVExporter extends ImmutablePureComponent { - - static propTypes = { - action: PropTypes.func.isRequired, - messages: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - state = { - isLoading: false, - } - - handleClick = (event) => { - const { dispatch, action, intl } = this.props; - - this.setState({ isLoading: true }); - dispatch(action(intl)).then(() => { - this.setState({ isLoading: false }); - }).catch((error) => { - this.setState({ isLoading: false }); - }); - } - - render() { - const { intl, messages } = this.props; - - return ( - <> - - {intl.formatMessage(messages.input_label)} - {intl.formatMessage(messages.input_hint)} - - - - -
- - ); - } - -} diff --git a/app/soapbox/features/export_data/components/csv_exporter.tsx b/app/soapbox/features/export_data/components/csv_exporter.tsx new file mode 100644 index 000000000..f44aaa424 --- /dev/null +++ b/app/soapbox/features/export_data/components/csv_exporter.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { useState } from 'react'; +import { MessageDescriptor, useIntl } from 'react-intl'; + +import { Button, Form, FormActions, Text } from 'soapbox/components/ui'; +import { useAppDispatch } from 'soapbox/hooks'; +import { AppDispatch } from 'soapbox/store'; + +interface ICSVExporter { + messages: { + input_label: MessageDescriptor, + input_hint: MessageDescriptor, + submit: MessageDescriptor, + }, + action: () => (dispatch: AppDispatch, getState: any) => Promise, +} + +const CSVExporter: React.FC = ({ messages, action }) => { + const dispatch = useAppDispatch(); + const intl = useIntl(); + + const [isLoading, setIsLoading] = useState(false); + + const handleClick: React.MouseEventHandler = (event) => { + setIsLoading(true); + dispatch(action()).then(() => { + setIsLoading(false); + }).catch(() => { + setIsLoading(false); + }); + }; + + return ( +
+ {intl.formatMessage(messages.input_label)} + {intl.formatMessage(messages.input_hint)} + + + + +
+ ); +}; + +export default CSVExporter; diff --git a/app/soapbox/features/export_data/index.js b/app/soapbox/features/export_data/index.tsx similarity index 60% rename from app/soapbox/features/export_data/index.js rename to app/soapbox/features/export_data/index.tsx index 4a73f700b..3a00b6051 100644 --- a/app/soapbox/features/export_data/index.js +++ b/app/soapbox/features/export_data/index.tsx @@ -1,15 +1,11 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; +import { defineMessages, useIntl } from 'react-intl'; import { exportFollows, exportBlocks, exportMutes, } from 'soapbox/actions/export_data'; -import { getFeatures } from 'soapbox/utils/features'; import Column from '../ui/components/column'; @@ -38,29 +34,16 @@ const muteMessages = defineMessages({ submit: { id: 'export_data.actions.export_mutes', defaultMessage: 'Export mutes' }, }); -const mapStateToProps = state => ({ - features: getFeatures(state.get('instance')), -}); +const ExportData = () => { + const intl = useIntl(); -export default @connect(mapStateToProps) -@injectIntl -class ExportData extends ImmutablePureComponent { + return ( + + + + + + ); +}; - static propTypes = { - intl: PropTypes.object.isRequired, - features: PropTypes.object, - }; - - render() { - const { intl } = this.props; - - return ( - - - - - - ); - } - -} +export default ExportData; diff --git a/app/soapbox/features/import_data/components/csv_importer.js b/app/soapbox/features/import_data/components/csv_importer.js deleted file mode 100644 index ff17cade4..000000000 --- a/app/soapbox/features/import_data/components/csv_importer.js +++ /dev/null @@ -1,71 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; - -import { Button, Form, FormActions, Text } from 'soapbox/components/ui'; - -export default @connect() -@injectIntl -class CSVImporter extends ImmutablePureComponent { - - static propTypes = { - action: PropTypes.func.isRequired, - messages: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - state = { - file: null, - isLoading: false, - } - - handleSubmit = (event) => { - const { dispatch, action, intl } = this.props; - - const params = new FormData(); - params.append('list', this.state.file); - - this.setState({ isLoading: true }); - dispatch(action(intl, params)).then(() => { - this.setState({ isLoading: false }); - }).catch((error) => { - this.setState({ isLoading: false }); - }); - - event.preventDefault(); - } - - handleFileChange = e => { - const [file] = e.target.files || []; - this.setState({ file }); - } - - render() { - const { intl, messages } = this.props; - - return ( -
- {intl.formatMessage(messages.input_label)} -
- - {intl.formatMessage(messages.input_hint)} -
- - - -
- ); - } - -} diff --git a/app/soapbox/features/import_data/components/csv_importer.tsx b/app/soapbox/features/import_data/components/csv_importer.tsx new file mode 100644 index 000000000..95ae99aba --- /dev/null +++ b/app/soapbox/features/import_data/components/csv_importer.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { useState } from 'react'; +import { MessageDescriptor, useIntl } from 'react-intl'; + +import { Button, FileInput, Form, FormActions, FormGroup, Text } from 'soapbox/components/ui'; +import { useAppDispatch } from 'soapbox/hooks'; +import { AppDispatch } from 'soapbox/store'; + +interface ICSVImporter { + messages: { + input_label: MessageDescriptor, + input_hint: MessageDescriptor, + submit: MessageDescriptor, + }, + action: (params: FormData) => (dispatch: AppDispatch, getState: any) => Promise, +} + +const CSVImporter: React.FC = ({ messages, action }) => { + const dispatch = useAppDispatch(); + const intl = useIntl(); + + const [isLoading, setIsLoading] = useState(false); + const [file, setFile] = useState(null); + + + const handleSubmit: React.FormEventHandler = (event) => { + const params = new FormData(); + params.append('list', file!); + + setIsLoading(true); + dispatch(action(params)).then(() => { + setIsLoading(false); + }).catch(() => { + setIsLoading(false); + }); + + event.preventDefault(); + }; + + const handleFileChange: React.ChangeEventHandler = e => { + const file = e.target.files?.item(0); + setFile(file); + }; + + return ( +
+ {intl.formatMessage(messages.input_label)} + {intl.formatMessage(messages.input_hint)}} + > + + + + + +
+ ); +}; + +export default CSVImporter; diff --git a/app/soapbox/features/import_data/index.js b/app/soapbox/features/import_data/index.tsx similarity index 61% rename from app/soapbox/features/import_data/index.js rename to app/soapbox/features/import_data/index.tsx index 6a3a267e2..b03b20f29 100644 --- a/app/soapbox/features/import_data/index.js +++ b/app/soapbox/features/import_data/index.tsx @@ -1,14 +1,12 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; +import { defineMessages, useIntl } from 'react-intl'; import { importFollows, importBlocks, importMutes, } from 'soapbox/actions/import_data'; +import { useAppSelector } from 'soapbox/hooks'; import { getFeatures } from 'soapbox/utils/features'; import Column from '../ui/components/column'; @@ -38,29 +36,17 @@ const muteMessages = defineMessages({ submit: { id: 'import_data.actions.import_mutes', defaultMessage: 'Import mutes' }, }); -const mapStateToProps = state => ({ - features: getFeatures(state.get('instance')), -}); +const ImportData = () => { + const intl = useIntl(); + const features = getFeatures(useAppSelector((state) => state.instance)); -export default @connect(mapStateToProps) -@injectIntl -class ImportData extends ImmutablePureComponent { + return ( + + + + {features.importMutes && } + + ); +}; - static propTypes = { - intl: PropTypes.object.isRequired, - features: PropTypes.object, - }; - - render() { - const { intl, features } = this.props; - - return ( - - - - {features.importMutes && } - - ); - } - -} +export default ImportData; From dd4df89f22d0e2cefa7e8b1ce1d82f66131c5b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 19 May 2022 15:32:30 +0200 Subject: [PATCH 05/13] Search styles on aliases page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/features/aliases/components/search.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/soapbox/features/aliases/components/search.tsx b/app/soapbox/features/aliases/components/search.tsx index 516a38884..8e601ccb0 100644 --- a/app/soapbox/features/aliases/components/search.tsx +++ b/app/soapbox/features/aliases/components/search.tsx @@ -40,23 +40,23 @@ const Search: React.FC = () => { const hasValue = value.length > 0; return ( -
-