diff --git a/app/controllers/api/v1/antennas/exclude_accounts_controller.rb b/app/controllers/api/v1/antennas/exclude_accounts_controller.rb
new file mode 100644
index 0000000000..cdb9173c11
--- /dev/null
+++ b/app/controllers/api/v1/antennas/exclude_accounts_controller.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+class Api::V1::Antennas::ExcludeAccountsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
+ before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]
+
+ before_action :require_user!
+ before_action :set_antenna
+
+ after_action :insert_pagination_headers, only: :show
+
+ def show
+ @accounts = load_accounts
+ render json: @accounts, each_serializer: REST::AccountSerializer
+ end
+
+ def create
+ new_accounts = @antenna.exclude_accounts || []
+ antenna_accounts.each do |account|
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.duplicate_account') if new_accounts.include?(account.id)
+
+ new_accounts << account.id
+ end
+
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.limit.accounts') if new_accounts.size > Antenna::ACCOUNTS_PER_ANTENNA_LIMIT
+
+ @antenna.update!(exclude_accounts: new_accounts)
+
+ render_empty
+ end
+
+ def destroy
+ new_accounts = @antenna.exclude_accounts || []
+ new_accounts -= antenna_accounts.pluck(:id)
+
+ @antenna.update!(exclude_accounts: new_accounts)
+
+ render_empty
+ end
+
+ private
+
+ def set_antenna
+ @antenna = Antenna.where(account: current_account).find(params[:antenna_id])
+ end
+
+ def load_accounts
+ return [] if @antenna.exclude_accounts.nil?
+
+ if unlimited?
+ Account.where(id: @antenna.exclude_accounts).without_suspended.includes(:account_stat).all
+ else
+ Account.where(id: @antenna.exclude_accounts).without_suspended.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
+ end
+ end
+
+ def antenna_accounts
+ Account.find(account_ids)
+ end
+
+ def account_ids
+ Array(resource_params[:account_ids])
+ end
+
+ def resource_params
+ params.permit(account_ids: [])
+ end
+
+ def insert_pagination_headers
+ set_pagination_headers(next_path, prev_path)
+ end
+
+ def next_path
+ return if unlimited?
+
+ api_v1_list_accounts_url pagination_params(max_id: pagination_max_id) if records_continue?
+ end
+
+ def prev_path
+ return if unlimited?
+
+ api_v1_list_accounts_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
+ end
+
+ def pagination_max_id
+ @accounts.last.id
+ end
+
+ def pagination_since_id
+ @accounts.first.id
+ end
+
+ def records_continue?
+ @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
+ end
+
+ def pagination_params(core_params)
+ params.slice(:limit).permit(:limit).merge(core_params)
+ end
+
+ def unlimited?
+ params[:limit] == '0'
+ end
+end
diff --git a/app/controllers/api/v1/antennas/exclude_domains_controller.rb b/app/controllers/api/v1/antennas/exclude_domains_controller.rb
new file mode 100644
index 0000000000..235a44d593
--- /dev/null
+++ b/app/controllers/api/v1/antennas/exclude_domains_controller.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+class Api::V1::Antennas::ExcludeDomainsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :write, :'write:lists' }
+
+ before_action :require_user!
+ before_action :set_antenna
+
+ def create
+ new_domains = @antenna.exclude_domains || []
+ domains.each do |domain|
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.duplicate_domain') if new_domains.include?(domain)
+
+ new_domains << domain
+ end
+
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.limit.domains') if new_domains.size > Antenna::KEYWORDS_PER_ANTENNA_LIMIT
+
+ @antenna.update!(exclude_domains: new_domains)
+
+ render_empty
+ end
+
+ def destroy
+ new_domains = @antenna.exclude_domains || []
+ new_domains -= domains
+
+ @antenna.update!(exclude_domains: new_domains)
+
+ render_empty
+ end
+
+ private
+
+ def set_antenna
+ @antenna = Antenna.where(account: current_account).find(params[:antenna_id])
+ end
+
+ def domains
+ Array(resource_params[:domains])
+ end
+
+ def resource_params
+ params.permit(domains: [])
+ end
+end
diff --git a/app/controllers/api/v1/antennas/exclude_keywords_controller.rb b/app/controllers/api/v1/antennas/exclude_keywords_controller.rb
new file mode 100644
index 0000000000..171dac5f80
--- /dev/null
+++ b/app/controllers/api/v1/antennas/exclude_keywords_controller.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+class Api::V1::Antennas::ExcludeKeywordsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :write, :'write:lists' }
+
+ before_action :require_user!
+ before_action :set_antenna
+
+ def create
+ new_keywords = @antenna.exclude_keywords || []
+ keywords.each do |keyword|
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.duplicate_keyword') if new_keywords.include?(keyword)
+
+ new_keywords << keyword
+ end
+
+ raise Mastodon::ValidationError, I18n.t('antennas.errors.limit.keywords') if new_keywords.size > Antenna::KEYWORDS_PER_ANTENNA_LIMIT
+
+ @antenna.update!(exclude_keywords: new_keywords)
+
+ render_empty
+ end
+
+ def destroy
+ new_keywords = @antenna.exclude_keywords || []
+ new_keywords -= keywords
+
+ @antenna.update!(exclude_keywords: new_keywords)
+
+ render_empty
+ end
+
+ private
+
+ def set_antenna
+ @antenna = Antenna.where(account: current_account).find(params[:antenna_id])
+ end
+
+ def keywords
+ Array(resource_params[:keywords])
+ end
+
+ def resource_params
+ params.permit(keywords: [])
+ end
+end
diff --git a/app/javascript/mastodon/actions/antennas.js b/app/javascript/mastodon/actions/antennas.js
index 37e6b13802..3e561cbacb 100644
--- a/app/javascript/mastodon/actions/antennas.js
+++ b/app/javascript/mastodon/actions/antennas.js
@@ -43,6 +43,18 @@ export const ANTENNA_EDITOR_REMOVE_REQUEST = 'ANTENNA_EDITOR_REMOVE_REQUEST';
export const ANTENNA_EDITOR_REMOVE_SUCCESS = 'ANTENNA_EDITOR_REMOVE_SUCCESS';
export const ANTENNA_EDITOR_REMOVE_FAIL = 'ANTENNA_EDITOR_REMOVE_FAIL';
+export const ANTENNA_EXCLUDE_ACCOUNTS_FETCH_REQUEST = 'ANTENNA_EXCLUDE_ACCOUNTS_FETCH_REQUEST';
+export const ANTENNA_EXCLUDE_ACCOUNTS_FETCH_SUCCESS = 'ANTENNA_EXCLUDE_ACCOUNTS_FETCH_SUCCESS';
+export const ANTENNA_EXCLUDE_ACCOUNTS_FETCH_FAIL = 'ANTENNA_EXCLUDE_ACCOUNTS_FETCH_FAIL';
+
+export const ANTENNA_EDITOR_ADD_EXCLUDE_REQUEST = 'ANTENNA_EDITOR_ADD_EXCLUDE_REQUEST';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_SUCCESS = 'ANTENNA_EDITOR_ADD_EXCLUDE_SUCCESS';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_FAIL = 'ANTENNA_EDITOR_ADD_EXCLUDE_FAIL';
+
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_REQUEST = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_REQUEST';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_SUCCESS = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_SUCCESS';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_FAIL = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_FAIL';
+
export const ANTENNA_EDITOR_FETCH_DOMAINS_REQUEST = 'ANTENNA_EDITOR_FETCH_DOMAINS_REQUEST';
export const ANTENNA_EDITOR_FETCH_DOMAINS_SUCCESS = 'ANTENNA_EDITOR_FETCH_DOMAINS_SUCCESS';
export const ANTENNA_EDITOR_FETCH_DOMAINS_FAIL = 'ANTENNA_EDITOR_FETCH_DOMAINS_FAIL';
@@ -51,10 +63,18 @@ export const ANTENNA_EDITOR_ADD_DOMAIN_REQUEST = 'ANTENNA_EDITOR_ADD_DOMAIN_REQU
export const ANTENNA_EDITOR_ADD_DOMAIN_SUCCESS = 'ANTENNA_EDITOR_ADD_DOMAIN_SUCCESS';
export const ANTENNA_EDITOR_ADD_DOMAIN_FAIL = 'ANTENNA_EDITOR_ADD_DOMAIN_FAIL';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_REQUEST = 'ANTENNA_EDITOR_ADD_EXCLUDEDOMAIN_REQUEST';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_SUCCESS = 'ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_SUCCESS';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_FAIL = 'ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_FAIL';
+
export const ANTENNA_EDITOR_REMOVE_DOMAIN_REQUEST = 'ANTENNA_EDITOR_REMOVE_DOMAIN_REQUEST';
export const ANTENNA_EDITOR_REMOVE_DOMAIN_SUCCESS = 'ANTENNA_EDITOR_REMOVE_DOMAIN_SUCCESS';
export const ANTENNA_EDITOR_REMOVE_DOMAIN_FAIL = 'ANTENNA_EDITOR_REMOVE_DOMAIN_FAIL';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_REQUEST = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_REQUEST';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_SUCCESS = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_SUCCESS';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_FAIL = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_FAIL';
+
export const ANTENNA_EDITOR_FETCH_KEYWORDS_REQUEST = 'ANTENNA_EDITOR_FETCH_KEYWORDS_REQUEST';
export const ANTENNA_EDITOR_FETCH_KEYWORDS_SUCCESS = 'ANTENNA_EDITOR_FETCH_KEYWORDS_SUCCESS';
export const ANTENNA_EDITOR_FETCH_KEYWORDS_FAIL = 'ANTENNA_EDITOR_FETCH_KEYWORDS_FAIL';
@@ -63,10 +83,18 @@ export const ANTENNA_EDITOR_ADD_KEYWORD_REQUEST = 'ANTENNA_EDITOR_ADD_KEYWORD_RE
export const ANTENNA_EDITOR_ADD_KEYWORD_SUCCESS = 'ANTENNA_EDITOR_ADD_KEYWORD_SUCCESS';
export const ANTENNA_EDITOR_ADD_KEYWORD_FAIL = 'ANTENNA_EDITOR_ADD_KEYWORD_FAIL';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_REQUEST = 'ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_REQUEST';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_SUCCESS = 'ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_SUCCESS';
+export const ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_FAIL = 'ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_FAIL';
+
export const ANTENNA_EDITOR_REMOVE_KEYWORD_REQUEST = 'ANTENNA_EDITOR_REMOVE_KEYWORD_REQUEST';
export const ANTENNA_EDITOR_REMOVE_KEYWORD_SUCCESS = 'ANTENNA_EDITOR_REMOVE_KEYWORD_SUCCESS';
export const ANTENNA_EDITOR_REMOVE_KEYWORD_FAIL = 'ANTENNA_EDITOR_REMOVE_KEYWORD_FAIL';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_REQUEST = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_REQUEST';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_SUCCESS = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_SUCCESS';
+export const ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_FAIL = 'ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_FAIL';
+
export const ANTENNA_ADDER_RESET = 'ANTENNA_ADDER_RESET';
export const ANTENNA_ADDER_SETUP = 'ANTENNA_ADDER_SETUP';
@@ -144,6 +172,15 @@ export const setupAntennaEditor = antennaId => (dispatch, getState) => {
dispatch(fetchAntennaAccounts(antennaId));
};
+export const setupExcludeAntennaEditor = antennaId => (dispatch, getState) => {
+ dispatch({
+ type: ANTENNA_EDITOR_SETUP,
+ antenna: getState().getIn(['antennas', antennaId]),
+ });
+
+ dispatch(fetchAntennaExcludeAccounts(antennaId));
+};
+
export const changeAntennaEditorTitle = value => ({
type: ANTENNA_EDITOR_TITLE_CHANGE,
value,
@@ -258,6 +295,33 @@ export const fetchAntennaAccountsFail = (id, error) => ({
error,
});
+export const fetchAntennaExcludeAccounts = antennaId => (dispatch, getState) => {
+ dispatch(fetchAntennaExcludeAccountsRequest(antennaId));
+
+ api(getState).get(`/api/v1/antennas/${antennaId}/exclude_accounts`, { params: { limit: 0 } }).then(({ data }) => {
+ dispatch(importFetchedAccounts(data));
+ dispatch(fetchAntennaExcludeAccountsSuccess(antennaId, data));
+ }).catch(err => dispatch(fetchAntennaExcludeAccountsFail(antennaId, err)));
+};
+
+export const fetchAntennaExcludeAccountsRequest = id => ({
+ type: ANTENNA_EXCLUDE_ACCOUNTS_FETCH_REQUEST,
+ id,
+});
+
+export const fetchAntennaExcludeAccountsSuccess = (id, accounts, next) => ({
+ type: ANTENNA_EXCLUDE_ACCOUNTS_FETCH_SUCCESS,
+ id,
+ accounts,
+ next,
+});
+
+export const fetchAntennaExcludeAccountsFail = (id, error) => ({
+ type: ANTENNA_EXCLUDE_ACCOUNTS_FETCH_FAIL,
+ id,
+ error,
+});
+
export const fetchAntennaSuggestions = q => (dispatch, getState) => {
const params = {
q,
@@ -316,6 +380,99 @@ export const addToAntennaFail = (antennaId, accountId, error) => ({
error,
});
+export const addExcludeToAntennaEditor = accountId => (dispatch, getState) => {
+ dispatch(addExcludeToAntenna(getState().getIn(['antennaEditor', 'antennaId']), accountId));
+};
+
+export const addExcludeToAntenna = (antennaId, accountId) => (dispatch, getState) => {
+ dispatch(addExcludeToAntennaRequest(antennaId, accountId));
+
+ api(getState).post(`/api/v1/antennas/${antennaId}/exclude_accounts`, { account_ids: [accountId] })
+ .then(() => dispatch(addExcludeToAntennaSuccess(antennaId, accountId)))
+ .catch(err => dispatch(addExcludeToAntennaFail(antennaId, accountId, err)));
+};
+
+export const addExcludeToAntennaRequest = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_REQUEST,
+ antennaId,
+ accountId,
+});
+
+export const addExcludeToAntennaSuccess = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_SUCCESS,
+ antennaId,
+ accountId,
+});
+
+export const addExcludeToAntennaFail = (antennaId, accountId, error) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_FAIL,
+ antennaId,
+ accountId,
+ error,
+});
+
+export const removeFromAntennaEditor = accountId => (dispatch, getState) => {
+ dispatch(removeFromAntenna(getState().getIn(['antennaEditor', 'antennaId']), accountId));
+};
+
+export const removeFromAntenna = (antennaId, accountId) => (dispatch, getState) => {
+ dispatch(removeFromAntennaRequest(antennaId, accountId));
+
+ api(getState).delete(`/api/v1/antennas/${antennaId}/accounts`, { params: { account_ids: [accountId] } })
+ .then(() => dispatch(removeFromAntennaSuccess(antennaId, accountId)))
+ .catch(err => dispatch(removeFromAntennaFail(antennaId, accountId, err)));
+};
+
+export const removeFromAntennaRequest = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_REMOVE_REQUEST,
+ antennaId,
+ accountId,
+});
+
+export const removeFromAntennaSuccess = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_REMOVE_SUCCESS,
+ antennaId,
+ accountId,
+});
+
+export const removeFromAntennaFail = (antennaId, accountId, error) => ({
+ type: ANTENNA_EDITOR_REMOVE_FAIL,
+ antennaId,
+ accountId,
+ error,
+});
+
+export const removeExcludeFromAntennaEditor = accountId => (dispatch, getState) => {
+ dispatch(removeExcludeFromAntenna(getState().getIn(['antennaEditor', 'antennaId']), accountId));
+};
+
+export const removeExcludeFromAntenna = (antennaId, accountId) => (dispatch, getState) => {
+ dispatch(removeExcludeFromAntennaRequest(antennaId, accountId));
+
+ api(getState).delete(`/api/v1/antennas/${antennaId}/exclude_accounts`, { params: { account_ids: [accountId] } })
+ .then(() => dispatch(removeExcludeFromAntennaSuccess(antennaId, accountId)))
+ .catch(err => dispatch(removeExcludeFromAntennaFail(antennaId, accountId, err)));
+};
+
+export const removeExcludeFromAntennaRequest = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_REQUEST,
+ antennaId,
+ accountId,
+});
+
+export const removeExcludeFromAntennaSuccess = (antennaId, accountId) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_SUCCESS,
+ antennaId,
+ accountId,
+});
+
+export const removeExcludeFromAntennaFail = (antennaId, accountId, error) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_FAIL,
+ antennaId,
+ accountId,
+ error,
+});
+
export const fetchAntennaDomains = antennaId => (dispatch, getState) => {
dispatch(fetchAntennaDomainsRequest(antennaId));
@@ -368,6 +525,87 @@ export const addDomainToAntennaFail = (antennaId, domain, error) => ({
error,
});
+export const removeDomainFromAntenna = (antennaId, domain) => (dispatch, getState) => {
+ dispatch(removeDomainFromAntennaRequest(antennaId, domain));
+
+ api(getState).delete(`/api/v1/antennas/${antennaId}/domains`, { params: { domains: [domain] } })
+ .then(() => dispatch(removeDomainFromAntennaSuccess(antennaId, domain)))
+ .catch(err => dispatch(removeDomainFromAntennaFail(antennaId, domain, err)));
+};
+
+export const removeDomainFromAntennaRequest = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_REMOVE_DOMAIN_REQUEST,
+ antennaId,
+ domain,
+});
+
+export const removeDomainFromAntennaSuccess = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_REMOVE_DOMAIN_SUCCESS,
+ antennaId,
+ domain,
+});
+
+export const removeDomainFromAntennaFail = (antennaId, domain, error) => ({
+ type: ANTENNA_EDITOR_REMOVE_DOMAIN_FAIL,
+ antennaId,
+ domain,
+ error,
+});
+
+export const addExcludeDomainToAntenna = (antennaId, domain) => (dispatch, getState) => {
+ dispatch(addExcludeDomainToAntennaRequest(antennaId, domain));
+
+ api(getState).post(`/api/v1/antennas/${antennaId}/exclude_domains`, { domains: [domain] })
+ .then(() => dispatch(addExcludeDomainToAntennaSuccess(antennaId, domain)))
+ .catch(err => dispatch(addExcludeDomainToAntennaFail(antennaId, domain, err)));
+};
+
+export const addExcludeDomainToAntennaRequest = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_REQUEST,
+ antennaId,
+ domain,
+});
+
+export const addExcludeDomainToAntennaSuccess = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_SUCCESS,
+ antennaId,
+ domain,
+});
+
+export const addExcludeDomainToAntennaFail = (antennaId, domain, error) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_DOMAIN_FAIL,
+ antennaId,
+ domain,
+ error,
+});
+
+export const removeExcludeDomainFromAntenna = (antennaId, domain) => (dispatch, getState) => {
+ dispatch(removeExcludeDomainFromAntennaRequest(antennaId, domain));
+
+ api(getState).delete(`/api/v1/antennas/${antennaId}/exclude_domains`, { params: { domains: [domain] } })
+ .then(() => dispatch(removeExcludeDomainFromAntennaSuccess(antennaId, domain)))
+ .catch(err => dispatch(removeExcludeDomainFromAntennaFail(antennaId, domain, err)));
+};
+
+export const removeExcludeDomainFromAntennaRequest = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_REQUEST,
+ antennaId,
+ domain,
+});
+
+export const removeExcludeDomainFromAntennaSuccess = (antennaId, domain) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_SUCCESS,
+ antennaId,
+ domain,
+});
+
+export const removeExcludeDomainFromAntennaFail = (antennaId, domain, error) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_DOMAIN_FAIL,
+ antennaId,
+ domain,
+ error,
+});
+
export const fetchAntennaKeywords = antennaId => (dispatch, getState) => {
dispatch(fetchAntennaKeywordsRequest(antennaId));
@@ -420,64 +658,6 @@ export const addKeywordToAntennaFail = (antennaId, keyword, error) => ({
error,
});
-export const removeFromAntennaEditor = accountId => (dispatch, getState) => {
- dispatch(removeFromAntenna(getState().getIn(['antennaEditor', 'antennaId']), accountId));
-};
-
-export const removeFromAntenna = (antennaId, accountId) => (dispatch, getState) => {
- dispatch(removeFromAntennaRequest(antennaId, accountId));
-
- api(getState).delete(`/api/v1/antennas/${antennaId}/accounts`, { params: { account_ids: [accountId] } })
- .then(() => dispatch(removeFromAntennaSuccess(antennaId, accountId)))
- .catch(err => dispatch(removeFromAntennaFail(antennaId, accountId, err)));
-};
-
-export const removeFromAntennaRequest = (antennaId, accountId) => ({
- type: ANTENNA_EDITOR_REMOVE_REQUEST,
- antennaId,
- accountId,
-});
-
-export const removeFromAntennaSuccess = (antennaId, accountId) => ({
- type: ANTENNA_EDITOR_REMOVE_SUCCESS,
- antennaId,
- accountId,
-});
-
-export const removeFromAntennaFail = (antennaId, accountId, error) => ({
- type: ANTENNA_EDITOR_REMOVE_FAIL,
- antennaId,
- accountId,
- error,
-});
-
-export const removeDomainFromAntenna = (antennaId, domain) => (dispatch, getState) => {
- dispatch(removeDomainFromAntennaRequest(antennaId, domain));
-
- api(getState).delete(`/api/v1/antennas/${antennaId}/domains`, { params: { domains: [domain] } })
- .then(() => dispatch(removeDomainFromAntennaSuccess(antennaId, domain)))
- .catch(err => dispatch(removeDomainFromAntennaFail(antennaId, domain, err)));
-};
-
-export const removeDomainFromAntennaRequest = (antennaId, domain) => ({
- type: ANTENNA_EDITOR_REMOVE_DOMAIN_REQUEST,
- antennaId,
- domain,
-});
-
-export const removeDomainFromAntennaSuccess = (antennaId, domain) => ({
- type: ANTENNA_EDITOR_REMOVE_DOMAIN_SUCCESS,
- antennaId,
- domain,
-});
-
-export const removeDomainFromAntennaFail = (antennaId, domain, error) => ({
- type: ANTENNA_EDITOR_REMOVE_DOMAIN_FAIL,
- antennaId,
- domain,
- error,
-});
-
export const removeKeywordFromAntenna = (antennaId, keyword) => (dispatch, getState) => {
dispatch(removeKeywordFromAntennaRequest(antennaId, keyword));
@@ -505,6 +685,60 @@ export const removeKeywordFromAntennaFail = (antennaId, keyword, error) => ({
error,
});
+export const addExcludeKeywordToAntenna = (antennaId, keyword) => (dispatch, getState) => {
+ dispatch(addExcludeKeywordToAntennaRequest(antennaId, keyword));
+
+ api(getState).post(`/api/v1/antennas/${antennaId}/exclude_keywords`, { keywords: [keyword] })
+ .then(() => dispatch(addExcludeKeywordToAntennaSuccess(antennaId, keyword)))
+ .catch(err => dispatch(addExcludeKeywordToAntennaFail(antennaId, keyword, err)));
+};
+
+export const addExcludeKeywordToAntennaRequest = (antennaId, keyword) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_REQUEST,
+ antennaId,
+ keyword,
+});
+
+export const addExcludeKeywordToAntennaSuccess = (antennaId, keyword) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_SUCCESS,
+ antennaId,
+ keyword,
+});
+
+export const addExcludeKeywordToAntennaFail = (antennaId, keyword, error) => ({
+ type: ANTENNA_EDITOR_ADD_EXCLUDE_KEYWORD_FAIL,
+ antennaId,
+ keyword,
+ error,
+});
+
+export const removeExcludeKeywordFromAntenna = (antennaId, keyword) => (dispatch, getState) => {
+ dispatch(removeExcludeKeywordFromAntennaRequest(antennaId, keyword));
+
+ api(getState).delete(`/api/v1/antennas/${antennaId}/exclude_keywords`, { params: { keywords: [keyword] } })
+ .then(() => dispatch(removeExcludeKeywordFromAntennaSuccess(antennaId, keyword)))
+ .catch(err => dispatch(removeExcludeKeywordFromAntennaFail(antennaId, keyword, err)));
+};
+
+export const removeExcludeKeywordFromAntennaRequest = (antennaId, keyword) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_REQUEST,
+ antennaId,
+ keyword,
+});
+
+export const removeExcludeKeywordFromAntennaSuccess = (antennaId, keyword) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_SUCCESS,
+ antennaId,
+ keyword,
+});
+
+export const removeExcludeKeywordFromAntennaFail = (antennaId, keyword, error) => ({
+ type: ANTENNA_EDITOR_REMOVE_EXCLUDE_KEYWORD_FAIL,
+ antennaId,
+ keyword,
+ error,
+});
+
export const resetAntennaAdder = () => ({
type: ANTENNA_ADDER_RESET,
});
diff --git a/app/javascript/mastodon/features/antenna_editor/components/account.jsx b/app/javascript/mastodon/features/antenna_editor/components/account.jsx
index 94daad4523..94cb4ea6a5 100644
--- a/app/javascript/mastodon/features/antenna_editor/components/account.jsx
+++ b/app/javascript/mastodon/features/antenna_editor/components/account.jsx
@@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
-import { removeFromAntennaEditor, addToAntennaEditor } from '../../../actions/antennas';
+import { removeFromAntennaEditor, addToAntennaEditor, removeExcludeFromAntennaEditor, addExcludeToAntennaEditor } from '../../../actions/antennas';
import { Avatar } from '../../../components/avatar';
import { DisplayName } from '../../../components/display_name';
import { IconButton } from '../../../components/icon_button';
@@ -20,9 +20,9 @@ const messages = defineMessages({
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
- const mapStateToProps = (state, { accountId, added }) => ({
+ const mapStateToProps = (state, { accountId, added, isExclude }) => ({
account: getAccount(state, accountId),
- added: typeof added === 'undefined' ? state.getIn(['antennaEditor', 'accounts', 'items']).includes(accountId) : added,
+ added: typeof added === 'undefined' ? state.getIn(['antennaEditor', isExclude ? 'excludeAccounts' : 'accounts', 'items']).includes(accountId) : added,
});
return mapStateToProps;
@@ -31,15 +31,20 @@ const makeMapStateToProps = () => {
const mapDispatchToProps = (dispatch, { accountId }) => ({
onRemove: () => dispatch(removeFromAntennaEditor(accountId)),
onAdd: () => dispatch(addToAntennaEditor(accountId)),
+ onExcludeRemove: () => dispatch(removeExcludeFromAntennaEditor(accountId)),
+ onExcludeAdd: () => dispatch(addExcludeToAntennaEditor(accountId)),
});
class Account extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
+ isExclude: PropTypes.bool.isRequired,
intl: PropTypes.object.isRequired,
onRemove: PropTypes.func.isRequired,
onAdd: PropTypes.func.isRequired,
+ onExcludeRemove: PropTypes.func.isRequired,
+ onExcludeAdd: PropTypes.func.isRequired,
added: PropTypes.bool,
};
@@ -48,14 +53,15 @@ class Account extends ImmutablePureComponent {
};
render () {
- const { account, intl, onRemove, onAdd, added } = this.props;
+ const { account, intl, isExclude, onRemove, onAdd, onExcludeRemove, onExcludeAdd, added } = this.props;
+ console.dir(isExclude)
let button;
if (added) {
- button =