@@ -23,6 +23,7 @@ export function blockDomain(domain) { | |||
api(getState).post('/api/v1/domain_blocks', { domain }).then(() => { | |||
const at_domain = '@' + domain; | |||
const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id')); | |||
dispatch(blockDomainSuccess(domain, accounts)); | |||
}).catch(err => { | |||
dispatch(blockDomainFail(domain, err)); | |||
@@ -8,6 +8,8 @@ import { | |||
CONVERSATIONS_UPDATE, | |||
CONVERSATIONS_READ, | |||
} from '../actions/conversations'; | |||
import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'mastodon/actions/accounts'; | |||
import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks'; | |||
import compareId from '../compare_id'; | |||
const initialState = ImmutableMap({ | |||
@@ -74,6 +76,10 @@ const expandNormalizedConversations = (state, conversations, next, isLoadingRece | |||
}); | |||
}; | |||
const filterConversations = (state, accountIds) => { | |||
return state.update('items', list => list.filterNot(item => item.get('accounts').some(accountId => accountIds.includes(accountId)))); | |||
}; | |||
export default function conversations(state = initialState, action) { | |||
switch (action.type) { | |||
case CONVERSATIONS_FETCH_REQUEST: | |||
@@ -96,6 +102,11 @@ export default function conversations(state = initialState, action) { | |||
return item; | |||
})); | |||
case ACCOUNT_BLOCK_SUCCESS: | |||
case ACCOUNT_MUTE_SUCCESS: | |||
return filterConversations(state, [action.relationship.id]); | |||
case DOMAIN_BLOCK_SUCCESS: | |||
return filterConversations(state, action.accounts); | |||
default: | |||
return state; | |||
} | |||
@@ -12,6 +12,7 @@ import { | |||
ACCOUNT_BLOCK_SUCCESS, | |||
ACCOUNT_MUTE_SUCCESS, | |||
} from '../actions/accounts'; | |||
import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks'; | |||
import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines'; | |||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; | |||
import compareId from '../compare_id'; | |||
@@ -83,8 +84,8 @@ const expandNormalizedNotifications = (state, notifications, next, usePendingIte | |||
}); | |||
}; | |||
const filterNotifications = (state, relationship) => { | |||
const helper = list => list.filterNot(item => item !== null && item.get('account') === relationship.id); | |||
const filterNotifications = (state, accountIds) => { | |||
const helper = list => list.filterNot(item => item !== null && accountIds.includes(item.get('account'))); | |||
return state.update('items', helper).update('pendingItems', helper); | |||
}; | |||
@@ -118,9 +119,11 @@ export default function notifications(state = initialState, action) { | |||
case NOTIFICATIONS_EXPAND_SUCCESS: | |||
return expandNormalizedNotifications(state, action.notifications, action.next, action.usePendingItems); | |||
case ACCOUNT_BLOCK_SUCCESS: | |||
return filterNotifications(state, action.relationship); | |||
return filterNotifications(state, [action.relationship.id]); | |||
case ACCOUNT_MUTE_SUCCESS: | |||
return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state; | |||
return action.relationship.muting_notifications ? filterNotifications(state, [action.relationship.id]) : state; | |||
case DOMAIN_BLOCK_SUCCESS: | |||
return filterNotifications(state, action.accounts); | |||
case NOTIFICATIONS_CLEAR: | |||
return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false); | |||
case TIMELINE_DELETE: | |||
@@ -4,6 +4,8 @@ import { | |||
SUGGESTIONS_FETCH_FAIL, | |||
SUGGESTIONS_DISMISS, | |||
} from '../actions/suggestions'; | |||
import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'mastodon/actions/accounts'; | |||
import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks'; | |||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; | |||
const initialState = ImmutableMap({ | |||
@@ -24,6 +26,11 @@ export default function suggestionsReducer(state = initialState, action) { | |||
return state.set('isLoading', false); | |||
case SUGGESTIONS_DISMISS: | |||
return state.update('items', list => list.filterNot(id => id === action.id)); | |||
case ACCOUNT_BLOCK_SUCCESS: | |||
case ACCOUNT_MUTE_SUCCESS: | |||
return state.update('items', list => list.filterNot(id => id === action.relationship.id)); | |||
case DOMAIN_BLOCK_SUCCESS: | |||
return state.update('items', list => list.filterNot(id => action.accounts.includes(id))); | |||
default: | |||
return state; | |||
} | |||
@@ -10,12 +10,24 @@ class AfterBlockDomainFromAccountService < BaseService | |||
@account = account | |||
@domain = domain | |||
clear_notifications! | |||
remove_follows! | |||
reject_existing_followers! | |||
reject_pending_follow_requests! | |||
end | |||
private | |||
def remove_follows! | |||
@account.active_relationships.where(account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).find_each do |follow| | |||
UnfollowService.new.call(@account, follow.target_account) | |||
end | |||
end | |||
def clear_notifications! | |||
Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all | |||
end | |||
def reject_existing_followers! | |||
@account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).find_each do |follow| | |||
reject_follow!(follow) | |||
@@ -2,43 +2,25 @@ | |||
class AfterBlockService < BaseService | |||
def call(account, target_account) | |||
clear_home_feed(account, target_account) | |||
clear_notifications(account, target_account) | |||
clear_conversations(account, target_account) | |||
@account = account | |||
@target_account = target_account | |||
clear_home_feed! | |||
clear_notifications! | |||
clear_conversations! | |||
end | |||
private | |||
def clear_home_feed(account, target_account) | |||
FeedManager.instance.clear_from_timeline(account, target_account) | |||
def clear_home_feed! | |||
FeedManager.instance.clear_from_timeline(@account, @target_account) | |||
end | |||
def clear_conversations(account, target_account) | |||
AccountConversation.where(account: account) | |||
.where('? = ANY(participant_account_ids)', target_account.id) | |||
.in_batches | |||
.destroy_all | |||
def clear_conversations! | |||
AccountConversation.where(account: @account).where('? = ANY(participant_account_ids)', @target_account.id).in_batches.destroy_all | |||
end | |||
def clear_notifications(account, target_account) | |||
Notification.where(account: account) | |||
.joins(:follow) | |||
.where(activity_type: 'Follow', follows: { account_id: target_account.id }) | |||
.delete_all | |||
Notification.where(account: account) | |||
.joins(mention: :status) | |||
.where(activity_type: 'Mention', statuses: { account_id: target_account.id }) | |||
.delete_all | |||
Notification.where(account: account) | |||
.joins(:favourite) | |||
.where(activity_type: 'Favourite', favourites: { account_id: target_account.id }) | |||
.delete_all | |||
Notification.where(account: account) | |||
.joins(:status) | |||
.where(activity_type: 'Status', statuses: { account_id: target_account.id }) | |||
.delete_all | |||
def clear_notifications! | |||
Notification.where(account: @account).where(from_account: @target_account).in_batches.delete_all | |||
end | |||
end |
@@ -13,7 +13,7 @@ class FollowService < BaseService | |||
target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true) | |||
raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended? | |||
raise Mastodon::NotPermittedError if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved? || (!target_account.local? && target_account.ostatus?) | |||
raise Mastodon::NotPermittedError if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved? || (!target_account.local? && target_account.ostatus?) || source_account.domain_blocking?(target_account.domain) | |||
if source_account.following?(target_account) | |||
# We're already following this account, but we'll call follow! again to | |||