diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 5724dbaea4f..12c7dd2b08c 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -71,11 +71,12 @@ class Api::V1::AccountsController < ApiController
def block
BlockService.new.call(current_user.account, @account)
- @following = { @account.id => false }
- @followed_by = { @account.id => false }
- @blocking = { @account.id => true }
- @requested = { @account.id => false }
- @muting = { @account.id => current_user.account.muting?(@account.id) }
+ @following = { @account.id => false }
+ @followed_by = { @account.id => false }
+ @blocking = { @account.id => true }
+ @requested = { @account.id => false }
+ @muting = { @account.id => current_account.muting?(@account.id) }
+ @domain_blocking = { @account.id => current_account.domain_blocking?(@account.domain) }
render :relationship
end
@@ -107,12 +108,13 @@ class Api::V1::AccountsController < ApiController
def relationships
ids = params[:id].is_a?(Enumerable) ? params[:id].map(&:to_i) : [params[:id].to_i]
- @accounts = Account.where(id: ids).select('id')
- @following = Account.following_map(ids, current_user.account_id)
- @followed_by = Account.followed_by_map(ids, current_user.account_id)
- @blocking = Account.blocking_map(ids, current_user.account_id)
- @muting = Account.muting_map(ids, current_user.account_id)
- @requested = Account.requested_map(ids, current_user.account_id)
+ @accounts = Account.where(id: ids).select('id')
+ @following = Account.following_map(ids, current_user.account_id)
+ @followed_by = Account.followed_by_map(ids, current_user.account_id)
+ @blocking = Account.blocking_map(ids, current_user.account_id)
+ @muting = Account.muting_map(ids, current_user.account_id)
+ @requested = Account.requested_map(ids, current_user.account_id)
+ @domain_blocking = Account.domain_blocking_map(ids, current_user.account_id)
end
def search
@@ -128,11 +130,12 @@ class Api::V1::AccountsController < ApiController
end
def set_relationship
- @following = Account.following_map([@account.id], current_user.account_id)
- @followed_by = Account.followed_by_map([@account.id], current_user.account_id)
- @blocking = Account.blocking_map([@account.id], current_user.account_id)
- @muting = Account.muting_map([@account.id], current_user.account_id)
- @requested = Account.requested_map([@account.id], current_user.account_id)
+ @following = Account.following_map([@account.id], current_user.account_id)
+ @followed_by = Account.followed_by_map([@account.id], current_user.account_id)
+ @blocking = Account.blocking_map([@account.id], current_user.account_id)
+ @muting = Account.muting_map([@account.id], current_user.account_id)
+ @requested = Account.requested_map([@account.id], current_user.account_id)
+ @domain_blocking = Account.domain_blocking_map([@account.id], current_user.account_id)
end
def pagination_params(core_params)
diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb
index e14547911c7..f223dd16ee5 100644
--- a/app/controllers/api/v1/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/domain_blocks_controller.rb
@@ -17,7 +17,7 @@ class Api::V1::DomainBlocksController < ApiController
end
def create
- current_account.block_domain!(domain_block_params[:domain])
+ BlockDomainFromAccountService.new.call(current_account, domain_block_params[:domain])
render_empty
end
diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js
new file mode 100644
index 00000000000..c884981176b
--- /dev/null
+++ b/app/javascript/mastodon/actions/domain_blocks.js
@@ -0,0 +1,117 @@
+import api, { getLinks } from '../api'
+
+export const DOMAIN_BLOCK_REQUEST = 'DOMAIN_BLOCK_REQUEST';
+export const DOMAIN_BLOCK_SUCCESS = 'DOMAIN_BLOCK_SUCCESS';
+export const DOMAIN_BLOCK_FAIL = 'DOMAIN_BLOCK_FAIL';
+
+export const DOMAIN_UNBLOCK_REQUEST = 'DOMAIN_UNBLOCK_REQUEST';
+export const DOMAIN_UNBLOCK_SUCCESS = 'DOMAIN_UNBLOCK_SUCCESS';
+export const DOMAIN_UNBLOCK_FAIL = 'DOMAIN_UNBLOCK_FAIL';
+
+export const DOMAIN_BLOCKS_FETCH_REQUEST = 'DOMAIN_BLOCKS_FETCH_REQUEST';
+export const DOMAIN_BLOCKS_FETCH_SUCCESS = 'DOMAIN_BLOCKS_FETCH_SUCCESS';
+export const DOMAIN_BLOCKS_FETCH_FAIL = 'DOMAIN_BLOCKS_FETCH_FAIL';
+
+export function blockDomain(domain, accountId) {
+ return (dispatch, getState) => {
+ dispatch(blockDomainRequest(domain));
+
+ api(getState).post('/api/v1/domain_blocks', { domain }).then(response => {
+ dispatch(blockDomainSuccess(domain, accountId));
+ }).catch(err => {
+ dispatch(blockDomainFail(domain, err));
+ });
+ };
+};
+
+export function blockDomainRequest(domain) {
+ return {
+ type: DOMAIN_BLOCK_REQUEST,
+ domain
+ };
+};
+
+export function blockDomainSuccess(domain, accountId) {
+ return {
+ type: DOMAIN_BLOCK_SUCCESS,
+ domain,
+ accountId
+ };
+};
+
+export function blockDomainFail(domain, error) {
+ return {
+ type: DOMAIN_BLOCK_FAIL,
+ domain,
+ error
+ };
+};
+
+export function unblockDomain(domain, accountId) {
+ return (dispatch, getState) => {
+ dispatch(unblockDomainRequest(domain));
+
+ api(getState).delete('/api/v1/domain_blocks', { params: { domain } }).then(response => {
+ dispatch(unblockDomainSuccess(domain, accountId));
+ }).catch(err => {
+ dispatch(unblockDomainFail(domain, err));
+ });
+ };
+};
+
+export function unblockDomainRequest(domain) {
+ return {
+ type: DOMAIN_UNBLOCK_REQUEST,
+ domain
+ };
+};
+
+export function unblockDomainSuccess(domain, accountId) {
+ return {
+ type: DOMAIN_UNBLOCK_SUCCESS,
+ domain,
+ accountId
+ };
+};
+
+export function unblockDomainFail(domain, error) {
+ return {
+ type: DOMAIN_UNBLOCK_FAIL,
+ domain,
+ error
+ };
+};
+
+export function fetchDomainBlocks() {
+ return (dispatch, getState) => {
+ dispatch(fetchDomainBlocksRequest());
+
+ api(getState).get().then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(fetchDomainBlocksSuccess(response.data, next ? next.uri : null));
+ }).catch(err => {
+ dispatch(fetchDomainBlocksFail(err));
+ });
+ };
+};
+
+export function fetchDomainBlocksRequest() {
+ return {
+ type: DOMAIN_BLOCKS_FETCH_REQUEST
+ };
+};
+
+export function fetchDomainBlocksSuccess(domains, next) {
+ return {
+ type: DOMAIN_BLOCKS_FETCH_SUCCESS,
+ domains,
+ next
+ };
+};
+
+export function fetchDomainBlocksFail(error) {
+ return {
+ type: DOMAIN_BLOCKS_FETCH_FAIL,
+ error
+ };
+};
diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js
index 44ed8af7d18..1997bf7b732 100644
--- a/app/javascript/mastodon/features/account/components/action_bar.js
+++ b/app/javascript/mastodon/features/account/components/action_bar.js
@@ -15,7 +15,9 @@ const messages = defineMessages({
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
follow: { id: 'account.follow', defaultMessage: 'Follow' },
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
- disclaimer: { id: 'account.disclaimer', defaultMessage: 'This user is from another instance. This number may be larger.' }
+ disclaimer: { id: 'account.disclaimer', defaultMessage: 'This user is from another instance. This number may be larger.' },
+ blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
+ unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
});
class ActionBar extends React.PureComponent {
@@ -28,6 +30,8 @@ class ActionBar extends React.PureComponent {
onMention: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
+ onBlockDomain: PropTypes.func.isRequired,
+ onUnblockDomain: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired
};
@@ -59,7 +63,16 @@ class ActionBar extends React.PureComponent {
}
if (account.get('acct') !== account.get('username')) {
+ const domain = account.get('acct').split('@')[1];
extraInfo = *;
+
+ menu.push(null);
+
+ if (account.getIn(['relationship', 'domain_blocking'])) {
+ menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain });
+ } else {
+ menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain });
+ }
}
return (
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index d7226d9b20b..f1a0e8d775b 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -15,7 +15,9 @@ class Header extends ImmutablePureComponent {
onBlock: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
- onMute: PropTypes.func.isRequired
+ onMute: PropTypes.func.isRequired,
+ onBlockDomain: PropTypes.func.isRequired,
+ onUnblockDomain: PropTypes.func.isRequired,
};
static contextTypes = {
@@ -43,6 +45,22 @@ class Header extends ImmutablePureComponent {
this.props.onMute(this.props.account);
}
+ handleBlockDomain = () => {
+ const domain = this.props.account.get('acct').split('@')[1];
+
+ if (!domain) return;
+
+ this.props.onBlockDomain(domain, this.props.account.get('id'));
+ }
+
+ handleUnblockDomain = () => {
+ const domain = this.props.account.get('acct').split('@')[1];
+
+ if (!domain) return;
+
+ this.props.onUnblockDomain(domain, this.props.account.get('id'));
+ }
+
render () {
const { account, me } = this.props;
@@ -65,6 +83,8 @@ class Header extends ImmutablePureComponent {
onMention={this.handleMention}
onReport={this.handleReport}
onMute={this.handleMute}
+ onBlockDomain={this.handleBlockDomain}
+ onUnblockDomain={this.handleUnblockDomain}
/>
);
diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
index 50999d2e0e6..0964efdcfee 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
@@ -13,11 +13,13 @@ import {
import { mentionCompose } from '../../../actions/compose';
import { initReport } from '../../../actions/reports';
import { openModal } from '../../../actions/modal';
+import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
const messages = defineMessages({
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
- muteConfirm: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' }
+ muteConfirm: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' },
+ blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
});
const makeMapStateToProps = () => {
@@ -70,6 +72,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onConfirm: () => dispatch(muteAccount(account.get('id')))
}));
}
+ },
+
+ onBlockDomain (domain, accountId) {
+ dispatch(openModal('CONFIRM', {
+ message: {domain} }} />,
+ confirm: intl.formatMessage(messages.blockDomainConfirm),
+ onConfirm: () => dispatch(blockDomain(domain, accountId))
+ }));
+ },
+
+ onUnblockDomain (domain, accountId) {
+ dispatch(unblockDomain(domain, accountId));
}
});
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index e30b7e84aec..2a9d00460a6 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,17 +1,20 @@
{
"account.block": "حظر @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "هذا المستخدم من مثيل خادم آخر. قد يكون هذا الرقم أكبر.",
"account.edit_profile": "تعديل الملف الشخصي",
"account.follow": "تابِع",
"account.followers": "المتابعون",
"account.follows": "يتبع",
"account.follows_you": "يتابعك",
+ "account.media": "Media",
"account.mention": "أُذكُر @{name}",
"account.mute": "أكتم @{name}",
"account.posts": "المشاركات",
"account.report": "أبلغ عن @{name}",
"account.requested": "في انتظار الموافقة",
"account.unblock": "إلغاء الحظر عن @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "إلغاء المتابعة",
"account.unmute": "إلغاء الكتم عن @{name}",
"boost_modal.combo": "يمكنك ضغط {combo} لتخطّي هذه في المرّة القادمة",
@@ -40,6 +43,8 @@
"confirmations.block.message": "هل أنت متأكد أنك تريد حجب {name} ؟",
"confirmations.delete.confirm": "حذف",
"confirmations.delete.message": "هل أنت متأكد أنك تريد حذف هذا المنشور ؟",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "أكتم",
"confirmations.mute.message": "هل أنت متأكد أنك تريد كتم {name} ؟",
"emoji_button.activity": "الأنشطة",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 3ca2f7775bb..a43cd3dabfe 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -1,17 +1,20 @@
{
"account.block": "Блокирай",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Редактирай профила си",
"account.follow": "Последвай",
"account.followers": "Последователи",
"account.follows": "Следвам",
"account.follows_you": "Твой последовател",
+ "account.media": "Media",
"account.mention": "Споменаване",
"account.mute": "Mute @{name}",
"account.posts": "Публикации",
"account.report": "Report @{name}",
"account.requested": "В очакване на одобрение",
"account.unblock": "Не блокирай",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Не следвай",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index f239a3d2fb5..61827220e66 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloquejar @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Aquest usuari és d'un altra instància. Aquest número podria ser més gran.",
"account.edit_profile": "Editar perfil",
"account.follow": "Seguir",
"account.followers": "Seguidors",
"account.follows": "Seguint",
"account.follows_you": "et segueix",
+ "account.media": "Media",
"account.mention": "Esmentar @{name}",
"account.mute": "Silenciar @{name}",
"account.posts": "Publicacions",
"account.report": "Informe @{name}",
"account.requested": "Esperant aprovació",
"account.unblock": "Desbloquejar @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Deixar de seguir",
"account.unmute": "Treure silenci de @{name}",
"boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Estàs segur que vols bloquejar {name}?",
"confirmations.delete.confirm": "Esborrar",
"confirmations.delete.message": "Estàs segur que vols esborrar aquest estat?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Silenciar",
"confirmations.mute.message": "Estàs segur que vols silenciar {name}?",
"emoji_button.activity": "Activitat",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 8a5b5e418dc..a82bee22d01 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -1,17 +1,20 @@
{
"account.block": "@{name} blocken",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Dieser Benutzer ist von einer anderen Instanz. Diese Zahl könnte größer sein.",
"account.edit_profile": "Profil bearbeiten",
"account.follow": "Folgen",
"account.followers": "Folgende",
"account.follows": "Folgt",
"account.follows_you": "Folgt dir",
+ "account.media": "Media",
"account.mention": "@{name} erwähnen",
"account.mute": "@{name} stummschalten",
"account.posts": "Beiträge",
"account.report": "@{name} melden",
"account.requested": "Warte auf Erlaubnis",
"account.unblock": "@{name} entblocken",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Entfolgen",
"account.unmute": "@{name} nicht mehr stummschalten",
"boost_modal.combo": "Du kannst {combo} drücken, um dies beim nächsten Mal zu überspringen",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 38d76828d44..67c7cc527ad 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -240,6 +240,15 @@
],
"path": "app/javascript/mastodon/containers/status_container.json"
},
+ {
+ "descriptors": [
+ {
+ "defaultMessage": "Media",
+ "id": "account.media"
+ }
+ ],
+ "path": "app/javascript/mastodon/features/account_gallery/index.json"
+ },
{
"descriptors": [
{
@@ -250,6 +259,10 @@
"defaultMessage": "Mute",
"id": "confirmations.mute.confirm"
},
+ {
+ "defaultMessage": "Hide entire domain",
+ "id": "confirmations.domain_block.confirm"
+ },
{
"defaultMessage": "Are you sure you want to block {name}?",
"id": "confirmations.block.message"
@@ -257,6 +270,10 @@
{
"defaultMessage": "Are you sure you want to mute {name}?",
"id": "confirmations.mute.message"
+ },
+ {
+ "defaultMessage": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
+ "id": "confirmations.domain_block.message"
}
],
"path": "app/javascript/mastodon/features/account_timeline/containers/header_container.json"
@@ -303,6 +320,14 @@
"defaultMessage": "This user is from another instance. This number may be larger.",
"id": "account.disclaimer"
},
+ {
+ "defaultMessage": "Hide everything from {domain}",
+ "id": "account.block_domain"
+ },
+ {
+ "defaultMessage": "Unhide {domain}",
+ "id": "account.unblock_domain"
+ },
{
"defaultMessage": "Posts",
"id": "account.posts"
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index f4a6a7512f6..6864123aec9 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -1,17 +1,20 @@
{
"account.block": "Block @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Edit profile",
"account.follow": "Follow",
"account.followers": "Followers",
"account.follows": "Follows",
"account.follows_you": "Follows you",
+ "account.media": "Media",
"account.mention": "Mention @{name}",
"account.mute": "Mute @{name}",
"account.posts": "Posts",
"account.report": "Report @{name}",
"account.requested": "Awaiting approval",
"account.unblock": "Unblock @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 904c08cc93f..3437bd9e993 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloki @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Redakti la profilon",
"account.follow": "Sekvi",
"account.followers": "Sekvantoj",
"account.follows": "Sekvatoj",
"account.follows_you": "Sekvas vin",
+ "account.media": "Media",
"account.mention": "Mencii @{name}",
"account.mute": "Mute @{name}",
"account.posts": "Mesaĝoj",
"account.report": "Report @{name}",
"account.requested": "Atendas aprobon",
"account.unblock": "Malbloki @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Malsekvi",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 605c14a098b..14b007a3e0c 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloquear",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Editar perfil",
"account.follow": "Seguir",
"account.followers": "Seguidores",
"account.follows": "Seguir",
"account.follows_you": "Te sigue",
+ "account.media": "Media",
"account.mention": "Mencionar",
"account.mute": "Silenciar",
"account.posts": "Publicaciones",
"account.report": "Report @{name}",
"account.requested": "Esperando aprobación",
"account.unblock": "Desbloquear",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Dejar de seguir",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 72e93869574..59266dcd94a 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -1,17 +1,20 @@
{
"account.block": "مسدودسازی @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "این کاربر عضو سرور متفاوتی است. شاید عدد واقعی بیشتر از این باشد.",
"account.edit_profile": "ویرایش نمایه",
"account.follow": "پی بگیرید",
"account.followers": "پیگیران",
"account.follows": "پی میگیرد",
"account.follows_you": "پیگیر شماست",
+ "account.media": "Media",
"account.mention": "نامبردن از @{name}",
"account.mute": "بیصدا کردن @{name}",
"account.posts": "نوشتهها",
"account.report": "گزارش @{name}",
"account.requested": "در انتظار پذیرش",
"account.unblock": "رفع انسداد @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "پایان پیگیری",
"account.unmute": "باصدا کردن @{name}",
"boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید",
@@ -40,6 +43,8 @@
"confirmations.block.message": "آیا واقعاً میخواهید {name} را مسدود کنید؟",
"confirmations.delete.confirm": "پاک کن",
"confirmations.delete.message": "آیا واقعاً میخواهید این نوشته را پاک کنید؟",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "بیصدا کن",
"confirmations.mute.message": "آیا واقعاً میخواهید {name} را بیصدا کنید؟",
"emoji_button.activity": "فعالیت",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index 42b1fbcb0b0..c544c955cd3 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,17 +1,20 @@
{
"account.block": "Estä @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Muokkaa",
"account.follow": "Seuraa",
"account.followers": "Seuraajia",
"account.follows": "Seuraa",
"account.follows_you": "Seuraa sinua",
+ "account.media": "Media",
"account.mention": "Mainitse @{name}",
"account.mute": "Mute @{name}",
"account.posts": "Postit",
"account.report": "Report @{name}",
"account.requested": "Odottaa hyväksyntää",
"account.unblock": "Salli @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Lopeta seuraaminen",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index c6665f43c13..d3c292707ff 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloquer",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Ce compte est situé sur une autre instance. Les nombres peuvent être plus grands.",
"account.edit_profile": "Modifier le profil",
"account.follow": "Suivre",
"account.followers": "Abonné⋅e⋅s",
"account.follows": "Abonnements",
"account.follows_you": "Vous suit",
+ "account.media": "Media",
"account.mention": "Mentionner",
"account.mute": "Masquer",
"account.posts": "Statuts",
"account.report": "Signaler",
"account.requested": "Invitation envoyée",
"account.unblock": "Débloquer",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Ne plus suivre",
"account.unmute": "Ne plus masquer",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour pouvoir passer ceci, la prochaine fois",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Confirmez vous le blocage de {name} ?",
"confirmations.delete.confirm": "Supprimer",
"confirmations.delete.message": "Confirmez vous la suppression de ce pouet ?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Silencer",
"confirmations.mute.message": "Confirmez vous la silenciation {name} ?",
"emoji_button.activity": "Activités",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 8e4baa0c5bd..0a38065b553 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -1,17 +1,20 @@
{
"account.block": "חסימת @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "משתמש זה מגיע מקהילה אחרת. המספר הזה עשוי להיות גדול יותר.",
"account.edit_profile": "עריכת פרופיל",
"account.follow": "מעקב",
"account.followers": "עוקבים",
"account.follows": "נעקבים",
"account.follows_you": "במעקב אחריך",
+ "account.media": "Media",
"account.mention": "אזכור של @{name}",
"account.mute": "להשתיק את @{name}",
"account.posts": "הודעות",
"account.report": "לדווח על @{name}",
"account.requested": "בהמתנה לאישור",
"account.unblock": "הסרת חסימה מעל @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "הפסקת מעקב",
"account.unmute": "הפסקת השתקת @{name}",
"boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
@@ -40,6 +43,8 @@
"confirmations.block.message": "לחסום את {name}?",
"confirmations.delete.confirm": "למחוק",
"confirmations.delete.message": "למחוק את ההודעה?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "להשתיק",
"confirmations.mute.message": "להשתיק את {name}?",
"emoji_button.activity": "פעילות",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index d263a73b90d..6d4b43c009a 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokiraj @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Ovaj korisnik je sa druge instance. Ovaj broj bi mogao biti veći.",
"account.edit_profile": "Uredi profil",
"account.follow": "Slijedi",
"account.followers": "Sljedbenici",
"account.follows": "Slijedi",
"account.follows_you": "te slijedi",
+ "account.media": "Media",
"account.mention": "Spomeni @{name}",
"account.mute": "Utišaj @{name}",
"account.posts": "Postovi",
"account.report": "Prijavi @{name}",
"account.requested": "Čeka pristanak",
"account.unblock": "Deblokiraj @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Prestani slijediti",
"account.unmute": "Poništi utišavanje @{name}",
"boost_modal.combo": "Možeš pritisnuti {combo} kako bi ovo preskočio sljedeći put",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index c50501d242c..ebe2d417179 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokkolás",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Profil szerkesztése",
"account.follow": "Követés",
"account.followers": "Követők",
"account.follows": "Követve",
"account.follows_you": "Követnek téged",
+ "account.media": "Media",
"account.mention": "Említés",
"account.mute": "Mute @{name}",
"account.posts": "Posts",
"account.report": "Report @{name}",
"account.requested": "Awaiting approval",
"account.unblock": "Blokkolás levétele",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Követés abbahagyása",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index ca821a5d5ee..45eea622b33 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokir @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Pengguna ini berasal dari server lain. Angka berikut mungkin lebih besar.",
"account.edit_profile": "Ubah profil",
"account.follow": "Ikuti",
"account.followers": "Pengikut",
"account.follows": "Mengikuti",
"account.follows_you": "Mengikuti anda",
+ "account.media": "Media",
"account.mention": "Balasan @{name}",
"account.mute": "Bisukan @{name}",
"account.posts": "Postingan",
"account.report": "Laporkan @{name}",
"account.requested": "Menunggu persetujuan",
"account.unblock": "Hapus blokir @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Berhenti mengikuti",
"account.unmute": "Berhenti membisukan @{name}",
"boost_modal.combo": "Anda dapat menekan {combo} untuk melewati ini",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Apa anda yakin ingin memblokir {name}?",
"confirmations.delete.confirm": "Hapus",
"confirmations.delete.message": "Apa anda yakin akan menghapus status ini?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Bisukan",
"confirmations.mute.message": "Apa anda yakin ingin membisukan {name}?",
"emoji_button.activity": "Aktivitas",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 34d38868f85..f6791d18090 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokusar @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Ca uzero esas de altra instaluro. Ca nombro forsan esas plu granda.",
"account.edit_profile": "Modifikar profilo",
"account.follow": "Sequar",
"account.followers": "Sequanti",
"account.follows": "Sequas",
"account.follows_you": "Sequas tu",
+ "account.media": "Media",
"account.mention": "Mencionar @{name}",
"account.mute": "Celar @{name}",
"account.posts": "Mesaji",
"account.report": "Denuncar @{name}",
"account.requested": "Vartante aprobo",
"account.unblock": "Desblokusar @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Ne plus sequar",
"account.unmute": "Ne plus celar @{name}",
"boost_modal.combo": "Tu povas presar sur {combo} por omisar co en la venonta foyo",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 8b92ce86d52..c09b705ebb5 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -1,17 +1,20 @@
{
"account.block": "Blocca @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Questo utente si trova su un altro server. Questo numero potrebbe essere maggiore.",
"account.edit_profile": "Modifica profilo",
"account.follow": "Segui",
"account.followers": "Seguaci",
"account.follows": "Segue",
"account.follows_you": "Ti segue",
+ "account.media": "Media",
"account.mention": "Menziona @{name}",
"account.mute": "Silenzia @{name}",
"account.posts": "Posts",
"account.report": "Segnala @{name}",
"account.requested": "In attesa di approvazione",
"account.unblock": "Sblocca @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Non seguire",
"account.unmute": "Non silenziare @{name}",
"boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio la prossima volta",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 5f1ac2381d2..38745e20ffa 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -1,17 +1,20 @@
{
"account.block": "ブロック",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "このユーザーは他のインスタンスに所属しているため、数字が正確で無い場合があります。",
"account.edit_profile": "プロフィールを編集",
"account.follow": "フォロー",
"account.followers": "フォロワー",
"account.follows": "フォロー",
"account.follows_you": "フォローされています",
+ "account.media": "Media",
"account.mention": "返信",
"account.mute": "ミュート",
"account.posts": "投稿",
"account.report": "通報",
"account.requested": "承認待ち",
"account.unblock": "ブロック解除",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "フォロー解除",
"account.unmute": "ミュート解除",
"boost_modal.combo": "次からは{combo}を押せば、これをスキップできます。",
@@ -40,6 +43,8 @@
"confirmations.block.message": "本当に{name}をブロックしますか?",
"confirmations.delete.confirm": "削除",
"confirmations.delete.message": "本当に削除しますか?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "ミュート",
"confirmations.mute.message": "本当に{name}をミュートしますか?",
"emoji_button.activity": "活動",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index e63f527c104..33e51a68017 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokkeer @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Deze gebruiker zit op een andere server. Dit getal kan hoger zijn.",
"account.edit_profile": "Profiel bewerken",
"account.follow": "Volgen",
"account.followers": "Volgers",
"account.follows": "Volgt",
"account.follows_you": "Volgt jou",
+ "account.media": "Media",
"account.mention": "Vermeld @{name}",
"account.mute": "Negeer @{name}",
"account.posts": "Berichten",
"account.report": "Rapporteer @{name}",
"account.requested": "Wacht op goedkeuring",
"account.unblock": "Deblokkeer @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Ontvolgen",
"account.unmute": "Negeer @{name} niet meer",
"boost_modal.combo": "Je kunt {combo} klikken om dit de volgende keer over te slaan",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Weet je zeker dat je {name} wilt blokkeren?",
"confirmations.delete.confirm": "Verwijderen",
"confirmations.delete.message": "Weet je zeker dat je deze toot wilt verwijderen?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Negeren",
"confirmations.mute.message": "Weet je zeker dat je {name} wilt negeren?",
"emoji_button.activity": "Activiteiten",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index d3fac55bdb2..1fddbaa2122 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokkér @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Denne brukeren er fra en annen instans. Dette tallet kan være høyere.",
"account.edit_profile": "Rediger profil",
"account.follow": "Følg",
"account.followers": "Følgere",
"account.follows": "Følger",
"account.follows_you": "Følger deg",
+ "account.media": "Media",
"account.mention": "Nevn @{name}",
"account.mute": "Demp @{name}",
"account.posts": "Innlegg",
"account.report": "Rapportér @{name}",
"account.requested": "Venter på godkjennelse",
"account.unblock": "Avblokker @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Avfølg",
"account.unmute": "Avdemp @{name}",
"boost_modal.combo": "You kan trykke {combo} for å hoppe over dette neste gang",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 8d4911187eb..506cf42e5ea 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -1,17 +1,20 @@
{
"account.block": "Blocar",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Aqueste compte es sus una autra instància. Los nombres pòdon èsser mai grandes.",
"account.edit_profile": "Modificar lo perfil",
"account.follow": "Sègre",
"account.followers": "Abonats",
"account.follows": "Abonaments",
"account.follows_you": "Vos sèc",
+ "account.media": "Media",
"account.mention": "Mencionar",
"account.mute": "Rescondre",
"account.posts": "Estatuts",
"account.report": "Senhalar",
"account.requested": "Invitacion mandada",
"account.unblock": "Desblocar",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Quitar de sègre",
"account.unmute": "Quitar de rescondre",
"boost_modal.combo": "Podètz butar {combo} per passar aquò lo còp que ven",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Sètz segur de voler blocar {name}?",
"confirmations.delete.confirm": "Suprimir",
"confirmations.delete.message": "Sètz segur de voler suprimir l’estatut ?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Metre en silenci",
"confirmations.mute.message": "Sètz segur de voler metre en silenci {name}?",
"emoji_button.activity": "Activitat",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 2a18dff8f1b..f51d2ee58d9 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -1,17 +1,20 @@
{
"account.block": "Blokuj @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Ten użytkownik pochodzi z innej instancji. Ta liczba może być większa.",
"account.edit_profile": "Edytuj profil",
"account.follow": "Obserwuj",
"account.followers": "Obserwujący",
"account.follows": "Obserwacje",
"account.follows_you": "Obserwują cię",
+ "account.media": "Media",
"account.mention": "Wspomnij o @{name}",
"account.mute": "Wycisz @{name}",
"account.posts": "Posty",
"account.report": "Zgłoś @{name}",
"account.requested": "Oczekująca prośba",
"account.unblock": "Odblokuj @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Przestań obserwować",
"account.unmute": "Cofnij wyciszenie @{name}",
"boost_modal.combo": "Naciśnij {combo}, aby pominąć to następnym razem",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Czy na pewno chcesz zablokować {name}?",
"confirmations.delete.confirm": "Usuń",
"confirmations.delete.message": "Czy na pewno chcesz usunąć ten status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Wycisz",
"confirmations.mute.message": "Czy na pewno chcesz wyciszyć {name}?",
"emoji_button.activity": "Aktywność",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 57b31733d23..c5af75d9c0a 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloquear @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Essa conta está localizado em outra instância. Os nomes podem ser maiores.",
"account.edit_profile": "Editar perfil",
"account.follow": "Seguir",
"account.followers": "Seguidores",
"account.follows": "Segue",
"account.follows_you": "É teu seguidor",
+ "account.media": "Media",
"account.mention": "Mencionar @{name}",
"account.mute": "Silenciar @{name}",
"account.posts": "Posts",
"account.report": "Denunciar @{name}",
"account.requested": "A aguardar aprovação",
"account.unblock": "Não bloquear @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Deixar de seguir",
"account.unmute": "Não silenciar @{name}",
"boost_modal.combo": "Pode clicar {combo} para não voltar a ver",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index 57b31733d23..c5af75d9c0a 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -1,17 +1,20 @@
{
"account.block": "Bloquear @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Essa conta está localizado em outra instância. Os nomes podem ser maiores.",
"account.edit_profile": "Editar perfil",
"account.follow": "Seguir",
"account.followers": "Seguidores",
"account.follows": "Segue",
"account.follows_you": "É teu seguidor",
+ "account.media": "Media",
"account.mention": "Mencionar @{name}",
"account.mute": "Silenciar @{name}",
"account.posts": "Posts",
"account.report": "Denunciar @{name}",
"account.requested": "A aguardar aprovação",
"account.unblock": "Não bloquear @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Deixar de seguir",
"account.unmute": "Não silenciar @{name}",
"boost_modal.combo": "Pode clicar {combo} para não voltar a ver",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"emoji_button.activity": "Activity",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 83d74c61952..ba4642ab99c 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -1,17 +1,20 @@
{
"account.block": "Блокировать",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Это пользователь с другого узла. Число может быть больше.",
"account.edit_profile": "Изменить профиль",
"account.follow": "Подписаться",
"account.followers": "Подписаны",
"account.follows": "Подписки",
"account.follows_you": "Подписан(а) на Вас",
+ "account.media": "Media",
"account.mention": "Упомянуть",
"account.mute": "Заглушить",
"account.posts": "Посты",
"account.report": "Пожаловаться",
"account.requested": "Ожидает подтверждения",
"account.unblock": "Разблокировать",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Отписаться",
"account.unmute": "Снять глушение",
"boost_modal.combo": "Нажмите {combo}, чтобы пропустить это в следующий раз",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Вы уверены, что хотите заблокировать {name}?",
"confirmations.delete.confirm": "Удалить",
"confirmations.delete.message": "Вы уверены, что хотите удалить этот статус?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Заглушить",
"confirmations.mute.message": "Вы уверены, что хотите заглушить {name}?",
"emoji_button.activity": "Занятия",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index ef9c43d0b72..ebfa95b845f 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -1,17 +1,20 @@
{
"account.block": "Engelle @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Bu kullanıcının hesabı farklı sunucuda bulunduğu için bu sayı daha fazla olabilir.",
"account.edit_profile": "Profili düzenle",
"account.follow": "Takip et",
"account.followers": "Takipçiler",
"account.follows": "Takip ettikleri",
"account.follows_you": "Seni takip ediyor",
+ "account.media": "Media",
"account.mention": "Bahset @{name}",
"account.mute": "Sustur @{name}",
"account.posts": "Gönderiler",
"account.report": "Rapor et @{name}",
"account.requested": "Onay bekleniyor",
"account.unblock": "Engeli kaldır @{name}",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Takipten vazgeç",
"account.unmute": "Sesi aç @{name}",
"boost_modal.combo": "Bir dahaki sefere {combo} tuşuna basabilirsiniz",
@@ -40,6 +43,8 @@
"confirmations.block.message": "{name} kullanıcısını engellemek istiyor musunuz?",
"confirmations.delete.confirm": "Sil",
"confirmations.delete.message": "Bu gönderiyi silmek istiyor musunuz?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Sessize al",
"confirmations.mute.message": "{name} kullanıcısını sessize almak istiyor musunuz?",
"emoji_button.activity": "Aktivite",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 99df3b4f4e3..cd2fa6b11b6 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -1,17 +1,20 @@
{
"account.block": "Заблокувати",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "Це користувач з іншої інстанції. Число може бути більше.",
"account.edit_profile": "Налаштування профілю",
"account.follow": "Підписатися",
"account.followers": "Підписники",
"account.follows": "Підписки",
"account.follows_you": "Підписаний(-а) на Вас",
+ "account.media": "Media",
"account.mention": "Згадати",
"account.mute": "Заглушити",
"account.posts": "Пости",
"account.report": "Поскаржитися",
"account.requested": "Очікує підтвердження",
"account.unblock": "Розблокувати",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "Відписатися",
"account.unmute": "Зняти глушення",
"boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу",
@@ -40,6 +43,8 @@
"confirmations.block.message": "Ви впевнені, що хочете заблокувати {name}?",
"confirmations.delete.confirm": "Видалити",
"confirmations.delete.message": "Ви впевнені, що хочете видалити цей допис?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "Заглушить",
"confirmations.mute.message": "Ви впевнені, що хочете заглушити {name}?",
"emoji_button.activity": "Заняття",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index fed311cf7c7..45eb663a0e4 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -1,17 +1,20 @@
{
"account.block": "屏蔽 @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "由于这个账户处于另一个服务站上,实际数字会比这个更多。",
"account.edit_profile": "修改个人资料",
"account.follow": "关注",
"account.followers": "关注者",
"account.follows": "正关注",
"account.follows_you": "关注你",
+ "account.media": "Media",
"account.mention": "提及 @{name}",
"account.mute": "将 @{name} 静音",
"account.posts": "嘟文",
"account.report": "举报 @{name}",
"account.requested": "等候审批",
"account.unblock": "解除对 @{name} 的屏蔽",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "取消关注",
"account.unmute": "取消 @{name} 的静音",
"boost_modal.combo": "如你想在下次路过时显示,请按{combo},",
@@ -40,6 +43,8 @@
"confirmations.block.message": "想好了,真的要屏蔽 {name}?",
"confirmations.delete.confirm": "删除",
"confirmations.delete.message": "想好了,真的要删除这条嘟文?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "静音",
"confirmations.mute.message": "想好了,真的要静音 {name}?",
"emoji_button.activity": "活动",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index f3637bf7404..23611ae97fb 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -1,17 +1,20 @@
{
"account.block": "封鎖 @{name}",
+ "account.block_domain": "Hide everything from {domain}",
"account.disclaimer": "由於這個用戶在另一個服務站,實際數字會比這個更多。",
"account.edit_profile": "修改個人資料",
"account.follow": "關注",
"account.followers": "關注的人",
"account.follows": "正在關注",
"account.follows_you": "關注你",
+ "account.media": "Media",
"account.mention": "提及 @{name}",
"account.mute": "將 @{name} 靜音",
"account.posts": "文章",
"account.report": "舉報 @{name}",
"account.requested": "等候審批",
"account.unblock": "解除對 @{name} 的封鎖",
+ "account.unblock_domain": "Unhide {domain}",
"account.unfollow": "取消關注",
"account.unmute": "取消 @{name} 的靜音",
"boost_modal.combo": "如你想在下次路過這顯示,請按{combo},",
@@ -40,6 +43,8 @@
"confirmations.block.message": "你確定要封鎖{name}嗎?",
"confirmations.delete.confirm": "刪除",
"confirmations.delete.message": "你確定要刪除{name}嗎?",
+ "confirmations.domain_block.confirm": "Hide entire domain",
+ "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
"confirmations.mute.confirm": "靜音",
"confirmations.mute.message": "你確定要將{name}靜音嗎?",
"emoji_button.activity": "活動",
diff --git a/app/javascript/mastodon/reducers/relationships.js b/app/javascript/mastodon/reducers/relationships.js
index c65c48b4313..f25c0b55a6e 100644
--- a/app/javascript/mastodon/reducers/relationships.js
+++ b/app/javascript/mastodon/reducers/relationships.js
@@ -7,6 +7,10 @@ import {
ACCOUNT_UNMUTE_SUCCESS,
RELATIONSHIPS_FETCH_SUCCESS
} from '../actions/accounts';
+import {
+ DOMAIN_BLOCK_SUCCESS,
+ DOMAIN_UNBLOCK_SUCCESS
+} from '../actions/domain_blocks';
import Immutable from 'immutable';
const normalizeRelationship = (state, relationship) => state.set(relationship.id, Immutable.fromJS(relationship));
@@ -32,6 +36,10 @@ export default function relationships(state = initialState, action) {
return normalizeRelationship(state, action.relationship);
case RELATIONSHIPS_FETCH_SUCCESS:
return normalizeRelationships(state, action.relationships);
+ case DOMAIN_BLOCK_SUCCESS:
+ return state.setIn([action.accountId, 'domain_blocking'], true);
+ case DOMAIN_UNBLOCK_SUCCESS:
+ return state.setIn([action.accountId, 'domain_blocking'], false);
default:
return state;
}
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index 9241d97205b..bdd64c01a0c 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -14,6 +14,7 @@ class AccountDomainBlock < ApplicationRecord
include Paginable
belongs_to :account, required: true
+ validates :domain, presence: true, uniqueness: { scope: :account_id }
after_create :remove_blocking_cache
after_destroy :remove_blocking_cache
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index c8006bd0b5b..0ef7512e299 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -23,6 +23,12 @@ module AccountInteractions
def requested_map(target_account_ids, account_id)
follow_mapping(FollowRequest.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
end
+
+ def domain_blocking_map(target_account_ids, account_id)
+ accounts_map = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
+ blocked_domains = AccountDomainBlock.where(account_id: account_id, domain: accounts_map.values).pluck(:domain)
+ accounts_map.map { |id, domain| [id, blocked_domains.include?(domain)] }.to_h
+ end
end
included do
diff --git a/app/models/status.rb b/app/models/status.rb
index 70021eb65b4..80f33a7c77a 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -67,7 +67,8 @@ class Status < ApplicationRecord
scope :local_only, -> { left_outer_joins(:account).where(accounts: { domain: nil }) }
scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: false }) }
scope :including_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: true }) }
- scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids, accounts: { domain: account.excluded_from_timeline_domains }) }
+ scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
+ scope :not_domain_blocked_by_account, ->(account) { left_outer_joins(:account).where.not(accounts: { domain: account.excluded_from_timeline_domains }) }
cache_associated :account, :application, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :application, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account
@@ -152,13 +153,13 @@ class Status < ApplicationRecord
def as_public_timeline(account = nil, local_only = false)
query = timeline_scope(local_only).without_replies
- apply_timeline_filters(query, account)
+ apply_timeline_filters(query, account, local_only)
end
def as_tag_timeline(tag, account = nil, local_only = false)
query = timeline_scope(local_only).tagged_with(tag)
- apply_timeline_filters(query, account)
+ apply_timeline_filters(query, account, local_only)
end
def as_outbox_timeline(account)
@@ -222,16 +223,17 @@ class Status < ApplicationRecord
.without_reblogs
end
- def apply_timeline_filters(query, account)
+ def apply_timeline_filters(query, account, local_only)
if account.nil?
filter_timeline_default(query)
else
- filter_timeline_for_account(query, account)
+ filter_timeline_for_account(query, account, local_only)
end
end
- def filter_timeline_for_account(query, account)
+ def filter_timeline_for_account(query, account, local_only)
query = query.not_excluded_by_account(account)
+ query = query.not_domain_blocked_by_account(account) unless local_only
query = query.in_allowed_languages(account) if account.allowed_languages.present?
query.merge(account_silencing_filter(account))
end
diff --git a/app/services/block_domain_from_account_service.rb b/app/services/block_domain_from_account_service.rb
new file mode 100644
index 00000000000..cae7abcbdc0
--- /dev/null
+++ b/app/services/block_domain_from_account_service.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class BlockDomainFromAccountService < BaseService
+ def call(account, domain)
+ account.block_domain!(domain)
+ account.passive_relationships.where(account: Account.where(domain: domain)).delete_all
+ end
+end
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index 150ffe6b281..ce22b650598 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -37,15 +37,15 @@ class NotifyService < BaseService
end
def blocked?
- blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
- blocked ||= @recipient.id == @notification.from_account.id # Skip for interactions with self
- blocked ||= @recipient.domain_blocking?(@notification.from_account.domain) # Skip for domain blocked accounts
- blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
- blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account)) # Hellban
- blocked ||= (@recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)) # Options
- blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account)) # Options
+ blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
+ blocked ||= @recipient.id == @notification.from_account.id # Skip for interactions with self
+ blocked ||= @recipient.domain_blocking?(@notification.from_account.domain) && !@recipient.following?(@notification.from_account) # Skip for domain blocked accounts
+ blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
+ blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account)) # Hellban
+ blocked ||= (@recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)) # Options
+ blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account)) # Options
blocked ||= conversation_muted?
- blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
+ blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
blocked
end
diff --git a/app/services/process_interaction_service.rb b/app/services/process_interaction_service.rb
index bc8361510c7..e9c01103d58 100644
--- a/app/services/process_interaction_service.rb
+++ b/app/services/process_interaction_service.rb
@@ -21,9 +21,9 @@ class ProcessInteractionService < BaseService
case verb(xml)
when :follow
- follow!(account, target_account) unless target_account.locked? || target_account.blocking?(account)
+ follow!(account, target_account) unless target_account.locked? || target_account.blocking?(account) || target_account.domain_blocking?(account.domain)
when :request_friend
- follow_request!(account, target_account) unless !target_account.locked? || target_account.blocking?(account)
+ follow_request!(account, target_account) unless !target_account.locked? || target_account.blocking?(account) || target_account.domain_blocking?(account.domain)
when :authorize
authorize_follow_request!(account, target_account)
when :reject
diff --git a/app/services/send_interaction_service.rb b/app/services/send_interaction_service.rb
index 99113eecaf2..504f41c7278 100644
--- a/app/services/send_interaction_service.rb
+++ b/app/services/send_interaction_service.rb
@@ -6,12 +6,22 @@ class SendInteractionService < BaseService
# @param [Account] source_account
# @param [Account] target_account
def call(xml, source_account, target_account)
- envelope = salmon.pack(xml, source_account.keypair)
- salmon.post(target_account.salmon_url, envelope)
+ @xml = xml
+ @source_account = source_account
+ @target_account = target_account
+
+ return if block_notification?
+
+ envelope = salmon.pack(@xml, @source_account.keypair)
+ salmon.post(@target_account.salmon_url, envelope)
end
private
+ def block_notification?
+ DomainBlock.blocked?(@target_account.domain)
+ end
+
def salmon
@salmon ||= OStatus2::Salmon.new
end
diff --git a/app/views/api/v1/accounts/relationship.rabl b/app/views/api/v1/accounts/relationship.rabl
index d6f1dd48ab6..4f7763d9d0e 100644
--- a/app/views/api/v1/accounts/relationship.rabl
+++ b/app/views/api/v1/accounts/relationship.rabl
@@ -1,8 +1,9 @@
object @account
attribute :id
-node(:following) { |account| @following[account.id] || false }
-node(:followed_by) { |account| @followed_by[account.id] || false }
-node(:blocking) { |account| @blocking[account.id] || false }
-node(:muting) { |account| @muting[account.id] || false }
-node(:requested) { |account| @requested[account.id] || false }
+node(:following) { |account| @following[account.id] || false }
+node(:followed_by) { |account| @followed_by[account.id] || false }
+node(:blocking) { |account| @blocking[account.id] || false }
+node(:muting) { |account| @muting[account.id] || false }
+node(:requested) { |account| @requested[account.id] || false }
+node(:domain_blocking) { |account| @domain_blocking[account.id] || false }
diff --git a/spec/services/block_domain_from_account_service_spec.rb b/spec/services/block_domain_from_account_service_spec.rb
new file mode 100644
index 00000000000..e7ee343723f
--- /dev/null
+++ b/spec/services/block_domain_from_account_service_spec.rb
@@ -0,0 +1,19 @@
+require 'rails_helper'
+
+RSpec.describe BlockDomainFromAccountService do
+ let!(:wolf) { Fabricate(:account, username: 'wolf', domain: 'evil.org') }
+ let!(:alice) { Fabricate(:account, username: 'alice') }
+
+ subject { BlockDomainFromAccountService.new }
+
+ it 'creates domain block' do
+ subject.call(alice, 'evil.org')
+ expect(alice.domain_blocking?('evil.org')).to be true
+ end
+
+ it 'purge followers from blocked domain' do
+ wolf.follow!(alice)
+ subject.call(alice, 'evil.org')
+ expect(wolf.following?(alice)).to be false
+ end
+end
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index 29bd741aa6e..7a66bd0fe4d 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -22,6 +22,12 @@ RSpec.describe NotifyService do
is_expected.to_not change(Notification, :count)
end
+ it 'does still notify when sender\'s domain is blocked but sender is followed' do
+ recipient.block_domain!(sender.domain)
+ recipient.follow!(sender)
+ is_expected.to change(Notification, :count)
+ end
+
it 'does not notify when sender is silenced and not followed' do
sender.update(silenced: true)
is_expected.to_not change(Notification, :count)