about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin/settings_controller.rb2
-rw-r--r--app/controllers/api/base_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/credentials_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/follower_accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/following_accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/lists_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/relationships_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/search_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts_controller.rb7
-rw-r--r--app/controllers/api/v1/blocks_controller.rb2
-rw-r--r--app/controllers/api/v1/domain_blocks_controller.rb3
-rw-r--r--app/controllers/api/v1/favourites_controller.rb2
-rw-r--r--app/controllers/api/v1/filters_controller.rb48
-rw-r--r--app/controllers/api/v1/follow_requests_controller.rb3
-rw-r--r--app/controllers/api/v1/follows_controller.rb2
-rw-r--r--app/controllers/api/v1/lists/accounts_controller.rb4
-rw-r--r--app/controllers/api/v1/lists_controller.rb4
-rw-r--r--app/controllers/api/v1/media_controller.rb2
-rw-r--r--app/controllers/api/v1/mutes_controller.rb2
-rw-r--r--app/controllers/api/v1/notifications_controller.rb3
-rw-r--r--app/controllers/api/v1/reports_controller.rb4
-rw-r--r--app/controllers/api/v1/search_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb7
-rw-r--r--app/controllers/api/v1/statuses/favourites_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/mutes_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/pins_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb7
-rw-r--r--app/controllers/api/v1/statuses/reblogs_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses_controller.rb9
-rw-r--r--app/controllers/api/v1/suggestions_controller.rb26
-rw-r--r--app/controllers/api/v1/timelines/direct_controller.rb2
-rw-r--r--app/controllers/api/v1/timelines/home_controller.rb2
-rw-r--r--app/controllers/api/v1/timelines/list_controller.rb2
-rw-r--r--app/controllers/auth/registrations_controller.rb10
-rw-r--r--app/controllers/concerns/signature_verification.rb4
-rw-r--r--app/controllers/filters_controller.rb62
-rw-r--r--app/controllers/remote_follow_controller.rb1
-rw-r--r--app/controllers/settings/keyword_mutes_controller.rb61
-rw-r--r--app/controllers/statuses_controller.rb5
-rw-r--r--app/helpers/application_helper.rb10
-rw-r--r--app/helpers/settings_helper.rb1
-rw-r--r--app/javascript/images/elephant-fren.pngbin40859 -> 34530 bytes
-rw-r--r--app/javascript/images/mailer/icon_cached.pngbin582 -> 423 bytes
-rw-r--r--app/javascript/images/mailer/icon_done.pngbin279 -> 253 bytes
-rw-r--r--app/javascript/images/mailer/icon_email.pngbin520 -> 387 bytes
-rw-r--r--app/javascript/images/mailer/icon_file_download.pngbin271 -> 225 bytes
-rw-r--r--app/javascript/images/mailer/icon_grade.pngbin541 -> 412 bytes
-rw-r--r--app/javascript/images/mailer/icon_lock_open.pngbin550 -> 387 bytes
-rw-r--r--app/javascript/images/mailer/icon_person_add.pngbin512 -> 376 bytes
-rw-r--r--app/javascript/images/mailer/icon_reply.pngbin391 -> 319 bytes
-rw-r--r--app/javascript/images/mailer/logo_full.pngbin3052 -> 2371 bytes
-rw-r--r--app/javascript/images/mailer/logo_transparent.pngbin627 -> 506 bytes
-rw-r--r--app/javascript/images/reticle.pngbin3053 -> 2199 bytes
-rw-r--r--app/javascript/images/void.pngbin174 -> 174 bytes
-rw-r--r--app/javascript/mastodon/actions/filters.js26
-rw-r--r--app/javascript/mastodon/actions/importer/index.js8
-rw-r--r--app/javascript/mastodon/actions/notifications.js17
-rw-r--r--app/javascript/mastodon/actions/streaming.js4
-rw-r--r--app/javascript/mastodon/components/account.js2
-rw-r--r--app/javascript/mastodon/components/media_gallery.js2
-rw-r--r--app/javascript/mastodon/components/status.js15
-rw-r--r--app/javascript/mastodon/components/status_list.js5
-rw-r--r--app/javascript/mastodon/containers/status_container.js2
-rw-r--r--app/javascript/mastodon/features/community_timeline/components/column_settings.js16
-rw-r--r--app/javascript/mastodon/features/compose/components/autosuggest_account.js2
-rw-r--r--app/javascript/mastodon/features/compose/containers/reply_indicator_container.js2
-rw-r--r--app/javascript/mastodon/features/direct_timeline/index.js5
-rw-r--r--app/javascript/mastodon/features/home_timeline/components/column_settings.js16
-rw-r--r--app/javascript/mastodon/features/notifications/components/notification.js1
-rw-r--r--app/javascript/mastodon/features/status/index.js5
-rw-r--r--app/javascript/mastodon/features/ui/components/media_modal.js20
-rw-r--r--app/javascript/mastodon/features/ui/components/tabs_bar.js2
-rw-r--r--app/javascript/mastodon/features/ui/containers/status_list_container.js14
-rw-r--r--app/javascript/mastodon/features/ui/index.js2
-rw-r--r--app/javascript/mastodon/locales/ar.json4
-rw-r--r--app/javascript/mastodon/locales/bg.json4
-rw-r--r--app/javascript/mastodon/locales/ca.json14
-rw-r--r--app/javascript/mastodon/locales/co.json4
-rw-r--r--app/javascript/mastodon/locales/da.json307
-rw-r--r--app/javascript/mastodon/locales/de.json4
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json53
-rw-r--r--app/javascript/mastodon/locales/el.json42
-rw-r--r--app/javascript/mastodon/locales/en.json6
-rw-r--r--app/javascript/mastodon/locales/eo.json4
-rw-r--r--app/javascript/mastodon/locales/es.json4
-rw-r--r--app/javascript/mastodon/locales/eu.json4
-rw-r--r--app/javascript/mastodon/locales/fa.json4
-rw-r--r--app/javascript/mastodon/locales/fi.json4
-rw-r--r--app/javascript/mastodon/locales/fr.json4
-rw-r--r--app/javascript/mastodon/locales/gl.json6
-rw-r--r--app/javascript/mastodon/locales/he.json4
-rw-r--r--app/javascript/mastodon/locales/hr.json4
-rw-r--r--app/javascript/mastodon/locales/hu.json4
-rw-r--r--app/javascript/mastodon/locales/hy.json4
-rw-r--r--app/javascript/mastodon/locales/id.json4
-rw-r--r--app/javascript/mastodon/locales/io.json4
-rw-r--r--app/javascript/mastodon/locales/it.json4
-rw-r--r--app/javascript/mastodon/locales/ja.json6
-rw-r--r--app/javascript/mastodon/locales/ko.json4
-rw-r--r--app/javascript/mastodon/locales/nl.json8
-rw-r--r--app/javascript/mastodon/locales/no.json4
-rw-r--r--app/javascript/mastodon/locales/oc.json20
-rw-r--r--app/javascript/mastodon/locales/pl.json14
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json14
-rw-r--r--app/javascript/mastodon/locales/pt.json4
-rw-r--r--app/javascript/mastodon/locales/ru.json4
-rw-r--r--app/javascript/mastodon/locales/sk.json38
-rw-r--r--app/javascript/mastodon/locales/sl.json4
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json4
-rw-r--r--app/javascript/mastodon/locales/sr.json4
-rw-r--r--app/javascript/mastodon/locales/sv.json38
-rw-r--r--app/javascript/mastodon/locales/te.json592
-rw-r--r--app/javascript/mastodon/locales/th.json4
-rw-r--r--app/javascript/mastodon/locales/tr.json4
-rw-r--r--app/javascript/mastodon/locales/uk.json4
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json4
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json22
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json240
-rw-r--r--app/javascript/mastodon/reducers/compose.js11
-rw-r--r--app/javascript/mastodon/reducers/filters.js11
-rw-r--r--app/javascript/mastodon/reducers/index.js2
-rw-r--r--app/javascript/mastodon/selectors/index.js47
-rw-r--r--app/javascript/mastodon/service_worker/entry.js16
-rw-r--r--app/javascript/mastodon/utils/__tests__/html-test.js10
-rw-r--r--app/javascript/mastodon/utils/html.js1
-rw-r--r--app/javascript/packs/public.js2
-rw-r--r--app/javascript/styles/application.scss1
-rw-r--r--app/javascript/styles/mastodon/about.scss21
-rw-r--r--app/javascript/styles/mastodon/accessibility.scss14
-rw-r--r--app/javascript/styles/mastodon/accounts.scss15
-rw-r--r--app/javascript/styles/mastodon/components.scss14
-rw-r--r--app/javascript/styles/mastodon/forms.scss20
-rw-r--r--app/javascript/styles/mastodon/modal.scss6
-rw-r--r--app/javascript/styles/mastodon/rtl.scss8
-rw-r--r--app/javascript/styles/mastodon/stream_entries.scss80
-rw-r--r--app/lib/feed_manager.rb54
-rw-r--r--app/lib/potential_friendship_tracker.rb39
-rw-r--r--app/lib/request.rb2
-rw-r--r--app/models/account.rb30
-rw-r--r--app/models/concerns/account_interactions.rb13
-rw-r--r--app/models/concerns/attachmentable.rb2
-rw-r--r--app/models/concerns/expireable.rb24
-rw-r--r--app/models/custom_filter.rb56
-rw-r--r--app/models/form/admin_settings.rb2
-rw-r--r--app/models/glitch.rb7
-rw-r--r--app/models/glitch/keyword_mute.rb123
-rw-r--r--app/models/glitch/keyword_mute_helper.rb27
-rw-r--r--app/models/invite.rb18
-rw-r--r--app/serializers/rest/filter_serializer.rb6
-rw-r--r--app/services/favourite_service.rb8
-rw-r--r--app/services/post_status_service.rb7
-rw-r--r--app/services/reblog_service.rb7
-rw-r--r--app/services/remove_status_service.rb4
-rw-r--r--app/validators/email_mx_validator.rb2
-rw-r--r--app/views/admin/settings/edit.html.haml6
-rw-r--r--app/views/filters/_fields.html.haml14
-rw-r--r--app/views/filters/edit.html.haml8
-rw-r--r--app/views/filters/index.html.haml20
-rw-r--r--app/views/filters/new.html.haml8
-rw-r--r--app/views/remote_follow/new.html.haml6
-rw-r--r--app/views/settings/applications/_fields.html.haml17
-rw-r--r--app/views/shared/_landing_strip.html.haml4
-rw-r--r--app/views/stream_entries/_detailed_status.html.haml6
-rw-r--r--app/views/stream_entries/_og_image.html.haml2
-rw-r--r--app/views/stream_entries/_simple_status.html.haml2
166 files changed, 1670 insertions, 1158 deletions
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index ce3208209..75d00326c 100644
--- a/app/controllers/admin/settings_controller.rb
+++ b/app/controllers/admin/settings_controller.rb
@@ -21,6 +21,7 @@ module Admin
       activity_api_enabled
       peers_api_enabled
       show_known_fediverse_at_about_page
+      preview_sensitive_media
     ).freeze
 
     BOOLEAN_SETTINGS = %w(
@@ -31,6 +32,7 @@ module Admin
       activity_api_enabled
       peers_api_enabled
       show_known_fediverse_at_about_page
+      preview_sensitive_media
     ).freeze
 
     UPLOAD_SETTINGS = %w(
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index b5c084e14..770a69921 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -78,4 +78,8 @@ class Api::BaseController < ApplicationController
   def render_empty
     render json: {}, status: 200
   end
+
+  def authorize_if_got_token!(*scopes)
+    doorkeeper_authorize!(*scopes) if doorkeeper_token
+  end
 end
diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb
index 2d0737ee4..dcd41b35c 100644
--- a/app/controllers/api/v1/accounts/credentials_controller.rb
+++ b/app/controllers/api/v1/accounts/credentials_controller.rb
@@ -1,8 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::CredentialsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }, except: [:update]
-  before_action -> { doorkeeper_authorize! :write }, only: [:update]
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update]
+  before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
   before_action :require_user!
 
   def show
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index 4578cf6ca..daa35769e 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
   before_action :set_account
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index ce2bbda85..6be97b87e 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
   before_action :set_account
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/accounts/lists_controller.rb b/app/controllers/api/v1/accounts/lists_controller.rb
index a7ba89ce2..72392453c 100644
--- a/app/controllers/api/v1/accounts/lists_controller.rb
+++ b/app/controllers/api/v1/accounts/lists_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::ListsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:lists' }
   before_action :require_user!
   before_action :set_account
 
diff --git a/app/controllers/api/v1/accounts/relationships_controller.rb b/app/controllers/api/v1/accounts/relationships_controller.rb
index 70236d1a8..ab8a0461f 100644
--- a/app/controllers/api/v1/accounts/relationships_controller.rb
+++ b/app/controllers/api/v1/accounts/relationships_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::RelationshipsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:follows' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb
index 7649da433..91c9f1547 100644
--- a/app/controllers/api/v1/accounts/search_controller.rb
+++ b/app/controllers/api/v1/accounts/search_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::SearchController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index c40155cb5..06fa6c762 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Accounts::StatusesController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
   before_action :set_account
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index b7133ca8e..1d5372a8c 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -1,8 +1,11 @@
 # frozen_string_literal: true
 
 class Api::V1::AccountsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
-  before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
+  before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
+  before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow]
+  before_action -> { doorkeeper_authorize! :follow, :'write:mutes' }, only: [:mute, :unmute]
+  before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, only: [:block, :unblock]
+
   before_action :require_user!, except: [:show]
   before_action :set_account
   before_action :check_account_suspension, only: [:show]
diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb
index a39701340..99c53d59a 100644
--- a/app/controllers/api/v1/blocks_controller.rb
+++ b/app/controllers/api/v1/blocks_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::BlocksController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :follow }
+  before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }
   before_action :require_user!
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb
index e55d622c3..af9e7a20f 100644
--- a/app/controllers/api/v1/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/domain_blocks_controller.rb
@@ -3,7 +3,8 @@
 class Api::V1::DomainBlocksController < Api::BaseController
   BLOCK_LIMIT = 100
 
-  before_action -> { doorkeeper_authorize! :follow }
+  before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }, only: :show
+  before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, except: :show
   before_action :require_user!
   after_action :insert_pagination_headers, only: :show
 
diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb
index b4265ed34..ab5204355 100644
--- a/app/controllers/api/v1/favourites_controller.rb
+++ b/app/controllers/api/v1/favourites_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::FavouritesController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:favourites' }
   before_action :require_user!
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/filters_controller.rb b/app/controllers/api/v1/filters_controller.rb
new file mode 100644
index 000000000..e5ebaff4d
--- /dev/null
+++ b/app/controllers/api/v1/filters_controller.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+class Api::V1::FiltersController < Api::BaseController
+  before_action -> { doorkeeper_authorize! :read, :'read:filters' }, only: [:index, :show]
+  before_action -> { doorkeeper_authorize! :write, :'write:filters' }, except: [:index, :show]
+  before_action :require_user!
+  before_action :set_filters, only: :index
+  before_action :set_filter, only: [:show, :update, :destroy]
+
+  respond_to :json
+
+  def index
+    render json: @filters, each_serializer: REST::FilterSerializer
+  end
+
+  def create
+    @filter = current_account.custom_filters.create!(resource_params)
+    render json: @filter, serializer: REST::FilterSerializer
+  end
+
+  def show
+    render json: @filter, serializer: REST::FilterSerializer
+  end
+
+  def update
+    @filter.update!(resource_params)
+    render json: @filter, serializer: REST::FilterSerializer
+  end
+
+  def destroy
+    @filter.destroy!
+    render_empty
+  end
+
+  private
+
+  def set_filters
+    @filters = current_account.custom_filters
+  end
+
+  def set_filter
+    @filter = current_account.custom_filters.find(params[:id])
+  end
+
+  def resource_params
+    params.permit(:phrase, :expires_in, :irreversible, :whole_word, context: [])
+  end
+end
diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb
index d5c7c565a..313fe2f81 100644
--- a/app/controllers/api/v1/follow_requests_controller.rb
+++ b/app/controllers/api/v1/follow_requests_controller.rb
@@ -1,7 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::FollowRequestsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :follow }
+  before_action -> { doorkeeper_authorize! :follow, :'read:follows' }, only: :index
+  before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, except: :index
   before_action :require_user!
   after_action :insert_pagination_headers, only: :index
 
diff --git a/app/controllers/api/v1/follows_controller.rb b/app/controllers/api/v1/follows_controller.rb
index 5a2b2f32f..5420c0533 100644
--- a/app/controllers/api/v1/follows_controller.rb
+++ b/app/controllers/api/v1/follows_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::FollowsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :follow }
+  before_action -> { doorkeeper_authorize! :follow, :'write:follows' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/lists/accounts_controller.rb b/app/controllers/api/v1/lists/accounts_controller.rb
index f2bded851..19de56732 100644
--- a/app/controllers/api/v1/lists/accounts_controller.rb
+++ b/app/controllers/api/v1/lists/accounts_controller.rb
@@ -1,8 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::Lists::AccountsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read },    only: [:show]
-  before_action -> { doorkeeper_authorize! :write }, except: [:show]
+  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_list
diff --git a/app/controllers/api/v1/lists_controller.rb b/app/controllers/api/v1/lists_controller.rb
index 180a91d81..b42b8b971 100644
--- a/app/controllers/api/v1/lists_controller.rb
+++ b/app/controllers/api/v1/lists_controller.rb
@@ -1,8 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::ListsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read },    only: [:index, :show]
-  before_action -> { doorkeeper_authorize! :write }, except: [:index, :show]
+  before_action -> { doorkeeper_authorize! :read, :'read:lists' },    only:  [:index, :show]
+  before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show]
 
   before_action :require_user!
   before_action :set_list, except: [:index, :create]
diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb
index d4e6337e7..aaa93b615 100644
--- a/app/controllers/api/v1/media_controller.rb
+++ b/app/controllers/api/v1/media_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::MediaController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :write }
+  before_action -> { doorkeeper_authorize! :write, :'write:media' }
   before_action :require_user!
 
   include ObfuscateFilename
diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb
index ddbf13caa..aea94d553 100644
--- a/app/controllers/api/v1/mutes_controller.rb
+++ b/app/controllers/api/v1/mutes_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::MutesController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :follow }
+  before_action -> { doorkeeper_authorize! :follow, :'read:mutes' }
   before_action :require_user!
   after_action :insert_pagination_headers
 
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index e58dda77f..a8ed5a63b 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -1,7 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::NotificationsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, except: [:clear, :dismiss]
+  before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: [:clear, :dismiss]
   before_action :require_user!
   after_action :insert_pagination_headers, only: :index
 
diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb
index f5095e073..a954101cb 100644
--- a/app/controllers/api/v1/reports_controller.rb
+++ b/app/controllers/api/v1/reports_controller.rb
@@ -1,8 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::ReportsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }, except: [:create]
-  before_action -> { doorkeeper_authorize! :write }, only:  [:create]
+  before_action -> { doorkeeper_authorize! :read, :'read:reports' }, except: [:create]
+  before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb
index 99b635ad9..895b22b7e 100644
--- a/app/controllers/api/v1/search_controller.rb
+++ b/app/controllers/api/v1/search_controller.rb
@@ -5,7 +5,7 @@ class Api::V1::SearchController < Api::BaseController
 
   RESULTS_LIMIT = 10
 
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:search' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
index 3fe304153..8f4070bc7 100644
--- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
   include Authorization
 
-  before_action :authorize_if_got_token
+  before_action -> { authorize_if_got_token! :read, :'read:accounts' }
   before_action :set_status
   after_action :insert_pagination_headers
 
@@ -71,11 +71,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
     raise ActiveRecord::RecordNotFound
   end
 
-  def authorize_if_got_token
-    request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
-    doorkeeper_authorize! :read if request_token
-  end
-
   def pagination_params(core_params)
     params.slice(:limit).permit(:limit).merge(core_params)
   end
diff --git a/app/controllers/api/v1/statuses/favourites_controller.rb b/app/controllers/api/v1/statuses/favourites_controller.rb
index 35f8a48cd..cceee9060 100644
--- a/app/controllers/api/v1/statuses/favourites_controller.rb
+++ b/app/controllers/api/v1/statuses/favourites_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::FavouritesController < Api::BaseController
   include Authorization
 
-  before_action -> { doorkeeper_authorize! :write }
+  before_action -> { doorkeeper_authorize! :write, :'write:favourites' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/statuses/mutes_controller.rb b/app/controllers/api/v1/statuses/mutes_controller.rb
index a4bf0acdd..b02469b4f 100644
--- a/app/controllers/api/v1/statuses/mutes_controller.rb
+++ b/app/controllers/api/v1/statuses/mutes_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::MutesController < Api::BaseController
   include Authorization
 
-  before_action -> { doorkeeper_authorize! :write }
+  before_action -> { doorkeeper_authorize! :write, :'write:mutes' }
   before_action :require_user!
   before_action :set_status
   before_action :set_conversation
diff --git a/app/controllers/api/v1/statuses/pins_controller.rb b/app/controllers/api/v1/statuses/pins_controller.rb
index 54f8be667..4118a8ce4 100644
--- a/app/controllers/api/v1/statuses/pins_controller.rb
+++ b/app/controllers/api/v1/statuses/pins_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::PinsController < Api::BaseController
   include Authorization
 
-  before_action -> { doorkeeper_authorize! :write }
+  before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
   before_action :require_user!
   before_action :set_status
 
diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
index b065db2c7..93b83ce48 100644
--- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
   include Authorization
 
-  before_action :authorize_if_got_token
+  before_action -> { authorize_if_got_token! :read, :'read:accounts' }
   before_action :set_status
   after_action :insert_pagination_headers
 
@@ -68,11 +68,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
     raise ActiveRecord::RecordNotFound
   end
 
-  def authorize_if_got_token
-    request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
-    doorkeeper_authorize! :read if request_token
-  end
-
   def pagination_params(core_params)
     params.slice(:limit).permit(:limit).merge(core_params)
   end
diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb
index 634af474f..04847a6b7 100644
--- a/app/controllers/api/v1/statuses/reblogs_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogs_controller.rb
@@ -3,7 +3,7 @@
 class Api::V1::Statuses::ReblogsController < Api::BaseController
   include Authorization
 
-  before_action -> { doorkeeper_authorize! :write }
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
   before_action :require_user!
 
   respond_to :json
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 289d91045..c6925d462 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -3,8 +3,8 @@
 class Api::V1::StatusesController < Api::BaseController
   include Authorization
 
-  before_action :authorize_if_got_token, except:            [:create, :destroy]
-  before_action -> { doorkeeper_authorize! :write }, only:  [:create, :destroy]
+  before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :destroy]
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only:   [:create, :destroy]
   before_action :require_user!, except:  [:show, :context, :card]
   before_action :set_status, only:       [:show, :context, :card]
 
@@ -84,9 +84,4 @@ class Api::V1::StatusesController < Api::BaseController
   def pagination_params(core_params)
     params.slice(:limit).permit(:limit).merge(core_params)
   end
-
-  def authorize_if_got_token
-    request_token = Doorkeeper::OAuth::Token.from_request(request, *Doorkeeper.configuration.access_token_methods)
-    doorkeeper_authorize! :read if request_token
-  end
 end
diff --git a/app/controllers/api/v1/suggestions_controller.rb b/app/controllers/api/v1/suggestions_controller.rb
new file mode 100644
index 000000000..9da2b60ae
--- /dev/null
+++ b/app/controllers/api/v1/suggestions_controller.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Api::V1::SuggestionsController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :read }
+  before_action :require_user!
+  before_action :set_accounts
+
+  respond_to :json
+
+  def index
+    render json: @accounts, each_serializer: REST::AccountSerializer
+  end
+
+  def destroy
+    PotentialFriendshipTracker.remove(current_account.id, params[:id])
+    render_empty
+  end
+
+  private
+
+  def set_accounts
+    @accounts = PotentialFriendshipTracker.get(current_account.id, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
+  end
+end
diff --git a/app/controllers/api/v1/timelines/direct_controller.rb b/app/controllers/api/v1/timelines/direct_controller.rb
index ef64078be..d8a76d153 100644
--- a/app/controllers/api/v1/timelines/direct_controller.rb
+++ b/app/controllers/api/v1/timelines/direct_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Timelines::DirectController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }, only: [:show]
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
   before_action :require_user!, only: [:show]
   after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
 
diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb
index cde4e8420..4412aaaa3 100644
--- a/app/controllers/api/v1/timelines/home_controller.rb
+++ b/app/controllers/api/v1/timelines/home_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Timelines::HomeController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }, only: [:show]
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
   before_action :require_user!, only: [:show]
   after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
 
diff --git a/app/controllers/api/v1/timelines/list_controller.rb b/app/controllers/api/v1/timelines/list_controller.rb
index 06d596c08..cfc5f3b5e 100644
--- a/app/controllers/api/v1/timelines/list_controller.rb
+++ b/app/controllers/api/v1/timelines/list_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class Api::V1::Timelines::ListController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :read }
+  before_action -> { doorkeeper_authorize! :read, :'read:lists' }
   before_action :require_user!
   before_action :set_list
   before_action :set_statuses
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index c5f43d583..8df8af4c7 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -40,6 +40,16 @@ class Auth::RegistrationsController < Devise::RegistrationsController
     new_user_session_path
   end
 
+  def after_sign_in_path_for(_resource)
+    set_invite
+
+    if @invite&.autofollow?
+      short_account_path(@invite.user.account)
+    else
+      super
+    end
+  end
+
   def after_inactive_sign_up_path_for(_resource)
     new_user_session_path
   end
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 41aa1c8a6..4d77fa432 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -58,11 +58,11 @@ module SignatureVerification
         @signed_request_account = account
         @signed_request_account
       else
-        @signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+        @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
         @signed_request_account = nil
       end
     else
-      @signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+      @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
       @signed_request_account = nil
     end
   end
diff --git a/app/controllers/filters_controller.rb b/app/controllers/filters_controller.rb
new file mode 100644
index 000000000..8f7f1bced
--- /dev/null
+++ b/app/controllers/filters_controller.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+class FiltersController < ApplicationController
+  include Authorization
+
+  layout 'admin'
+
+  before_action :set_filters, only: :index
+  before_action :set_filter, only: [:edit, :update, :destroy]
+  before_action :set_pack
+
+  def index
+    @filters = current_account.custom_filters
+  end
+
+  def new
+    @filter = current_account.custom_filters.build
+  end
+
+  def create
+    @filter = current_account.custom_filters.build(resource_params)
+
+    if @filter.save
+      redirect_to filters_path
+    else
+      render action: :new
+    end
+  end
+
+  def edit; end
+
+  def update
+    if @filter.update(resource_params)
+      redirect_to filters_path
+    else
+      render action: :edit
+    end
+  end
+
+  def destroy
+    @filter.destroy
+    redirect_to filters_path
+  end
+
+  private
+
+  def set_pack
+    use_pack 'settings'
+  end
+
+  def set_filters
+    @filters = current_account.custom_filters
+  end
+
+  def set_filter
+    @filter = current_account.custom_filters.find(params[:id])
+  end
+
+  def resource_params
+    params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, context: [])
+  end
+end
diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb
index 41c021781..128e80a67 100644
--- a/app/controllers/remote_follow_controller.rb
+++ b/app/controllers/remote_follow_controller.rb
@@ -6,6 +6,7 @@ class RemoteFollowController < ApplicationController
   before_action :set_account
   before_action :set_pack
   before_action :gone, if: :suspended_account?
+  before_action :set_body_classes
 
   def new
     @remote_follow = RemoteFollow.new(session_params)
diff --git a/app/controllers/settings/keyword_mutes_controller.rb b/app/controllers/settings/keyword_mutes_controller.rb
deleted file mode 100644
index cf364a903..000000000
--- a/app/controllers/settings/keyword_mutes_controller.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-class Settings::KeywordMutesController < Settings::BaseController
-  before_action :load_keyword_mute, only: [:edit, :update, :destroy]
-
-  def index
-    @keyword_mutes = paginated_keyword_mutes_for_account
-  end
-
-  def new
-    @keyword_mute = keyword_mutes_for_account.build
-  end
-
-  def create
-    @keyword_mute = keyword_mutes_for_account.create(keyword_mute_params)
-
-    if @keyword_mute.persisted?
-      redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
-    else
-      render :new
-    end
-  end
-
-  def update
-    if @keyword_mute.update(keyword_mute_params)
-      redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
-    else
-      render :edit
-    end
-  end
-
-  def destroy
-    @keyword_mute.destroy!
-
-    redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
-  end
-
-  def destroy_all
-    keyword_mutes_for_account.delete_all
-
-    redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
-  end
-
-  private
-
-  def keyword_mutes_for_account
-    Glitch::KeywordMute.where(account: current_account)
-  end
-
-  def load_keyword_mute
-    @keyword_mute = keyword_mutes_for_account.find(params[:id])
-  end
-
-  def keyword_mute_params
-    params.require(:keyword_mute).permit(:keyword, :whole_word, :apply_to_mentions)
-  end
-
-  def paginated_keyword_mutes_for_account
-    keyword_mutes_for_account.order(:keyword).page params[:page]
-  end
-end
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index 2e9cf14e0..f4ac1d03b 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -48,7 +48,12 @@ class StatusesController < ApplicationController
 
   def embed
     use_pack 'embed'
+    raise ActiveRecord::RecordNotFound if @status.hidden?
+
+    skip_session!
+    expires_in 180, public: true
     response.headers['X-Frame-Options'] = 'ALLOWALL'
+
     render 'stream_entries/embed', layout: 'embedded'
   end
 
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 95863ab1f..327901e4e 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,6 +1,12 @@
 # frozen_string_literal: true
 
 module ApplicationHelper
+  DANGEROUS_SCOPES = %w(
+    read
+    write
+    follow
+  ).freeze
+
   def active_nav_class(path)
     current_page?(path) ? 'active' : ''
   end
@@ -43,6 +49,10 @@ module ApplicationHelper
     Rails.env.production? ? site_title : "#{site_title} (Dev)"
   end
 
+  def class_for_scope(scope)
+    'scope-danger' if DANGEROUS_SCOPES.include?(scope.to_s)
+  end
+
   def can?(action, record)
     return false if record.nil?
     policy(record).public_send("#{action}?")
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
index ba728eb32..740f7bf77 100644
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -7,6 +7,7 @@ module SettingsHelper
     bg: 'Български',
     ca: 'Català',
     co: 'Corsu',
+    da: 'Dansk',
     de: 'Deutsch',
     el: 'Ελληνικά',
     eo: 'Esperanto',
diff --git a/app/javascript/images/elephant-fren.png b/app/javascript/images/elephant-fren.png
index 3b64edf08..38b1e3cba 100644
--- a/app/javascript/images/elephant-fren.png
+++ b/app/javascript/images/elephant-fren.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_cached.png b/app/javascript/images/mailer/icon_cached.png
index 210833d34..5c993dbee 100644
--- a/app/javascript/images/mailer/icon_cached.png
+++ b/app/javascript/images/mailer/icon_cached.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_done.png b/app/javascript/images/mailer/icon_done.png
index 0d2ef0cb8..f7f95a0e8 100644
--- a/app/javascript/images/mailer/icon_done.png
+++ b/app/javascript/images/mailer/icon_done.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_email.png b/app/javascript/images/mailer/icon_email.png
index aae9d2bb9..13967009a 100644
--- a/app/javascript/images/mailer/icon_email.png
+++ b/app/javascript/images/mailer/icon_email.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_file_download.png b/app/javascript/images/mailer/icon_file_download.png
index 8a6a8673b..3f7ac429b 100644
--- a/app/javascript/images/mailer/icon_file_download.png
+++ b/app/javascript/images/mailer/icon_file_download.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_grade.png b/app/javascript/images/mailer/icon_grade.png
index 895b57d0a..8c212b7ee 100644
--- a/app/javascript/images/mailer/icon_grade.png
+++ b/app/javascript/images/mailer/icon_grade.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_lock_open.png b/app/javascript/images/mailer/icon_lock_open.png
index 9f62eadc2..c854c3bdb 100644
--- a/app/javascript/images/mailer/icon_lock_open.png
+++ b/app/javascript/images/mailer/icon_lock_open.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_person_add.png b/app/javascript/images/mailer/icon_person_add.png
index 3453060ae..6290a42ae 100644
--- a/app/javascript/images/mailer/icon_person_add.png
+++ b/app/javascript/images/mailer/icon_person_add.png
Binary files differdiff --git a/app/javascript/images/mailer/icon_reply.png b/app/javascript/images/mailer/icon_reply.png
index 8bce4955c..a70093356 100644
--- a/app/javascript/images/mailer/icon_reply.png
+++ b/app/javascript/images/mailer/icon_reply.png
Binary files differdiff --git a/app/javascript/images/mailer/logo_full.png b/app/javascript/images/mailer/logo_full.png
index 1c4f33287..82d981fc6 100644
--- a/app/javascript/images/mailer/logo_full.png
+++ b/app/javascript/images/mailer/logo_full.png
Binary files differdiff --git a/app/javascript/images/mailer/logo_transparent.png b/app/javascript/images/mailer/logo_transparent.png
index 8fda4f67f..6dbcc2e8d 100644
--- a/app/javascript/images/mailer/logo_transparent.png
+++ b/app/javascript/images/mailer/logo_transparent.png
Binary files differdiff --git a/app/javascript/images/reticle.png b/app/javascript/images/reticle.png
index 998994f5c..41a5d1c3a 100644
--- a/app/javascript/images/reticle.png
+++ b/app/javascript/images/reticle.png
Binary files differdiff --git a/app/javascript/images/void.png b/app/javascript/images/void.png
index 10b274f18..d73066688 100644
--- a/app/javascript/images/void.png
+++ b/app/javascript/images/void.png
Binary files differdiff --git a/app/javascript/mastodon/actions/filters.js b/app/javascript/mastodon/actions/filters.js
new file mode 100644
index 000000000..7fa1c9a70
--- /dev/null
+++ b/app/javascript/mastodon/actions/filters.js
@@ -0,0 +1,26 @@
+import api from '../api';
+
+export const FILTERS_FETCH_REQUEST = 'FILTERS_FETCH_REQUEST';
+export const FILTERS_FETCH_SUCCESS = 'FILTERS_FETCH_SUCCESS';
+export const FILTERS_FETCH_FAIL    = 'FILTERS_FETCH_FAIL';
+
+export const fetchFilters = () => (dispatch, getState) => {
+  dispatch({
+    type: FILTERS_FETCH_REQUEST,
+    skipLoading: true,
+  });
+
+  api(getState)
+    .get('/api/v1/filters')
+    .then(({ data }) => dispatch({
+      type: FILTERS_FETCH_SUCCESS,
+      filters: data,
+      skipLoading: true,
+    }))
+    .catch(err => dispatch({
+      type: FILTERS_FETCH_FAIL,
+      err,
+      skipLoading: true,
+      skipAlert: true,
+    }));
+};
diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js
index 5b18cbc1d..931711f4b 100644
--- a/app/javascript/mastodon/actions/importer/index.js
+++ b/app/javascript/mastodon/actions/importer/index.js
@@ -1,5 +1,5 @@
-import { autoPlayGif } from '../../initial_state';
-import { putAccounts, putStatuses } from '../../storage/modifier';
+// import { autoPlayGif } from '../../initial_state';
+// import { putAccounts, putStatuses } from '../../storage/modifier';
 import { normalizeAccount, normalizeStatus } from './normalizer';
 
 export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
@@ -45,7 +45,7 @@ export function importFetchedAccounts(accounts) {
   }
 
   accounts.forEach(processAccount);
-  putAccounts(normalAccounts, !autoPlayGif);
+  //putAccounts(normalAccounts, !autoPlayGif);
 
   return importAccounts(normalAccounts);
 }
@@ -69,7 +69,7 @@ export function importFetchedStatuses(statuses) {
     }
 
     statuses.forEach(processStatus);
-    putStatuses(normalStatuses);
+    //putStatuses(normalStatuses);
 
     dispatch(importFetchedAccounts(accounts));
     dispatch(importStatuses(normalStatuses));
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index 3f95f6667..ad6430b82 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -9,6 +9,7 @@ import {
 } from './importer';
 import { defineMessages } from 'react-intl';
 import { unescapeHTML } from '../utils/html';
+import { getFilters, regexFromFilters } from '../selectors';
 
 export const NOTIFICATIONS_UPDATE      = 'NOTIFICATIONS_UPDATE';
 export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP';
@@ -38,6 +39,16 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
     const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true);
     const showAlert    = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
     const playSound    = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
+    const filters      = getFilters(getState(), { contextType: 'notifications' });
+
+    let filtered = false;
+
+    if (notification.type === 'mention') {
+      const regex       = regexFromFilters(filters);
+      const searchIndex = notification.status.spoiler_text + '\n' + unescapeHTML(notification.status.content);
+
+      filtered = regex && regex.test(searchIndex);
+    }
 
     if (showInColumn) {
       dispatch(importFetchedAccount(notification.account));
@@ -49,11 +60,11 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
       dispatch({
         type: NOTIFICATIONS_UPDATE,
         notification,
-        meta: playSound ? { sound: 'boop' } : undefined,
+        meta: (playSound && !filtered) ? { sound: 'boop' } : undefined,
       });
 
       fetchRelatedRelationships(dispatch, [notification]);
-    } else if (playSound) {
+    } else if (playSound && !filtered) {
       dispatch({
         type: NOTIFICATIONS_UPDATE_NOOP,
         meta: { sound: 'boop' },
@@ -61,7 +72,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
     }
 
     // Desktop notifications
-    if (typeof window.Notification !== 'undefined' && showAlert) {
+    if (typeof window.Notification !== 'undefined' && showAlert && !filtered) {
       const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
       const body  = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
 
diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js
index f56853bff..32fc67e67 100644
--- a/app/javascript/mastodon/actions/streaming.js
+++ b/app/javascript/mastodon/actions/streaming.js
@@ -6,6 +6,7 @@ import {
   disconnectTimeline,
 } from './timelines';
 import { updateNotifications, expandNotifications } from './notifications';
+import { fetchFilters } from './filters';
 import { getLocale } from '../locales';
 
 const { messages } = getLocale();
@@ -30,6 +31,9 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
         case 'notification':
           dispatch(updateNotifications(JSON.parse(data.payload), messages, locale));
           break;
+        case 'filters_changed':
+          dispatch(fetchFilters());
+          break;
         }
       },
     };
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js
index a3642e61d..8e6aa9d92 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.js
@@ -101,7 +101,7 @@ export default class Account extends ImmutablePureComponent {
     return (
       <div className='account'>
         <div className='account__wrapper'>
-          <Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
+          <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/accounts/${account.get('id')}`}>
             <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
             <DisplayName account={account} />
           </Permalink>
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index 7c4444e0e..1d351279f 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -122,7 +122,7 @@ class Item extends React.PureComponent {
       const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number';
 
       const srcSet = hasSize ? `${originalUrl} ${originalWidth}w, ${previewUrl} ${previewWidth}w` : null;
-      const sizes  = hasSize ? `${displayWidth * (width / 100)}px` : null;
+      const sizes  = hasSize && (displayWidth > 0) ? `${displayWidth * (width / 100)}px` : null;
 
       const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
       const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index fd08ff3b7..922b609ec 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -157,6 +157,21 @@ export default class Status extends ImmutablePureComponent {
       );
     }
 
+    if (status.get('filtered') || status.getIn(['reblog', 'filtered'])) {
+      const minHandlers = this.props.muted ? {} : {
+        moveUp: this.handleHotkeyMoveUp,
+        moveDown: this.handleHotkeyMoveDown,
+      };
+
+      return (
+        <HotKeys handlers={minHandlers}>
+          <div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0'>
+            <FormattedMessage id='status.filtered' defaultMessage='Filtered' />
+          </div>
+        </HotKeys>
+      );
+    }
+
     if (featured) {
       prepend = (
         <div className='status__prepend'>
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index 1c34d0640..68c9eef54 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -25,6 +25,7 @@ export default class StatusList extends ImmutablePureComponent {
     prepend: PropTypes.node,
     emptyMessage: PropTypes.node,
     alwaysPrepend: PropTypes.bool,
+    timelineId: PropTypes.string.isRequired,
   };
 
   static defaultProps = {
@@ -70,7 +71,7 @@ export default class StatusList extends ImmutablePureComponent {
   }
 
   render () {
-    const { statusIds, featuredStatusIds, onLoadMore, ...other }  = this.props;
+    const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other }  = this.props;
     const { isLoading, isPartial } = other;
 
     if (isPartial) {
@@ -102,6 +103,7 @@ export default class StatusList extends ImmutablePureComponent {
           id={statusId}
           onMoveUp={this.handleMoveUp}
           onMoveDown={this.handleMoveDown}
+          contextType={timelineId}
         />
       ))
     ) : null;
@@ -114,6 +116,7 @@ export default class StatusList extends ImmutablePureComponent {
           featured
           onMoveUp={this.handleMoveUp}
           onMoveDown={this.handleMoveDown}
+          contextType={timelineId}
         />
       )).concat(scrollableContent);
     }
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index 3e7b5215b..eb6329fdc 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -42,7 +42,7 @@ const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
 
   const mapStateToProps = (state, props) => ({
-    status: getStatus(state, props.id),
+    status: getStatus(state, props),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
index 3a1d19aa8..f4325f58d 100644
--- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
@@ -1,15 +1,9 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import SettingText from '../../../components/setting_text';
+import { injectIntl, FormattedMessage } from 'react-intl';
 import SettingToggle from '../../notifications/components/setting_toggle';
 
-const messages = defineMessages({
-  filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
-  settings: { id: 'home.settings', defaultMessage: 'Column settings' },
-});
-
 @injectIntl
 export default class ColumnSettings extends React.PureComponent {
 
@@ -21,19 +15,13 @@ export default class ColumnSettings extends React.PureComponent {
   };
 
   render () {
-    const { settings, onChange, intl } = this.props;
+    const { settings, onChange } = this.props;
 
     return (
       <div>
         <div className='column-settings__row'>
           <SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media Only' />} />
         </div>
-
-        <span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
-
-        <div className='column-settings__row'>
-          <SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
-        </div>
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/compose/components/autosuggest_account.js b/app/javascript/mastodon/features/compose/components/autosuggest_account.js
index e7de3716b..1451be0e6 100644
--- a/app/javascript/mastodon/features/compose/components/autosuggest_account.js
+++ b/app/javascript/mastodon/features/compose/components/autosuggest_account.js
@@ -14,7 +14,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent {
     const { account } = this.props;
 
     return (
-      <div className='autosuggest-account'>
+      <div className='autosuggest-account' title={account.get('acct')}>
         <div className='autosuggest-account-icon'><Avatar account={account} size={18} /></div>
         <DisplayName account={account} />
       </div>
diff --git a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
index 73f394c1a..5eb1eb72a 100644
--- a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
+++ b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
@@ -7,7 +7,7 @@ const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
 
   const mapStateToProps = state => ({
-    status: getStatus(state, state.getIn(['compose', 'in_reply_to'])),
+    status: getStatus(state, { id: state.getIn(['compose', 'in_reply_to']) }),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/mastodon/features/direct_timeline/index.js b/app/javascript/mastodon/features/direct_timeline/index.js
index fda57f69a..63dc41d9e 100644
--- a/app/javascript/mastodon/features/direct_timeline/index.js
+++ b/app/javascript/mastodon/features/direct_timeline/index.js
@@ -7,7 +7,6 @@ import ColumnHeader from '../../components/column_header';
 import { expandDirectTimeline } from '../../actions/timelines';
 import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import ColumnSettingsContainer from './containers/column_settings_container';
 import { connectDirectStream } from '../../actions/streaming';
 
 const messages = defineMessages({
@@ -86,9 +85,7 @@ export default class DirectTimeline extends React.PureComponent {
           onClick={this.handleHeaderClick}
           pinned={pinned}
           multiColumn={multiColumn}
-        >
-          <ColumnSettingsContainer />
-        </ColumnHeader>
+        />
 
         <StatusListContainer
           trackScroll={!pinned}
diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
index 0c0c4fa36..932ac2049 100644
--- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
@@ -1,14 +1,8 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import { injectIntl, FormattedMessage } from 'react-intl';
 import SettingToggle from '../../notifications/components/setting_toggle';
-import SettingText from '../../../components/setting_text';
-
-const messages = defineMessages({
-  filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' },
-  settings: { id: 'home.settings', defaultMessage: 'Column settings' },
-});
 
 @injectIntl
 export default class ColumnSettings extends React.PureComponent {
@@ -20,7 +14,7 @@ export default class ColumnSettings extends React.PureComponent {
   };
 
   render () {
-    const { settings, onChange, intl } = this.props;
+    const { settings, onChange } = this.props;
 
     return (
       <div>
@@ -33,12 +27,6 @@ export default class ColumnSettings extends React.PureComponent {
         <div className='column-settings__row'>
           <SettingToggle prefix='home_timeline' settings={settings} settingPath={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
         </div>
-
-        <span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
-
-        <div className='column-settings__row'>
-          <SettingText prefix='home_timeline' settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
-        </div>
       </div>
     );
   }
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js
index 6db62b330..f58224a8b 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.js
@@ -91,6 +91,7 @@ export default class Notification extends ImmutablePureComponent {
         hidden={this.props.hidden}
         onMoveDown={this.handleMoveDown}
         onMoveUp={this.handleMoveUp}
+        contextType='notifications'
       />
     );
   }
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index ca792043f..d7b50786c 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -58,7 +58,7 @@ const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
 
   const mapStateToProps = (state, props) => {
-    const status = getStatus(state, props.params.statusId);
+    const status = getStatus(state, { id: props.params.statusId });
     let ancestorsIds = Immutable.List();
     let descendantsIds = Immutable.List();
 
@@ -276,7 +276,7 @@ export default class Status extends ImmutablePureComponent {
 
   handleHotkeyMention = e => {
     e.preventDefault();
-    this.handleMentionClick(this.props.status);
+    this.handleMentionClick(this.props.status.get('account'));
   }
 
   handleHotkeyOpenProfile = () => {
@@ -336,6 +336,7 @@ export default class Status extends ImmutablePureComponent {
         id={id}
         onMoveUp={this.handleMoveUp}
         onMoveDown={this.handleMoveDown}
+        contextType='thread'
       />
     ));
   }
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index f4d6b5c4e..6af0a101c 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -16,6 +16,8 @@ const messages = defineMessages({
   next: { id: 'lightbox.next', defaultMessage: 'Next' },
 });
 
+const previewState = 'previewMediaModal';
+
 @injectIntl
 export default class MediaModal extends ImmutablePureComponent {
 
@@ -26,6 +28,10 @@ export default class MediaModal extends ImmutablePureComponent {
     intl: PropTypes.object.isRequired,
   };
 
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
   state = {
     index: null,
     navigationHidden: false,
@@ -61,10 +67,24 @@ export default class MediaModal extends ImmutablePureComponent {
 
   componentDidMount () {
     window.addEventListener('keyup', this.handleKeyUp, false);
+    if (this.context.router) {
+      const history = this.context.router.history;
+      history.push(history.location.pathname, previewState);
+      this.unlistenHistory = history.listen(() => {
+        this.props.onClose();
+      });
+    }
   }
 
   componentWillUnmount () {
     window.removeEventListener('keyup', this.handleKeyUp);
+    if (this.context.router) {
+      this.unlistenHistory();
+
+      if (this.context.router.history.location.state === previewState) {
+        this.context.router.history.goBack();
+      }
+    }
   }
 
   getIndex () {
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index ed6de6f39..60bc56eef 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -8,10 +8,10 @@ import { isUserTouching } from '../../../is_mobile';
 export const links = [
   <NavLink className='tabs-bar__link primary' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><i className='fa fa-fw fa-home' /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>,
   <NavLink className='tabs-bar__link primary' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><i className='fa fa-fw fa-bell' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>,
-  <NavLink className='tabs-bar__link primary' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
 
   <NavLink className='tabs-bar__link secondary' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><i className='fa fa-fw fa-users' /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>,
   <NavLink className='tabs-bar__link secondary' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><i className='fa fa-fw fa-globe' /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>,
+  <NavLink className='tabs-bar__link primary' to='/search' data-preview-title-id='tabs_bar.search' data-preview-icon='bell' ><i className='fa fa-fw fa-search' /><FormattedMessage id='tabs_bar.search' defaultMessage='Search' /></NavLink>,
 
   <NavLink className='tabs-bar__link primary' style={{ flexGrow: '0', flexBasis: '30px' }} to='/getting-started' data-preview-title-id='getting_started.heading' data-preview-icon='bars' ><i className='fa fa-fw fa-bars' /></NavLink>,
 ];
diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js
index e5b1edc4a..3df5b7bea 100644
--- a/app/javascript/mastodon/features/ui/containers/status_list_container.js
+++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js
@@ -11,15 +11,6 @@ const makeGetStatusIds = () => createSelector([
   (state, { type }) => state.getIn(['timelines', type, 'items'], ImmutableList()),
   (state)           => state.get('statuses'),
 ], (columnSettings, statusIds, statuses) => {
-  const rawRegex = columnSettings.getIn(['regex', 'body'], '').trim();
-  let regex      = null;
-
-  try {
-    regex = rawRegex && new RegExp(rawRegex, 'i');
-  } catch (e) {
-    // Bad regex, don't affect filters
-  }
-
   return statusIds.filter(id => {
     if (id === null) return true;
 
@@ -34,11 +25,6 @@ const makeGetStatusIds = () => createSelector([
       showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
     }
 
-    if (showStatus && regex && statusForId.get('account') !== me) {
-      const searchIndex = statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'search_index']) : statusForId.get('search_index');
-      showStatus = !regex.test(searchIndex);
-    }
-
     return showStatus;
   });
 });
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 3c1a266e3..56a856230 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -12,6 +12,7 @@ import { debounce } from 'lodash';
 import { uploadCompose, resetCompose } from '../../actions/compose';
 import { expandHomeTimeline } from '../../actions/timelines';
 import { expandNotifications } from '../../actions/notifications';
+import { fetchFilters } from '../../actions/filters';
 import { clearHeight } from '../../actions/height_cache';
 import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
 import UploadArea from './components/upload_area';
@@ -297,6 +298,7 @@ export default class UI extends React.PureComponent {
 
     this.props.dispatch(expandHomeTimeline());
     this.props.dispatch(expandNotifications());
+    setTimeout(() => this.props.dispatch(fetchFilters()), 500);
   }
 
   componentDidMount () {
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 88f592a09..a8a87c729 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "ماستدون برنامج مفتوح المصدر. يمكنك المساهمة، أو الإبلاغ عن تقارير الأخطاء، على جيت هب {github}.",
   "getting_started.security": "الأمان",
   "getting_started.terms": "شروط الخدمة",
-  "home.column_settings.advanced": "متقدمة",
   "home.column_settings.basic": "أساسية",
-  "home.column_settings.filter_regex": "تصفية حسب التعبيرات العادية",
   "home.column_settings.show_reblogs": "عرض الترقيات",
   "home.column_settings.show_replies": "عرض الردود",
-  "home.settings": "إعدادات العمود",
   "keyboard_shortcuts.back": "للعودة",
   "keyboard_shortcuts.boost": "للترقية",
   "keyboard_shortcuts.column": "للتركيز على منشور على أحد الأعمدة",
@@ -259,6 +256,7 @@
   "status.direct": "رسالة خاصة إلى @{name}",
   "status.embed": "إدماج",
   "status.favourite": "أضف إلى المفضلة",
+  "status.filtered": "Filtered",
   "status.load_more": "حمّل المزيد",
   "status.media_hidden": "الصورة مستترة",
   "status.mention": "أذكُر @{name}",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 37590d86f..7b38f9dde 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Advanced",
   "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Предпочитани",
+  "status.filtered": "Filtered",
   "status.load_more": "Load more",
   "status.media_hidden": "Media hidden",
   "status.mention": "Споменаване",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index e2fb1bb99..aa80ed555 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -59,7 +59,7 @@
   "column_header.show_settings": "Mostra la configuració",
   "column_header.unpin": "No fixis",
   "column_subheading.settings": "Configuració",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Només multimèdia",
   "compose_form.direct_message_warning": "Aquest toot només serà enviat als usuaris esmentats. De totes maneres, els operadors de la teva o de qualsevol de les instàncies receptores poden inspeccionar aquest missatge.",
   "compose_form.direct_message_warning_learn_more": "Aprèn més",
   "compose_form.hashtag_warning": "Aquest toot no es mostrarà en cap etiqueta ja que no està llistat. Només els toots públics poden ser cercats per etiqueta.",
@@ -114,20 +114,17 @@
   "empty_column.public": "No hi ha res aquí! Escriu alguna cosa públicament o segueix manualment usuaris d'altres instàncies per omplir-ho",
   "follow_request.authorize": "Autoritzar",
   "follow_request.reject": "Rebutjar",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Desenvolupadors",
   "getting_started.documentation": "Documentació",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Troba amics de Twitter",
   "getting_started.heading": "Començant",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Convida gent",
   "getting_started.open_source_notice": "Mastodon és un programari de codi obert. Pots contribuir o informar de problemes a GitHub a {github}.",
-  "getting_started.security": "Security",
+  "getting_started.security": "Seguretat",
   "getting_started.terms": "Termes del servei",
-  "home.column_settings.advanced": "Avançat",
   "home.column_settings.basic": "Bàsic",
-  "home.column_settings.filter_regex": "Filtrar per expressió regular",
   "home.column_settings.show_reblogs": "Mostrar impulsos",
   "home.column_settings.show_replies": "Mostrar respostes",
-  "home.settings": "Ajustos de columna",
   "keyboard_shortcuts.back": "navegar enrera",
   "keyboard_shortcuts.boost": "impulsar",
   "keyboard_shortcuts.column": "per centrar un estat en una de les columnes",
@@ -259,6 +256,7 @@
   "status.direct": "Missatge directe @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorit",
+  "status.filtered": "Filtered",
   "status.load_more": "Carrega més",
   "status.media_hidden": "Multimèdia amagat",
   "status.mention": "Esmentar @{name}",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index da1b45d73..09207287a 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avanzati",
   "home.column_settings.basic": "Bàsichi",
-  "home.column_settings.filter_regex": "Filtrà cù spressione regulare (regex)",
   "home.column_settings.show_reblogs": "Vede e spartere",
   "home.column_settings.show_replies": "Vede e risposte",
-  "home.settings": "Parametri di a colonna",
   "keyboard_shortcuts.back": "rivultà",
   "keyboard_shortcuts.boost": "sparte",
   "keyboard_shortcuts.column": "fucalizà un statutu indè una colonna",
@@ -259,6 +256,7 @@
   "status.direct": "Mandà un missaghju @{name}",
   "status.embed": "Integrà",
   "status.favourite": "Aghjunghje à i favuriti",
+  "status.filtered": "Filtered",
   "status.load_more": "Vede di più",
   "status.media_hidden": "Media piattata",
   "status.mention": "Mintuvà @{name}",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
new file mode 100644
index 000000000..d1857cd19
--- /dev/null
+++ b/app/javascript/mastodon/locales/da.json
@@ -0,0 +1,307 @@
+{
+  "account.badges.bot": "Robot",
+  "account.block": "Bloker @{name}",
+  "account.block_domain": "Skjul alt fra {domain}",
+  "account.blocked": "Blokeret",
+  "account.direct": "Send en direkte besked til @{name}",
+  "account.disclaimer_full": "Nedenstående oplysninger reflekterer ikke nødvendigvis brugerens profil fuldstændigt.",
+  "account.domain_blocked": "Domænet er blevet skjult",
+  "account.edit_profile": "Rediger profil",
+  "account.follow": "Følg",
+  "account.followers": "Følgere",
+  "account.follows": "Følger",
+  "account.follows_you": "Følger dig",
+  "account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
+  "account.media": "Multimedier",
+  "account.mention": "Nævn @{name}",
+  "account.moved_to": "{name} er flyttet til:",
+  "account.mute": "Dæmp @{name}",
+  "account.mute_notifications": "Dæmp notifikationer fra @{name}",
+  "account.muted": "Dæmpet",
+  "account.posts": "Dyt",
+  "account.posts_with_replies": "Toots og svar",
+  "account.report": "Rapporter @{name}",
+  "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
+  "account.share": "Del @{name}s profil",
+  "account.show_reblogs": "Vis fremhævelserne fra @{name}",
+  "account.unblock": "Fjern blokeringen af @{name}",
+  "account.unblock_domain": "Skjul ikke længere {domain}",
+  "account.unfollow": "Følg ikke længere",
+  "account.unmute": "Fjern dæmpningen af @{name}",
+  "account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}",
+  "account.view_full_profile": "Se fuld profil",
+  "alert.unexpected.message": "Der opstod en uventet fejl.",
+  "alert.unexpected.title": "Ups!",
+  "boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang",
+  "bundle_column_error.body": "Noget gik galt under indlæsningen af dette komponent.",
+  "bundle_column_error.retry": "Prøv igen",
+  "bundle_column_error.title": "Netværksfejl",
+  "bundle_modal_error.close": "Luk",
+  "bundle_modal_error.message": "Noget gik galt under indlæsningen af dette komponent.",
+  "bundle_modal_error.retry": "Prøv igen",
+  "column.blocks": "Blokerede brugere",
+  "column.community": "Lokal tidslinje",
+  "column.direct": "Direkte beskeder",
+  "column.domain_blocks": "Skjulte domæner",
+  "column.favourites": "Favoritter",
+  "column.follow_requests": "Anmodning om at følge",
+  "column.home": "Hjem",
+  "column.lists": "Lister",
+  "column.mutes": "Dæmpede brugere",
+  "column.notifications": "Notifikationer",
+  "column.pins": "Fastgjorte toots",
+  "column.public": "Fælles tidslinje",
+  "column_back_button.label": "Tilbage",
+  "column_header.hide_settings": "Skjul indstillinger",
+  "column_header.moveLeft_settings": "Flyt kolonne til venstre",
+  "column_header.moveRight_settings": "Flyt kolonne til højre",
+  "column_header.pin": "Fastgør",
+  "column_header.show_settings": "Vis indstillinger",
+  "column_header.unpin": "Fastgør ikke længere",
+  "column_subheading.settings": "Indstillinger",
+  "community.column_settings.media_only": "Kun multimedier",
+  "compose_form.direct_message_warning": "Dette toot vil kun blive sendt til de nævnte brugere.",
+  "compose_form.direct_message_warning_learn_more": "Lær mere",
+  "compose_form.hashtag_warning": "Dette toot vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige toots kan blive vist under søgninger med hashtags.",
+  "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine følger-kun indlæg.",
+  "compose_form.lock_disclaimer.lock": "låst",
+  "compose_form.placeholder": "Hvad har du på hjertet?",
+  "compose_form.publish": "Toot",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.sensitive.marked": "Multimedie er markeret som værende følsomt",
+  "compose_form.sensitive.unmarked": "Multimediet er ikke markeret som værende følsomt",
+  "compose_form.spoiler.marked": "Teksten er skjult bag en advarsel",
+  "compose_form.spoiler.unmarked": "Teksten er ikke skjult",
+  "compose_form.spoiler_placeholder": "Skriv din advarsel her",
+  "confirmation_modal.cancel": "Annuller",
+  "confirmations.block.confirm": "Bloker",
+  "confirmations.block.message": "Er du sikker på, du vil blokere {name}?",
+  "confirmations.delete.confirm": "Slet",
+  "confirmations.delete.message": "Er du sikker på, du vil slette denne status?",
+  "confirmations.delete_list.confirm": "Slet",
+  "confirmations.delete_list.message": "Er du sikker på, du vil slette denne liste?",
+  "confirmations.domain_block.confirm": "Skjul helt domæne",
+  "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
+  "confirmations.mute.confirm": "Dæmp",
+  "confirmations.mute.message": "Er du sikker på, du vil dæmpe {name}?",
+  "confirmations.redraft.confirm": "Slet & omskriv",
+  "confirmations.redraft.message": "Er du sikker på, du vil slette denne status og omskrive den? Du vil miste alle svar, fremhævelser og favoritter der medfølger.",
+  "confirmations.unfollow.confirm": "Følg ikke længere",
+  "confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?",
+  "embed.instructions": "Indlejre denne status på din side ved at kopiere nedenstående kode.",
+  "embed.preview": "Det kommer til at se således ud:",
+  "emoji_button.activity": "Aktivitet",
+  "emoji_button.custom": "Bruger defineret",
+  "emoji_button.flags": "Flag",
+  "emoji_button.food": "Mad og drikke",
+  "emoji_button.label": "Indsæt humørikon",
+  "emoji_button.nature": "Natur",
+  "emoji_button.not_found": "Ingen emojos!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Objekter",
+  "emoji_button.people": "Mennesker",
+  "emoji_button.recent": "Oftest brugt",
+  "emoji_button.search": "Søg...",
+  "emoji_button.search_results": "Søgeresultat",
+  "emoji_button.symbols": "Symboler",
+  "emoji_button.travel": "Rejser & steder",
+  "empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at starte lavinen!",
+  "empty_column.direct": "Du har endnu ingen direkte beskeder. Når du sender eller modtager en, vil den vises her.",
+  "empty_column.hashtag": "Dette hashtag indeholder endnu ikke noget.",
+  "empty_column.home": "Din hjemme tidslinje er tom! Besøg {public} eller brug søgningen for at komme igang og møde andre brugere.",
+  "empty_column.home.public_timeline": "den offentlige tidslinje",
+  "empty_column.list": "Der er endnu intet i denne liste. Når medlemmer af denne liste poster nye statusser, vil de vises her.",
+  "empty_column.notifications": "Du har endnu ingen notifikationer. Tag ud og bland dig med folkemængden for at starte samtalen.",
+  "empty_column.public": "Der er ikke noget at se her! Skriv noget offentligt eller start ud med manuelt at følge brugere fra andre instanser for st udfylde tomrummet",
+  "follow_request.authorize": "Godkend",
+  "follow_request.reject": "Afvis",
+  "getting_started.developers": "Udviklere",
+  "getting_started.documentation": "Dokumentation",
+  "getting_started.find_friends": "Find venner fra Twitter",
+  "getting_started.heading": "Kom igang",
+  "getting_started.invite": "Inviter folk",
+  "getting_started.open_source_notice": "Mastodon er et open source software. Du kan bidrage eller rapporterer fejl på GitHub {github}.",
+  "getting_started.security": "Sikkerhed",
+  "getting_started.terms": "Vilkår",
+  "home.column_settings.basic": "Grundlæggende",
+  "home.column_settings.show_reblogs": "Vis fremhævelser",
+  "home.column_settings.show_replies": "Vis svar",
+  "keyboard_shortcuts.back": "for at navigere dig tilbage",
+  "keyboard_shortcuts.boost": "for at fremhæve",
+  "keyboard_shortcuts.column": "for at fokusere på en status i en af kolonnerne",
+  "keyboard_shortcuts.compose": "for at fokusere på skriveområdet",
+  "keyboard_shortcuts.description": "Beskrivelse",
+  "keyboard_shortcuts.down": "for at rykke ned ad listen",
+  "keyboard_shortcuts.enter": "for at åbne status",
+  "keyboard_shortcuts.favourite": "for at favorisere",
+  "keyboard_shortcuts.heading": "Tastaturgenveje",
+  "keyboard_shortcuts.hotkey": "Hurtigtast",
+  "keyboard_shortcuts.legend": "for at vise denne legende",
+  "keyboard_shortcuts.mention": "for at nævne forfatteren",
+  "keyboard_shortcuts.reply": "for at svare",
+  "keyboard_shortcuts.search": "for at fokusere søgningen",
+  "keyboard_shortcuts.toggle_hidden": "for at vise/skjule tekst bag CW",
+  "keyboard_shortcuts.toot": "for at påbegynde en helt ny toot",
+  "keyboard_shortcuts.unfocus": "for at fjerne fokus fra skriveområde/søgning",
+  "keyboard_shortcuts.up": "for at bevæge dig op ad listen",
+  "lightbox.close": "Luk",
+  "lightbox.next": "Næste",
+  "lightbox.previous": "Forrige",
+  "lists.account.add": "Tilføj til liste",
+  "lists.account.remove": "Fjern fra liste",
+  "lists.delete": "Slet liste",
+  "lists.edit": "Rediger liste",
+  "lists.new.create": "Tilføj liste",
+  "lists.new.title_placeholder": "Ny liste titel",
+  "lists.search": "Søg iblandt folk du følger",
+  "lists.subheading": "Dine lister",
+  "loading_indicator.label": "Indlæser...",
+  "media_gallery.toggle_visible": "Ændre synlighed",
+  "missing_indicator.label": "Ikke fundet",
+  "missing_indicator.sublabel": "Denne ressource kunne ikke blive fundet",
+  "mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?",
+  "navigation_bar.blocks": "Blokerede brugere",
+  "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.direct": "Direkte beskeder",
+  "navigation_bar.discover": "Opdag",
+  "navigation_bar.domain_blocks": "Skjulte domæner",
+  "navigation_bar.edit_profile": "Rediger profil",
+  "navigation_bar.favourites": "Favoritter",
+  "navigation_bar.follow_requests": "Følgeanmodninger",
+  "navigation_bar.info": "Om denne instans",
+  "navigation_bar.keyboard_shortcuts": "Hurtigtast",
+  "navigation_bar.lists": "Lister",
+  "navigation_bar.logout": "Logud",
+  "navigation_bar.mutes": "Dæmpede brugere",
+  "navigation_bar.personal": "Personligt",
+  "navigation_bar.pins": "Fastgjorte toots",
+  "navigation_bar.preferences": "Indstillinger",
+  "navigation_bar.public_timeline": "Fælles tidslinje",
+  "navigation_bar.security": "Sikkerhed",
+  "notification.favourite": "{name} favoriserede din status",
+  "notification.follow": "{name} fulgte dig",
+  "notification.mention": "{name} nævnte dig",
+  "notification.reblog": "{name} fremhævede din status",
+  "notifications.clear": "Ryd notifikationer",
+  "notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?",
+  "notifications.column_settings.alert": "Skrivebords notifikationer",
+  "notifications.column_settings.favourite": "Favoritter:",
+  "notifications.column_settings.follow": "Nye følgere:",
+  "notifications.column_settings.mention": "Omtale:",
+  "notifications.column_settings.push": "Push notifikationer",
+  "notifications.column_settings.push_meta": "Denne enhed",
+  "notifications.column_settings.reblog": "Fremhævelser:",
+  "notifications.column_settings.show": "Vis i kolonne",
+  "notifications.column_settings.sound": "Afspil lyd",
+  "notifications.group": "{count} notifikationer",
+  "onboarding.done": "Færdig",
+  "onboarding.next": "Næste",
+  "onboarding.page_five.public_timelines": "Den lokale tidslinje viser offentlige opslag fra alle i {domain}. Den fælles tidslinje viser opslag fra alle der følges af folk i {domain}. Disse er de offentlige tidslinjer, hvilket er en god måde at møde nye mennesker på.",
+  "onboarding.page_four.home": "Hjem tidslinjen viser opslag fra folk som du følger.",
+  "onboarding.page_four.notifications": "Notifikations kolonnen viser når nogen interagerer med dig.",
+  "onboarding.page_one.federation": "Mastodon er et netværk af uafhængige serverer der forbindes til at udgøre et større socialt netværk. Vi kalder disse servere for instanser.",
+  "onboarding.page_one.full_handle": "Dit fulde brugernavn",
+  "onboarding.page_one.handle_hint": "Dette er hvad du vil fortælle dine venner hvad de skal søge efter.",
+  "onboarding.page_one.welcome": "Velkommen til Mastodon!",
+  "onboarding.page_six.admin": "Administratoren for denne instans er {admin}.",
+  "onboarding.page_six.almost_done": "Næsten færdig...",
+  "onboarding.page_six.appetoot": "God Appetoot!",
+  "onboarding.page_six.apps_available": "Der er {apps} tilgængelige for iOS, Android og andre platforme.",
+  "onboarding.page_six.github": "Mastodon er frit open-source software. Du kan rapportere fejl, anmode om features, eller bidrage til koden ved at gå til {github}.",
+  "onboarding.page_six.guidelines": "retningslinjer for fællesskabet",
+  "onboarding.page_six.read_guidelines": "Læs venligst {domain}s {guidelines}!",
+  "onboarding.page_six.various_app": "apps til mobilen",
+  "onboarding.page_three.profile": "Rediger din profil for at ændre profilbillede, beskrivelse og visningsnavn. Der vil du også finde andre indstillinger.",
+  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+  "onboarding.skip": "Spring over",
+  "privacy.change": "Ændre status privatliv",
+  "privacy.direct.long": "Post til kun de nævnte brugere",
+  "privacy.direct.short": "Direkte",
+  "privacy.private.long": "Post kun til følgere",
+  "privacy.private.short": "Kun for følgere",
+  "privacy.public.long": "Post til offentlige tidslinjer",
+  "privacy.public.short": "Offentligt",
+  "privacy.unlisted.long": "Post ikke til offentlige tidslinjer",
+  "privacy.unlisted.short": "Ikke listet",
+  "regeneration_indicator.label": "Indlæser…",
+  "regeneration_indicator.sublabel": "Din startside er ved at blive forberedt!",
+  "relative_time.days": "{number}d",
+  "relative_time.hours": "{number}t",
+  "relative_time.just_now": "nu",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "reply_indicator.cancel": "Annuller",
+  "report.forward": "Videresend til {target}",
+  "report.forward_hint": "Kontoen er fra en anden server. Vil du også sende en anonym kopi af anmeldelsen dertil?",
+  "report.hint": "Anmeldelsen vil blive sendt til moderatorene af din instans. Du kan give en forklaring for hvorfor du anmelder denne konto nedenfor:",
+  "report.placeholder": "Yderligere kommentarer",
+  "report.submit": "Indsend",
+  "report.target": "Anmelder {target}",
+  "search.placeholder": "Søg",
+  "search_popout.search_format": "Avanceret søgeformat",
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.hashtag": "emnetag",
+  "search_popout.tips.status": "status",
+  "search_popout.tips.text": "Simpelt tekst returnerer passende visningsnavne, brugernavne og hashtags",
+  "search_popout.tips.user": "bruger",
+  "search_results.accounts": "Folk",
+  "search_results.hashtags": "Emnetags",
+  "search_results.statuses": "Toote",
+  "search_results.total": "{count, number} {count, plural, et {result} andre {results}}",
+  "standalone.public_title": "Et kig indenfor...",
+  "status.block": "Bloker @{name}",
+  "status.cancel_reblog_private": "Fremhæv ikke længere",
+  "status.cannot_reblog": "Denne post kan ikke fremhæves",
+  "status.delete": "Slet",
+  "status.direct": "Send direkte besked til @{name}",
+  "status.embed": "Indlejre",
+  "status.favourite": "Favorit",
+  "status.filtered": "Filtered",
+  "status.load_more": "Indlæs mere",
+  "status.media_hidden": "Multimedia skjult",
+  "status.mention": "Nævn @{name}",
+  "status.more": "Mere",
+  "status.mute": "Dæmp @{name}",
+  "status.mute_conversation": "Dæmp samtale",
+  "status.open": "Udvid denne status",
+  "status.pin": "Fastgør til profil",
+  "status.pinned": "Fastgjort toot",
+  "status.reblog": "Fremhæv",
+  "status.reblog_private": "Fremhæv til oprindeligt publikum",
+  "status.reblogged_by": "{name} fremhævede",
+  "status.redraft": "Slet og omskriv",
+  "status.reply": "Svar",
+  "status.replyAll": "Svar tråd",
+  "status.report": "Anmeld @{name}",
+  "status.sensitive_toggle": "Tryk for at se",
+  "status.sensitive_warning": "Følsomt indhold",
+  "status.share": "Del",
+  "status.show_less": "Vis mindre",
+  "status.show_less_all": "Vis mindre for alle",
+  "status.show_more": "Vis mere",
+  "status.show_more_all": "Vis mere for alle",
+  "status.unmute_conversation": "Fjern dæmpningen fra samtale",
+  "status.unpin": "Fjern som fastgjort fra profil",
+  "tabs_bar.federated_timeline": "Fælles",
+  "tabs_bar.home": "Hjem",
+  "tabs_bar.local_timeline": "Lokal",
+  "tabs_bar.notifications": "Notifikationer",
+  "tabs_bar.search": "Søg",
+  "trends.count_by_accounts": "{count} {rawCount, flere, en {person} flere {people}} snakker",
+  "ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Mastodon.",
+  "upload_area.title": "Træk og slip for at uploade",
+  "upload_button.label": "Tilføj multimedier",
+  "upload_form.description": "Beskrivelse for de svagtseende",
+  "upload_form.focus": "Beskær",
+  "upload_form.undo": "Slet",
+  "upload_progress.label": "Uploader...",
+  "video.close": "Luk video",
+  "video.exit_fullscreen": "Gå ud af fuldskærm",
+  "video.expand": "Udvid video",
+  "video.fullscreen": "Fuldskærm",
+  "video.hide": "Skjul video",
+  "video.mute": "Dæmp lyd",
+  "video.pause": "Sæt på pause",
+  "video.play": "Afspil",
+  "video.unmute": "Fjern dæmpningen af lyd"
+}
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 2e32c86a4..ac14f037d 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon ist quelloffene Software. Du kannst auf GitHub unter {github} dazu beitragen oder Probleme melden.",
   "getting_started.security": "Sicherheit",
   "getting_started.terms": "Nutzungsbedingungen",
-  "home.column_settings.advanced": "Erweitert",
   "home.column_settings.basic": "Einfach",
-  "home.column_settings.filter_regex": "Mit regulären Ausdrücken filtern",
   "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
   "home.column_settings.show_replies": "Antworten anzeigen",
-  "home.settings": "Spalteneinstellungen",
   "keyboard_shortcuts.back": "zurück navigieren",
   "keyboard_shortcuts.boost": "boosten",
   "keyboard_shortcuts.column": "einen Status in einer der Spalten fokussieren",
@@ -259,6 +256,7 @@
   "status.direct": "Direktnachricht @{name}",
   "status.embed": "Einbetten",
   "status.favourite": "Favorisieren",
+  "status.filtered": "Filtered",
   "status.load_more": "Weitere laden",
   "status.media_hidden": "Medien versteckt",
   "status.mention": "@{name} erwähnen",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 18ae3b3a2..132399b87 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -335,6 +335,10 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Filtered",
+        "id": "status.filtered"
+      },
+      {
         "defaultMessage": "Pinned toot",
         "id": "status.pinned"
       },
@@ -633,20 +637,8 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Filter out by regular expressions",
-        "id": "home.column_settings.filter_regex"
-      },
-      {
-        "defaultMessage": "Column settings",
-        "id": "home.settings"
-      },
-      {
         "defaultMessage": "Media Only",
         "id": "community.column_settings.media_only"
-      },
-      {
-        "defaultMessage": "Advanced",
-        "id": "home.column_settings.advanced"
       }
     ],
     "path": "app/javascript/mastodon/features/community_timeline/components/column_settings.json"
@@ -1022,23 +1014,6 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Filter out by regular expressions",
-        "id": "home.column_settings.filter_regex"
-      },
-      {
-        "defaultMessage": "Column settings",
-        "id": "home.settings"
-      },
-      {
-        "defaultMessage": "Advanced",
-        "id": "home.column_settings.advanced"
-      }
-    ],
-    "path": "app/javascript/mastodon/features/direct_timeline/components/column_settings.json"
-  },
-  {
-    "descriptors": [
-      {
         "defaultMessage": "Direct messages",
         "id": "column.direct"
       },
@@ -1222,14 +1197,6 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Filter out by regular expressions",
-        "id": "home.column_settings.filter_regex"
-      },
-      {
-        "defaultMessage": "Column settings",
-        "id": "home.settings"
-      },
-      {
         "defaultMessage": "Basic",
         "id": "home.column_settings.basic"
       },
@@ -1240,10 +1207,6 @@
       {
         "defaultMessage": "Show replies",
         "id": "home.column_settings.show_replies"
-      },
-      {
-        "defaultMessage": "Advanced",
-        "id": "home.column_settings.advanced"
       }
     ],
     "path": "app/javascript/mastodon/features/home_timeline/components/column_settings.json"
@@ -1948,16 +1911,16 @@
         "id": "tabs_bar.notifications"
       },
       {
-        "defaultMessage": "Search",
-        "id": "tabs_bar.search"
-      },
-      {
         "defaultMessage": "Local",
         "id": "tabs_bar.local_timeline"
       },
       {
         "defaultMessage": "Federated",
         "id": "tabs_bar.federated_timeline"
+      },
+      {
+        "defaultMessage": "Search",
+        "id": "tabs_bar.search"
       }
     ],
     "path": "app/javascript/mastodon/features/ui/components/tabs_bar.json"
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 936fba71e..b9bc474eb 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -3,7 +3,7 @@
   "account.block": "Απόκλεισε τον/την @{name}",
   "account.block_domain": "Απόκρυψε τα πάντα από τον/την",
   "account.blocked": "Αποκλεισμένος/η",
-  "account.direct": "Άμεσο μήνυμα προς @{name}",
+  "account.direct": "Προσωπικό μήνυμα προς @{name}",
   "account.disclaimer_full": "Οι παρακάτω πληροφορίες μπορει να μην αντανακλούν το προφίλ του χρήστη επαρκως.",
   "account.domain_blocked": "Κρυμμένος τομέας",
   "account.edit_profile": "Επεξεργάσου το προφίλ",
@@ -21,7 +21,7 @@
   "account.posts": "Τουτ",
   "account.posts_with_replies": "Τουτ και απαντήσεις",
   "account.report": "Κατάγγειλε τον/την @{name}",
-  "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα ακολούθησης",
+  "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης",
   "account.share": "Μοιράσου το προφίλ του/της @{name}",
   "account.show_reblogs": "Δείξε τις προωθήσεις του/της @{name}",
   "account.unblock": "Ξεμπλόκαρε τον/την @{name}",
@@ -41,7 +41,7 @@
   "bundle_modal_error.retry": "Δοκίμασε ξανά",
   "column.blocks": "Αποκλεισμένοι χρήστες",
   "column.community": "Τοπική ροή",
-  "column.direct": "Απευθείας μηνύματα",
+  "column.direct": "Προσωπικά μηνύματα",
   "column.domain_blocks": "Κρυμμένοι τομείς",
   "column.favourites": "Αγαπημένα",
   "column.follow_requests": "Αιτήματα ακολούθησης",
@@ -59,13 +59,13 @@
   "column_header.show_settings": "Εμφάνιση ρυθμίσεων",
   "column_header.unpin": "Ξεκαρφίτσωμα",
   "column_subheading.settings": "Ρυθμίσεις",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Μόνο πολυμέσα",
   "compose_form.direct_message_warning": "Αυτό το τουτ θα σταλεί μόνο στους αναφερόμενους χρήστες.",
   "compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
   "compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
   "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
   "compose_form.lock_disclaimer.lock": "κλειδωμένος",
-  "compose_form.placeholder": "Τι σκέφτεσαι;",
+  "compose_form.placeholder": "Τι έχεις στο μυαλό σου;",
   "compose_form.publish": "Τουτ",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "Το πολυμέσο έχει σημειωθεί ως ευαίσθητο",
@@ -105,7 +105,7 @@
   "emoji_button.symbols": "Σύμβολα",
   "emoji_button.travel": "Ταξίδια & Τοποθεσίες",
   "empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσιο παραμύθι ν' αρχινίσει!",
-  "empty_column.direct": "Δεν έχεις απευθείας μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
+  "empty_column.direct": "Δεν έχεις προσωπικά μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.",
   "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ταμπέλα.",
   "empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.",
   "empty_column.home.public_timeline": "η δημόσια ροή",
@@ -114,20 +114,17 @@
   "empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλα instances για να τη γεμίσεις",
   "follow_request.authorize": "Ενέκρινε",
   "follow_request.reject": "Απέρριψε",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Προγραμματιστές",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Βρες φίλους/ες από το Twitter",
   "getting_started.heading": "Ξεκινώντας",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Προσκάλεσε κόσμο",
   "getting_started.open_source_notice": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να συνεισφέρεις ή να αναφέρεις ζητήματα στο GitHub στο {github}.",
-  "getting_started.security": "Security",
+  "getting_started.security": "Ασφάλεια",
   "getting_started.terms": "Όροι χρήσης",
-  "home.column_settings.advanced": "Προχωρημένα",
   "home.column_settings.basic": "Βασικά",
-  "home.column_settings.filter_regex": "Φιλτράρετε μέσω regular expressions",
   "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
   "home.column_settings.show_replies": "Εμφάνιση απαντήσεων",
-  "home.settings": "Ρυθμίσεις στηλών",
   "keyboard_shortcuts.back": "για επιστροφή πίσω",
   "keyboard_shortcuts.boost": "για προώθηση",
   "keyboard_shortcuts.column": "για εστίαση μιας κατάστασης σε μια από τις στήλες",
@@ -164,7 +161,7 @@
   "mute_modal.hide_notifications": "Απόκρυψη ειδοποιήσεων αυτού του χρήστη;",
   "navigation_bar.blocks": "Αποκλεισμένοι χρήστες",
   "navigation_bar.community_timeline": "Τοπική ροή",
-  "navigation_bar.direct": "Απευθείας μηνύματα",
+  "navigation_bar.direct": "Προσωπικά μηνύματα",
   "navigation_bar.discover": "Ανακάλυψη",
   "navigation_bar.domain_blocks": "Κρυφοί τομείς",
   "navigation_bar.edit_profile": "Επεξεργασία προφίλ",
@@ -219,7 +216,7 @@
   "onboarding.skip": "Παράληψη",
   "privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης",
   "privacy.direct.long": "Δημοσίευση μόνο σε όσους και όσες αναφέρονται",
-  "privacy.direct.short": "Απευθείας",
+  "privacy.direct.short": "Προσωπικά",
   "privacy.private.long": "Δημοσίευση μόνο στους ακόλουθους",
   "privacy.private.short": "Μόνο ακόλουθοι",
   "privacy.public.long": "Δημοσίευσε στις δημόσιες ροές",
@@ -238,7 +235,7 @@
   "report.forward_hint": "Ο λογαριασμός είναι από διαφορετικό διακομιστή. Να σταλεί ανώνυμο αντίγραφο της καταγγελίας κι εκεί;",
   "report.hint": "Η καταγγελία θα σταλεί στους διαχειριστές του κόμβου σου. Μπορείς να περιγράψεις γιατί καταγγέλεις το λογαριασμό παρακάτω:",
   "report.placeholder": "Επιπλέον σχόλια",
-  "report.submit": "Submit",
+  "report.submit": "Υποβολή",
   "report.target": "Καταγγελία {target}",
   "search.placeholder": "Αναζήτηση",
   "search_popout.search_format": "Προχωρημένη αναζήτηση",
@@ -256,9 +253,10 @@
   "status.cancel_reblog_private": "Ακύρωσε την προώθηση",
   "status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
   "status.delete": "Διαγραφή",
-  "status.direct": "Απευθείας μήνυμα προς @{name}",
+  "status.direct": "Προσωπικό μήνυμα προς @{name}",
   "status.embed": "Ενσωμάτωσε",
   "status.favourite": "Σημείωσε ως αγαπημένο",
+  "status.filtered": "Filtered",
   "status.load_more": "Φόρτωσε περισσότερα",
   "status.media_hidden": "Κρυμμένο πολυμέσο",
   "status.mention": "Ανέφερε τον/την @{name}",
@@ -269,7 +267,7 @@
   "status.pin": "Καρφίτσωσε στο προφίλ",
   "status.pinned": "Καρφιτσωμένο τουτ",
   "status.reblog": "Προώθησε",
-  "status.reblog_private": "Προώθησε στο αρχικό κοινό",
+  "status.reblog_private": "Προώθησε στους αρχικούς παραλήπτες",
   "status.reblogged_by": "{name} προώθησε",
   "status.redraft": "Σβήσε & ξαναγράψε",
   "status.reply": "Απάντησε",
@@ -298,12 +296,12 @@
   "upload_form.undo": "Διαγραφή",
   "upload_progress.label": "Ανεβαίνει...",
   "video.close": "Κλείσε το βίντεο",
-  "video.exit_fullscreen": "Έξοδος πλήρης οθόνης",
+  "video.exit_fullscreen": "Έξοδος από πλήρη οθόνη",
   "video.expand": "Επέκταση βίντεο",
   "video.fullscreen": "Πλήρης οθόνη",
   "video.hide": "Κρύψε βίντεο",
-  "video.mute": "Mute sound",
+  "video.mute": "Σίγαση ήχου",
   "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "video.play": "Αναπαραγωγή",
+  "video.unmute": "Αναπαραγωγή ήχου"
 }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 08dbfcece..6ed35ebf7 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -69,7 +69,7 @@
   "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
-  "compose_form.placeholder": "What is on your mind?",
+  "compose_form.placeholder": "What's on your mind?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "Media is marked as sensitive",
@@ -126,12 +126,9 @@
   "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Advanced",
   "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -264,6 +261,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
   "status.load_more": "Load more",
   "status.media_hidden": "Media hidden",
   "status.mention": "Mention @{name}",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index c160ec0fb..93bf53b9f 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aŭ raporti problemojn en GitHub je {github}.",
   "getting_started.security": "Sekureco",
   "getting_started.terms": "Uzkondiĉoj",
-  "home.column_settings.advanced": "Precizaj agordoj",
   "home.column_settings.basic": "Bazaj agordoj",
-  "home.column_settings.filter_regex": "Filtri per regulesprimoj",
   "home.column_settings.show_reblogs": "Montri diskonigojn",
   "home.column_settings.show_replies": "Montri respondojn",
-  "home.settings": "Kolumnaj agordoj",
   "keyboard_shortcuts.back": "por reveni",
   "keyboard_shortcuts.boost": "por diskonigi",
   "keyboard_shortcuts.column": "por fokusigi mesaĝon en unu el la kolumnoj",
@@ -259,6 +256,7 @@
   "status.direct": "Rekte mesaĝi @{name}",
   "status.embed": "Enkorpigi",
   "status.favourite": "Stelumi",
+  "status.filtered": "Filtered",
   "status.load_more": "Ŝargi pli",
   "status.media_hidden": "Aŭdovidaĵo kaŝita",
   "status.mention": "Mencii @{name}",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index f1f370bbb..a56620e2b 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon es software libre. Puedes contribuir o reportar errores en {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avanzado",
   "home.column_settings.basic": "Básico",
-  "home.column_settings.filter_regex": "Filtrar con expresiones regulares",
   "home.column_settings.show_reblogs": "Mostrar retoots",
   "home.column_settings.show_replies": "Mostrar respuestas",
-  "home.settings": "Ajustes de columna",
   "keyboard_shortcuts.back": "volver atrás",
   "keyboard_shortcuts.boost": "retootear",
   "keyboard_shortcuts.column": "enfocar un estado en una de las columnas",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Incrustado",
   "status.favourite": "Favorito",
+  "status.filtered": "Filtered",
   "status.load_more": "Cargar más",
   "status.media_hidden": "Contenido multimedia oculto",
   "status.mention": "Mencionar",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index c92adcf4e..e67dd02ef 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon software librea da. Ekarpenak egin ditzakezu edo akatsen berri eman GitHub bidez: {github}.",
   "getting_started.security": "Segurtasuna",
   "getting_started.terms": "Erabilera baldintzak",
-  "home.column_settings.advanced": "Aurreratua",
   "home.column_settings.basic": "Oinarrizkoa",
-  "home.column_settings.filter_regex": "Iragazi adierazpen erregularren bidez",
   "home.column_settings.show_reblogs": "Erakutsi bultzadak",
   "home.column_settings.show_replies": "Erakutsi erantzunak",
-  "home.settings": "Zutabearen ezarpenak",
   "keyboard_shortcuts.back": "atzera nabigatzeko",
   "keyboard_shortcuts.boost": "bultzada ematea",
   "keyboard_shortcuts.column": "mezu bat zutabe batean fokatzea",
@@ -259,6 +256,7 @@
   "status.direct": "Mezu zuzena @{name}(r)i",
   "status.embed": "Txertatu",
   "status.favourite": "Gogokoa",
+  "status.filtered": "Filtered",
   "status.load_more": "Kargatu gehiago",
   "status.media_hidden": "Multimedia ezkutatua",
   "status.mention": "Aipatu @{name}",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index ff039324d..d6aea20d5 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "ماستدون یک نرم‌افزار آزاد است. می‌توانید در ساخت آن مشارکت کنید یا مشکلاتش را در {github} گزارش دهید.",
   "getting_started.security": "امنیت",
   "getting_started.terms": "شرایط استفاده",
-  "home.column_settings.advanced": "پیشرفته",
   "home.column_settings.basic": "اصلی",
-  "home.column_settings.filter_regex": "با عبارت‌های باقاعده (regexp) فیلتر کنید",
   "home.column_settings.show_reblogs": "نمایش بازبوق‌ها",
   "home.column_settings.show_replies": "نمایش پاسخ‌ها",
-  "home.settings": "تنظیمات ستون",
   "keyboard_shortcuts.back": "برای بازگشت",
   "keyboard_shortcuts.boost": "برای بازبوقیدن",
   "keyboard_shortcuts.column": "برای برجسته‌کردن یک نوشته در یکی از ستون‌ها",
@@ -259,6 +256,7 @@
   "status.direct": "پیغام مستقیم به @{name}",
   "status.embed": "جاگذاری",
   "status.favourite": "پسندیدن",
+  "status.filtered": "Filtered",
   "status.load_more": "بیشتر نشان بده",
   "status.media_hidden": "تصویر پنهان شده",
   "status.mention": "نام‌بردن از @{name}",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index b4678c1d2..009938d5e 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon on avoimen lähdekoodin ohjelma. Voit avustaa tai raportoida ongelmia GitHubissa: {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Lisäasetukset",
   "home.column_settings.basic": "Perusasetukset",
-  "home.column_settings.filter_regex": "Suodata säännöllisillä lausekkeilla",
   "home.column_settings.show_reblogs": "Näytä buustaukset",
   "home.column_settings.show_replies": "Näytä vastaukset",
-  "home.settings": "Sarakeasetukset",
   "keyboard_shortcuts.back": "liiku taaksepäin",
   "keyboard_shortcuts.boost": "buustaa",
   "keyboard_shortcuts.column": "siirrä fokus tietyn sarakkeen tilapäivitykseen",
@@ -259,6 +256,7 @@
   "status.direct": "Viesti käyttäjälle @{name}",
   "status.embed": "Upota",
   "status.favourite": "Tykkää",
+  "status.filtered": "Filtered",
   "status.load_more": "Lataa lisää",
   "status.media_hidden": "Media piilotettu",
   "status.mention": "Mainitse @{name}",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 1e9756d05..22ebc5df5 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon est un logiciel libre. Vous pouvez contribuer et envoyer vos commentaires et rapports de bogues via {github} sur GitHub.",
   "getting_started.security": "Sécurité",
   "getting_started.terms": "Conditions d’utilisation",
-  "home.column_settings.advanced": "Avancé",
   "home.column_settings.basic": "Basique",
-  "home.column_settings.filter_regex": "Filtrer avec une expression rationnelle",
   "home.column_settings.show_reblogs": "Afficher les partages",
   "home.column_settings.show_replies": "Afficher les réponses",
-  "home.settings": "Paramètres de la colonne",
   "keyboard_shortcuts.back": "revenir en arrière",
   "keyboard_shortcuts.boost": "partager",
   "keyboard_shortcuts.column": "focaliser un statut dans l'une des colonnes",
@@ -259,6 +256,7 @@
   "status.direct": "Envoyer un message direct à @{name}",
   "status.embed": "Intégrer",
   "status.favourite": "Ajouter aux favoris",
+  "status.filtered": "Filtered",
   "status.load_more": "Charger plus",
   "status.media_hidden": "Média caché",
   "status.mention": "Mentionner",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index da4fa83b5..7693c7671 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -65,7 +65,7 @@
   "compose_form.hashtag_warning": "Esta mensaxe non será listada baixo ningunha etiqueta xa que está marcada como non listada. Só os toots públicos poden buscarse por etiquetas.",
   "compose_form.lock_disclaimer": "A súa conta non está {locked}. Calquera pode seguila para ver as súas mensaxes só-para-seguidoras.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
-  "compose_form.placeholder": "A qué andas?",
+  "compose_form.placeholder": "Qué contas?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "Medios marcados como sensibles",
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon é software de código aberto. Pode contribuír ou informar de fallos en GitHub en {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avanzado",
   "home.column_settings.basic": "Básico",
-  "home.column_settings.filter_regex": "Filtrar expresións regulares",
   "home.column_settings.show_reblogs": "Mostrar repeticións",
   "home.column_settings.show_replies": "Mostrar respostas",
-  "home.settings": "Axustes da columna",
   "keyboard_shortcuts.back": "voltar atrás",
   "keyboard_shortcuts.boost": "promover",
   "keyboard_shortcuts.column": "destacar un estado en unha das columnas",
@@ -259,6 +256,7 @@
   "status.direct": "Mensaxe directa @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorita",
+  "status.filtered": "Filtered",
   "status.load_more": "Cargar máis",
   "status.media_hidden": "Medios ocultos",
   "status.mention": "Mencionar @{name}",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 4457e2a9b..61a5700e1 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "מסטודון היא תוכנה חופשית (בקוד פתוח). ניתן לתרום או לדווח על בעיות בגיטהאב: {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "למתקדמים",
   "home.column_settings.basic": "למתחילים",
-  "home.column_settings.filter_regex": "סינון באמצעות ביטויים רגולריים (regular expressions)",
   "home.column_settings.show_reblogs": "הצגת הדהודים",
   "home.column_settings.show_replies": "הצגת תגובות",
-  "home.settings": "הגדרות טור",
   "keyboard_shortcuts.back": "ניווט חזרה",
   "keyboard_shortcuts.boost": "להדהד",
   "keyboard_shortcuts.column": "להתמקד בהודעה באחד מהטורים",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "הטמעה",
   "status.favourite": "חיבוב",
+  "status.filtered": "Filtered",
   "status.load_more": "עוד",
   "status.media_hidden": "מדיה מוסתרת",
   "status.mention": "פניה אל @{name}",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 110246e8a..dcef385da 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon je softver otvorenog koda. Možeš pridonijeti ili prijaviti probleme na GitHubu  {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Napredno",
   "home.column_settings.basic": "Osnovno",
-  "home.column_settings.filter_regex": "Filtriraj s regularnim izrazima",
   "home.column_settings.show_reblogs": "Pokaži boostove",
   "home.column_settings.show_replies": "Pokaži odgovore",
-  "home.settings": "Postavke Stupca",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Označi omiljenim",
+  "status.filtered": "Filtered",
   "status.load_more": "Učitaj više",
   "status.media_hidden": "Sakriven media sadržaj",
   "status.mention": "Spomeni @{name}",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 187ce7c42..2072b740a 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon egy nyílt forráskódú szoftver. Hozzájárulás vagy problémák jelentése a GitHub-on {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Fejlett",
   "home.column_settings.basic": "Alap",
-  "home.column_settings.filter_regex": "Szűrje ki reguláris kifejezésekkel",
   "home.column_settings.show_reblogs": "Ismétlések mutatása",
   "home.column_settings.show_replies": "Válaszok mutatása",
-  "home.settings": "Oszlop beállításai",
   "keyboard_shortcuts.back": "vissza navigálás",
   "keyboard_shortcuts.boost": "ismétlés",
   "keyboard_shortcuts.column": "összpontosítson egy státuszra az egyik oszlopban",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Beágyaz",
   "status.favourite": "Kedvenc",
+  "status.filtered": "Filtered",
   "status.load_more": "Többet",
   "status.media_hidden": "Média elrejtve",
   "status.mention": "Említés",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 5d5ceb46b..d06d1c302 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Մաստոդոնը բաց ելատեքստով ծրագրակազմ է։ Կարող ես ներդրում անել կամ վրեպներ զեկուցել ԳիթՀաբում՝ {github}։",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Առաջադեմ",
   "home.column_settings.basic": "Հիմնական",
-  "home.column_settings.filter_regex": "Զտել օրինաչափ արտահայտությամբ",
   "home.column_settings.show_reblogs": "Ցուցադրել տարածածները",
   "home.column_settings.show_replies": "Ցուցադրել պատասխանները",
-  "home.settings": "Սյան կարգավորումներ",
   "keyboard_shortcuts.back": "ետ նավարկելու համար",
   "keyboard_shortcuts.boost": "տարածելու համար",
   "keyboard_shortcuts.column": "սյուներից մեկի վրա սեւեռվելու համար",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Ներդնել",
   "status.favourite": "Հավանել",
+  "status.filtered": "Filtered",
   "status.load_more": "Բեռնել ավելին",
   "status.media_hidden": "մեդիաբովանդակությունը թաքցված է",
   "status.mention": "Նշել @{name}֊ին",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 2b337fa20..fe98cf00b 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon adalah perangkat lunak yang bersifat terbuka. Anda dapat berkontribusi atau melaporkan permasalahan/bug di Github {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Tingkat Lanjut",
   "home.column_settings.basic": "Dasar",
-  "home.column_settings.filter_regex": "Saring dengan regular expressions",
   "home.column_settings.show_reblogs": "Tampilkan boost",
   "home.column_settings.show_replies": "Tampilkan balasan",
-  "home.settings": "Pengaturan kolom",
   "keyboard_shortcuts.back": "untuk kembali",
   "keyboard_shortcuts.boost": "untuk menyebarkan",
   "keyboard_shortcuts.column": "untuk fokus kepada sebuah status di sebuah kolom",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Difavoritkan",
+  "status.filtered": "Filtered",
   "status.load_more": "Tampilkan semua",
   "status.media_hidden": "Media disembunyikan",
   "status.mention": "Balasan @{name}",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 7789c9994..24758bd2e 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon esas programaro kun apertita kodexo. Tu povas kontributar o signalar problemi en GitHub ye {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Komplexa",
   "home.column_settings.basic": "Simpla",
-  "home.column_settings.filter_regex": "Ekfiltrar per reguloza expresuri",
   "home.column_settings.show_reblogs": "Montrar repeti",
   "home.column_settings.show_replies": "Montrar respondi",
-  "home.settings": "Aranji di la kolumno",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorizar",
+  "status.filtered": "Filtered",
   "status.load_more": "Kargar pluse",
   "status.media_hidden": "Kontenajo celita",
   "status.mention": "Mencionar @{name}",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 61eba2f5a..287549769 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon è un software open source. Puoi contribuire o segnalare errori su GitHub all'indirizzo {github}.",
   "getting_started.security": "Sicurezza",
   "getting_started.terms": "Condizioni del servizio",
-  "home.column_settings.advanced": "Avanzato",
   "home.column_settings.basic": "Semplice",
-  "home.column_settings.filter_regex": "Filtra con espressioni regolari",
   "home.column_settings.show_reblogs": "Mostra post condivisi",
   "home.column_settings.show_replies": "Mostra risposte",
-  "home.settings": "Impostazioni colonna",
   "keyboard_shortcuts.back": "per tornare indietro",
   "keyboard_shortcuts.boost": "per condividere",
   "keyboard_shortcuts.column": "per portare il focus su uno status in una delle colonne",
@@ -259,6 +256,7 @@
   "status.direct": "Messaggio diretto @{name}",
   "status.embed": "Incorpora",
   "status.favourite": "Apprezzato",
+  "status.filtered": "Filtered",
   "status.load_more": "Mostra di più",
   "status.media_hidden": "Allegato nascosto",
   "status.mention": "Nomina @{name}",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 22d65c74c..e7947acf8 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -120,18 +120,15 @@
   "follow_request.reject": "拒否",
   "getting_started.developers": "開発",
   "getting_started.documentation": "ドキュメント",
-  "getting_started.find_friends": "Twitterでの友達を探す",
+  "getting_started.find_friends": "Twitterの友達を探す",
   "getting_started.heading": "スタート",
   "getting_started.invite": "招待",
   "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub({github})から開発に参加したり、問題を報告したりできます。",
   "getting_started.security": "セキュリティ",
   "getting_started.terms": "プライバシーポリシー",
-  "home.column_settings.advanced": "高度な設定",
   "home.column_settings.basic": "基本設定",
-  "home.column_settings.filter_regex": "正規表現でフィルター",
   "home.column_settings.show_reblogs": "ブースト表示",
   "home.column_settings.show_replies": "返信表示",
-  "home.settings": "カラム設定",
   "keyboard_shortcuts.back": "戻る",
   "keyboard_shortcuts.boost": "ブースト",
   "keyboard_shortcuts.column": "左からn番目のカラム内最新トゥートに移動",
@@ -264,6 +261,7 @@
   "status.direct": "@{name}さんにダイレクトメッセージ",
   "status.embed": "埋め込み",
   "status.favourite": "お気に入り",
+  "status.filtered": "Filtered",
   "status.load_more": "もっと見る",
   "status.media_hidden": "非表示のメディア",
   "status.mention": "@{name}さんにトゥート",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 1a3a4d23f..10da7d358 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon은 오픈 소스 소프트웨어입니다. 누구나 GitHub({github})에서 개발에 참여하거나, 문제를 보고할 수 있습니다.",
   "getting_started.security": "보안",
   "getting_started.terms": "이용 약관",
-  "home.column_settings.advanced": "고급 사용자용",
   "home.column_settings.basic": "기본 설정",
-  "home.column_settings.filter_regex": "정규 표현식으로 필터링",
   "home.column_settings.show_reblogs": "부스트 표시",
   "home.column_settings.show_replies": "답글 표시",
-  "home.settings": "컬럼 설정",
   "keyboard_shortcuts.back": "뒤로가기",
   "keyboard_shortcuts.boost": "부스트",
   "keyboard_shortcuts.column": "해당 열에 포커스",
@@ -259,6 +256,7 @@
   "status.direct": "@{name}에게 다이렉트 메시지",
   "status.embed": "공유하기",
   "status.favourite": "즐겨찾기",
+  "status.filtered": "Filtered",
   "status.load_more": "더 보기",
   "status.media_hidden": "미디어 숨겨짐",
   "status.mention": "답장",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 891e5b45b..ac785fb24 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon is vrije software. Je kunt bijdragen of problemen melden op GitHub via {github}.",
   "getting_started.security": "Beveiliging",
   "getting_started.terms": "Voorwaarden",
-  "home.column_settings.advanced": "Geavanceerd",
   "home.column_settings.basic": "Algemeen",
-  "home.column_settings.filter_regex": "Wegfilteren met reguliere expressies",
   "home.column_settings.show_reblogs": "Boosts tonen",
   "home.column_settings.show_replies": "Reacties tonen",
-  "home.settings": "Kolom-instellingen",
   "keyboard_shortcuts.back": "om terug te gaan",
   "keyboard_shortcuts.boost": "om te boosten",
   "keyboard_shortcuts.column": "om op een toot te focussen in één van de kolommen",
@@ -170,12 +167,12 @@
   "navigation_bar.edit_profile": "Profiel bewerken",
   "navigation_bar.favourites": "Favorieten",
   "navigation_bar.follow_requests": "Volgverzoeken",
-  "navigation_bar.info": "Uitgebreide informatie",
+  "navigation_bar.info": "Over deze server",
   "navigation_bar.keyboard_shortcuts": "Sneltoetsen",
   "navigation_bar.lists": "Lijsten",
   "navigation_bar.logout": "Afmelden",
   "navigation_bar.mutes": "Genegeerde gebruikers",
-  "navigation_bar.personal": "Personal",
+  "navigation_bar.personal": "Persoonlijk",
   "navigation_bar.pins": "Vastgezette toots",
   "navigation_bar.preferences": "Instellingen",
   "navigation_bar.public_timeline": "Globale tijdlijn",
@@ -259,6 +256,7 @@
   "status.direct": "Directe toot @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favoriet",
+  "status.filtered": "Filtered",
   "status.load_more": "Meer laden",
   "status.media_hidden": "Media verborgen",
   "status.mention": "Vermeld @{name}",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 0491d3f7a..295d44ae8 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon er fri programvare. Du kan bidra eller rapportere problemer på GitHub på {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avansert",
   "home.column_settings.basic": "Enkel",
-  "home.column_settings.filter_regex": "Filtrér med regulære uttrykk",
   "home.column_settings.show_reblogs": "Vis fremhevinger",
   "home.column_settings.show_replies": "Vis svar",
-  "home.settings": "Kolonneinnstillinger",
   "keyboard_shortcuts.back": "for å navigere tilbake",
   "keyboard_shortcuts.boost": "å fremheve",
   "keyboard_shortcuts.column": "å fokusere en status i en av kolonnene",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Bygge inn",
   "status.favourite": "Lik",
+  "status.filtered": "Filtered",
   "status.load_more": "Last mer",
   "status.media_hidden": "Media skjult",
   "status.mention": "Nevn @{name}",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index bf92ff433..cb9ff8713 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -83,9 +83,9 @@
   "confirmations.domain_block.confirm": "Amagar tot lo domeni",
   "confirmations.domain_block.message": "Volètz vertadièrament blocar complètament {domain} ? De còps cal pas que blocar o rescondre unas personas solament.\nVeiretz pas cap de contengut d’aquel domeni dins cap de flux public o dins vòstras notificacions. Vòstres seguidors d’aquel domeni seràn levats.",
   "confirmations.mute.confirm": "Rescondre",
-  "confirmations.mute.message": "Sètz segur de voler rescondre {name} ?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.mute.message": "Volètz vertadièrament rescondre {name} ?",
+  "confirmations.redraft.confirm": "Escafar & tornar formular",
+  "confirmations.redraft.message": "Volètz vertadièrament escafar aqueste estatut e lo reformular ? Perdretz totas sas responsas, sos partiments e favorits.",
   "confirmations.unfollow.confirm": "Quitar de sègre",
   "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?",
   "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.",
@@ -114,20 +114,17 @@
   "empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autras instàncias per garnir lo flux public",
   "follow_request.authorize": "Acceptar",
   "follow_request.reject": "Regetar",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Desvelopaires",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Trobar d’amics de Twitter",
   "getting_started.heading": "Per començar",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Convidar de monde",
   "getting_started.open_source_notice": "Mastodon es un logicial liure. Podètz contribuir e mandar vòstres comentaris e rapòrt de bug via {github} sus GitHub.",
-  "getting_started.security": "Security",
+  "getting_started.security": "Seguretat",
   "getting_started.terms": "Condicions d’utilizacion",
-  "home.column_settings.advanced": "Avançat",
   "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filtrar amb una expression racionala",
   "home.column_settings.show_reblogs": "Mostrar los partatges",
   "home.column_settings.show_replies": "Mostrar las responsas",
-  "home.settings": "Paramètres de la colomna",
   "keyboard_shortcuts.back": "anar enrèire",
   "keyboard_shortcuts.boost": "partejar",
   "keyboard_shortcuts.column": "centrar un estatut a una colomna",
@@ -259,6 +256,7 @@
   "status.direct": "Messatge per @{name}",
   "status.embed": "Embarcar",
   "status.favourite": "Apondre als favorits",
+  "status.filtered": "Filtered",
   "status.load_more": "Cargar mai",
   "status.media_hidden": "Mèdia rescondut",
   "status.mention": "Mencionar",
@@ -271,7 +269,7 @@
   "status.reblog": "Partejar",
   "status.reblog_private": "Partejar a l’audiéncia d’origina",
   "status.reblogged_by": "{name} a partejat",
-  "status.redraft": "Delete & re-draft",
+  "status.redraft": "Escafar e tornar formular",
   "status.reply": "Respondre",
   "status.replyAll": "Respondre a la conversacion",
   "status.report": "Senhalar @{name}",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 96e13fed4..da35af8e4 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -63,7 +63,7 @@
   "column_subheading.lists": "Listy",
   "column_subheading.navigation": "Nawigacja",
   "column_subheading.settings": "Ustawienia",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Tylko zawartość multimedialna",
   "compose_form.direct_message_warning": "Ten wpis będzie widoczny tylko dla wszystkich wspomnianych użytkowników.",
   "compose_form.direct_message_warning_learn_more": "Dowiedz się więcej",
   "compose_form.hashtag_warning": "Ten wpis nie będzie widoczny pod podanymi hashtagami, ponieważ jest oznaczony jako niewidoczny. Tylko publiczne wpisy mogą zostać znalezione z użyciem hashtagów.",
@@ -118,20 +118,17 @@
   "empty_column.public": "Tu nic nie ma! Napisz coś publicznie, lub dodaj ludzi z innych instancji, aby to wyświetlić",
   "follow_request.authorize": "Autoryzuj",
   "follow_request.reject": "Odrzuć",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Dla programistów",
   "getting_started.documentation": "Dokumentacja",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Znajdź znajomych z Twittera",
   "getting_started.heading": "Rozpocznij",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Zaproś znajomych",
   "getting_started.open_source_notice": "Mastodon jest oprogramowaniem o otwartym źródle. Możesz pomóc w rozwoju lub zgłaszać błędy na GitHubie tutaj: {github}.",
-  "getting_started.security": "Security",
+  "getting_started.security": "Bezpieczeństwo",
   "getting_started.terms": "Zasady użytkowania",
-  "home.column_settings.advanced": "Zaawansowane",
   "home.column_settings.basic": "Podstawowe",
-  "home.column_settings.filter_regex": "Filtruj z użyciem wyrażeń regularnych",
   "home.column_settings.show_reblogs": "Pokazuj podbicia",
   "home.column_settings.show_replies": "Pokazuj odpowiedzi",
-  "home.settings": "Ustawienia kolumny",
   "keyboard_shortcuts.back": "aby cofnąć się",
   "keyboard_shortcuts.boost": "aby podbić wpis",
   "keyboard_shortcuts.column": "aby przejść do wpisu z jednej z kolumn",
@@ -264,6 +261,7 @@
   "status.direct": "Wyślij wiadomość bezpośrednią do @{name}",
   "status.embed": "Osadź",
   "status.favourite": "Dodaj do ulubionych",
+  "status.filtered": "Filtrowany",
   "status.load_more": "Załaduj więcej",
   "status.media_hidden": "Zawartość multimedialna ukryta",
   "status.mention": "Wspomnij o @{name}",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 0697d9ab9..37684efb7 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -59,7 +59,7 @@
   "column_header.show_settings": "Mostrar configurações",
   "column_header.unpin": "Desafixar",
   "column_subheading.settings": "Configurações",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Apenas mídia",
   "compose_form.direct_message_warning": "Este toot só será enviado aos usuários mencionados.",
   "compose_form.direct_message_warning_learn_more": "Saber mais",
   "compose_form.hashtag_warning": "Esse toot não será listado em nenhuma hashtag por ser não listado. Somente toots públicos podem ser pesquisados por hashtag.",
@@ -114,20 +114,17 @@
   "empty_column.public": "Não há nada aqui! Escreva algo publicamente ou siga manualmente usuários de outras instâncias",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rejeitar",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Desenvolvedores",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Encontre amizades do Twitter",
   "getting_started.heading": "Primeiros passos",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Convide pessoas",
   "getting_started.open_source_notice": "Mastodon é um software de código aberto. Você pode contribuir ou reportar problemas na página do GitHub do projeto: {github}.",
-  "getting_started.security": "Security",
+  "getting_started.security": "Segurança",
   "getting_started.terms": "Termos de serviço",
-  "home.column_settings.advanced": "Avançado",
   "home.column_settings.basic": "Básico",
-  "home.column_settings.filter_regex": "Filtrar com uma expressão regular",
   "home.column_settings.show_reblogs": "Mostrar compartilhamentos",
   "home.column_settings.show_replies": "Mostrar as respostas",
-  "home.settings": "Configurações de colunas",
   "keyboard_shortcuts.back": "para navegar de volta",
   "keyboard_shortcuts.boost": "para compartilhar",
   "keyboard_shortcuts.column": "Focar um status em uma das colunas",
@@ -259,6 +256,7 @@
   "status.direct": "Enviar mensagem direta a @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
+  "status.filtered": "Filtered",
   "status.load_more": "Carregar mais",
   "status.media_hidden": "Mídia escondida",
   "status.mention": "Mencionar @{name}",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index fb0cfc445..bda1020aa 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avançado",
   "home.column_settings.basic": "Básico",
-  "home.column_settings.filter_regex": "Filtrar com uma expressão regular",
   "home.column_settings.show_reblogs": "Mostrar as partilhas",
   "home.column_settings.show_replies": "Mostrar as respostas",
-  "home.settings": "Parâmetros da listagem",
   "keyboard_shortcuts.back": "para voltar",
   "keyboard_shortcuts.boost": "para partilhar",
   "keyboard_shortcuts.column": "para focar uma publicação numa das colunas",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
+  "status.filtered": "Filtered",
   "status.load_more": "Carregar mais",
   "status.media_hidden": "Media escondida",
   "status.mention": "Mencionar @{name}",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 57bd413ea..8bf6012e2 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon - программа с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Дополнительные",
   "home.column_settings.basic": "Основные",
-  "home.column_settings.filter_regex": "Отфильтровать регулярным выражением",
   "home.column_settings.show_reblogs": "Показывать продвижения",
   "home.column_settings.show_replies": "Показывать ответы",
-  "home.settings": "Настройки колонки",
   "keyboard_shortcuts.back": "перейти назад",
   "keyboard_shortcuts.boost": "продвинуть пост",
   "keyboard_shortcuts.column": "фокус на одном из столбцов",
@@ -259,6 +256,7 @@
   "status.direct": "Написать @{name}",
   "status.embed": "Встроить",
   "status.favourite": "Нравится",
+  "status.filtered": "Filtered",
   "status.load_more": "Показать еще",
   "status.media_hidden": "Медиаконтент скрыт",
   "status.mention": "Упомянуть @{name}",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index efe0a2f30..839ef70f9 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -4,7 +4,7 @@
   "account.block_domain": "Ukry všetko z {domain}",
   "account.blocked": "Blokovaný/á",
   "account.direct": "Súkromná správa pre @{name}",
-  "account.disclaimer_full": "Inofrmácie nižšie nemusia byť úplným odrazom uživateľovho účtu.",
+  "account.disclaimer_full": "Inofrmácie uvedené nižšie nemusia byť úplným odrazom uživateľovho účtu.",
   "account.domain_blocked": "Doména ukrytá",
   "account.edit_profile": "Upraviť profil",
   "account.follow": "Následovať",
@@ -65,8 +65,8 @@
   "compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
   "compose_form.lock_disclaimer": "Váš účet nie je zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
   "compose_form.lock_disclaimer.lock": "zamknutý",
-  "compose_form.placeholder": "Na čo myslíš?",
-  "compose_form.publish": "Toot",
+  "compose_form.placeholder": "Čo máš na mysli?",
+  "compose_form.publish": "Pošli",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.marked": "Médiálny obsah je označený ako chúlostivý",
   "compose_form.sensitive.unmarked": "Médiálny obsah nieje označený ako chúlostivý",
@@ -75,13 +75,13 @@
   "compose_form.spoiler_placeholder": "Sem napíšte vaše varovanie",
   "confirmation_modal.cancel": "Zrušiť",
   "confirmations.block.confirm": "Blokovať",
-  "confirmations.block.message": "Ste si istý, že chcete blokovať {name}?",
+  "confirmations.block.message": "Si si istý, že chcete blokovať {name}?",
   "confirmations.delete.confirm": "Zmazať",
-  "confirmations.delete.message": "Naozaj chcete vymazať túto správu?",
+  "confirmations.delete.message": "Si si naozaj istá/ý, že chceš vymazať túto správu?",
   "confirmations.delete_list.confirm": "Vymazať",
-  "confirmations.delete_list.message": "Ste si istý/á, že chceťe navždy vymazať tento zoznam?",
+  "confirmations.delete_list.message": "Si si istý/á, že chceš navždy vymazať tento zoznam?",
   "confirmations.domain_block.confirm": "Skryť celú doménu",
-  "confirmations.domain_block.message": "Si si naozaj istý, že chceš blokovať celú {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych používateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.",
+  "confirmations.domain_block.message": "Si si naozaj istý, že chceš blokovať celú {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych užívateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.",
   "confirmations.mute.confirm": "Ignoruj",
   "confirmations.mute.message": "Naozaj chcete ignorovať {name}?",
   "confirmations.redraft.confirm": "Vyčistiť a prepísať",
@@ -107,11 +107,11 @@
   "empty_column.community": "Lokálna časová os je prázdna. Napíšte niečo, aby sa to tu začalo hýbať!",
   "empty_column.direct": "Ešte nemáš žiadne súkromné správy. Keď nejakú pošleš, alebo dostaneš, ukáže sa tu.",
   "empty_column.hashtag": "Pod týmto hashtagom sa ešte nič nenachádza.",
-  "empty_column.home": "Vaša lokálna osa je zatiaľ prázdna! Pre začiatok pozrite {public} alebo použite vyhľadávanie a nájdite tak ostatných používateľov.",
+  "empty_column.home": "Tvoja lokálna osa je zatiaľ prázdna! Pre začiatok navštív {public}, alebo použi vyhľadávanie a nájdi tak aj iných užívateľov.",
   "empty_column.home.public_timeline": "verejná časová os",
   "empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.",
   "empty_column.notifications": "Nemáš ešte žiadne oznámenia. Zapoj sa s niekym do debaty a komunikuj s ostatnými aby diskusia mohla začať.",
-  "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne alebo začnite sledovať používateľov z iných Mastodon serverov aby tu niečo pribudlo",
+  "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne alebo začnite sledovať užívateľov z iných Mastodon serverov, aby tu tak niečo pribudlo",
   "follow_request.authorize": "Povoľ prístup",
   "follow_request.reject": "Odmietni",
   "getting_started.developers": "Vývojári",
@@ -119,15 +119,12 @@
   "getting_started.find_friends": "Nájdi priateľov z Twitteru",
   "getting_started.heading": "Začni tu",
   "getting_started.invite": "Pozvať ľudí",
-  "getting_started.open_source_notice": "Mastodon má otvorený kód. Nahlásiť chyby, alebo prispieť môžeš na GitHube v {github}.",
+  "getting_started.open_source_notice": "Mastodon je softvér s otvoreným kódom. Nahlásiť chyby, alebo prispievať môžeš na GitHube v {github}.",
   "getting_started.security": "Zabezpečenie",
   "getting_started.terms": "Podmienky prevozu",
-  "home.column_settings.advanced": "Pokročilé",
   "home.column_settings.basic": "Základné",
-  "home.column_settings.filter_regex": "Filtrovať použitím regulárnych výrazov",
   "home.column_settings.show_reblogs": "Zobraziť povýšené",
   "home.column_settings.show_replies": "Ukázať odpovede",
-  "home.settings": "Nastavenia stĺpcov",
   "keyboard_shortcuts.back": "dostať sa naspäť",
   "keyboard_shortcuts.boost": "vyzdvihnúť",
   "keyboard_shortcuts.column": "zamerať sa na status v jednom zo stĺpcov",
@@ -156,8 +153,8 @@
   "lists.new.create": "Pridať zoznam",
   "lists.new.title_placeholder": "Názov nového zoznamu",
   "lists.search": "Vyhľadávajte medzi užívateľmi ktorých sledujete",
-  "lists.subheading": "Vaše zoznamy",
-  "loading_indicator.label": "Nahrávam...",
+  "lists.subheading": "Tvoje zoznamy",
+  "loading_indicator.label": "Načítam...",
   "media_gallery.toggle_visible": "Zapnúť/Vypnúť viditeľnosť",
   "missing_indicator.label": "Nenájdené",
   "missing_indicator.sublabel": "Tento zdroj sa nepodarilo nájsť",
@@ -203,9 +200,9 @@
   "onboarding.page_four.notifications": "Stĺpec s notifikáciami zobrazí keď budete s niekým komunikovať.",
   "onboarding.page_one.federation": "Mastodon je sieť nezávislých serverov, spojením ktorých vzniká jedna veľká federovaná sociálna sieť.",
   "onboarding.page_one.full_handle": "Vaša celá prezývka aj s adresou",
-  "onboarding.page_one.handle_hint": "Toto je čo by ste povedali vaším priateľom že majú hľadať.",
-  "onboarding.page_one.welcome": "Vitajte na Mastodone!",
-  "onboarding.page_six.admin": "Správca tohto servera je {admin}.",
+  "onboarding.page_one.handle_hint": "Toto je čo by si povedal/a vaším kamarátom, že majú hľadať.",
+  "onboarding.page_one.welcome": "Vitaj na Mastodone!",
+  "onboarding.page_six.admin": "Správcom tvojej instancie je {admin}.",
   "onboarding.page_six.almost_done": "Takmer hotovo...",
   "onboarding.page_six.appetoot": "Bon Appetoot!",
   "onboarding.page_six.apps_available": "Aplikácie {apps} sú dostupné na pre iOS, Android and ďalšie platformy.",
@@ -259,7 +256,8 @@
   "status.direct": "Súkromná správa @{name}",
   "status.embed": "Vložiť",
   "status.favourite": "Páči sa mi",
-  "status.load_more": "Zobraz viac",
+  "status.filtered": "Filtered",
+  "status.load_more": "Ukáž viac",
   "status.media_hidden": "Skryté médiá",
   "status.mention": "Spomeň @{name}",
   "status.more": "Viac",
@@ -280,7 +278,7 @@
   "status.share": "Zdieľať",
   "status.show_less": "Zobraz menej",
   "status.show_less_all": "Všetkým ukáž menej",
-  "status.show_more": "Zobraziť viac",
+  "status.show_more": "Ukáž viac",
   "status.show_more_all": "Všetkým ukáž viac",
   "status.unmute_conversation": "Prestať ignorovať konverzáciu",
   "status.unpin": "Odopnúť z profilu",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 7e4307c2a..f738274db 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon je odprtokodna programska oprema. V GitHubu na {github} lahko prispevate ali poročate o napakah.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Napredno",
   "home.column_settings.basic": "Osnovno",
-  "home.column_settings.filter_regex": "Filtrirajte z navadnimi izrazi",
   "home.column_settings.show_reblogs": "Pokaži sunke",
   "home.column_settings.show_replies": "Pokaži odgovore",
-  "home.settings": "Nastavitve stolpcev",
   "keyboard_shortcuts.back": "za krmarjenje nazaj",
   "keyboard_shortcuts.boost": "suniti",
   "keyboard_shortcuts.column": "osredotočiti status v enega od stolpcev",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
   "status.load_more": "Load more",
   "status.media_hidden": "Media hidden",
   "status.mention": "Mention @{name}",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index 7a72ba6fb..6c7e56fe8 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodont je softver otvorenog koda. Možete mu doprineti ili prijaviti probleme preko GitHub-a na {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Napredno",
   "home.column_settings.basic": "Osnovno",
-  "home.column_settings.filter_regex": "Filtriraj regularnim izrazima",
   "home.column_settings.show_reblogs": "Prikaži i podržavanja",
   "home.column_settings.show_replies": "Prikaži odgovore",
-  "home.settings": "Postavke kolone",
   "keyboard_shortcuts.back": "da odete nazad",
   "keyboard_shortcuts.boost": "da podržite",
   "keyboard_shortcuts.column": "da se prebacite na status u jednoj od kolona",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Ugradi na sajt",
   "status.favourite": "Omiljeno",
+  "status.filtered": "Filtered",
   "status.load_more": "Učitaj još",
   "status.media_hidden": "Multimedija sakrivena",
   "status.mention": "Pomeni korisnika @{name}",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index c699bd8fd..6a9e80559 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Мастoдонт је софтвер отвореног кода. Можете му допринети или пријавити проблеме преко GitHub-а на {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Напредно",
   "home.column_settings.basic": "Основно",
-  "home.column_settings.filter_regex": "Филтрирај регуларним изразима",
   "home.column_settings.show_reblogs": "Прикажи и подржавања",
   "home.column_settings.show_replies": "Прикажи одговоре",
-  "home.settings": "Поставке колоне",
   "keyboard_shortcuts.back": "да одете назад",
   "keyboard_shortcuts.boost": "да подржите",
   "keyboard_shortcuts.column": "да се пребаците на статус у једној од колона",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Угради на сајт",
   "status.favourite": "Омиљено",
+  "status.filtered": "Filtered",
   "status.load_more": "Учитај још",
   "status.media_hidden": "Мултимедија сакривена",
   "status.mention": "Помени корисника @{name}",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 00d2fee8e..0701bf925 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -1,5 +1,5 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Robot",
   "account.block": "Blockera @{name}",
   "account.block_domain": "Dölj allt från {domain}",
   "account.blocked": "Blockerad",
@@ -59,9 +59,9 @@
   "column_header.show_settings": "Visa inställningar",
   "column_header.unpin": "Ångra fäst",
   "column_subheading.settings": "Inställningar",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "Enbart media",
   "compose_form.direct_message_warning": "Denna toot kommer endast att skickas nämnda nämnda användare.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "compose_form.direct_message_warning_learn_more": "Visa mer",
   "compose_form.hashtag_warning": "Denna toot kommer inte att listas under någon hashtag eftersom den är onoterad. Endast offentliga toots kan sökas med hashtag.",
   "compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vemsomhelst kan följa dig och även se dina inlägg skrivna för endast dina följare.",
   "compose_form.lock_disclaimer.lock": "låst",
@@ -81,11 +81,11 @@
   "confirmations.delete_list.confirm": "Delete",
   "confirmations.delete_list.message": "Är du säker på att du vill radera denna lista permanent?",
   "confirmations.domain_block.confirm": "Blockera hela domänen",
-  "confirmations.domain_block.message": "Är du verkligen, verkligen säker på att du vill blockera hela {domain}? I de flesta fall är några riktade blockeringar eller nedtystade tillräckligt och föredras.",
+  "confirmations.domain_block.message": "Är du verkligen säker på att du vill blockera hela {domain}? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer sluta se innehåll från {domain}-domänen i den allmänna tidslinjen och i dina egna notifieringar. Du kommer även sluta följa alla eventuella följare du har från {domain}.",
   "confirmations.mute.confirm": "Tysta",
   "confirmations.mute.message": "Är du säker du vill tysta ner {name}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.redraft.confirm": "Radera och gör om",
+  "confirmations.redraft.message": "Är du säker på att du vill radera meddelandet och göra om det? Du kommer förlora alla svar, knuffar och favoriter som hänvisar till meddelandet.",
   "confirmations.unfollow.confirm": "Sluta följa",
   "confirmations.unfollow.message": "Är du säker på att du vill sluta följa {name}?",
   "embed.instructions": "Bädda in den här statusen på din webbplats genom att kopiera koden nedan.",
@@ -114,20 +114,17 @@
   "empty_column.public": "Det finns inget här! Skriv något offentligt, eller följ manuellt användarna från andra instanser för att fylla på det",
   "follow_request.authorize": "Godkänn",
   "follow_request.reject": "Avvisa",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "Utvecklare",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "Hitta vänner från Twitter",
   "getting_started.heading": "Kom igång",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "Skicka inbjudningar",
   "getting_started.open_source_notice": "Mastodon är programvara med öppen källkod. Du kan bidra eller rapportera problem via GitHub på {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Avancerad",
+  "getting_started.security": "Säkerhet",
+  "getting_started.terms": "Användarvillkor",
   "home.column_settings.basic": "Grundläggande",
-  "home.column_settings.filter_regex": "Filtrera ut med regelbundna uttryck",
   "home.column_settings.show_reblogs": "Visa knuffar",
   "home.column_settings.show_replies": "Visa svar",
-  "home.settings": "Kolumninställningar",
   "keyboard_shortcuts.back": "att navigera tillbaka",
   "keyboard_shortcuts.boost": "att knuffa",
   "keyboard_shortcuts.column": "att fokusera en status i en av kolumnerna",
@@ -165,7 +162,7 @@
   "navigation_bar.blocks": "Blockerade användare",
   "navigation_bar.community_timeline": "Lokal tidslinje",
   "navigation_bar.direct": "Direktmeddelanden",
-  "navigation_bar.discover": "Discover",
+  "navigation_bar.discover": "Upptäck",
   "navigation_bar.domain_blocks": "Dolda domäner",
   "navigation_bar.edit_profile": "Redigera profil",
   "navigation_bar.favourites": "Favoriter",
@@ -179,7 +176,7 @@
   "navigation_bar.pins": "Nålade inlägg (toots)",
   "navigation_bar.preferences": "Inställningar",
   "navigation_bar.public_timeline": "Förenad tidslinje",
-  "navigation_bar.security": "Security",
+  "navigation_bar.security": "Säkerhet",
   "notification.favourite": "{name} favoriserade din status",
   "notification.follow": "{name} följer dig",
   "notification.mention": "{name} nämnde dig",
@@ -195,7 +192,7 @@
   "notifications.column_settings.reblog": "Knuffar:",
   "notifications.column_settings.show": "Visa i kolumnen",
   "notifications.column_settings.sound": "Spela upp ljud",
-  "notifications.group": "{count} notifications",
+  "notifications.group": "{count} aviseringar",
   "onboarding.done": "Klart",
   "onboarding.next": "Nästa",
   "onboarding.page_five.public_timelines": "Den lokala tidslinjen visar offentliga inlägg från alla på {domain}. Den förenade tidslinjen visar offentliga inlägg från alla personer på {domain} som följer. Dom här offentliga tidslinjerna är ett bra sätt att upptäcka nya människor.",
@@ -259,6 +256,7 @@
   "status.direct": "Direktmeddela @{name}",
   "status.embed": "Bädda in",
   "status.favourite": "Favorit",
+  "status.filtered": "Filtered",
   "status.load_more": "Ladda fler",
   "status.media_hidden": "Media dold",
   "status.mention": "Omnämn @{name}",
@@ -271,7 +269,7 @@
   "status.reblog": "Knuff",
   "status.reblog_private": "Knuffa till de ursprungliga åhörarna",
   "status.reblogged_by": "{name} knuffade",
-  "status.redraft": "Delete & re-draft",
+  "status.redraft": "Radera & gör om",
   "status.reply": "Svara",
   "status.replyAll": "Svara på tråden",
   "status.report": "Rapportera @{name}",
@@ -289,7 +287,7 @@
   "tabs_bar.local_timeline": "Lokal",
   "tabs_bar.notifications": "Meddelanden",
   "tabs_bar.search": "Sök",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.count_by_accounts": "{count} {rawCount, plural, en {person} andra {people}} pratar",
   "ui.beforeunload": "Ditt utkast kommer att förloras om du lämnar Mastodon.",
   "upload_area.title": "Dra & släpp för att ladda upp",
   "upload_button.label": "Lägg till media",
@@ -300,7 +298,7 @@
   "video.close": "Stäng video",
   "video.exit_fullscreen": "Stäng helskärm",
   "video.expand": "Expandera video",
-  "video.fullscreen": "Fullskärm",
+  "video.fullscreen": "Helskärm",
   "video.hide": "Dölj video",
   "video.mute": "Stäng av ljud",
   "video.pause": "Pause",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 74fe732e1..8928bfb9b 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -1,309 +1,307 @@
 {
-  "account.badges.bot": "Bot",
-  "account.block": "Block @{name}",
-  "account.block_domain": "Hide everything from {domain}",
-  "account.blocked": "Blocked",
-  "account.direct": "Direct message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
-  "account.edit_profile": "Edit profile",
-  "account.follow": "Follow",
-  "account.followers": "Followers",
-  "account.follows": "Follows",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.media": "Media",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Toots",
-  "account.posts_with_replies": "Toots and replies",
-  "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval. Click to cancel follow request",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "boost_modal.combo": "You can press {combo} to skip this next time",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Try again",
-  "bundle_column_error.title": "Network error",
-  "bundle_modal_error.close": "Close",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Try again",
-  "column.blocks": "Blocked users",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
-  "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
-  "column.notifications": "Notifications",
+  "account.badges.bot": "బాట్",
+  "account.block": "@{name} ను బ్లాక్ చేయి",
+  "account.block_domain": "{domain} నుంచి అన్నీ దాచిపెట్టు",
+  "account.blocked": "బ్లాక్ అయినవి",
+  "account.direct": "@{name}కు నేరుగా సందేశం పంపు",
+  "account.disclaimer_full": "క్రింది సమాచారం వాడుకరి యొక్క ప్రొఫైల్ను అసంపూర్తిగా ప్రతిబింబించవచ్చు.",
+  "account.domain_blocked": "డొమైన్ దాచిపెట్టబడినది",
+  "account.edit_profile": "ప్రొఫైల్ని సవరించండి",
+  "account.follow": "అనుసరించు",
+  "account.followers": "అనుచరులు",
+  "account.follows": "అనుసరిస్తున్నవి",
+  "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు",
+  "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు",
+  "account.media": "మీడియా",
+  "account.mention": "@{name}ను ప్రస్తావించు",
+  "account.moved_to": "{name} ఇక్కడికి మారారు:",
+  "account.mute": "@{name}ను మ్యూట్ చెయ్యి",
+  "account.mute_notifications": "@{name}నుంచి ప్రకటనలను మ్యూట్ చెయ్యి",
+  "account.muted": "మ్యూట్ అయినవి",
+  "account.posts": "టూట్లు",
+  "account.posts_with_replies": "టూట్లు మరియు ప్రత్యుత్తరములు",
+  "account.report": "@{name}పై ఫిర్యాదుచేయు",
+  "account.requested": "ఆమోదం కోసం వేచి ఉంది. అభ్యర్థనను రద్దు చేయడానికి క్లిక్ చేయండి",
+  "account.share": "@{name} యొక్క ప్రొఫైల్ను పంచుకోండి",
+  "account.show_reblogs": "@{name}నుంచి బూస్ట్ లను చూపించు",
+  "account.unblock": "@{name}పై బ్లాక్ ను తొలగించు",
+  "account.unblock_domain": "{domain}ను దాచవద్దు",
+  "account.unfollow": "అనుసరించవద్దు",
+  "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు",
+  "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు",
+  "account.view_full_profile": "పూర్తి ప్రొఫైల్ను చూడండి",
+  "alert.unexpected.message": "అనుకోని తప్పు జరిగినది.",
+  "alert.unexpected.title": "అయ్యో!",
+  "boost_modal.combo": "మీరు తదుపరిసారి దీనిని దాటవేయడానికి {combo} నొక్కవచ్చు",
+  "bundle_column_error.body": "ఈ భాగం లోడ్ అవుతున్నప్పుడు ఏదో తప్పు జరిగింది.",
+  "bundle_column_error.retry": "మళ్ళీ ప్రయత్నించండి",
+  "bundle_column_error.title": "నెట్వర్క్ లోపం",
+  "bundle_modal_error.close": "మూసివేయు",
+  "bundle_modal_error.message": "ఈ భాగం లోడ్ అవుతున్నప్పుడు ఏదో తప్పు జరిగింది.",
+  "bundle_modal_error.retry": "మళ్ళీ ప్రయత్నించండి",
+  "column.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు",
+  "column.community": "స్థానిక కాలక్రమం",
+  "column.direct": "ప్రత్యక్ష సందేశాలు",
+  "column.domain_blocks": "దాచిన డొమైన్లు",
+  "column.favourites": "ఇష్టపడినవి",
+  "column.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
+  "column.home": "హోమ్",
+  "column.lists": "జాబితాలు",
+  "column.mutes": "మ్యూట్ చేయబడిన వినియోగదారులు",
+  "column.notifications": "ప్రకటనలు",
   "column.pins": "Pinned toot",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "column_header.hide_settings": "Hide settings",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
-  "column_header.pin": "Pin",
-  "column_header.show_settings": "Show settings",
-  "column_header.unpin": "Unpin",
-  "column_subheading.settings": "Settings",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
-  "compose_form.lock_disclaimer.lock": "locked",
-  "compose_form.placeholder": "What is on your mind?",
-  "compose_form.publish": "Toot",
+  "column.public": "సమాఖ్య కాలక్రమం",
+  "column_back_button.label": "వెనక్కి",
+  "column_header.hide_settings": "అమర్పులను దాచిపెట్టు",
+  "column_header.moveLeft_settings": "నిలువు వరుసను ఎడమకి తరలించు",
+  "column_header.moveRight_settings": "నిలువు వరుసను కుడికి తరలించు",
+  "column_header.pin": "అతికించు",
+  "column_header.show_settings": "అమర్పులను చూపించు",
+  "column_header.unpin": "పీకివేయు",
+  "column_subheading.settings": "అమర్పులు",
+  "community.column_settings.media_only": "మీడియా మాత్రమే",
+  "compose_form.direct_message_warning": "ఈ టూట్ పేర్కొన్న వినియోగదారులకు మాత్రమే పంపబడుతుంది.",
+  "compose_form.direct_message_warning_learn_more": "మరింత తెలుసుకోండి",
+  "compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
+  "compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
+  "compose_form.lock_disclaimer.lock": "బిగించబడినది",
+  "compose_form.placeholder": "మీ మనస్సులో ఏమి ఉంది?",
+  "compose_form.publish": "టూట్",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Write your warning here",
-  "confirmation_modal.cancel": "Cancel",
-  "confirmations.block.confirm": "Block",
-  "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.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
-  "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}?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
-  "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.hashtag": "There is nothing in this hashtag yet.",
-  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
-  "empty_column.home.public_timeline": "the public timeline",
-  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
-  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
-  "follow_request.authorize": "Authorize",
-  "follow_request.reject": "Reject",
-  "getting_started.developers": "Developers",
+  "compose_form.sensitive.marked": "మీడియా సున్నితమైనదిగా గుర్తించబడింది",
+  "compose_form.sensitive.unmarked": "మీడియా సున్నితమైనదిగా గుర్తించబడలేదు",
+  "compose_form.spoiler.marked": "హెచ్చరిక వెనుక పాఠ్యం దాచబడింది",
+  "compose_form.spoiler.unmarked": "పాఠ్యం దాచబడలేదు",
+  "compose_form.spoiler_placeholder": "ఇక్కడ మీ హెచ్చరికను రాయండి",
+  "confirmation_modal.cancel": "రద్దు చెయ్యి",
+  "confirmations.block.confirm": "బ్లాక్ చేయి",
+  "confirmations.block.message": "మీరు ఖచ్చితంగా {name}ని బ్లాక్ చేయాలనుకుంటున్నారా?",
+  "confirmations.delete.confirm": "తొలగించు",
+  "confirmations.delete.message": "మీరు ఖచ్చితంగా ఈ స్టేటస్ ని తొలగించాలనుకుంటున్నారా?",
+  "confirmations.delete_list.confirm": "తొలగించు",
+  "confirmations.delete_list.message": "మీరు ఖచ్చితంగా ఈ జాబితాను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?",
+  "confirmations.domain_block.confirm": "మొత్తం డొమైన్ను దాచు",
+  "confirmations.domain_block.message": "మీరు నిజంగా నిజంగా మొత్తం {domain} ని బ్లాక్ చేయాలనుకుంటున్నారా? చాలా సందర్భాలలో కొన్ని లక్ష్యంగా ఉన్న బ్లాక్స్ లేదా మ్యూట్స్ సరిపోతాయి మరియు ఉత్తమమైనవి. మీరు ఆ డొమైన్ నుండి కంటెంట్ను ఏ ప్రజా కాలక్రమాలలో లేదా మీ నోటిఫికేషన్లలో చూడలేరు. ఆ డొమైన్ నుండి మీ అనుచరులు తీసివేయబడతారు.",
+  "confirmations.mute.confirm": "మ్యూట్ చేయి",
+  "confirmations.mute.message": "{name}ను మీరు ఖచ్చితంగా మ్యూట్ చేయాలనుకుంటున్నారా?",
+  "confirmations.redraft.confirm": "తొలగించు & తిరగరాయు",
+  "confirmations.redraft.message": "మీరు ఖచ్చితంగా ఈ స్టేటస్ ని తొలగించి తిరగరాయాలనుకుంటున్నారా? మీరు అన్ని ప్రత్యుత్తరాలను, బూస్ట్ లను మరియు ఇష్టపడినవి కోల్పోతారు.",
+  "confirmations.unfollow.confirm": "అనుసరించవద్దు",
+  "confirmations.unfollow.message": "{name}ను మీరు ఖచ్చితంగా అనుసరించవద్దనుకుంటున్నారా?",
+  "embed.instructions": "దిగువ కోడ్ను కాపీ చేయడం ద్వారా మీ వెబ్సైట్లో ఈ స్టేటస్ ని పొందుపరచండి.",
+  "embed.preview": "అది ఈ క్రింది విధంగా కనిపిస్తుంది:",
+  "emoji_button.activity": "కార్యకలాపాలు",
+  "emoji_button.custom": "అనుకూలీకరించిన",
+  "emoji_button.flags": "ఫ్లాగ్స్",
+  "emoji_button.food": "ఆహారం & పానీయం",
+  "emoji_button.label": "ఎమోజి చొప్పించు",
+  "emoji_button.nature": "ప్రకృతి",
+  "emoji_button.not_found": "ఎమోజీలు లేవు!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "వస్తువులు",
+  "emoji_button.people": "ప్రజలు",
+  "emoji_button.recent": "తరచుగా ఉపయోగించునవి",
+  "emoji_button.search": "వెదుకు...",
+  "emoji_button.search_results": "శోధన ఫలితాలు",
+  "emoji_button.symbols": "చిహ్నాలు",
+  "emoji_button.travel": "ప్రయాణం & ప్రదేశాలు",
+  "empty_column.community": "స్థానిక కాలక్రమం ఖాళీగా ఉంది. మొదలుపెట్టడానికి బహిరంగంగా ఏదో ఒకటి వ్రాయండి!",
+  "empty_column.direct": "మీకు ఇంకా ఏ ప్రత్యక్ష సందేశాలు లేవు. మీరు ఒకదాన్ని పంపినప్పుడు లేదా స్వీకరించినప్పుడు, అది ఇక్కడ చూపబడుతుంది.",
+  "empty_column.hashtag": "ఇంకా హాష్ ట్యాగ్లో ఏమీ లేదు.",
+  "empty_column.home": "మీ హోమ్ కాలక్రమం ఖాళీగా ఉంది! {Public} ను సందర్శించండి లేదా ఇతర వినియోగదారులను కలుసుకోవడానికి మరియు అన్వేషణ కోసం శోధనను ఉపయోగించండి.",
+  "empty_column.home.public_timeline": "ప్రజా కాలక్రమం",
+  "empty_column.list": "ఇంకా ఈ జాబితాలో ఏదీ లేదు. ఈ జాబితాలోని సభ్యులు కొత్త స్టేటస్ లను పోస్ట్ చేసినప్పుడు, అవి ఇక్కడ కనిపిస్తాయి.",
+  "empty_column.notifications": "మీకు ఇంకా ఏ నోటిఫికేషన్లు లేవు. సంభాషణను ప్రారంభించడానికి ఇతరులతో ప్రతిస్పందించండి.",
+  "empty_column.public": "ఇక్కడ ఏమీ లేదు! దీన్ని నింపడానికి బహిరంగంగా ఏదైనా వ్రాయండి, లేదా ఇతర దృష్టాంతాల్లోని వినియోగదారులను అనుసరించండి",
+  "follow_request.authorize": "అనుమతించు",
+  "follow_request.reject": "తిరస్కరించు",
+  "getting_started.developers": "డెవలపర్లు",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
-  "getting_started.heading": "Getting started",
-  "getting_started.invite": "Invite people",
-  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Advanced",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "getting_started.find_friends": "ట్విట్టర్ నుండి స్నేహితులను కనుగొనండి",
+  "getting_started.heading": "మొదలుపెడదాం",
+  "getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
+  "getting_started.open_source_notice": "మాస్టొడొన్ ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు {github} వద్ద GitHub పై సమస్యలను నివేదించవచ్చు లేదా తోడ్పడచ్చు.",
+  "getting_started.security": "భద్రత",
+  "getting_started.terms": "సేవా నిబంధనలు",
+  "home.column_settings.basic": "ప్రాథమిక",
+  "home.column_settings.show_reblogs": "బూస్ట్ లను చూపించు",
+  "home.column_settings.show_replies": "ప్రత్యుత్తరాలను చూపించు",
+  "keyboard_shortcuts.back": "వెనక్కి తిరిగి వెళ్ళడానికి",
+  "keyboard_shortcuts.boost": "బూస్ట్ చేయడానికి",
+  "keyboard_shortcuts.column": "నిలువు వరుసలలో ఒకదానిపై దృష్టి పెట్టడానికి",
+  "keyboard_shortcuts.compose": "కంపోజ్ టెక్స్ట్ఏరియా పై దృష్టి పెట్టడానికి",
   "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.down": "జాబితాలో క్రిందికి వెళ్ళడానికి",
   "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "lists.delete": "Delete list",
-  "lists.edit": "Edit list",
-  "lists.new.create": "Add list",
-  "lists.new.title_placeholder": "New list title",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
-  "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
-  "missing_indicator.label": "Not found",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.community_timeline": "Local timeline",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
-  "navigation_bar.edit_profile": "Edit profile",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "Extended information",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
-  "navigation_bar.mutes": "Muted users",
-  "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Pinned toots",
-  "navigation_bar.preferences": "Preferences",
-  "navigation_bar.public_timeline": "Federated timeline",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name} favourited your status",
-  "notification.follow": "{name} followed you",
-  "notification.mention": "{name} mentioned you",
-  "notification.reblog": "{name} boosted your status",
-  "notifications.clear": "Clear notifications",
-  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.alert": "Desktop notifications",
-  "notifications.column_settings.favourite": "Favourites:",
-  "notifications.column_settings.follow": "New followers:",
-  "notifications.column_settings.mention": "Mentions:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.group": "{count} notifications",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
-  "privacy.change": "Adjust status privacy",
-  "privacy.direct.long": "Post to mentioned users only",
-  "privacy.direct.short": "Direct",
-  "privacy.private.long": "Post to followers only",
-  "privacy.private.short": "Followers-only",
-  "privacy.public.long": "Post to public timelines",
-  "privacy.public.short": "Public",
-  "privacy.unlisted.long": "Do not show in public timelines",
-  "privacy.unlisted.short": "Unlisted",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "keyboard_shortcuts.favourite": "ఇష్టపడడానికి",
+  "keyboard_shortcuts.heading": "కీబోర్డ్ సత్వరమార్గాలు",
+  "keyboard_shortcuts.hotkey": "హాట్ కీ",
+  "keyboard_shortcuts.legend": "ఈ లెజెండ్ ప్రదర్శించడానికి",
+  "keyboard_shortcuts.mention": "రచయితను ప్రస్తావించడానికి",
+  "keyboard_shortcuts.reply": "ప్రత్యుత్తరం ఇవ్వడానికి",
+  "keyboard_shortcuts.search": "శోధనపై దృష్టి పెట్టండి",
+  "keyboard_shortcuts.toggle_hidden": "CW వెనుక ఉన్న పాఠ్యాన్ని చూపడానికి / దాచడానికి",
+  "keyboard_shortcuts.toot": "ఒక సరికొత్త టూట్ను ప్రారంభించడానికి",
+  "keyboard_shortcuts.unfocus": "పాఠ్యం వ్రాసే ఏరియా/శోధన పట్టిక నుండి బయటకు రావడానికి",
+  "keyboard_shortcuts.up": "జాబితాలో పైకి తరలించడానికి",
+  "lightbox.close": "మూసివేయు",
+  "lightbox.next": "తరువాత",
+  "lightbox.previous": "మునుపటి",
+  "lists.account.add": "జాబితాకు జోడించు",
+  "lists.account.remove": "జాబితా నుండి తొలగించు",
+  "lists.delete": "జాబితాను తొలగించు",
+  "lists.edit": "జాబితాను సవరించు",
+  "lists.new.create": "జాబితాను జోడించు",
+  "lists.new.title_placeholder": "కొత్త జాబితా శీర్షిక",
+  "lists.search": "మీరు అనుసరించే వ్యక్తులలో శోధించండి",
+  "lists.subheading": "మీ జాబితాలు",
+  "loading_indicator.label": "లోడ్ అవుతోంది...",
+  "media_gallery.toggle_visible": "దృశ్యమానతను టోగుల్ చేయండి",
+  "missing_indicator.label": "దొరకలేదు",
+  "missing_indicator.sublabel": "ఈ వనరు కనుగొనబడలేదు",
+  "mute_modal.hide_notifications": "ఈ వినియోగదారు నుండి నోటిఫికేషన్లను దాచాలా?",
+  "navigation_bar.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు",
+  "navigation_bar.community_timeline": "స్థానిక కాలక్రమం",
+  "navigation_bar.direct": "ప్రత్యక్ష సందేశాలు",
+  "navigation_bar.discover": "కనుగొను",
+  "navigation_bar.domain_blocks": "దాచిన డొమైన్లు",
+  "navigation_bar.edit_profile": "ప్రొఫైల్ని సవరించండి",
+  "navigation_bar.favourites": "ఇష్టపడినవి",
+  "navigation_bar.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు",
+  "navigation_bar.info": "ఈ దృష్టాంతం గురించి",
+  "navigation_bar.keyboard_shortcuts": "హాట్ కీలు",
+  "navigation_bar.lists": "జాబితాలు",
+  "navigation_bar.logout": "లాగ్ అవుట్ చేయండి",
+  "navigation_bar.mutes": "మ్యూట్ చేయబడిన వినియోగదారులు",
+  "navigation_bar.personal": "వ్యక్తిగతం",
+  "navigation_bar.pins": "అతికించిన టూట్లు",
+  "navigation_bar.preferences": "ప్రాధాన్యతలు",
+  "navigation_bar.public_timeline": "సమాఖ్య కాలక్రమం",
+  "navigation_bar.security": "భద్రత",
+  "notification.favourite": "{name} మీ స్టేటస్ ను ఇష్టపడ్డారు",
+  "notification.follow": "{name} మిమ్మల్ని అనుసరిస్తున్నారు",
+  "notification.mention": "{name} మిమ్మల్ని ప్రస్తావించారు",
+  "notification.reblog": "{name} మీ స్టేటస్ ను బూస్ట్ చేసారు",
+  "notifications.clear": "ప్రకటనలను తుడిచివేయు",
+  "notifications.clear_confirmation": "మీరు మీ అన్ని నోటిఫికేషన్లను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?",
+  "notifications.column_settings.alert": "డెస్క్టాప్ నోటిఫికేషన్లు",
+  "notifications.column_settings.favourite": "ఇష్టపడినవి:",
+  "notifications.column_settings.follow": "క్రొత్త అనుచరులు:",
+  "notifications.column_settings.mention": "ప్రస్తావనలు:",
+  "notifications.column_settings.push": "పుష్ ప్రకటనలు",
+  "notifications.column_settings.push_meta": "ఈ పరికరం",
+  "notifications.column_settings.reblog": "బూస్ట్ లు:",
+  "notifications.column_settings.show": "నిలువు వరుసలో చూపు",
+  "notifications.column_settings.sound": "ధ్వనిని ప్లే చేయి",
+  "notifications.group": "{count} ప్రకటనలు",
+  "onboarding.done": "పూర్తయింది",
+  "onboarding.next": "తరువాత",
+  "onboarding.page_five.public_timelines": "స్థానిక కాలక్రమం {domain}లో ప్రతి ఒక్కరి నుండి పబ్లిక్ పోస్ట్లను చూపుతుంది. సమాఖ్య కాలక్రమం {డొమైన్} లోని వ్యక్తులు అనుసరించే ప్రతి ఒక్కరి నుండి పబ్లిక్ పోస్ట్లను చూపుతుంది. ఈ పబ్లిక్ కాలక్రమాలు క్రొత్త వ్యక్తులను కనుగొనడానికి ఒక గొప్ప మార్గం.",
+  "onboarding.page_four.home": "హోమ్ కాలక్రమం మీరు అనుసరించే వ్యక్తుల నుండి పోస్ట్లను చూపిస్తుంది.",
+  "onboarding.page_four.notifications": "ఎవరైనా మీతో సంభాషించినప్పుడు నోటిఫికేషన్ల నిలువు వరుసలో కనిపిస్తుంది.",
+  "onboarding.page_one.federation": "మాస్టొడొన్ అనేది అనేక స్వతంత్ర సేవికల సమాహారం వలన ఏర్పడిన ఒక సోషల్ నెట్వర్క్. మేము ఈ సేవికలను దుష్టాంతాలని అంటాము.",
+  "onboarding.page_one.full_handle": "మీ పూర్తి హ్యాండిల్",
+  "onboarding.page_one.handle_hint": "మీరు మీ స్నేహితులకు శోధించమని చెప్పేది ఇదే.",
+  "onboarding.page_one.welcome": "మాస్తోడాన్ కు స్వాగతం!",
+  "onboarding.page_six.admin": "మీ దృష్టాంతం యొక్క నిర్వాహకులు {admin}.",
+  "onboarding.page_six.almost_done": "దాదాపుగా అయిపోయింది...",
+  "onboarding.page_six.appetoot": "బాన్ ఆప్పెటూట్!",
+  "onboarding.page_six.apps_available": "iOS, Android మరియు ఇతర ప్లాట్ఫారమ్లకు {apps} అందుబాటులో ఉన్నాయి.",
+  "onboarding.page_six.github": "మాస్టొడొన్ ఉచిత ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు దోషాలను నివేదించవచ్చు, ఫీచర్లను అభ్యర్థించవచ్చు లేదా {github} లో కోడ్కు దోహదం చేయవచ్చు.",
+  "onboarding.page_six.guidelines": "సంఘం మార్గదర్శకాలు",
+  "onboarding.page_six.read_guidelines": "దయచేసి {domain} యొక్క {guidelines} చదవండి!",
+  "onboarding.page_six.various_app": "మొబైల్ అనువర్తనాలు",
+  "onboarding.page_three.profile": "మీ అవతార్, బయో, ప్రదర్శన పేరు మార్చడానికి మీ ప్రొఫైల్ను సవరించండి. అక్కడ, మీరు ఇతర ప్రాధాన్యతలను కూడా కనుగొంటారు.",
+  "onboarding.page_three.search": "వ్యక్తులను కనుగొనడానికి లేదా {illustration} మరియు {introductions} వంటి హ్యాష్ట్యాగ్లను చూడటానికి శోధన పట్టీని ఉపయోగించండి. ఈ దుష్టాంతంలో లేని ఒక వ్యక్తి కోసం శోధించేందుకు, వారి పూర్తి హ్యాండిల్ను ఉపయోగించండి.",
+  "onboarding.page_two.compose": "కంపోజ్ నిలువు వరుస నుండి పోస్ట్లను వ్రాయండి. మీరు చిత్రాలను అప్లోడ్ చెయ్యవచ్చు, గోప్యతా సెట్టింగ్లను మార్చవచ్చు మరియు దిగువ చిహ్నాలతో కంటెంట్ హెచ్చరికలను జోడించవచ్చు.",
+  "onboarding.skip": "దాటవేయి",
+  "privacy.change": "స్టేటస్ గోప్యతను సర్దుబాటు చేయండి",
+  "privacy.direct.long": "పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయి",
+  "privacy.direct.short": "ప్రత్యక్ష",
+  "privacy.private.long": "అనుచరులకు మాత్రమే పోస్ట్ చేయి",
+  "privacy.private.short": "అనుచరులకు మాత్రమే",
+  "privacy.public.long": "ప్రజా కాలక్రమాలకు పోస్ట్ చేయండి",
+  "privacy.public.short": "ప్రజా",
+  "privacy.unlisted.long": "ప్రజా కాలక్రమాలలో చూపించవద్దు",
+  "privacy.unlisted.short": "జాబితా చేయబడనిది",
+  "regeneration_indicator.label": "లోడ్ అవుతోంది…",
+  "regeneration_indicator.sublabel": "మీ హోమ్ ఫీడ్ సిద్ధమవుతోంది!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.just_now": "ఇప్పుడు",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
-  "reply_indicator.cancel": "Cancel",
-  "report.forward": "Forward to {target}",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
-  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
-  "report.placeholder": "Additional comments",
-  "report.submit": "Submit",
-  "report.target": "Report {target}",
-  "search.placeholder": "Search",
-  "search_popout.search_format": "Advanced search format",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
-  "search_popout.tips.user": "user",
-  "search_results.accounts": "People",
-  "search_results.hashtags": "Hashtags",
-  "search_results.statuses": "Toots",
+  "reply_indicator.cancel": "రద్దు చెయ్యి",
+  "report.forward": "{target}కి ఫార్వార్డ్ చేయండి",
+  "report.forward_hint": "ఖాతా మరొక సర్వర్లో ఉంది. నివేదిక యొక్క ఒక అనామకంగా ఉన్న కాపీని అక్కడికి కూడా పంపించమంటారా?",
+  "report.hint": "మీ దుష్టాంత మోడరేటర్లకు నివేదిక పంపబడుతుంది. దిగువ ఈ ఖాతాను ఎందుకు నివేదిస్తున్నారనేదాని వివరణను మీరు అందించవచ్చు:",
+  "report.placeholder": "అదనపు వ్యాఖ్యలు",
+  "report.submit": "సమర్పించండి",
+  "report.target": "{target}పై ఫిర్యాదు చేయండి",
+  "search.placeholder": "శోధన",
+  "search_popout.search_format": "అధునాతన శోధన ఆకృతి",
+  "search_popout.tips.full_text": "సాధారణ వచనం మీరు వ్రాసిన, ఇష్టపడే, పెంచబడిన లేదా పేర్కొనబడిన, అలాగే యూజర్పేర్లు, ప్రదర్శన పేర్లు, మరియు హ్యాష్ట్యాగ్లను నమోదు చేసిన హోదాలను అందిస్తుంది.",
+  "search_popout.tips.hashtag": "హాష్ ట్యాగ్",
+  "search_popout.tips.status": "స్టేటస్",
+  "search_popout.tips.text": "సింపుల్ టెక్స్ట్ ప్రదర్శన పేర్లు, యూజర్ పేర్లు మరియు హ్యాష్ట్యాగ్లను సరిపోలుస్తుంది",
+  "search_popout.tips.user": "వాడుకరి",
+  "search_results.accounts": "వ్యక్తులు",
+  "search_results.hashtags": "హాష్ ట్యాగ్లు",
+  "search_results.statuses": "టూట్లు",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "standalone.public_title": "A look inside...",
-  "status.block": "Block @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "This post cannot be boosted",
-  "status.delete": "Delete",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
-  "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.reblog": "Boost",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} boosted",
-  "status.redraft": "Delete & re-draft",
-  "status.reply": "Reply",
-  "status.replyAll": "Reply to thread",
-  "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
-  "status.sensitive_warning": "Sensitive content",
-  "status.share": "Share",
-  "status.show_less": "Show less",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "Show more",
-  "status.show_more_all": "Show more for all",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "tabs_bar.federated_timeline": "Federated",
-  "tabs_bar.home": "Home",
-  "tabs_bar.local_timeline": "Local",
-  "tabs_bar.notifications": "Notifications",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media",
-  "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
-  "upload_form.undo": "Undo",
-  "upload_progress.label": "Uploading...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
-  "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "standalone.public_title": "లోపలికి ఒక చూపు...",
+  "status.block": "@{name} ను బ్లాక్ చేయి",
+  "status.cancel_reblog_private": "బూస్ట్ను తొలగించు",
+  "status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు",
+  "status.delete": "తొలగించు",
+  "status.direct": "@{name}కు నేరుగా సందేశం పంపు",
+  "status.embed": "ఎంబెడ్",
+  "status.favourite": "ఇష్టపడు",
+  "status.filtered": "Filtered",
+  "status.load_more": "మరిన్ని లోడ్ చేయి",
+  "status.media_hidden": "మీడియా దాచబడింది",
+  "status.mention": "@{name}ను ప్రస్తావించు",
+  "status.more": "ఇంకొన్ని",
+  "status.mute": "@{name}ను మ్యూట్ చెయ్యి",
+  "status.mute_conversation": "సంభాషణను మ్యూట్ చెయ్యి",
+  "status.open": "ఈ స్టేటస్ ను విస్తరించు",
+  "status.pin": "ప్రొఫైల్లో అతికించు",
+  "status.pinned": "అతికించిన టూట్",
+  "status.reblog": "బూస్ట్",
+  "status.reblog_private": "అసలు ప్రేక్షకులకు బూస్ట్ చేయి",
+  "status.reblogged_by": "{name} బూస్ట్ చేసారు",
+  "status.redraft": "తొలగించు & తిరగరాయు",
+  "status.reply": "ప్రత్యుత్తరం",
+  "status.replyAll": "సంభాషణకు ప్రత్యుత్తరం ఇవ్వండి",
+  "status.report": "@{name}పై ఫిర్యాదుచేయు",
+  "status.sensitive_toggle": "వీక్షించడానికి క్లిక్ చేయండి",
+  "status.sensitive_warning": "సున్నితమైన కంటెంట్",
+  "status.share": "పంచుకోండి",
+  "status.show_less": "తక్కువ చూపించు",
+  "status.show_less_all": "అన్నిటికీ తక్కువ చూపించు",
+  "status.show_more": "ఇంకా చూపించు",
+  "status.show_more_all": "అన్నిటికీ ఇంకా చూపించు",
+  "status.unmute_conversation": "సంభాషణను అన్మ్యూట్ చేయి",
+  "status.unpin": "ప్రొఫైల్ నుండి పీకివేయు",
+  "tabs_bar.federated_timeline": "సమాఖ్య",
+  "tabs_bar.home": "హోమ్",
+  "tabs_bar.local_timeline": "స్థానిక",
+  "tabs_bar.notifications": "ప్రకటనలు",
+  "tabs_bar.search": "శోధన",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} మాట్లాడుతున్నారు",
+  "ui.beforeunload": "మీరు మాస్టొడొన్ను వదిలివేస్తే మీ డ్రాఫ్ట్లు పోతాయి.",
+  "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి",
+  "upload_button.label": "మీడియాను జోడించండి",
+  "upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి",
+  "upload_form.focus": "కత్తిరించు",
+  "upload_form.undo": "తొలగించు",
+  "upload_progress.label": "అప్లోడ్ అవుతోంది...",
+  "video.close": "వీడియోని మూసివేయి",
+  "video.exit_fullscreen": "పూర్తి స్క్రీన్ నుండి నిష్క్రమించు",
+  "video.expand": "వీడియోను విస్తరించండి",
+  "video.fullscreen": "పూర్తి స్క్రీన్",
+  "video.hide": "వీడియోను దాచు",
+  "video.mute": "ధ్వనిని మ్యూట్ చేయి",
+  "video.pause": "పాజ్ చేయి",
+  "video.play": "ప్లే చేయి",
+  "video.unmute": "ధ్వనిని అన్మ్యూట్ చేయి"
 }
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 07cce99d5..57a0bb01f 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Advanced",
   "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
+  "status.filtered": "Filtered",
   "status.load_more": "Load more",
   "status.media_hidden": "Media hidden",
   "status.mention": "Mention @{name}",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index e46084467..475ee4f05 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon açık kaynaklı bir yazılımdır. Github {github}. {apps} üzerinden katkıda bulunabilir, hata raporlayabilirsiniz.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Gelişmiş",
   "home.column_settings.basic": "Temel",
-  "home.column_settings.filter_regex": "Regex kullanarak filtrele",
   "home.column_settings.show_reblogs": "Boost edilenleri göster",
   "home.column_settings.show_replies": "Cevapları göster",
-  "home.settings": "Kolon ayarları",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorilere ekle",
+  "status.filtered": "Filtered",
   "status.load_more": "Daha fazla",
   "status.media_hidden": "Gizli görsel",
   "status.mention": "Bahset @{name}",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index a73c04e5b..bf3262558 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon - програма з відкритим вихідним кодом. Ви можете допомогти проекту, або повідомити про проблеми на GitHub за адресою {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "Додаткові",
   "home.column_settings.basic": "Основні",
-  "home.column_settings.filter_regex": "Відфільтрувати регулярним виразом",
   "home.column_settings.show_reblogs": "Показувати передмухи",
   "home.column_settings.show_replies": "Показувати відповіді",
-  "home.settings": "Налаштування колонок",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
@@ -259,6 +256,7 @@
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Подобається",
+  "status.filtered": "Filtered",
   "status.load_more": "Завантажити більше",
   "status.media_hidden": "Медіаконтент приховано",
   "status.mention": "Згадати",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index de3cd0090..1b1997cff 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -122,12 +122,9 @@
   "getting_started.open_source_notice": "Mastodon 是一个开源软件。欢迎前往 GitHub({github})贡献代码或反馈问题。",
   "getting_started.security": "帐户安全",
   "getting_started.terms": "使用条款",
-  "home.column_settings.advanced": "高级设置",
   "home.column_settings.basic": "基本设置",
-  "home.column_settings.filter_regex": "使用正则表达式(regex)过滤",
   "home.column_settings.show_reblogs": "显示转嘟",
   "home.column_settings.show_replies": "显示回复",
-  "home.settings": "栏目设置",
   "keyboard_shortcuts.back": "返回上一页",
   "keyboard_shortcuts.boost": "转嘟",
   "keyboard_shortcuts.column": "选择第 X 栏中的嘟文",
@@ -259,6 +256,7 @@
   "status.direct": "发送私信给 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "收藏",
+  "status.filtered": "Filtered",
   "status.load_more": "加载更多",
   "status.media_hidden": "隐藏媒体内容",
   "status.mention": "提及 @{name}",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 90a6500ae..9e964ee88 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -59,7 +59,7 @@
   "column_header.show_settings": "顯示設定",
   "column_header.unpin": "取下",
   "column_subheading.settings": "設定",
-  "community.column_settings.media_only": "Media Only",
+  "community.column_settings.media_only": "僅媒體",
   "compose_form.direct_message_warning": "這文章只有被提及的用戶才可以看到。",
   "compose_form.direct_message_warning_learn_more": "了解更多",
   "compose_form.hashtag_warning": "這文章因為不是公開,所以不會被標籤搜索。只有公開的文章才會被標籤搜索。",
@@ -81,11 +81,11 @@
   "confirmations.delete_list.confirm": "刪除",
   "confirmations.delete_list.message": "你確定要永久刪除這列表嗎?",
   "confirmations.domain_block.confirm": "隱藏整個網站",
-  "confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或靜音幾個特定目標就好。",
+  "confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或靜音幾個特定目標就好。你從此將不會再看到該站的內容和通知。來自該站的關注者亦會被移除。",
   "confirmations.mute.confirm": "靜音",
   "confirmations.mute.message": "你確定要將{name}靜音嗎?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.redraft.confirm": "刪除並編輯",
+  "confirmations.redraft.message": "你確定要刪除並重新編輯嗎?所有相關的回覆、轉推與最愛都會被刪除。",
   "confirmations.unfollow.confirm": "取消關注",
   "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?",
   "embed.instructions": "要內嵌此文章,請將以下代碼貼進你的網站。",
@@ -114,20 +114,17 @@
   "empty_column.public": "跨站時間軸暫時沒有內容!快寫一些公共的文章,或者關注另一些服務站的用戶吧!你和本站、友站的交流,將決定這裏出現的內容。",
   "follow_request.authorize": "批准",
   "follow_request.reject": "拒絕",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "開發者",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "尋找 Twitter 好友",
   "getting_started.heading": "開始使用",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "邀請使用者",
   "getting_started.open_source_notice": "Mastodon(萬象)是一個開放源碼的軟件。你可以在官方 GitHub ({github}) 貢獻或者回報問題。",
-  "getting_started.security": "Security",
+  "getting_started.security": "帳戶安全",
   "getting_started.terms": "服務條款",
-  "home.column_settings.advanced": "進階",
   "home.column_settings.basic": "基本",
-  "home.column_settings.filter_regex": "使用正規表達式 (regular expression) 過濾",
   "home.column_settings.show_reblogs": "顯示被轉推的文章",
   "home.column_settings.show_replies": "顯示回應文章",
-  "home.settings": "欄位設定",
   "keyboard_shortcuts.back": "後退",
   "keyboard_shortcuts.boost": "轉推",
   "keyboard_shortcuts.column": "把標示移動到其中一列",
@@ -259,6 +256,7 @@
   "status.direct": "私訊 @{name}",
   "status.embed": "鑲嵌",
   "status.favourite": "收藏",
+  "status.filtered": "Filtered",
   "status.load_more": "載入更多",
   "status.media_hidden": "隱藏媒體內容",
   "status.mention": "提及 @{name}",
@@ -271,7 +269,7 @@
   "status.reblog": "轉推",
   "status.reblog_private": "轉推到原讀者",
   "status.reblogged_by": "{name} 轉推",
-  "status.redraft": "Delete & re-draft",
+  "status.redraft": "刪除並編輯",
   "status.reply": "回應",
   "status.replyAll": "回應所有人",
   "status.report": "舉報 @{name}",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 1ba277e28..7221d3383 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,34 +1,34 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "機器人",
   "account.block": "封鎖 @{name}",
   "account.block_domain": "隱藏來自 {domain} 的一切貼文",
   "account.blocked": "已被封鎖的",
-  "account.direct": "給 @{name} 私人訊息",
+  "account.direct": "發送私訊給 @{name}",
   "account.disclaimer_full": "下列資料不一定完整。",
-  "account.domain_blocked": "域名隱藏",
+  "account.domain_blocked": "站點被隱藏",
   "account.edit_profile": "編輯使用者資訊",
   "account.follow": "關注",
   "account.followers": "關注者",
-  "account.follows": "正關注",
+  "account.follows": "正在關注",
   "account.follows_you": "關注你",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉推",
   "account.media": "媒體",
   "account.mention": "提到 @{name}",
   "account.moved_to": "{name} 已經移至:",
-  "account.mute": "消音 @{name}",
-  "account.mute_notifications": "消音來自 @{name} 的通知",
-  "account.muted": "消音的",
-  "account.posts": "貼文",
-  "account.posts_with_replies": "貼文及回覆",
+  "account.mute": "靜音 @{name}",
+  "account.mute_notifications": "靜音來自 @{name} 的通知",
+  "account.muted": "靜音",
+  "account.posts": "嘟文",
+  "account.posts_with_replies": "嘟文與回覆",
   "account.report": "檢舉 @{name}",
-  "account.requested": "正在等待許可",
-  "account.share": "分享 @{name} 的用者資訊",
-  "account.show_reblogs": "Show boosts from @{name}",
+  "account.requested": "正在等待對方同意。點擊以取消發送關注請求",
+  "account.share": "分享 @{name} 的使用者資訊",
+  "account.show_reblogs": "顯示來自 @{name} 的嘟文",
   "account.unblock": "取消封鎖 @{name}",
   "account.unblock_domain": "不再隱藏 {domain}",
   "account.unfollow": "取消關注",
-  "account.unmute": "不再消音 @{name}",
-  "account.unmute_notifications": "不再對來自 @{name} 的通知消音",
+  "account.unmute": "不再靜音 @{name}",
+  "account.unmute_notifications": "不再對來自 @{name} 的通知靜音",
   "account.view_full_profile": "查看完整資訊",
   "alert.unexpected.message": "發生非預期的錯誤。",
   "alert.unexpected.title": "哎呀!",
@@ -41,16 +41,16 @@
   "bundle_modal_error.retry": "重試",
   "column.blocks": "封鎖的使用者",
   "column.community": "本地時間軸",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "隱藏域名",
+  "column.direct": "私訊",
+  "column.domain_blocks": "隱藏的站點",
   "column.favourites": "最愛",
   "column.follow_requests": "關注請求",
-  "column.home": "家",
+  "column.home": "主頁",
   "column.lists": "名單",
-  "column.mutes": "消音的使用者",
+  "column.mutes": "靜音的使用者",
   "column.notifications": "通知",
-  "column.pins": "置頂貼文",
-  "column.public": "聯盟時間軸",
+  "column.pins": "置頂嘟文",
+  "column.public": "其他站點時間軸",
   "column_back_button.label": "上一頁",
   "column_header.hide_settings": "隱藏設定",
   "column_header.moveLeft_settings": "將欄左移",
@@ -59,9 +59,9 @@
   "column_header.show_settings": "顯示設定",
   "column_header.unpin": "取下",
   "column_subheading.settings": "設定",
-  "community.column_settings.media_only": "Media Only",
-  "compose_form.direct_message_warning": "此則推文只會被所有提到的使用者看見。",
-  "compose_form.direct_message_warning_learn_more": "Learn more",
+  "community.column_settings.media_only": "僅媒體",
+  "compose_form.direct_message_warning": "這條嘟文僅對有被提及的使用者才能看到。",
+  "compose_form.direct_message_warning_learn_more": "了解更多",
   "compose_form.hashtag_warning": "此則推文將不會在任何主題標籤中看見,只有公開的推文可以用主題標籤來搜尋。",
   "compose_form.lock_disclaimer": "你的帳號沒有{locked}。任何人都可以關注你,看到發給關注者的貼文。",
   "compose_form.lock_disclaimer.lock": "上鎖",
@@ -81,11 +81,11 @@
   "confirmations.delete_list.confirm": "刪除",
   "confirmations.delete_list.message": "確定要永久性地刪除這個名單嗎?",
   "confirmations.domain_block.confirm": "隱藏整個網域",
-  "confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或消音幾個特定目標就好。",
+  "confirmations.domain_block.message": "你真的確定要靜音所有來自 {domain} 的內容嗎? 多數情況下,封鎖或靜音幾個特定用戶應該就能滿足你的需求了。來自該站點的內容將不再出現在你的公共時間軸或通知裡。來自該站點的關注者將會被移除。",
   "confirmations.mute.confirm": "消音",
   "confirmations.mute.message": "你確定要消音 {name} ?",
-  "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.redraft.confirm": "刪除 & 編輯",
+  "confirmations.redraft.message": "你確定要刪除這條嘟文並重新編輯它嗎? 所有相關的回覆、轉嘟與最愛都會被刪除。",
   "confirmations.unfollow.confirm": "取消關注",
   "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?",
   "embed.instructions": "要內嵌此貼文,請將以下代碼貼進你的網站。",
@@ -98,54 +98,51 @@
   "emoji_button.nature": "自然",
   "emoji_button.not_found": "沒有表情符號吼!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "物件",
-  "emoji_button.people": "人",
+  "emoji_button.people": "使用者",
   "emoji_button.recent": "常用",
   "emoji_button.search": "搜尋…",
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊與地點",
   "empty_column.community": "本地時間軸是空的。公開寫點什麼吧!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.direct": "你還沒有使用過私訊。當你發出或著收到私訊時,它會在這裡顯示。",
   "empty_column.hashtag": "這個主題標籤下什麼都沒有。",
   "empty_column.home": "你還沒關注任何人。造訪{public}或利用搜尋功能找到其他用者。",
   "empty_column.home.public_timeline": "公開時間軸",
   "empty_column.list": "此份清單尚未有東西。當此清單的成員貼出了新的狀態時,它們就會出現在這裡。",
   "empty_column.notifications": "還沒有任何通知。和別的使用者互動來開始對話。",
-  "empty_column.public": "這裡什麼都沒有!公開寫些什麼,或是關注其他副本的使用者。",
+  "empty_column.public": "這裡什麼都沒有! 寫一些公開的嘟文,或著關注其他站點的使用者後,這裡就會有嘟文出現了",
   "follow_request.authorize": "授權",
   "follow_request.reject": "拒絕",
-  "getting_started.developers": "Developers",
+  "getting_started.developers": "開發",
   "getting_started.documentation": "Documentation",
-  "getting_started.find_friends": "Find friends from Twitter",
+  "getting_started.find_friends": "尋找 Twitter 好友",
   "getting_started.heading": "馬上開始",
-  "getting_started.invite": "Invite people",
+  "getting_started.invite": "邀請使用者",
   "getting_started.open_source_notice": "Mastodon 是開源軟體。你可以在 GitHub {github} 上做出貢獻或是回報問題。",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "home.column_settings.advanced": "進階",
+  "getting_started.security": "登入資訊",
+  "getting_started.terms": "使用條款",
   "home.column_settings.basic": "基本",
-  "home.column_settings.filter_regex": "以正規表示式過濾",
   "home.column_settings.show_reblogs": "顯示轉推",
   "home.column_settings.show_replies": "顯示回應",
-  "home.settings": "欄位設定",
   "keyboard_shortcuts.back": "回到上一個",
   "keyboard_shortcuts.boost": "到轉推",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
+  "keyboard_shortcuts.column": "選擇第 X 欄中的嘟文",
   "keyboard_shortcuts.compose": "焦點移至撰寫文字區塊",
   "keyboard_shortcuts.description": "描述",
-  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.down": "在列表往下移動",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "收藏",
   "keyboard_shortcuts.heading": "鍵盤快速鍵",
   "keyboard_shortcuts.hotkey": "快速鍵",
-  "keyboard_shortcuts.legend": "to display this legend",
+  "keyboard_shortcuts.legend": "顯示這個說明",
   "keyboard_shortcuts.mention": "到提到的作者",
   "keyboard_shortcuts.reply": "到回應",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
+  "keyboard_shortcuts.search": "把滑鼠移動到搜尋",
+  "keyboard_shortcuts.toggle_hidden": "顯示或隱藏被標為敏感的嘟文",
+  "keyboard_shortcuts.toot": "新的嘟文",
+  "keyboard_shortcuts.unfocus": "取消輸入",
+  "keyboard_shortcuts.up": "在列表往上移動",
   "lightbox.close": "關閉",
   "lightbox.next": "繼續",
   "lightbox.previous": "回退",
@@ -164,26 +161,26 @@
   "mute_modal.hide_notifications": "隱藏來自這個使用者的通知?",
   "navigation_bar.blocks": "封鎖的使用者",
   "navigation_bar.community_timeline": "本地時間軸",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "隱藏的域名",
-  "navigation_bar.edit_profile": "編輯用者資訊",
+  "navigation_bar.direct": "私訊",
+  "navigation_bar.discover": "探索",
+  "navigation_bar.domain_blocks": "隱藏的站點",
+  "navigation_bar.edit_profile": "編輯使用者資訊",
   "navigation_bar.favourites": "最愛",
   "navigation_bar.follow_requests": "關注請求",
   "navigation_bar.info": "關於本站",
-  "navigation_bar.keyboard_shortcuts": "快速鍵",
+  "navigation_bar.keyboard_shortcuts": "快捷鍵",
   "navigation_bar.lists": "名單",
   "navigation_bar.logout": "登出",
-  "navigation_bar.mutes": "消音的使用者",
-  "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "置頂貼文",
+  "navigation_bar.mutes": "靜音的使用者",
+  "navigation_bar.personal": "個人",
+  "navigation_bar.pins": "置頂嘟文",
   "navigation_bar.preferences": "偏好設定",
-  "navigation_bar.public_timeline": "聯盟時間軸",
-  "navigation_bar.security": "Security",
-  "notification.favourite": "{name}收藏了你的狀態",
+  "navigation_bar.public_timeline": "其他站點時間軸",
+  "navigation_bar.security": "登入資訊",
+  "notification.favourite": "{name}把你的嘟文加入了最愛",
   "notification.follow": "{name}關注了你",
   "notification.mention": "{name}提到了你",
-  "notification.reblog": "{name}推了你的狀態",
+  "notification.reblog": "{name}轉嘟了你的嘟文",
   "notifications.clear": "清除通知",
   "notifications.clear_confirmation": "確定要永久清除你的通知嗎?",
   "notifications.column_settings.alert": "桌面通知",
@@ -192,118 +189,119 @@
   "notifications.column_settings.mention": "提到:",
   "notifications.column_settings.push": "推送通知",
   "notifications.column_settings.push_meta": "這臺設備",
-  "notifications.column_settings.reblog": "轉推:",
+  "notifications.column_settings.reblog": "轉嘟:",
   "notifications.column_settings.show": "顯示在欄位中",
   "notifications.column_settings.sound": "播放音效",
-  "notifications.group": "{count} notifications",
+  "notifications.group": "{count} 條通知",
   "onboarding.done": "完成",
   "onboarding.next": "下一步",
-  "onboarding.page_five.public_timelines": "本地時間軸顯示 {domain} 上所有人的公開貼文。聯盟時間軸顯示 {domain} 上所有人關注的公開貼文。這就是公開時間軸,發現新朋友的好地方。",
-  "onboarding.page_four.home": "家時間軸顯示所有你關注的人的貼文。",
+  "onboarding.page_five.public_timelines": "本站時間軸顯示 {domain} 上所有的公開嘟文。其他站點時間軸顯示 {domain} 上所有人關注的公開嘟文。這就是公開時間軸,發現新朋友的好地方。",
+  "onboarding.page_four.home": "主頁時間軸顯示所有你關注的人的嘟文。",
   "onboarding.page_four.notifications": "通知欄顯示別人和你的互動。",
-  "onboarding.page_one.federation": "Mastodon 是由獨立的伺服器連結起來,形成的大社群網路。我們把這些伺服器稱為副本。",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
+  "onboarding.page_one.federation": "Mastodon 是由獨立的伺服器連結起來,形成的大社群網路。我們把這些伺服器稱為站點。",
+  "onboarding.page_one.full_handle": "你的完整帳戶名稱",
+  "onboarding.page_one.handle_hint": "你的朋友們可以從這個帳戶全名找到你。",
   "onboarding.page_one.welcome": "歡迎來到 Mastodon !",
-  "onboarding.page_six.admin": "你的副本的管理員是 {admin} 。",
+  "onboarding.page_six.admin": "你的站點的管理員是 {admin} 。",
   "onboarding.page_six.almost_done": "快好了…",
-  "onboarding.page_six.appetoot": "貼口大開!",
+  "onboarding.page_six.appetoot": "嗷嗚~!",
   "onboarding.page_six.apps_available": "在 iOS 、 Android 和其他平台上有這些 {apps} 可以用。",
-  "onboarding.page_six.github": "Mastodon 是自由的開源軟體。你可以在 {github} 上回報臭蟲、請求新功能或是做出貢獻。",
+  "onboarding.page_six.github": "Mastodon 是自由的開源軟體。你可以在 {github} 上回報問題、請求新功能或是做出貢獻。",
   "onboarding.page_six.guidelines": "社群指南",
   "onboarding.page_six.read_guidelines": "請閱讀 {domain} 的 {guidelines} !",
   "onboarding.page_six.various_app": "行動版應用程式",
-  "onboarding.page_three.profile": "編輯你的大頭貼、自傳和顯示名稱。你也可以在這邊找到其他設定。",
-  "onboarding.page_three.search": "利用搜尋列來找到其他人或是主題標籤,像是 {illustration} 或 {introductions} 。用完整的帳號名稱來找不在這個副本上的使用者。",
+  "onboarding.page_three.profile": "編輯你的頭貼、簡介與顯示名稱。你也可以在這邊找到其他設定。",
+  "onboarding.page_three.search": "利用搜尋列來找到其他人或是主題標籤,像是 {illustration} 或 {introductions} 。用完整的帳戶名稱來找其他站點上的使用者。",
   "onboarding.page_two.compose": "在編輯欄寫些什麼。可以上傳圖片、改變隱私設定或是用下面的圖示加上內容警告。",
   "onboarding.skip": "跳過",
   "privacy.change": "調整隱私狀態",
-  "privacy.direct.long": "只貼給提到的使用者",
-  "privacy.direct.short": "直接貼",
-  "privacy.private.long": "只貼給關注者",
-  "privacy.private.short": "關注貼",
+  "privacy.direct.long": "只有被提到的使用者能看到",
+  "privacy.direct.short": "私訊",
+  "privacy.private.long": "只有關注你的使用者能看到",
+  "privacy.private.short": "僅關注者",
   "privacy.public.long": "貼到公開時間軸",
-  "privacy.public.short": "公開貼",
-  "privacy.unlisted.long": "不要貼到公開時間軸",
-  "privacy.unlisted.short": "不列出來",
+  "privacy.public.short": "公開",
+  "privacy.unlisted.long": "公開,但不會顯示在公開時間軸",
+  "privacy.unlisted.short": "不公開",
   "regeneration_indicator.label": "載入中…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "regeneration_indicator.sublabel": "你的主頁時間軸正在準備中!",
   "relative_time.days": "{number} 天",
-  "relative_time.hours": "{number} 時",
-  "relative_time.just_now": "現在",
+  "relative_time.hours": "{number} 小時",
+  "relative_time.just_now": "剛剛",
   "relative_time.minutes": "{number} 分",
   "relative_time.seconds": "{number} 秒",
   "reply_indicator.cancel": "取消",
-  "report.forward": "Forward to {target}",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
-  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
+  "report.forward": "轉寄到 {target}",
+  "report.forward_hint": "這個帳戶屬於其他站點。要像該站點發送匿名的檢舉訊息嗎?",
+  "report.hint": "這項訊息會發送到你該站點的管理員。你可以提供檢舉這個帳戶的理由:",
   "report.placeholder": "更多訊息",
   "report.submit": "送出",
-  "report.target": "通報中",
+  "report.target": "檢舉 {target}",
   "search.placeholder": "搜尋",
   "search_popout.search_format": "進階搜尋格式",
-  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.full_text": "輸入簡單的文字,搜尋由你撰寫、最愛、轉嘟或提你的嘟文,以及符合使用者名稱、帳戶名稱和標籤。",
   "search_popout.tips.hashtag": "主題標籤",
   "search_popout.tips.status": "狀態",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.text": "輸入簡單的文字,搜尋符合的使用者名稱,帳戶名稱與標籤",
   "search_popout.tips.user": "使用者",
-  "search_results.accounts": "人",
+  "search_results.accounts": "使用者",
   "search_results.hashtags": "主題標籤",
-  "search_results.statuses": "推文",
+  "search_results.statuses": "嘟文",
   "search_results.total": "{count, number} 項結果",
   "standalone.public_title": "站點一瞥…",
   "status.block": "封鎖 @{name}",
-  "status.cancel_reblog_private": "Unboost",
-  "status.cannot_reblog": "此貼文無法轉推",
+  "status.cancel_reblog_private": "取消轉嘟",
+  "status.cannot_reblog": "這篇嘟文無法被轉嘟",
   "status.delete": "刪除",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "收藏",
+  "status.direct": "發送私訊給 @{name}",
+  "status.embed": "嵌入",
+  "status.favourite": "最愛",
+  "status.filtered": "Filtered",
   "status.load_more": "載入更多",
-  "status.media_hidden": "媒體已隱藏",
+  "status.media_hidden": "隱藏媒體內容",
   "status.mention": "提到 @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "消音對話",
-  "status.open": "展開這個狀態",
+  "status.more": "更多",
+  "status.mute": "靜音 @{name}",
+  "status.mute_conversation": "靜音對話",
+  "status.open": "展開嘟文",
   "status.pin": "置頂到個人資訊頁",
-  "status.pinned": "置頂的推文",
-  "status.reblog": "轉推",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} 轉推了",
-  "status.redraft": "Delete & re-draft",
-  "status.reply": "回應",
-  "status.replyAll": "回應這串",
-  "status.report": "通報 @{name}",
-  "status.sensitive_toggle": "點來看",
+  "status.pinned": "置頂嘟文",
+  "status.reblog": "轉嘟",
+  "status.reblog_private": "轉嘟給原有關注者",
+  "status.reblogged_by": "{name} 轉嘟了",
+  "status.redraft": "刪除 & 編輯",
+  "status.reply": "回覆",
+  "status.replyAll": "回覆所有人",
+  "status.report": "檢舉 @{name}",
+  "status.sensitive_toggle": "點擊顯示",
   "status.sensitive_warning": "敏感內容",
   "status.share": "分享",
-  "status.show_less": "看少點",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "看更多",
-  "status.show_more_all": "Show more for all",
-  "status.unmute_conversation": "不消音對話",
+  "status.show_less": "減少顯示",
+  "status.show_less_all": "減少顯示這類嘟文",
+  "status.show_more": "顯示更多",
+  "status.show_more_all": "顯示更多這類嘟文",
+  "status.unmute_conversation": "解除此對話的靜音",
   "status.unpin": "解除置頂",
-  "tabs_bar.federated_timeline": "聯盟",
-  "tabs_bar.home": "家",
-  "tabs_bar.local_timeline": "本地",
+  "tabs_bar.federated_timeline": "其他站點",
+  "tabs_bar.home": "主頁",
+  "tabs_bar.local_timeline": "本站",
   "tabs_bar.notifications": "通知",
-  "tabs_bar.search": "Search",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "tabs_bar.search": "搜尋",
+  "trends.count_by_accounts": "{count} 位使用者在討論",
   "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。",
   "upload_area.title": "拖放來上傳",
-  "upload_button.label": "增加媒體",
-  "upload_form.description": "爲視障者加上描述",
+  "upload_button.label": "上傳媒體檔案",
+  "upload_form.description": "為視障人士增加文字說明",
   "upload_form.focus": "裁切",
-  "upload_form.undo": "復原",
+  "upload_form.undo": "刪除",
   "upload_progress.label": "上傳中...",
   "video.close": "關閉影片",
   "video.exit_fullscreen": "退出全螢幕",
   "video.expand": "展開影片",
   "video.fullscreen": "全螢幕",
   "video.hide": "隱藏影片",
-  "video.mute": "消音",
+  "video.mute": "靜音",
   "video.pause": "暫停",
   "video.play": "播放",
-  "video.unmute": "解除消音"
+  "video.unmute": "解除靜音"
 }
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 8524ddb8e..552f659c9 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -151,15 +151,8 @@ const insertEmoji = (state, position, emojiData, needsSpace) => {
 };
 
 const privacyPreference = (a, b) => {
-  if (a === 'direct' || b === 'direct') {
-    return 'direct';
-  } else if (a === 'private' || b === 'private') {
-    return 'private';
-  } else if (a === 'unlisted' || b === 'unlisted') {
-    return 'unlisted';
-  } else {
-    return 'public';
-  }
+  const order = ['public', 'unlisted', 'private', 'direct'];
+  return order[Math.max(order.indexOf(a), order.indexOf(b), 0)];
 };
 
 const hydrate = (state, hydratedState) => {
diff --git a/app/javascript/mastodon/reducers/filters.js b/app/javascript/mastodon/reducers/filters.js
new file mode 100644
index 000000000..33f0c6732
--- /dev/null
+++ b/app/javascript/mastodon/reducers/filters.js
@@ -0,0 +1,11 @@
+import { FILTERS_FETCH_SUCCESS } from '../actions/filters';
+import { List as ImmutableList, fromJS } from 'immutable';
+
+export default function filters(state = ImmutableList(), action) {
+  switch(action.type) {
+  case FILTERS_FETCH_SUCCESS:
+    return fromJS(action.filters);
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index 3d9a6a132..4a981fada 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -26,6 +26,7 @@ import height_cache from './height_cache';
 import custom_emojis from './custom_emojis';
 import lists from './lists';
 import listEditor from './list_editor';
+import filters from './filters';
 
 const reducers = {
   dropdown_menu,
@@ -55,6 +56,7 @@ const reducers = {
   custom_emojis,
   lists,
   listEditor,
+  filters,
 };
 
 export default combineReducers(reducers);
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index e47ec5183..d0212c379 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -19,16 +19,49 @@ export const makeGetAccount = () => {
   });
 };
 
+const toServerSideType = columnType => {
+  switch (columnType) {
+  case 'home':
+  case 'notifications':
+  case 'public':
+  case 'thread':
+    return columnType;
+  default:
+    if (columnType.indexOf('list:') > -1) {
+      return 'home';
+    } else {
+      return 'public'; // community, account, hashtag
+    }
+  }
+};
+
+export const getFilters = (state, { contextType }) => state.get('filters', ImmutableList()).filter(filter => contextType && filter.get('context').includes(toServerSideType(contextType)) && (filter.get('expires_at') === null || Date.parse(filter.get('expires_at')) > (new Date())));
+
+const escapeRegExp = string =>
+  string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+
+export const regexFromFilters = filters => {
+  if (filters.size === 0) {
+    return null;
+  }
+
+  return new RegExp(filters.map(filter => {
+    let expr = escapeRegExp(filter.get('phrase'));
+    return filter.get('whole_word') ? `\\b${expr}\\b` : expr;
+  }).join('|'), 'i');
+};
+
 export const makeGetStatus = () => {
   return createSelector(
     [
-      (state, id) => state.getIn(['statuses', id]),
-      (state, id) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
-      (state, id) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
-      (state, id) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
+      (state, { id }) => state.getIn(['statuses', id]),
+      (state, { id }) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
+      (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
+      (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
+      getFilters,
     ],
 
-    (statusBase, statusReblog, accountBase, accountReblog) => {
+    (statusBase, statusReblog, accountBase, accountReblog, filters) => {
       if (!statusBase) {
         return null;
       }
@@ -39,9 +72,13 @@ export const makeGetStatus = () => {
         statusReblog = null;
       }
 
+      const regex    = regexFromFilters(filters);
+      const filtered = regex && regex.test(statusBase.get('reblog') ? statusReblog.get('search_index') : statusBase.get('search_index'));
+
       return statusBase.withMutations(map => {
         map.set('reblog', statusReblog);
         map.set('account', accountBase);
+        map.set('filtered', filtered);
       });
     }
   );
diff --git a/app/javascript/mastodon/service_worker/entry.js b/app/javascript/mastodon/service_worker/entry.js
index 17b05a837..b354f3b33 100644
--- a/app/javascript/mastodon/service_worker/entry.js
+++ b/app/javascript/mastodon/service_worker/entry.js
@@ -1,9 +1,9 @@
-import { freeStorage, storageFreeable } from '../storage/modifier';
+// import { freeStorage, storageFreeable } from '../storage/modifier';
 import './web_push_notifications';
 
-function openSystemCache() {
-  return caches.open('mastodon-system');
-}
+// function openSystemCache() {
+//   return caches.open('mastodon-system');
+// }
 
 function openWebCache() {
   return caches.open('mastodon-web');
@@ -13,8 +13,8 @@ function fetchRoot() {
   return fetch('/', { credentials: 'include', redirect: 'manual' });
 }
 
-const firefox = navigator.userAgent.match(/Firefox\/(\d+)/);
-const invalidOnlyIfCached = firefox && firefox[1] < 60;
+// const firefox = navigator.userAgent.match(/Firefox\/(\d+)/);
+// const invalidOnlyIfCached = firefox && firefox[1] < 60;
 
 // Cause a new version of a registered Service Worker to replace an existing one
 // that is already installed, and replace the currently active worker on open pages.
@@ -52,7 +52,7 @@ self.addEventListener('fetch', function(event) {
 
       return response;
     }));
-  } else if (storageFreeable && (ATTACHMENT_HOST ? url.host === ATTACHMENT_HOST : url.pathname.startsWith('/system/'))) {
+  } /* else if (storageFreeable && (ATTACHMENT_HOST ? url.host === ATTACHMENT_HOST : url.pathname.startsWith('/system/'))) {
     event.respondWith(openSystemCache().then(cache => {
       return cache.match(event.request.url).then(cached => {
         if (cached === undefined) {
@@ -73,5 +73,5 @@ self.addEventListener('fetch', function(event) {
         return cached;
       });
     }));
-  }
+  } */
 });
diff --git a/app/javascript/mastodon/utils/__tests__/html-test.js b/app/javascript/mastodon/utils/__tests__/html-test.js
new file mode 100644
index 000000000..ef9296e6c
--- /dev/null
+++ b/app/javascript/mastodon/utils/__tests__/html-test.js
@@ -0,0 +1,10 @@
+import * as html from '../html';
+
+describe('html', () => {
+  describe('unsecapeHTML', () => {
+    it('returns unescaped HTML', () => {
+      const output = html.unescapeHTML('<p>lorem</p><p>ipsum</p><br>&lt;br&gt;');
+      expect(output).toEqual('lorem\n\nipsum\n<br>');
+    });
+  });
+});
diff --git a/app/javascript/mastodon/utils/html.js b/app/javascript/mastodon/utils/html.js
index 5159df9db..247e98c88 100644
--- a/app/javascript/mastodon/utils/html.js
+++ b/app/javascript/mastodon/utils/html.js
@@ -1,3 +1,4 @@
+// NB: This function can still return unsafe HTML
 export const unescapeHTML = (html) => {
   const wrapper = document.createElement('div');
   wrapper.innerHTML = html.replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n').replace(/<[^>]*>/g, '');
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index 1e6ee62af..d273231bd 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -46,7 +46,7 @@ function main() {
     [].forEach.call(document.querySelectorAll('.logo-button'), (content) => {
       content.addEventListener('click', (e) => {
         e.preventDefault();
-        window.open(e.target.href, 'mastodon-intent', 'width=400,height=400,resizable=no,menubar=no,status=no,scrollbars=yes');
+        window.open(e.target.href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
       });
     });
 
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 300040173..f207c02a6 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -22,3 +22,4 @@
 @import 'mastodon/tables';
 @import 'mastodon/admin';
 @import 'mastodon/rtl';
+@import 'mastodon/accessibility';
diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss
index 77728995d..19e14fe95 100644
--- a/app/javascript/styles/mastodon/about.scss
+++ b/app/javascript/styles/mastodon/about.scss
@@ -901,6 +901,27 @@ $small-breakpoint: 960px;
       }
     }
 
+    .attachment-list__list {
+      margin-left: 0;
+      list-style: none;
+
+      li {
+        font-size: inherit;
+        line-height: inherit;
+        font-weight: inherit;
+        margin-bottom: 0;
+
+        a {
+          color: $dark-text-color;
+          text-decoration: none;
+
+          &:hover {
+            text-decoration: underline;
+          }
+        }
+      }
+    }
+
     @media screen and (max-width: $column-breakpoint) {
       height: 90vh;
     }
diff --git a/app/javascript/styles/mastodon/accessibility.scss b/app/javascript/styles/mastodon/accessibility.scss
new file mode 100644
index 000000000..373bcd4ac
--- /dev/null
+++ b/app/javascript/styles/mastodon/accessibility.scss
@@ -0,0 +1,14 @@
+$black-emojis: '8ball' 'ant' 'back' 'black_circle' 'black_large_square' 'black_medium_small_square' 'black_medium_square' 'black_nib' 'black_small_square' 'bomb' 'bust_in_silhouette' 'camera' 'camera_with_flash' 'clubs' 'copyright' 'curly_loop' 'currency_exchange' 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'lower_left_fountain_pen' 'on' 'registered' 'soon' 'spades' 'spider' 'tm' 'top' 'waving_black_flag' 'wavy_dash' 'video_game';
+
+%white-emoji-outline {
+  filter: drop-shadow(1px 1px 0 $white) drop-shadow(-1px 1px 0 $white) drop-shadow(1px -1px 0 $white) drop-shadow(-1px -1px 0 $white);
+  transform: scale(.71);
+}
+
+.emojione {
+  @each $emoji in $black-emojis {
+    &[title=':#{$emoji}:'] {
+      @extend %white-emoji-outline;
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index 14dc5dd62..b4612b063 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -440,6 +440,20 @@
       overflow: hidden;
       text-overflow: ellipsis;
       height: 5.5em;
+      position: relative;
+
+      &::after {
+        display: block;
+        content: "";
+        width: 100%;
+        height: 100px;
+        position: absolute;
+        bottom: 0;
+        background: linear-gradient(to bottom, rgba($simple-background-color, 0.01) 0%, rgba($simple-background-color, 1) 100%);
+        left: 0;
+        border-radius: 0 0 4px 4px;
+        pointer-events: none;
+      }
     }
   }
 }
@@ -464,6 +478,7 @@
   background: $simple-background-color;
 
   &__header {
+    background: $base-shadow-color;
     background-size: cover;
     background-position: center center;
     height: 90px;
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 6905eaa1e..de8538dd1 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -725,6 +725,20 @@
   vertical-align: middle;
 }
 
+.status__wrapper--filtered {
+  color: $dark-text-color;
+  border: 0;
+  font-size: inherit;
+  text-align: center;
+  line-height: inherit;
+  margin: 0;
+  padding: 15px;
+  box-sizing: border-box;
+  width: 100%;
+  clear: both;
+  border-bottom: 1px solid lighten($ui-base-color, 8%);
+}
+
 .status__prepend-icon-wrapper {
   left: -26px;
   position: absolute;
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index f1ed2c90b..375c7b64b 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -352,7 +352,7 @@ code {
     position: relative;
 
     .input input {
-      padding-right: 127px;
+      padding-right: 142px;
     }
 
     .append {
@@ -366,6 +366,20 @@ code {
       font-family: inherit;
       pointer-events: none;
       cursor: default;
+      max-width: 140px;
+      white-space: nowrap;
+      overflow: hidden;
+
+      &::after {
+        content: '';
+        display: block;
+        position: absolute;
+        top: 0;
+        right: 0;
+        bottom: 1px;
+        width: 5px;
+        background-image: linear-gradient(to right, rgba($ui-base-color, 0), $ui-base-color);
+      }
     }
   }
 }
@@ -598,3 +612,7 @@ code {
     display: block;
   }
 }
+
+.scope-danger {
+  color: $warning-red;
+}
diff --git a/app/javascript/styles/mastodon/modal.scss b/app/javascript/styles/mastodon/modal.scss
index ceb79bbb9..10de454c6 100644
--- a/app/javascript/styles/mastodon/modal.scss
+++ b/app/javascript/styles/mastodon/modal.scss
@@ -18,3 +18,9 @@
     background: url('~images/elephant_ui_plane.svg') no-repeat left bottom / contain;
   }
 }
+
+@media screen and (max-width: 600px) {
+  .account-header {
+    margin-top: 0;
+  }
+}
diff --git a/app/javascript/styles/mastodon/rtl.scss b/app/javascript/styles/mastodon/rtl.scss
index e9099a9e9..b8c0efad8 100644
--- a/app/javascript/styles/mastodon/rtl.scss
+++ b/app/javascript/styles/mastodon/rtl.scss
@@ -206,13 +206,19 @@ body.rtl {
   }
 
   .simple_form .input-with-append .input input {
-    padding-left: 127px;
+    padding-left: 142px;
     padding-right: 0;
   }
 
   .simple_form .input-with-append .append {
     right: auto;
     left: 0;
+
+    &::after {
+      right: auto;
+      left: 0;
+      background-image: linear-gradient(to left, rgba($ui-base-color, 0), $ui-base-color);
+    }
   }
 
   .table th,
diff --git a/app/javascript/styles/mastodon/stream_entries.scss b/app/javascript/styles/mastodon/stream_entries.scss
index 281cbaf83..9188c2206 100644
--- a/app/javascript/styles/mastodon/stream_entries.scss
+++ b/app/javascript/styles/mastodon/stream_entries.scss
@@ -307,53 +307,57 @@
 .embed {
   .activity-stream {
     box-shadow: none;
+  }
+}
 
-    .entry {
+.entry {
+  .detailed-status.light {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    align-items: flex-start;
 
-      .detailed-status.light {
-        display: flex;
-        flex-wrap: wrap;
-        justify-content: space-between;
-        align-items: flex-start;
+    .detailed-status__display-name {
+      flex: 1;
+      margin: 0 5px 15px 0;
+    }
 
-        .detailed-status__display-name {
-          flex: 1;
-          margin: 0 5px 15px 0;
+    .button.button-secondary.logo-button {
+      flex: 0 auto;
+      font-size: 14px;
+      background: $ui-highlight-color;
+      color: $primary-text-color;
+      border: 0;
+
+      svg {
+        width: 20px;
+        height: auto;
+        vertical-align: middle;
+        margin-right: 5px;
+
+        path:first-child {
+          fill: $primary-text-color;
         }
 
-        .button.button-secondary.logo-button {
-          flex: 0 auto;
-          font-size: 14px;
-
-          svg {
-            width: 20px;
-            height: auto;
-            vertical-align: middle;
-            margin-right: 5px;
-
-            path:first-child {
-              fill: $ui-primary-color;
-            }
-
-            path:last-child {
-              fill: $simple-background-color;
-            }
-          }
-
-          &:active,
-          &:focus,
-          &:hover {
-            svg path:first-child {
-              fill: lighten($ui-primary-color, 4%);
-            }
-          }
+        path:last-child {
+          fill: $ui-highlight-color;
         }
+      }
 
-        .status__content,
-        .detailed-status__meta {
-          flex: 100%;
+      &:active,
+      &:focus,
+      &:hover {
+        background: lighten($ui-highlight-color, 10%);
+
+        svg path:last-child {
+          fill: lighten($ui-highlight-color, 10%);
         }
       }
     }
+
+    .status__content,
+    .detailed-status__meta {
+      flex: 100%;
+    }
   }
 }
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index f30b00aa2..c247ab21d 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -153,11 +153,15 @@ class FeedManager
   def filter_from_home?(status, receiver_id)
     return false if receiver_id == status.account_id
     return true  if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?)
-    return true  if keyword_filter_from_home?(status, receiver_id)
+    return true  if phrase_filtered?(status, receiver_id, :home)
 
     check_for_blocks = status.mentions.pluck(:account_id)
     check_for_blocks.concat([status.account_id])
-    check_for_blocks.concat([status.reblog.account_id]) if status.reblog?
+
+    if status.reblog?
+      check_for_blocks.concat([status.reblog.account_id])
+      check_for_blocks.concat(status.reblog.mentions.pluck(:account_id))
+    end
 
     return true if blocks_or_mutes?(receiver_id, check_for_blocks, :home)
 
@@ -176,28 +180,9 @@ class FeedManager
     false
   end
 
-  def keyword_filter_from_home?(status, receiver_id)
-    # If this status mentions the receiver, use the mentions scope: it's
-    # possible that the status will show up in the receiver's mentions, which
-    # means it ought to show up in the home feed as well.
-    #
-    # If it doesn't mention the receiver but is still headed for the home feed,
-    # use the home feed scope.
-    scope = if status.mentions.pluck(:account_id).include?(receiver_id)
-              Glitch::KeywordMute::Scopes::Mentions
-            else
-              Glitch::KeywordMute::Scopes::HomeFeed
-            end
-
-    return true if keyword_filter?(status, receiver_id, scope)
-  end
-
-  def keyword_filter?(status, receiver_id, scope)
-    Glitch::KeywordMuteHelper.new(receiver_id).matches?(status, scope)
-  end
-
   def filter_from_mentions?(status, receiver_id)
     return true if receiver_id == status.account_id
+    return true if phrase_filtered?(status, receiver_id, :notifications)
 
     # This filter is called from NotifyService, but already after the sender of
     # the notification has been checked for mute/block. Therefore, it's not
@@ -207,11 +192,34 @@ class FeedManager
 
     should_filter   = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions)                                                         # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted)
     should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them
-    should_filter ||= keyword_filter?(status, receiver_id, Glitch::KeywordMute::Scopes::Mentions)                                        # or if the mention contains a muted keyword
 
     should_filter
   end
 
+  def phrase_filtered?(status, receiver_id, context)
+    active_filters = Rails.cache.fetch("filters:#{receiver_id}") { CustomFilter.where(account_id: receiver_id).active_irreversible.to_a }.to_a
+
+    active_filters.select! { |filter| filter.context.include?(context.to_s) && !filter.expired? }
+    active_filters.map! do |filter|
+      if filter.whole_word
+        sb = filter.phrase =~ /\A[[:word:]]/ ? '\b' : ''
+        eb = filter.phrase =~ /[[:word:]]\Z/ ? '\b' : ''
+
+        /(?mix:#{sb}#{Regexp.escape(filter.phrase)}#{eb})/
+      else
+        /#{Regexp.escape(filter.phrase)}/i
+      end
+    end
+
+    return false if active_filters.empty?
+
+    combined_regex = active_filters.reduce { |memo, obj| Regexp.union(memo, obj) }
+    status         = status.reblog if status.reblog?
+
+    !combined_regex.match(Formatter.instance.plaintext(status)).nil? ||
+      (status.spoiler_text.present? && !combined_regex.match(status.spoiler_text).nil?)
+  end
+
   # Adds a status to an account's feed, returning true if a status was
   # added, and false if it was not added to the feed. Note that this is
   # an internal helper: callers must call trim or push updates if
diff --git a/app/lib/potential_friendship_tracker.rb b/app/lib/potential_friendship_tracker.rb
new file mode 100644
index 000000000..362482669
--- /dev/null
+++ b/app/lib/potential_friendship_tracker.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+class PotentialFriendshipTracker
+  EXPIRE_AFTER = 90.days.seconds
+  MAX_ITEMS    = 80
+
+  WEIGHTS = {
+    reply: 1,
+    favourite: 10,
+    reblog: 20,
+  }.freeze
+
+  class << self
+    def record(account_id, target_account_id, action)
+      key    = "interactions:#{account_id}"
+      weight = WEIGHTS[action]
+
+      redis.zincrby(key, weight, target_account_id)
+      redis.zremrangebyrank(key, 0, -MAX_ITEMS)
+      redis.expire(key, EXPIRE_AFTER)
+    end
+
+    def remove(account_id, target_account_id)
+      redis.zrem("interactions:#{account_id}", target_account_id)
+    end
+
+    def get(account_id, limit: 20, offset: 0)
+      account_ids = redis.zrevrange("interactions:#{account_id}", offset, limit)
+      return [] if account_ids.empty?
+      Account.searchable.where(id: account_ids)
+    end
+
+    private
+
+    def redis
+      Redis.current
+    end
+  end
+end
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 397614fac..576ed23ca 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -154,7 +154,7 @@ class Request
       alias new open
 
       def thru_hidden_service?(host)
-        Rails.configuration.x.hidden_service_via_transparent_proxy && /\.(onion|i2p)$/.match(host)
+        Rails.configuration.x.access_to_hidden_service && /\.(onion|i2p)$/.match(host)
       end
     end
   end
diff --git a/app/models/account.rb b/app/models/account.rb
index 5099e4953..4abcd438a 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -102,6 +102,7 @@ class Account < ApplicationRecord
   has_many :targeted_reports, class_name: 'Report', foreign_key: :target_account_id
 
   has_many :report_notes, dependent: :destroy
+  has_many :custom_filters, inverse_of: :account, dependent: :destroy
 
   # Moderation notes
   has_many :account_moderation_notes, dependent: :destroy
@@ -129,6 +130,7 @@ class Account < ApplicationRecord
   scope :matches_username, ->(value) { where(arel_table[:username].matches("#{value}%")) }
   scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) }
   scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
+  scope :searchable, -> { where(suspended: false).where(moved_to_account_id: nil) }
 
   delegate :email,
            :unconfirmed_email,
@@ -311,34 +313,6 @@ class Account < ApplicationRecord
       DeliveryFailureTracker.filter(urls)
     end
 
-    def triadic_closures(account, limit: 5, offset: 0)
-      sql = <<-SQL.squish
-        WITH first_degree AS (
-          SELECT target_account_id
-          FROM follows
-          WHERE account_id = :account_id
-        )
-        SELECT accounts.*
-        FROM follows
-        INNER JOIN accounts ON follows.target_account_id = accounts.id
-        WHERE
-          account_id IN (SELECT * FROM first_degree)
-          AND target_account_id NOT IN (SELECT * FROM first_degree)
-          AND target_account_id NOT IN (:excluded_account_ids)
-          AND accounts.suspended = false
-        GROUP BY target_account_id, accounts.id
-        ORDER BY count(account_id) DESC
-        OFFSET :offset
-        LIMIT :limit
-      SQL
-
-      excluded_account_ids = account.excluded_from_timeline_account_ids + [account.id]
-
-      find_by_sql(
-        [sql, { account_id: account.id, excluded_account_ids: excluded_account_ids, limit: limit, offset: offset }]
-      )
-    end
-
     def search_for(terms, limit = 10)
       textsearch, query = generate_query_for_search(terms)
 
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index d067415fd..cacee54e0 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -89,10 +89,13 @@ module AccountInteractions
                               .find_or_create_by!(target_account: other_account)
 
     rel.update!(show_reblogs: reblogs)
+    remove_potential_friendship(other_account)
+
     rel
   end
 
   def block!(other_account, uri: nil)
+    remove_potential_friendship(other_account)
     block_relationships.create_with(uri: uri)
                        .find_or_create_by!(target_account: other_account)
   end
@@ -100,10 +103,13 @@ module AccountInteractions
   def mute!(other_account, notifications: nil)
     notifications = true if notifications.nil?
     mute = mute_relationships.create_with(hide_notifications: notifications).find_or_create_by!(target_account: other_account)
+    remove_potential_friendship(other_account)
+
     # When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
     if mute.hide_notifications? != notifications
       mute.update!(hide_notifications: notifications)
     end
+
     mute
   end
 
@@ -198,4 +204,11 @@ module AccountInteractions
     lists.joins(account: :user)
          .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago)
   end
+
+  private
+
+  def remove_potential_friendship(other_account, mutual = false)
+    PotentialFriendshipTracker.remove(id, other_account.id)
+    PotentialFriendshipTracker.remove(other_account.id, id) if mutual
+  end
 end
diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb
index 44bdfa39a..de4cf8775 100644
--- a/app/models/concerns/attachmentable.rb
+++ b/app/models/concerns/attachmentable.rb
@@ -28,7 +28,7 @@ module Attachmentable
     self.class.attachment_definitions.each_key do |attachment_name|
       attachment = send(attachment_name)
 
-      next if attachment.blank? || !attachment.content_type.match?(/image.*/) || attachment.queued_for_write[:original].blank?
+      next if attachment.blank? || !/image.*/.match?(attachment.content_type) || attachment.queued_for_write[:original].blank?
 
       width, height = FastImage.size(attachment.queued_for_write[:original].path)
 
diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb
new file mode 100644
index 000000000..444ccdfdb
--- /dev/null
+++ b/app/models/concerns/expireable.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Expireable
+  extend ActiveSupport::Concern
+
+  included do
+    scope :expired, -> { where.not(expires_at: nil).where('expires_at < ?', Time.now.utc) }
+
+    attr_reader :expires_in
+
+    def expires_in=(interval)
+      self.expires_at = interval.to_i.seconds.from_now unless interval.blank?
+      @expires_in     = interval
+    end
+
+    def expire!
+      touch(:expires_at)
+    end
+
+    def expired?
+      !expires_at.nil? && expires_at < Time.now.utc
+    end
+  end
+end
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb
new file mode 100644
index 000000000..342207a55
--- /dev/null
+++ b/app/models/custom_filter.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: custom_filters
+#
+#  id           :bigint(8)        not null, primary key
+#  account_id   :bigint(8)
+#  expires_at   :datetime
+#  phrase       :text             default(""), not null
+#  context      :string           default([]), not null, is an Array
+#  whole_word   :boolean          default(TRUE), not null
+#  irreversible :boolean          default(FALSE), not null
+#  created_at   :datetime         not null
+#  updated_at   :datetime         not null
+#
+
+class CustomFilter < ApplicationRecord
+  VALID_CONTEXTS = %w(
+    home
+    notifications
+    public
+    thread
+  ).freeze
+
+  include Expireable
+
+  belongs_to :account
+
+  validates :phrase, :context, presence: true
+  validate :context_must_be_valid
+  validate :irreversible_must_be_within_context
+
+  scope :active_irreversible, -> { where(irreversible: true).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) }
+
+  before_validation :clean_up_contexts
+  after_commit :remove_cache
+
+  private
+
+  def clean_up_contexts
+    self.context = Array(context).map(&:strip).map(&:presence).compact
+  end
+
+  def remove_cache
+    Rails.cache.delete("filters:#{account_id}")
+    Redis.current.publish("timeline:#{account_id}", Oj.dump(event: :filters_changed))
+  end
+
+  def context_must_be_valid
+    errors.add(:context, I18n.t('filters.errors.invalid_context')) if context.empty? || context.any? { |c| !VALID_CONTEXTS.include?(c) }
+  end
+
+  def irreversible_must_be_within_context
+    errors.add(:irreversible, I18n.t('filters.errors.invalid_irreversible')) if irreversible? && !context.include?('home') && !context.include?('notifications')
+  end
+end
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 32922e7f1..723480bdd 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -36,6 +36,8 @@ class Form::AdminSettings
     :peers_api_enabled=,
     :show_known_fediverse_at_about_page,
     :show_known_fediverse_at_about_page=,
+    :preview_sensitive_media,
+    :preview_sensitive_media=,
     to: Setting
   )
 end
diff --git a/app/models/glitch.rb b/app/models/glitch.rb
deleted file mode 100644
index 0e497babc..000000000
--- a/app/models/glitch.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module Glitch
-  def self.table_name_prefix
-    'glitch_'
-  end
-end
diff --git a/app/models/glitch/keyword_mute.rb b/app/models/glitch/keyword_mute.rb
deleted file mode 100644
index 49769cb73..000000000
--- a/app/models/glitch/keyword_mute.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-# frozen_string_literal: true
-# == Schema Information
-#
-# Table name: glitch_keyword_mutes
-#
-#  id                :bigint(8)        not null, primary key
-#  account_id        :bigint(8)        not null
-#  keyword           :string           not null
-#  whole_word        :boolean          default(TRUE), not null
-#  created_at        :datetime         not null
-#  updated_at        :datetime         not null
-#  apply_to_mentions :boolean          default(TRUE), not null
-#
-
-class Glitch::KeywordMute < ApplicationRecord
-  belongs_to :account, required: true
-
-  validates_presence_of :keyword
-
-  after_commit :invalidate_cached_matchers
-
-  module Scopes
-    Unscoped = 0b00
-    HomeFeed = 0b01
-    Mentions = 0b10
-  end
-
-  def self.text_matcher_for(account_id)
-    TextMatcher.new(account_id)
-  end
-
-  def self.tag_matcher_for(account_id)
-    TagMatcher.new(account_id)
-  end
-
-  def scope
-    s = Scopes::Unscoped
-    s |= Scopes::HomeFeed
-    s |= Scopes::Mentions if apply_to_mentions?
-    s
-  end
-
-  private
-
-  def invalidate_cached_matchers
-    Rails.cache.delete(TextMatcher.cache_key(account_id))
-    Rails.cache.delete(TagMatcher.cache_key(account_id))
-  end
-
-  class CachedKeywordMute
-    attr_reader :keyword
-    attr_reader :whole_word
-    attr_reader :scope
-
-    def initialize(keyword, whole_word, scope)
-      @keyword = keyword
-      @whole_word = whole_word
-      @scope = scope
-    end
-
-    def boundary_regex_for_keyword
-      sb = keyword =~ /\A[[:word:]]/ ? '\b' : ''
-      eb = keyword =~ /[[:word:]]\Z/ ? '\b' : ''
-
-      /(?mix:#{sb}#{Regexp.escape(keyword)}#{eb})/
-    end
-
-    def matches?(str, required_scope)
-      ((required_scope & scope) == required_scope) && \
-        str =~ (whole_word ? boundary_regex_for_keyword : /#{Regexp.escape(keyword)}/i)
-    end
-  end
-
-  class Matcher
-    attr_reader :account_id
-    attr_reader :keywords
-
-    def initialize(account_id)
-      @account_id = account_id
-      @keywords = Rails.cache.fetch(self.class.cache_key(account_id)) { fetch_keywords }
-    end
-
-    protected
-
-    def fetch_keywords
-      Glitch::KeywordMute.select(:whole_word, :keyword, :apply_to_mentions)
-        .where(account_id: account_id)
-        .map { |kw| CachedKeywordMute.new(transform_keyword(kw.keyword), kw.whole_word, kw.scope) }
-    end
-
-    def transform_keyword(keyword)
-      keyword
-    end
-  end
-
-  class TextMatcher < Matcher
-    def self.cache_key(account_id)
-      format('keyword_mutes:regex:text:%s', account_id)
-    end
-
-    def matches?(str, scope)
-      keywords.any? { |kw| kw.matches?(str, scope) }
-    end
-  end
-
-  class TagMatcher < Matcher
-    def self.cache_key(account_id)
-      format('keyword_mutes:regex:tag:%s', account_id)
-    end
-
-    def matches?(tags, scope)
-      tags.pluck(:name).any? do |n|
-        keywords.any? { |kw| kw.matches?(n, scope) }
-      end
-    end
-
-    protected
-
-    def transform_keyword(kw)
-      Tag::HASHTAG_RE =~ kw ? $1 : kw
-    end
-  end
-end
diff --git a/app/models/glitch/keyword_mute_helper.rb b/app/models/glitch/keyword_mute_helper.rb
deleted file mode 100644
index 955c3b1f3..000000000
--- a/app/models/glitch/keyword_mute_helper.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'html2text'
-
-class Glitch::KeywordMuteHelper
-  attr_reader :text_matcher
-  attr_reader :tag_matcher
-
-  def initialize(receiver_id)
-    @text_matcher   = Glitch::KeywordMute.text_matcher_for(receiver_id)
-    @tag_matcher    = Glitch::KeywordMute.tag_matcher_for(receiver_id)
-  end
-
-  def matches?(status, scope)
-    matchers_match?(status, scope) || (status.reblog? && matchers_match?(status.reblog, scope))
-  end
-
-  private
-
-  def matchers_match?(status, scope)
-    text_matcher.matches?(prepare_text(status.text), scope) ||
-      text_matcher.matches?(prepare_text(status.spoiler_text), scope) ||
-      tag_matcher.matches?(status.tags, scope)
-  end
-
-  def prepare_text(text)
-    Html2Text.convert(text)
-  end
-end
diff --git a/app/models/invite.rb b/app/models/invite.rb
index d0cc427c4..fe2322462 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -15,33 +15,19 @@
 #
 
 class Invite < ApplicationRecord
+  include Expireable
+
   belongs_to :user
   has_many :users, inverse_of: :invite
 
   scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) }
-  scope :expired, -> { where.not(expires_at: nil).where('expires_at < ?', Time.now.utc) }
 
   before_validation :set_code
 
-  attr_reader :expires_in
-
-  def expires_in=(interval)
-    self.expires_at = interval.to_i.seconds.from_now unless interval.blank?
-    @expires_in     = interval
-  end
-
   def valid_for_use?
     (max_uses.nil? || uses < max_uses) && !expired?
   end
 
-  def expire!
-    touch(:expires_at)
-  end
-
-  def expired?
-    !expires_at.nil? && expires_at < Time.now.utc
-  end
-
   private
 
   def set_code
diff --git a/app/serializers/rest/filter_serializer.rb b/app/serializers/rest/filter_serializer.rb
new file mode 100644
index 000000000..3134be371
--- /dev/null
+++ b/app/serializers/rest/filter_serializer.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class REST::FilterSerializer < ActiveModel::Serializer
+  attributes :id, :phrase, :context, :whole_word, :expires_at,
+             :irreversible
+end
diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb
index bc2d1547a..6e1ac3ba9 100644
--- a/app/services/favourite_service.rb
+++ b/app/services/favourite_service.rb
@@ -15,7 +15,10 @@ class FavouriteService < BaseService
     return favourite unless favourite.nil?
 
     favourite = Favourite.create!(account: account, status: status)
+
     create_notification(favourite)
+    bump_potential_friendship(account, status)
+
     favourite
   end
 
@@ -33,6 +36,11 @@ class FavouriteService < BaseService
     end
   end
 
+  def bump_potential_friendship(account, status)
+    return if account.following?(status.account_id)
+    PotentialFriendshipTracker.record(account.id, status.account_id, :favourite)
+  end
+
   def build_json(favourite)
     Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       favourite,
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 8b8fe51c1..a27f28ef6 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -50,6 +50,8 @@ class PostStatusService < BaseService
       redis.setex("idempotency:status:#{account.id}:#{options[:idempotency]}", 3_600, status.id)
     end
 
+    bump_potential_friendship(account, status)
+
     status
   end
 
@@ -82,4 +84,9 @@ class PostStatusService < BaseService
   def redis
     Redis.current
   end
+
+  def bump_potential_friendship(account, status)
+    return if !status.reply? || account.following?(status.in_reply_to_account_id)
+    PotentialFriendshipTracker.record(account.id, status.in_reply_to_account_id, :reply)
+  end
 end
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 8d8b15a41..955a2bdbc 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -27,6 +27,8 @@ class ReblogService < BaseService
     end
 
     create_notification(reblog)
+    bump_potential_friendship(account, reblog)
+
     reblog
   end
 
@@ -44,6 +46,11 @@ class ReblogService < BaseService
     end
   end
 
+  def bump_potential_friendship(account, reblog)
+    return if account.following?(reblog.reblog.account_id)
+    PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
+  end
+
   def build_json(reblog)
     Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       reblog,
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index b9631077c..238099169 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -67,7 +67,9 @@ class RemoveStatusService < BaseService
     # delete notification - so here, we explicitly
     # send it to them
 
-    target_accounts = (@mentions.map(&:account).reject(&:local?) + @reblogs.map(&:account).reject(&:local?)).uniq(&:id)
+    target_accounts = (@mentions.map(&:account).reject(&:local?) + @reblogs.map(&:account).reject(&:local?))
+    target_accounts << @status.reblog.account if @status.reblog? && !@status.reblog.account.local?
+    target_accounts.uniq!(&:id)
 
     # Ostatus
     NotificationWorker.push_bulk(target_accounts.select(&:ostatus?).uniq(&:domain)) do |target_account|
diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb
index 3cc5853c6..e9e6b56e8 100644
--- a/app/validators/email_mx_validator.rb
+++ b/app/validators/email_mx_validator.rb
@@ -16,6 +16,8 @@ class EmailMxValidator < ActiveModel::Validator
     return true if domain.nil?
 
     records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
+    records = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.exchange.to_s } if records.empty?
+
     records.empty? || on_blacklist?(records)
   end
 
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index 08d05d738..f5c5deca8 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -2,6 +2,9 @@
   = t('admin.settings.title')
 
 = simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f|
+  .actions.actions--top
+    = f.button :button, t('generic.save_changes'), type: :submit
+
   .fields-group
     = f.input :site_title, placeholder: t('admin.settings.site_title')
     = f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 8 }
@@ -58,5 +61,8 @@
   .fields-group
     = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html')
 
+  .fields-group
+    = f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
+
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/filters/_fields.html.haml b/app/views/filters/_fields.html.haml
new file mode 100644
index 000000000..a5a3f0337
--- /dev/null
+++ b/app/views/filters/_fields.html.haml
@@ -0,0 +1,14 @@
+.fields-group
+  = f.input :phrase, as: :string, wrapper: :with_block_label
+
+.fields-group
+  = f.input :context, wrapper: :with_block_label, collection: CustomFilter::VALID_CONTEXTS, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label_method: lambda { |context| I18n.t("filters.contexts.#{context}") }, include_blank: false
+
+.fields-group
+  = f.input :irreversible, wrapper: :with_label
+
+.fields-group
+  = f.input :whole_word, wrapper: :with_label
+
+.fields-group
+  = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
diff --git a/app/views/filters/edit.html.haml b/app/views/filters/edit.html.haml
new file mode 100644
index 000000000..e971215ac
--- /dev/null
+++ b/app/views/filters/edit.html.haml
@@ -0,0 +1,8 @@
+- content_for :page_title do
+  = t('filters.edit.title')
+
+= simple_form_for @filter, url: filter_path(@filter), method: :put do |f|
+  = render 'fields', f: f
+
+  .actions
+    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/filters/index.html.haml b/app/views/filters/index.html.haml
new file mode 100644
index 000000000..18ebee570
--- /dev/null
+++ b/app/views/filters/index.html.haml
@@ -0,0 +1,20 @@
+- content_for :page_title do
+  = t('filters.index.title')
+
+.table-wrapper
+  %table.table
+    %thead
+      %tr
+        %th= t('simple_form.labels.defaults.phrase')
+        %th= t('simple_form.labels.defaults.context')
+        %th
+    %tbody
+      - @filters.each do |filter|
+        %tr
+          %td= filter.phrase
+          %td= filter.context.map { |context| I18n.t("filters.contexts.#{context}") }.join(', ')
+          %td
+            = table_link_to 'pencil', t('filters.edit.title'), edit_filter_path(filter)
+            = table_link_to 'times', t('filters.index.delete'), filter_path(filter), method: :delete
+
+= link_to t('filters.new.title'), new_filter_path, class: 'button'
diff --git a/app/views/filters/new.html.haml b/app/views/filters/new.html.haml
new file mode 100644
index 000000000..05bec343f
--- /dev/null
+++ b/app/views/filters/new.html.haml
@@ -0,0 +1,8 @@
+- content_for :page_title do
+  = t('filters.new.title')
+
+= simple_form_for @filter, url: filters_path do |f|
+  = render 'fields', f: f
+
+  .actions
+    = f.button :button, t('filters.new.title'), type: :submit
diff --git a/app/views/remote_follow/new.html.haml b/app/views/remote_follow/new.html.haml
index fc5c4da20..9b22fda5f 100644
--- a/app/views/remote_follow/new.html.haml
+++ b/app/views/remote_follow/new.html.haml
@@ -1,3 +1,7 @@
+- content_for :header_tags do
+  - if @account.user&.setting_noindex
+    %meta{ name: 'robots', content: 'noindex' }/
+
 .form-container
   .follow-prompt
     %h2= t('remote_follow.prompt')
@@ -11,3 +15,5 @@
 
     .actions
       = f.button :button, t('remote_follow.proceed'), type: :submit
+
+    %p.hint.subtle-hint= t('remote_follow.no_account_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml
index b21f3cca6..db90df349 100644
--- a/app/views/settings/applications/_fields.html.haml
+++ b/app/views/settings/applications/_fields.html.haml
@@ -8,14 +8,9 @@
   %p.hint= t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: Doorkeeper.configuration.native_redirect_uri)
 
 .field-group
-  = f.input :scopes,
-    label: t('activerecord.attributes.doorkeeper/application.scopes'),
-    collection: Doorkeeper.configuration.scopes,
-    wrapper: :with_label,
-    include_blank: false,
-    label_method: lambda { |scope| safe_join([scope, content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) },
-    selected: f.object.scopes.all,
-    required: false,
-    as: :check_boxes,
-    collection_wrapper_tag: 'ul',
-    item_wrapper_tag: 'li'
+  .input.with_block_label
+    %label= t('activerecord.attributes.doorkeeper/application.scopes')
+    %span.hint= t('simple_form.hints.defaults.scopes')
+
+  - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each do |k, v|
+    = f.input :scopes, label: false, hint: false, collection: v.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |scope| safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, selected: f.object.scopes.all, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
diff --git a/app/views/shared/_landing_strip.html.haml b/app/views/shared/_landing_strip.html.haml
index 78f5ed4bc..9a4144723 100644
--- a/app/views/shared/_landing_strip.html.haml
+++ b/app/views/shared/_landing_strip.html.haml
@@ -3,6 +3,4 @@
 
   %div
     = t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path))
-
-    - if open_registrations?
-      = t('landing_strip_signup_html', sign_up_path: new_user_registration_path)
+    = t('landing_strip_signup_html', sign_up_path: open_registrations? ? new_user_registration_path : 'https://joinmastodon.org/#getting-started')
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index c0f1e4f0f..85e90a237 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -7,12 +7,12 @@
       %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
       %span= acct(status.account)
 
-  - if embedded_view?
-    = link_to "web+mastodon://follow?uri=#{status.account.local_username_and_domain}", class: 'button button-secondary logo-button', target: '_new' do
+  - if !user_signed_in? || embedded_view?
+    = link_to account_remote_follow_path(status.account), class: 'button button-secondary logo-button', target: '_new' do
       = render file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')
       = t('accounts.follow')
 
-  .status__content.p-name.emojify<
+  .status__content.emojify<
     - if status.spoiler_text?
       %p{ style: 'margin-bottom: 0' }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;
diff --git a/app/views/stream_entries/_og_image.html.haml b/app/views/stream_entries/_og_image.html.haml
index 40530f567..e1b977da3 100644
--- a/app/views/stream_entries/_og_image.html.haml
+++ b/app/views/stream_entries/_og_image.html.haml
@@ -1,4 +1,4 @@
-- if activity.is_a?(Status) && activity.non_sensitive_with_media?
+- if activity.is_a?(Status) && (activity.non_sensitive_with_media? || (activity.with_media? && Setting.preview_sensitive_media))
   - player_card = false
   - activity.media_attachments.each do |media|
     - if media.image?
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index 990e45094..397b8dca3 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -13,7 +13,7 @@
         %strong.p-name.emojify= display_name(status.account, custom_emojify: true)
         %span= acct(status.account)
 
-  .status__content.p-name.emojify<
+  .status__content.emojify<
     - if status.spoiler_text?
       %p{ style: 'margin-bottom: 0' }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;