about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2023-02-25 14:00:40 +0100
committerClaire <claire.github-309c@sitedethib.com>2023-02-25 14:00:40 +0100
commit4ed09276d5267181061dff438a0b10770db9f226 (patch)
treecb8f358d58669626332ea01bcf0186d08b5eac90 /app
parent45087c1092143e95dfcc85b6c9abc5c6c0a0a5c2 (diff)
parent730bb3e211a84a2f30e3e2bbeae3f77149824a68 (diff)
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts:
- `.prettierignore`:
  Upstream added a line at the end of the file, while glitch-soc had its own
  extra lines.
  Took upstream's change.
- `CONTRIBUTING.md`:
  We have our custom CONTRIBUTING.md quoting upstream. Upstream made changes.
  Ported upstream changes.
- `app/controllers/application_controller.rb`:
  Upstream made code style changes in a method that is entirely replaced
  in glitch-soc.
  Ignored the change.
- `app/models/account.rb`:
  Code style changes textually close to glitch-soc-specific changes.
  Ported upstream changes.
- `lib/sanitize_ext/sanitize_config.rb`:
  Upstream code style changes.
  Ignored them.
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/emails/confirmations_controller.rb4
-rw-r--r--app/controllers/api/v1/notifications_controller.rb2
-rw-r--r--app/controllers/api/v1/tags_controller.rb1
-rw-r--r--app/controllers/auth/sessions_controller.rb4
-rw-r--r--app/controllers/concerns/session_tracking_concern.rb1
-rw-r--r--app/controllers/concerns/signature_verification.rb1
-rw-r--r--app/controllers/concerns/two_factor_authentication_concern.rb4
-rw-r--r--app/controllers/media_controller.rb2
-rw-r--r--app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb2
-rw-r--r--app/helpers/application_helper.rb1
-rw-r--r--app/helpers/languages_helper.rb1
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.jsx.snap (renamed from app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap)0
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap (renamed from app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap)0
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.jsx.snap (renamed from app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap)0
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/button-test.jsx.snap (renamed from app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap)0
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap (renamed from app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.js.snap)0
-rw-r--r--app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.jsx (renamed from app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js)0
-rw-r--r--app/javascript/mastodon/components/__tests__/avatar-test.jsx (renamed from app/javascript/mastodon/components/__tests__/avatar-test.js)0
-rw-r--r--app/javascript/mastodon/components/__tests__/avatar_overlay-test.jsx (renamed from app/javascript/mastodon/components/__tests__/avatar_overlay-test.js)0
-rw-r--r--app/javascript/mastodon/components/__tests__/button-test.jsx (renamed from app/javascript/mastodon/components/__tests__/button-test.js)0
-rw-r--r--app/javascript/mastodon/components/__tests__/display_name-test.jsx (renamed from app/javascript/mastodon/components/__tests__/display_name-test.js)0
-rw-r--r--app/javascript/mastodon/components/account.jsx (renamed from app/javascript/mastodon/components/account.js)0
-rw-r--r--app/javascript/mastodon/components/admin/Counter.jsx (renamed from app/javascript/mastodon/components/admin/Counter.js)0
-rw-r--r--app/javascript/mastodon/components/admin/Dimension.jsx (renamed from app/javascript/mastodon/components/admin/Dimension.js)0
-rw-r--r--app/javascript/mastodon/components/admin/ReportReasonSelector.jsx (renamed from app/javascript/mastodon/components/admin/ReportReasonSelector.js)0
-rw-r--r--app/javascript/mastodon/components/admin/Retention.jsx (renamed from app/javascript/mastodon/components/admin/Retention.js)0
-rw-r--r--app/javascript/mastodon/components/admin/Trends.jsx (renamed from app/javascript/mastodon/components/admin/Trends.js)0
-rw-r--r--app/javascript/mastodon/components/animated_number.jsx (renamed from app/javascript/mastodon/components/animated_number.js)0
-rw-r--r--app/javascript/mastodon/components/attachment_list.jsx (renamed from app/javascript/mastodon/components/attachment_list.js)0
-rw-r--r--app/javascript/mastodon/components/autosuggest_emoji.jsx (renamed from app/javascript/mastodon/components/autosuggest_emoji.js)0
-rw-r--r--app/javascript/mastodon/components/autosuggest_hashtag.jsx (renamed from app/javascript/mastodon/components/autosuggest_hashtag.js)0
-rw-r--r--app/javascript/mastodon/components/autosuggest_input.jsx (renamed from app/javascript/mastodon/components/autosuggest_input.js)0
-rw-r--r--app/javascript/mastodon/components/autosuggest_textarea.jsx (renamed from app/javascript/mastodon/components/autosuggest_textarea.js)0
-rw-r--r--app/javascript/mastodon/components/avatar.jsx (renamed from app/javascript/mastodon/components/avatar.js)0
-rw-r--r--app/javascript/mastodon/components/avatar_composite.jsx (renamed from app/javascript/mastodon/components/avatar_composite.js)0
-rw-r--r--app/javascript/mastodon/components/avatar_overlay.jsx (renamed from app/javascript/mastodon/components/avatar_overlay.js)0
-rw-r--r--app/javascript/mastodon/components/blurhash.jsx (renamed from app/javascript/mastodon/components/blurhash.js)0
-rw-r--r--app/javascript/mastodon/components/button.jsx (renamed from app/javascript/mastodon/components/button.js)0
-rw-r--r--app/javascript/mastodon/components/check.jsx (renamed from app/javascript/mastodon/components/check.js)0
-rw-r--r--app/javascript/mastodon/components/column.jsx (renamed from app/javascript/mastodon/components/column.js)0
-rw-r--r--app/javascript/mastodon/components/column_back_button.jsx (renamed from app/javascript/mastodon/components/column_back_button.js)0
-rw-r--r--app/javascript/mastodon/components/column_back_button_slim.jsx (renamed from app/javascript/mastodon/components/column_back_button_slim.js)0
-rw-r--r--app/javascript/mastodon/components/column_header.jsx (renamed from app/javascript/mastodon/components/column_header.js)0
-rw-r--r--app/javascript/mastodon/components/common_counter.jsx (renamed from app/javascript/mastodon/components/common_counter.js)0
-rw-r--r--app/javascript/mastodon/components/dismissable_banner.jsx (renamed from app/javascript/mastodon/components/dismissable_banner.js)0
-rw-r--r--app/javascript/mastodon/components/display_name.jsx (renamed from app/javascript/mastodon/components/display_name.js)0
-rw-r--r--app/javascript/mastodon/components/domain.jsx (renamed from app/javascript/mastodon/components/domain.js)0
-rw-r--r--app/javascript/mastodon/components/dropdown_menu.jsx (renamed from app/javascript/mastodon/components/dropdown_menu.js)0
-rw-r--r--app/javascript/mastodon/components/edited_timestamp/index.jsx (renamed from app/javascript/mastodon/components/edited_timestamp/index.js)0
-rw-r--r--app/javascript/mastodon/components/error_boundary.jsx (renamed from app/javascript/mastodon/components/error_boundary.js)0
-rw-r--r--app/javascript/mastodon/components/gifv.jsx (renamed from app/javascript/mastodon/components/gifv.js)0
-rw-r--r--app/javascript/mastodon/components/hashtag.jsx (renamed from app/javascript/mastodon/components/hashtag.js)0
-rw-r--r--app/javascript/mastodon/components/icon.jsx (renamed from app/javascript/mastodon/components/icon.js)0
-rw-r--r--app/javascript/mastodon/components/icon_button.jsx (renamed from app/javascript/mastodon/components/icon_button.js)0
-rw-r--r--app/javascript/mastodon/components/icon_with_badge.jsx (renamed from app/javascript/mastodon/components/icon_with_badge.js)0
-rw-r--r--app/javascript/mastodon/components/image.jsx (renamed from app/javascript/mastodon/components/image.js)0
-rw-r--r--app/javascript/mastodon/components/inline_account.jsx (renamed from app/javascript/mastodon/components/inline_account.js)0
-rw-r--r--app/javascript/mastodon/components/intersection_observer_article.jsx (renamed from app/javascript/mastodon/components/intersection_observer_article.js)0
-rw-r--r--app/javascript/mastodon/components/load_gap.jsx (renamed from app/javascript/mastodon/components/load_gap.js)0
-rw-r--r--app/javascript/mastodon/components/load_more.jsx (renamed from app/javascript/mastodon/components/load_more.js)0
-rw-r--r--app/javascript/mastodon/components/load_pending.jsx (renamed from app/javascript/mastodon/components/load_pending.js)0
-rw-r--r--app/javascript/mastodon/components/loading_indicator.jsx (renamed from app/javascript/mastodon/components/loading_indicator.js)0
-rw-r--r--app/javascript/mastodon/components/logo.jsx (renamed from app/javascript/mastodon/components/logo.js)0
-rw-r--r--app/javascript/mastodon/components/media_attachments.jsx (renamed from app/javascript/mastodon/components/media_attachments.js)0
-rw-r--r--app/javascript/mastodon/components/media_gallery.jsx (renamed from app/javascript/mastodon/components/media_gallery.js)0
-rw-r--r--app/javascript/mastodon/components/missing_indicator.jsx (renamed from app/javascript/mastodon/components/missing_indicator.js)0
-rw-r--r--app/javascript/mastodon/components/modal_root.jsx (renamed from app/javascript/mastodon/components/modal_root.js)0
-rw-r--r--app/javascript/mastodon/components/navigation_portal.jsx (renamed from app/javascript/mastodon/components/navigation_portal.js)0
-rw-r--r--app/javascript/mastodon/components/not_signed_in_indicator.jsx (renamed from app/javascript/mastodon/components/not_signed_in_indicator.js)0
-rw-r--r--app/javascript/mastodon/components/picture_in_picture_placeholder.jsx (renamed from app/javascript/mastodon/components/picture_in_picture_placeholder.js)0
-rw-r--r--app/javascript/mastodon/components/poll.jsx (renamed from app/javascript/mastodon/components/poll.js)0
-rw-r--r--app/javascript/mastodon/components/radio_button.jsx (renamed from app/javascript/mastodon/components/radio_button.js)0
-rw-r--r--app/javascript/mastodon/components/regeneration_indicator.jsx (renamed from app/javascript/mastodon/components/regeneration_indicator.js)0
-rw-r--r--app/javascript/mastodon/components/relative_timestamp.jsx (renamed from app/javascript/mastodon/components/relative_timestamp.js)0
-rw-r--r--app/javascript/mastodon/components/scrollable_list.jsx (renamed from app/javascript/mastodon/components/scrollable_list.js)0
-rw-r--r--app/javascript/mastodon/components/server_banner.jsx (renamed from app/javascript/mastodon/components/server_banner.js)0
-rw-r--r--app/javascript/mastodon/components/short_number.jsx (renamed from app/javascript/mastodon/components/short_number.js)0
-rw-r--r--app/javascript/mastodon/components/skeleton.jsx (renamed from app/javascript/mastodon/components/skeleton.js)0
-rw-r--r--app/javascript/mastodon/components/status.jsx (renamed from app/javascript/mastodon/components/status.js)5
-rw-r--r--app/javascript/mastodon/components/status_action_bar.jsx (renamed from app/javascript/mastodon/components/status_action_bar.js)0
-rw-r--r--app/javascript/mastodon/components/status_content.jsx (renamed from app/javascript/mastodon/components/status_content.js)0
-rw-r--r--app/javascript/mastodon/components/status_list.jsx (renamed from app/javascript/mastodon/components/status_list.js)0
-rw-r--r--app/javascript/mastodon/components/timeline_hint.jsx (renamed from app/javascript/mastodon/components/timeline_hint.js)0
-rw-r--r--app/javascript/mastodon/containers/account_container.jsx (renamed from app/javascript/mastodon/containers/account_container.js)0
-rw-r--r--app/javascript/mastodon/containers/admin_component.jsx (renamed from app/javascript/mastodon/containers/admin_component.js)0
-rw-r--r--app/javascript/mastodon/containers/compose_container.jsx (renamed from app/javascript/mastodon/containers/compose_container.js)0
-rw-r--r--app/javascript/mastodon/containers/domain_container.jsx (renamed from app/javascript/mastodon/containers/domain_container.js)0
-rw-r--r--app/javascript/mastodon/containers/mastodon.jsx (renamed from app/javascript/mastodon/containers/mastodon.js)0
-rw-r--r--app/javascript/mastodon/containers/media_container.jsx (renamed from app/javascript/mastodon/containers/media_container.js)0
-rw-r--r--app/javascript/mastodon/containers/status_container.jsx (renamed from app/javascript/mastodon/containers/status_container.js)0
-rw-r--r--app/javascript/mastodon/features/about/index.jsx (renamed from app/javascript/mastodon/features/about/index.js)0
-rw-r--r--app/javascript/mastodon/features/account/components/account_note.jsx (renamed from app/javascript/mastodon/features/account/components/account_note.js)0
-rw-r--r--app/javascript/mastodon/features/account/components/featured_tags.jsx (renamed from app/javascript/mastodon/features/account/components/featured_tags.js)0
-rw-r--r--app/javascript/mastodon/features/account/components/follow_request_note.jsx (renamed from app/javascript/mastodon/features/account/components/follow_request_note.js)0
-rw-r--r--app/javascript/mastodon/features/account/components/header.jsx (renamed from app/javascript/mastodon/features/account/components/header.js)0
-rw-r--r--app/javascript/mastodon/features/account/navigation.jsx (renamed from app/javascript/mastodon/features/account/navigation.js)0
-rw-r--r--app/javascript/mastodon/features/account_gallery/components/media_item.jsx (renamed from app/javascript/mastodon/features/account_gallery/components/media_item.js)0
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.jsx (renamed from app/javascript/mastodon/features/account_gallery/index.js)0
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/header.jsx (renamed from app/javascript/mastodon/features/account_timeline/components/header.js)0
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/limited_account_hint.jsx (renamed from app/javascript/mastodon/features/account_timeline/components/limited_account_hint.js)0
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/moved_note.jsx (renamed from app/javascript/mastodon/features/account_timeline/components/moved_note.js)0
-rw-r--r--app/javascript/mastodon/features/account_timeline/containers/header_container.jsx (renamed from app/javascript/mastodon/features/account_timeline/containers/header_container.js)0
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.jsx (renamed from app/javascript/mastodon/features/account_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/audio/index.jsx (renamed from app/javascript/mastodon/features/audio/index.js)0
-rw-r--r--app/javascript/mastodon/features/blocks/index.jsx (renamed from app/javascript/mastodon/features/blocks/index.js)0
-rw-r--r--app/javascript/mastodon/features/bookmarked_statuses/index.jsx (renamed from app/javascript/mastodon/features/bookmarked_statuses/index.js)0
-rw-r--r--app/javascript/mastodon/features/closed_registrations_modal/index.jsx (renamed from app/javascript/mastodon/features/closed_registrations_modal/index.js)0
-rw-r--r--app/javascript/mastodon/features/community_timeline/components/column_settings.jsx (renamed from app/javascript/mastodon/features/community_timeline/components/column_settings.js)0
-rw-r--r--app/javascript/mastodon/features/community_timeline/index.jsx (renamed from app/javascript/mastodon/features/community_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/action_bar.jsx (renamed from app/javascript/mastodon/features/compose/components/action_bar.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/autosuggest_account.jsx (renamed from app/javascript/mastodon/features/compose/components/autosuggest_account.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/character_counter.jsx (renamed from app/javascript/mastodon/features/compose/components/character_counter.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/compose_form.jsx (renamed from app/javascript/mastodon/features/compose/components/compose_form.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx (renamed from app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/language_dropdown.jsx (renamed from app/javascript/mastodon/features/compose/components/language_dropdown.js)2
-rw-r--r--app/javascript/mastodon/features/compose/components/navigation_bar.jsx (renamed from app/javascript/mastodon/features/compose/components/navigation_bar.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/poll_button.jsx (renamed from app/javascript/mastodon/features/compose/components/poll_button.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/poll_form.jsx (renamed from app/javascript/mastodon/features/compose/components/poll_form.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx (renamed from app/javascript/mastodon/features/compose/components/privacy_dropdown.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/reply_indicator.jsx (renamed from app/javascript/mastodon/features/compose/components/reply_indicator.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/search.jsx (renamed from app/javascript/mastodon/features/compose/components/search.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/search_results.jsx (renamed from app/javascript/mastodon/features/compose/components/search_results.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/text_icon_button.jsx (renamed from app/javascript/mastodon/features/compose/components/text_icon_button.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/upload.jsx (renamed from app/javascript/mastodon/features/compose/components/upload.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/upload_button.jsx (renamed from app/javascript/mastodon/features/compose/components/upload_button.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/upload_form.jsx (renamed from app/javascript/mastodon/features/compose/components/upload_form.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/upload_progress.jsx (renamed from app/javascript/mastodon/features/compose/components/upload_progress.js)0
-rw-r--r--app/javascript/mastodon/features/compose/components/warning.jsx (renamed from app/javascript/mastodon/features/compose/components/warning.js)0
-rw-r--r--app/javascript/mastodon/features/compose/containers/sensitive_button_container.jsx (renamed from app/javascript/mastodon/features/compose/containers/sensitive_button_container.js)2
-rw-r--r--app/javascript/mastodon/features/compose/containers/warning_container.jsx (renamed from app/javascript/mastodon/features/compose/containers/warning_container.js)0
-rw-r--r--app/javascript/mastodon/features/compose/index.jsx (renamed from app/javascript/mastodon/features/compose/index.js)0
-rw-r--r--app/javascript/mastodon/features/direct_timeline/components/conversation.jsx (renamed from app/javascript/mastodon/features/direct_timeline/components/conversation.js)0
-rw-r--r--app/javascript/mastodon/features/direct_timeline/components/conversations_list.jsx (renamed from app/javascript/mastodon/features/direct_timeline/components/conversations_list.js)0
-rw-r--r--app/javascript/mastodon/features/direct_timeline/index.jsx (renamed from app/javascript/mastodon/features/direct_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/directory/components/account_card.jsx (renamed from app/javascript/mastodon/features/directory/components/account_card.js)0
-rw-r--r--app/javascript/mastodon/features/directory/index.jsx (renamed from app/javascript/mastodon/features/directory/index.js)0
-rw-r--r--app/javascript/mastodon/features/domain_blocks/index.jsx (renamed from app/javascript/mastodon/features/domain_blocks/index.js)0
-rw-r--r--app/javascript/mastodon/features/explore/components/story.jsx (renamed from app/javascript/mastodon/features/explore/components/story.js)0
-rw-r--r--app/javascript/mastodon/features/explore/index.jsx (renamed from app/javascript/mastodon/features/explore/index.js)0
-rw-r--r--app/javascript/mastodon/features/explore/links.jsx (renamed from app/javascript/mastodon/features/explore/links.js)0
-rw-r--r--app/javascript/mastodon/features/explore/results.jsx (renamed from app/javascript/mastodon/features/explore/results.js)0
-rw-r--r--app/javascript/mastodon/features/explore/statuses.jsx (renamed from app/javascript/mastodon/features/explore/statuses.js)0
-rw-r--r--app/javascript/mastodon/features/explore/suggestions.jsx (renamed from app/javascript/mastodon/features/explore/suggestions.js)0
-rw-r--r--app/javascript/mastodon/features/explore/tags.jsx (renamed from app/javascript/mastodon/features/explore/tags.js)0
-rw-r--r--app/javascript/mastodon/features/favourited_statuses/index.jsx (renamed from app/javascript/mastodon/features/favourited_statuses/index.js)0
-rw-r--r--app/javascript/mastodon/features/favourites/index.jsx (renamed from app/javascript/mastodon/features/favourites/index.js)0
-rw-r--r--app/javascript/mastodon/features/filters/added_to_filter.jsx (renamed from app/javascript/mastodon/features/filters/added_to_filter.js)0
-rw-r--r--app/javascript/mastodon/features/filters/select_filter.jsx (renamed from app/javascript/mastodon/features/filters/select_filter.js)0
-rw-r--r--app/javascript/mastodon/features/follow_recommendations/components/account.jsx (renamed from app/javascript/mastodon/features/follow_recommendations/components/account.js)0
-rw-r--r--app/javascript/mastodon/features/follow_recommendations/index.jsx (renamed from app/javascript/mastodon/features/follow_recommendations/index.js)0
-rw-r--r--app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx (renamed from app/javascript/mastodon/features/follow_requests/components/account_authorize.js)0
-rw-r--r--app/javascript/mastodon/features/follow_requests/index.jsx (renamed from app/javascript/mastodon/features/follow_requests/index.js)0
-rw-r--r--app/javascript/mastodon/features/followed_tags/index.jsx (renamed from app/javascript/mastodon/features/followed_tags/index.js)0
-rw-r--r--app/javascript/mastodon/features/followers/index.jsx (renamed from app/javascript/mastodon/features/followers/index.js)0
-rw-r--r--app/javascript/mastodon/features/following/index.jsx (renamed from app/javascript/mastodon/features/following/index.js)0
-rw-r--r--app/javascript/mastodon/features/generic_not_found/index.jsx (renamed from app/javascript/mastodon/features/generic_not_found/index.js)0
-rw-r--r--app/javascript/mastodon/features/getting_started/components/announcements.jsx (renamed from app/javascript/mastodon/features/getting_started/components/announcements.js)0
-rw-r--r--app/javascript/mastodon/features/getting_started/components/trends.jsx (renamed from app/javascript/mastodon/features/getting_started/components/trends.js)0
-rw-r--r--app/javascript/mastodon/features/getting_started/index.jsx (renamed from app/javascript/mastodon/features/getting_started/index.js)0
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx (renamed from app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js)0
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/index.jsx (renamed from app/javascript/mastodon/features/hashtag_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/home_timeline/components/column_settings.jsx (renamed from app/javascript/mastodon/features/home_timeline/components/column_settings.js)0
-rw-r--r--app/javascript/mastodon/features/home_timeline/index.jsx (renamed from app/javascript/mastodon/features/home_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/interaction_modal/index.jsx (renamed from app/javascript/mastodon/features/interaction_modal/index.js)0
-rw-r--r--app/javascript/mastodon/features/keyboard_shortcuts/index.jsx (renamed from app/javascript/mastodon/features/keyboard_shortcuts/index.js)0
-rw-r--r--app/javascript/mastodon/features/list_adder/components/account.jsx (renamed from app/javascript/mastodon/features/list_adder/components/account.js)0
-rw-r--r--app/javascript/mastodon/features/list_adder/components/list.jsx (renamed from app/javascript/mastodon/features/list_adder/components/list.js)0
-rw-r--r--app/javascript/mastodon/features/list_adder/index.jsx (renamed from app/javascript/mastodon/features/list_adder/index.js)0
-rw-r--r--app/javascript/mastodon/features/list_editor/components/account.jsx (renamed from app/javascript/mastodon/features/list_editor/components/account.js)0
-rw-r--r--app/javascript/mastodon/features/list_editor/components/edit_list_form.jsx (renamed from app/javascript/mastodon/features/list_editor/components/edit_list_form.js)0
-rw-r--r--app/javascript/mastodon/features/list_editor/components/search.jsx (renamed from app/javascript/mastodon/features/list_editor/components/search.js)0
-rw-r--r--app/javascript/mastodon/features/list_editor/index.jsx (renamed from app/javascript/mastodon/features/list_editor/index.js)0
-rw-r--r--app/javascript/mastodon/features/list_timeline/index.jsx (renamed from app/javascript/mastodon/features/list_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/lists/components/new_list_form.jsx (renamed from app/javascript/mastodon/features/lists/components/new_list_form.js)0
-rw-r--r--app/javascript/mastodon/features/lists/index.jsx (renamed from app/javascript/mastodon/features/lists/index.js)0
-rw-r--r--app/javascript/mastodon/features/mutes/index.jsx (renamed from app/javascript/mastodon/features/mutes/index.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/clear_column_button.jsx (renamed from app/javascript/mastodon/features/notifications/components/clear_column_button.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/column_settings.jsx (renamed from app/javascript/mastodon/features/notifications/components/column_settings.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/filter_bar.jsx (renamed from app/javascript/mastodon/features/notifications/components/filter_bar.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/follow_request.jsx (renamed from app/javascript/mastodon/features/notifications/components/follow_request.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/grant_permission_button.jsx (renamed from app/javascript/mastodon/features/notifications/components/grant_permission_button.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/notification.jsx (renamed from app/javascript/mastodon/features/notifications/components/notification.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx (renamed from app/javascript/mastodon/features/notifications/components/notifications_permission_banner.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/report.jsx (renamed from app/javascript/mastodon/features/notifications/components/report.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/components/setting_toggle.jsx (renamed from app/javascript/mastodon/features/notifications/components/setting_toggle.js)0
-rw-r--r--app/javascript/mastodon/features/notifications/index.jsx (renamed from app/javascript/mastodon/features/notifications/index.js)0
-rw-r--r--app/javascript/mastodon/features/picture_in_picture/components/footer.jsx (renamed from app/javascript/mastodon/features/picture_in_picture/components/footer.js)0
-rw-r--r--app/javascript/mastodon/features/picture_in_picture/components/header.jsx (renamed from app/javascript/mastodon/features/picture_in_picture/components/header.js)0
-rw-r--r--app/javascript/mastodon/features/picture_in_picture/index.jsx (renamed from app/javascript/mastodon/features/picture_in_picture/index.js)0
-rw-r--r--app/javascript/mastodon/features/pinned_statuses/index.jsx (renamed from app/javascript/mastodon/features/pinned_statuses/index.js)0
-rw-r--r--app/javascript/mastodon/features/privacy_policy/index.jsx (renamed from app/javascript/mastodon/features/privacy_policy/index.js)0
-rw-r--r--app/javascript/mastodon/features/public_timeline/components/column_settings.jsx (renamed from app/javascript/mastodon/features/public_timeline/components/column_settings.js)0
-rw-r--r--app/javascript/mastodon/features/public_timeline/index.jsx (renamed from app/javascript/mastodon/features/public_timeline/index.js)0
-rw-r--r--app/javascript/mastodon/features/reblogs/index.jsx (renamed from app/javascript/mastodon/features/reblogs/index.js)0
-rw-r--r--app/javascript/mastodon/features/report/category.jsx (renamed from app/javascript/mastodon/features/report/category.js)0
-rw-r--r--app/javascript/mastodon/features/report/comment.jsx (renamed from app/javascript/mastodon/features/report/comment.js)0
-rw-r--r--app/javascript/mastodon/features/report/components/option.jsx (renamed from app/javascript/mastodon/features/report/components/option.js)0
-rw-r--r--app/javascript/mastodon/features/report/components/status_check_box.jsx (renamed from app/javascript/mastodon/features/report/components/status_check_box.js)0
-rw-r--r--app/javascript/mastodon/features/report/rules.jsx (renamed from app/javascript/mastodon/features/report/rules.js)0
-rw-r--r--app/javascript/mastodon/features/report/statuses.jsx (renamed from app/javascript/mastodon/features/report/statuses.js)0
-rw-r--r--app/javascript/mastodon/features/report/thanks.jsx (renamed from app/javascript/mastodon/features/report/thanks.js)0
-rw-r--r--app/javascript/mastodon/features/standalone/compose/index.jsx (renamed from app/javascript/mastodon/features/standalone/compose/index.js)0
-rw-r--r--app/javascript/mastodon/features/status/components/action_bar.jsx (renamed from app/javascript/mastodon/features/status/components/action_bar.js)0
-rw-r--r--app/javascript/mastodon/features/status/components/card.jsx (renamed from app/javascript/mastodon/features/status/components/card.js)3
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.jsx (renamed from app/javascript/mastodon/features/status/components/detailed_status.js)0
-rw-r--r--app/javascript/mastodon/features/status/index.jsx (renamed from app/javascript/mastodon/features/status/index.js)0
-rw-r--r--app/javascript/mastodon/features/subscribed_languages_modal/index.jsx (renamed from app/javascript/mastodon/features/subscribed_languages_modal/index.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx (renamed from app/javascript/mastodon/features/ui/components/__tests__/column-test.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/actions_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/actions_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/audio_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/audio_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/block_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/block_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/boost_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/boost_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/bundle.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/bundle_column_error.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle_column_error.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx (renamed from app/javascript/mastodon/features/ui/components/bundle_modal_error.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/column.jsx (renamed from app/javascript/mastodon/features/ui/components/column.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/column_header.jsx (renamed from app/javascript/mastodon/features/ui/components/column_header.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/column_link.jsx (renamed from app/javascript/mastodon/features/ui/components/column_link.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/column_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/column_loading.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/column_subheading.jsx (renamed from app/javascript/mastodon/features/ui/components/column_subheading.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/columns_area.jsx (renamed from app/javascript/mastodon/features/ui/components/columns_area.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/compare_history_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/compare_history_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/compose_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/compose_panel.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/confirmation_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/confirmation_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx (renamed from app/javascript/mastodon/features/ui/components/disabled_account_banner.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/drawer_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/drawer_loading.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/embed_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/embed_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/filter_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/filter_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/focal_point_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/focal_point_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx (renamed from app/javascript/mastodon/features/ui/components/follow_requests_column_link.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/header.jsx (renamed from app/javascript/mastodon/features/ui/components/header.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/image_loader.jsx (renamed from app/javascript/mastodon/features/ui/components/image_loader.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/image_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/image_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/link_footer.jsx (renamed from app/javascript/mastodon/features/ui/components/link_footer.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/list_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/list_panel.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/media_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/media_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/modal_loading.jsx (renamed from app/javascript/mastodon/features/ui/components/modal_loading.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/modal_root.jsx (renamed from app/javascript/mastodon/features/ui/components/modal_root.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/mute_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/mute_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/navigation_panel.jsx (renamed from app/javascript/mastodon/features/ui/components/navigation_panel.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/report_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/report_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/sign_in_banner.jsx (renamed from app/javascript/mastodon/features/ui/components/sign_in_banner.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/upload_area.jsx (renamed from app/javascript/mastodon/features/ui/components/upload_area.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/video_modal.jsx (renamed from app/javascript/mastodon/features/ui/components/video_modal.js)0
-rw-r--r--app/javascript/mastodon/features/ui/components/zoomable_image.jsx (renamed from app/javascript/mastodon/features/ui/components/zoomable_image.js)0
-rw-r--r--app/javascript/mastodon/features/ui/index.jsx (renamed from app/javascript/mastodon/features/ui/index.js)0
-rw-r--r--app/javascript/mastodon/features/ui/util/react_router_helpers.jsx (renamed from app/javascript/mastodon/features/ui/util/react_router_helpers.js)0
-rw-r--r--app/javascript/mastodon/features/ui/util/reduced_motion.jsx (renamed from app/javascript/mastodon/features/ui/util/reduced_motion.js)0
-rw-r--r--app/javascript/mastodon/features/video/index.jsx (renamed from app/javascript/mastodon/features/video/index.js)0
-rw-r--r--app/javascript/mastodon/locales/ast.json30
-rw-r--r--app/javascript/mastodon/locales/be.json4
-rw-r--r--app/javascript/mastodon/locales/bg.json8
-rw-r--r--app/javascript/mastodon/locales/ca.json68
-rw-r--r--app/javascript/mastodon/locales/cy.json20
-rw-r--r--app/javascript/mastodon/locales/de.json14
-rw-r--r--app/javascript/mastodon/locales/es-MX.json2
-rw-r--r--app/javascript/mastodon/locales/fr-QC.json4
-rw-r--r--app/javascript/mastodon/locales/ko.json30
-rw-r--r--app/javascript/mastodon/locales/lv.json2
-rw-r--r--app/javascript/mastodon/locales/my.json10
-rw-r--r--app/javascript/mastodon/locales/ru.json8
-rw-r--r--app/javascript/mastodon/locales/th.json2
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json16
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json84
-rw-r--r--app/javascript/mastodon/main.jsx (renamed from app/javascript/mastodon/main.js)0
-rw-r--r--app/javascript/mastodon/utils/icons.jsx (renamed from app/javascript/mastodon/utils/icons.js)0
-rw-r--r--app/javascript/packs/admin.jsx (renamed from app/javascript/packs/admin.js)0
-rw-r--r--app/javascript/packs/public.jsx (renamed from app/javascript/packs/public.js)0
-rw-r--r--app/javascript/packs/share.jsx (renamed from app/javascript/packs/share.js)0
-rw-r--r--app/javascript/styles/mastodon-light/diff.scss4
-rw-r--r--app/javascript/styles/mastodon/admin.scss2
-rw-r--r--app/javascript/styles/mastodon/components.scss13
-rw-r--r--app/lib/activitypub/activity.rb1
-rw-r--r--app/lib/activitypub/case_transform.rb2
-rw-r--r--app/lib/activitypub/linked_data_signature.rb2
-rw-r--r--app/lib/activitypub/tag_manager.rb2
-rw-r--r--app/lib/importer/base_importer.rb2
-rw-r--r--app/lib/link_details_extractor.rb8
-rw-r--r--app/lib/ostatus/tag_manager.rb32
-rw-r--r--app/lib/request.rb1
-rw-r--r--app/lib/request_pool.rb2
-rw-r--r--app/lib/settings/scoped_settings.rb2
-rw-r--r--app/lib/status_filter.rb1
-rw-r--r--app/lib/tag_manager.rb1
-rw-r--r--app/lib/validation_error_formatter.rb2
-rw-r--r--app/lib/webfinger.rb1
-rw-r--r--app/mailers/application_mailer.rb6
-rw-r--r--app/models/account.rb8
-rw-r--r--app/models/account/field.rb4
-rw-r--r--app/models/account_conversation.rb2
-rw-r--r--app/models/account_domain_block.rb1
-rw-r--r--app/models/account_moderation_note.rb1
-rw-r--r--app/models/account_note.rb1
-rw-r--r--app/models/account_pin.rb1
-rw-r--r--app/models/account_stat.rb1
-rw-r--r--app/models/account_summary.rb1
-rw-r--r--app/models/account_warning.rb13
-rw-r--r--app/models/admin/import.rb1
-rw-r--r--app/models/announcement.rb2
-rw-r--r--app/models/backup.rb1
-rw-r--r--app/models/block.rb1
-rw-r--r--app/models/bookmark.rb1
-rw-r--r--app/models/canonical_email_block.rb1
-rw-r--r--app/models/concerns/account_interactions.rb4
-rw-r--r--app/models/conversation.rb1
-rw-r--r--app/models/conversation_mute.rb1
-rw-r--r--app/models/custom_emoji.rb1
-rw-r--r--app/models/custom_filter.rb9
-rw-r--r--app/models/custom_filter_keyword.rb1
-rw-r--r--app/models/custom_filter_status.rb1
-rw-r--r--app/models/device.rb1
-rw-r--r--app/models/domain_block.rb3
-rw-r--r--app/models/email_domain_block.rb1
-rw-r--r--app/models/encrypted_message.rb1
-rw-r--r--app/models/favourite.rb2
-rw-r--r--app/models/featured_tag.rb1
-rw-r--r--app/models/follow.rb1
-rw-r--r--app/models/follow_recommendation.rb3
-rw-r--r--app/models/follow_recommendation_suppression.rb1
-rw-r--r--app/models/follow_request.rb1
-rw-r--r--app/models/form/admin_settings.rb1
-rw-r--r--app/models/identity.rb1
-rw-r--r--app/models/import.rb3
-rw-r--r--app/models/instance.rb1
-rw-r--r--app/models/invite.rb1
-rw-r--r--app/models/ip_block.rb1
-rw-r--r--app/models/list.rb3
-rw-r--r--app/models/list_account.rb1
-rw-r--r--app/models/login_activity.rb1
-rw-r--r--app/models/media_attachment.rb7
-rw-r--r--app/models/mention.rb1
-rw-r--r--app/models/mute.rb1
-rw-r--r--app/models/notification.rb11
-rw-r--r--app/models/one_time_key.rb1
-rw-r--r--app/models/poll.rb8
-rw-r--r--app/models/poll_vote.rb1
-rw-r--r--app/models/preview_card.rb5
-rw-r--r--app/models/preview_card_provider.rb1
-rw-r--r--app/models/relay.rb3
-rw-r--r--app/models/report.rb3
-rw-r--r--app/models/report_note.rb1
-rw-r--r--app/models/session_activation.rb2
-rw-r--r--app/models/setting.rb4
-rw-r--r--app/models/site_upload.rb1
-rw-r--r--app/models/status.rb7
-rw-r--r--app/models/status_edit.rb2
-rw-r--r--app/models/status_pin.rb1
-rw-r--r--app/models/status_stat.rb1
-rw-r--r--app/models/tag.rb1
-rw-r--r--app/models/unavailable_domain.rb1
-rw-r--r--app/models/user.rb4
-rw-r--r--app/models/user_ip.rb3
-rw-r--r--app/models/user_role.rb2
-rw-r--r--app/models/web/push_subscription.rb1
-rw-r--r--app/models/web/setting.rb1
-rw-r--r--app/models/webauthn_credential.rb1
-rw-r--r--app/presenters/account_relationships_presenter.rb18
-rw-r--r--app/serializers/initial_state_serializer.rb1
-rw-r--r--app/serializers/rest/preview_card_serializer.rb2
-rw-r--r--app/serializers/rest/privacy_policy_serializer.rb2
-rw-r--r--app/services/activitypub/fetch_remote_actor_service.rb3
-rw-r--r--app/services/activitypub/fetch_remote_status_service.rb1
-rw-r--r--app/services/activitypub/fetch_replies_service.rb1
-rw-r--r--app/services/activitypub/process_account_service.rb2
-rw-r--r--app/services/backup_service.rb10
-rw-r--r--app/services/favourite_service.rb1
-rw-r--r--app/services/fetch_link_card_service.rb2
-rw-r--r--app/services/import_service.rb2
-rw-r--r--app/services/keys/claim_service.rb6
-rw-r--r--app/services/keys/query_service.rb6
-rw-r--r--app/services/notify_service.rb1
-rw-r--r--app/services/post_status_service.rb3
-rw-r--r--app/services/vote_service.rb2
-rw-r--r--app/validators/follow_limit_validator.rb1
-rw-r--r--app/validators/html_validator.rb20
-rw-r--r--app/validators/unreserved_username_validator.rb2
-rw-r--r--app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb26
-rw-r--r--app/workers/web/push_notification_worker.rb12
379 files changed, 396 insertions, 312 deletions
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index be84720aa..7dff66efa 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -30,7 +30,7 @@ class Api::V1::AccountsController < Api::BaseController
     self.response_body = Oj.dump(response.body)
     self.status        = response.status
   rescue ActiveRecord::RecordInvalid => e
-    render json: ValidationErrorFormatter.new(e, 'account.username': :username, 'invite_request.text': :reason).as_json, status: :unprocessable_entity
+    render json: ValidationErrorFormatter.new(e, 'account.username': :username, 'invite_request.text': :reason).as_json, status: 422
   end
 
   def follow
diff --git a/app/controllers/api/v1/emails/confirmations_controller.rb b/app/controllers/api/v1/emails/confirmations_controller.rb
index 3faaea2fb..32fb8e39f 100644
--- a/app/controllers/api/v1/emails/confirmations_controller.rb
+++ b/app/controllers/api/v1/emails/confirmations_controller.rb
@@ -15,10 +15,10 @@ class Api::V1::Emails::ConfirmationsController < Api::BaseController
   private
 
   def require_user_owned_by_application!
-    render json: { error: 'This method is only available to the application the user originally signed-up with' }, status: :forbidden unless current_user && current_user.created_by_application_id == doorkeeper_token.application_id
+    render json: { error: 'This method is only available to the application the user originally signed-up with' }, status: 403 unless current_user && current_user.created_by_application_id == doorkeeper_token.application_id
   end
 
   def require_user_not_confirmed!
-    render json: { error: 'This method is only available while the e-mail is awaiting confirmation' }, status: :forbidden unless !current_user.confirmed? || current_user.unconfirmed_email.present?
+    render json: { error: 'This method is only available while the e-mail is awaiting confirmation' }, status: 403 unless !current_user.confirmed? || current_user.unconfirmed_email.present?
   end
 end
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index 871221d4a..7a64d1300 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -28,7 +28,7 @@ class Api::V1::NotificationsController < Api::BaseController
   end
 
   def dismiss
-    current_account.notifications.find_by!(id: params[:id]).destroy!
+    current_account.notifications.find(params[:id]).destroy!
     render_empty
   end
 
diff --git a/app/controllers/api/v1/tags_controller.rb b/app/controllers/api/v1/tags_controller.rb
index 272362c31..a08fd2187 100644
--- a/app/controllers/api/v1/tags_controller.rb
+++ b/app/controllers/api/v1/tags_controller.rb
@@ -25,6 +25,7 @@ class Api::V1::TagsController < Api::BaseController
 
   def set_or_create_tag
     return not_found unless Tag::HASHTAG_NAME_RE.match?(params[:id])
+
     @tag = Tag.find_normalized(params[:id]) || Tag.new(name: Tag.normalize(params[:id]), display_name: params[:id])
   end
 end
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 3183088e7..b1abb9f1d 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -53,9 +53,9 @@ class Auth::SessionsController < Devise::SessionsController
 
       session[:webauthn_challenge] = options_for_get.challenge
 
-      render json: options_for_get, status: :ok
+      render json: options_for_get, status: 200
     else
-      render json: { error: t('webauthn_credentials.not_enabled') }, status: :unauthorized
+      render json: { error: t('webauthn_credentials.not_enabled') }, status: 401
     end
   end
 
diff --git a/app/controllers/concerns/session_tracking_concern.rb b/app/controllers/concerns/session_tracking_concern.rb
index eaaa4ac59..3f56c0d02 100644
--- a/app/controllers/concerns/session_tracking_concern.rb
+++ b/app/controllers/concerns/session_tracking_concern.rb
@@ -13,6 +13,7 @@ module SessionTrackingConcern
 
   def set_session_activity
     return unless session_needs_update?
+
     current_session.touch
   end
 
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 9c04ab4ca..b0a087d53 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -165,6 +165,7 @@ module SignatureVerification
     end
 
     raise SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a SHA-256 digest. Given digest: #{sha256[1]}" if digest_size != 32
+
     raise SignatureVerificationError, "Invalid Digest value. Computed SHA-256 digest: #{body_digest}; given: #{sha256[1]}"
   end
 
diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb
index 3233e3e8d..b30cd354d 100644
--- a/app/controllers/concerns/two_factor_authentication_concern.rb
+++ b/app/controllers/concerns/two_factor_authentication_concern.rb
@@ -57,10 +57,10 @@ module TwoFactorAuthenticationConcern
 
     if valid_webauthn_credential?(user, webauthn_credential)
       on_authentication_success(user, :webauthn)
-      render json: { redirect_path: after_sign_in_path_for(user) }, status: :ok
+      render json: { redirect_path: after_sign_in_path_for(user) }, status: 200
     else
       on_authentication_failure(user, :webauthn, :invalid_credential)
-      render json: { error: t('webauthn_credentials.invalid_credential') }, status: :unprocessable_entity
+      render json: { error: t('webauthn_credentials.invalid_credential') }, status: 422
     end
   end
 
diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb
index f9160d8c4..37c5dcb99 100644
--- a/app/controllers/media_controller.rb
+++ b/app/controllers/media_controller.rb
@@ -33,7 +33,7 @@ class MediaController < ApplicationController
 
     scope = MediaAttachment.local.attached
     # If id is 19 characters long, it's a shortcode, otherwise it's an identifier
-    @media_attachment = id.size == 19 ? scope.find_by!(shortcode: id) : scope.find_by!(id: id)
+    @media_attachment = id.size == 19 ? scope.find_by!(shortcode: id) : scope.find(id)
   end
 
   def verify_permitted_status!
diff --git a/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb b/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb
index 7e2d43dcd..952c14e0b 100644
--- a/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb
+++ b/app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb
@@ -27,7 +27,7 @@ module Settings
 
         session[:webauthn_challenge] = options_for_create.challenge
 
-        render json: options_for_create, status: :ok
+        render json: options_for_create, status: 200
       end
 
       def create
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e0bf36cbc..0605457e8 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -105,6 +105,7 @@ module ApplicationHelper
 
   def can?(action, record)
     return false if record.nil?
+
     policy(record).public_send("#{action}?")
   end
 
diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb
index bb35ce08c..584394758 100644
--- a/app/helpers/languages_helper.rb
+++ b/app/helpers/languages_helper.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # rubocop:disable Metrics/ModuleLength, Style/WordArray
 
 module LanguagesHelper
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.jsx.snap
index 1c3727848..1c3727848 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/autosuggest_emoji-test.jsx.snap
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap
index 7fbdedeb2..7fbdedeb2 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.jsx.snap
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.jsx.snap
index f8385357a..f8385357a 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.jsx.snap
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.jsx.snap
index bfc091d45..bfc091d45 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/button-test.jsx.snap
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap
index 9c37580d7..9c37580d7 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap
diff --git a/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js b/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.jsx
index 05616e444..05616e444 100644
--- a/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.js
+++ b/app/javascript/mastodon/components/__tests__/autosuggest_emoji-test.jsx
diff --git a/app/javascript/mastodon/components/__tests__/avatar-test.js b/app/javascript/mastodon/components/__tests__/avatar-test.jsx
index dd3f7b7d2..dd3f7b7d2 100644
--- a/app/javascript/mastodon/components/__tests__/avatar-test.js
+++ b/app/javascript/mastodon/components/__tests__/avatar-test.jsx
diff --git a/app/javascript/mastodon/components/__tests__/avatar_overlay-test.js b/app/javascript/mastodon/components/__tests__/avatar_overlay-test.jsx
index 44addea83..44addea83 100644
--- a/app/javascript/mastodon/components/__tests__/avatar_overlay-test.js
+++ b/app/javascript/mastodon/components/__tests__/avatar_overlay-test.jsx
diff --git a/app/javascript/mastodon/components/__tests__/button-test.js b/app/javascript/mastodon/components/__tests__/button-test.jsx
index f5a649f70..f5a649f70 100644
--- a/app/javascript/mastodon/components/__tests__/button-test.js
+++ b/app/javascript/mastodon/components/__tests__/button-test.jsx
diff --git a/app/javascript/mastodon/components/__tests__/display_name-test.js b/app/javascript/mastodon/components/__tests__/display_name-test.jsx
index 0d040c4cd..0d040c4cd 100644
--- a/app/javascript/mastodon/components/__tests__/display_name-test.js
+++ b/app/javascript/mastodon/components/__tests__/display_name-test.jsx
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.jsx
index 7706c3f88..7706c3f88 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.jsx
diff --git a/app/javascript/mastodon/components/admin/Counter.js b/app/javascript/mastodon/components/admin/Counter.jsx
index 5a5b2b869..5a5b2b869 100644
--- a/app/javascript/mastodon/components/admin/Counter.js
+++ b/app/javascript/mastodon/components/admin/Counter.jsx
diff --git a/app/javascript/mastodon/components/admin/Dimension.js b/app/javascript/mastodon/components/admin/Dimension.jsx
index 977c8208d..977c8208d 100644
--- a/app/javascript/mastodon/components/admin/Dimension.js
+++ b/app/javascript/mastodon/components/admin/Dimension.jsx
diff --git a/app/javascript/mastodon/components/admin/ReportReasonSelector.js b/app/javascript/mastodon/components/admin/ReportReasonSelector.jsx
index 1f91d2517..1f91d2517 100644
--- a/app/javascript/mastodon/components/admin/ReportReasonSelector.js
+++ b/app/javascript/mastodon/components/admin/ReportReasonSelector.jsx
diff --git a/app/javascript/mastodon/components/admin/Retention.js b/app/javascript/mastodon/components/admin/Retention.jsx
index f312a45eb..f312a45eb 100644
--- a/app/javascript/mastodon/components/admin/Retention.js
+++ b/app/javascript/mastodon/components/admin/Retention.jsx
diff --git a/app/javascript/mastodon/components/admin/Trends.js b/app/javascript/mastodon/components/admin/Trends.jsx
index d01b8437e..d01b8437e 100644
--- a/app/javascript/mastodon/components/admin/Trends.js
+++ b/app/javascript/mastodon/components/admin/Trends.jsx
diff --git a/app/javascript/mastodon/components/animated_number.js b/app/javascript/mastodon/components/animated_number.jsx
index ce688f04f..ce688f04f 100644
--- a/app/javascript/mastodon/components/animated_number.js
+++ b/app/javascript/mastodon/components/animated_number.jsx
diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.jsx
index 0e23889de..0e23889de 100644
--- a/app/javascript/mastodon/components/attachment_list.js
+++ b/app/javascript/mastodon/components/attachment_list.jsx
diff --git a/app/javascript/mastodon/components/autosuggest_emoji.js b/app/javascript/mastodon/components/autosuggest_emoji.jsx
index 4937e4d98..4937e4d98 100644
--- a/app/javascript/mastodon/components/autosuggest_emoji.js
+++ b/app/javascript/mastodon/components/autosuggest_emoji.jsx
diff --git a/app/javascript/mastodon/components/autosuggest_hashtag.js b/app/javascript/mastodon/components/autosuggest_hashtag.jsx
index 9e9d888f8..9e9d888f8 100644
--- a/app/javascript/mastodon/components/autosuggest_hashtag.js
+++ b/app/javascript/mastodon/components/autosuggest_hashtag.jsx
diff --git a/app/javascript/mastodon/components/autosuggest_input.js b/app/javascript/mastodon/components/autosuggest_input.jsx
index f9616c581..f9616c581 100644
--- a/app/javascript/mastodon/components/autosuggest_input.js
+++ b/app/javascript/mastodon/components/autosuggest_input.jsx
diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.jsx
index c04491298..c04491298 100644
--- a/app/javascript/mastodon/components/autosuggest_textarea.js
+++ b/app/javascript/mastodon/components/autosuggest_textarea.jsx
diff --git a/app/javascript/mastodon/components/avatar.js b/app/javascript/mastodon/components/avatar.jsx
index 013454ccf..013454ccf 100644
--- a/app/javascript/mastodon/components/avatar.js
+++ b/app/javascript/mastodon/components/avatar.jsx
diff --git a/app/javascript/mastodon/components/avatar_composite.js b/app/javascript/mastodon/components/avatar_composite.jsx
index 220bf5b4f..220bf5b4f 100644
--- a/app/javascript/mastodon/components/avatar_composite.js
+++ b/app/javascript/mastodon/components/avatar_composite.jsx
diff --git a/app/javascript/mastodon/components/avatar_overlay.js b/app/javascript/mastodon/components/avatar_overlay.jsx
index 034e8ba56..034e8ba56 100644
--- a/app/javascript/mastodon/components/avatar_overlay.js
+++ b/app/javascript/mastodon/components/avatar_overlay.jsx
diff --git a/app/javascript/mastodon/components/blurhash.js b/app/javascript/mastodon/components/blurhash.jsx
index 2af5cfc56..2af5cfc56 100644
--- a/app/javascript/mastodon/components/blurhash.js
+++ b/app/javascript/mastodon/components/blurhash.jsx
diff --git a/app/javascript/mastodon/components/button.js b/app/javascript/mastodon/components/button.jsx
index a05a75e89..a05a75e89 100644
--- a/app/javascript/mastodon/components/button.js
+++ b/app/javascript/mastodon/components/button.jsx
diff --git a/app/javascript/mastodon/components/check.js b/app/javascript/mastodon/components/check.jsx
index ee2ef1595..ee2ef1595 100644
--- a/app/javascript/mastodon/components/check.js
+++ b/app/javascript/mastodon/components/check.jsx
diff --git a/app/javascript/mastodon/components/column.js b/app/javascript/mastodon/components/column.jsx
index 5780a1397..5780a1397 100644
--- a/app/javascript/mastodon/components/column.js
+++ b/app/javascript/mastodon/components/column.jsx
diff --git a/app/javascript/mastodon/components/column_back_button.js b/app/javascript/mastodon/components/column_back_button.jsx
index 5bbf11652..5bbf11652 100644
--- a/app/javascript/mastodon/components/column_back_button.js
+++ b/app/javascript/mastodon/components/column_back_button.jsx
diff --git a/app/javascript/mastodon/components/column_back_button_slim.js b/app/javascript/mastodon/components/column_back_button_slim.jsx
index cc8bfb151..cc8bfb151 100644
--- a/app/javascript/mastodon/components/column_back_button_slim.js
+++ b/app/javascript/mastodon/components/column_back_button_slim.jsx
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.jsx
index 38f6ad60f..38f6ad60f 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.jsx
diff --git a/app/javascript/mastodon/components/common_counter.js b/app/javascript/mastodon/components/common_counter.jsx
index dd9b62de9..dd9b62de9 100644
--- a/app/javascript/mastodon/components/common_counter.js
+++ b/app/javascript/mastodon/components/common_counter.jsx
diff --git a/app/javascript/mastodon/components/dismissable_banner.js b/app/javascript/mastodon/components/dismissable_banner.jsx
index 47ca7e4bc..47ca7e4bc 100644
--- a/app/javascript/mastodon/components/dismissable_banner.js
+++ b/app/javascript/mastodon/components/dismissable_banner.jsx
diff --git a/app/javascript/mastodon/components/display_name.js b/app/javascript/mastodon/components/display_name.jsx
index 1dd9fb1d6..1dd9fb1d6 100644
--- a/app/javascript/mastodon/components/display_name.js
+++ b/app/javascript/mastodon/components/display_name.jsx
diff --git a/app/javascript/mastodon/components/domain.js b/app/javascript/mastodon/components/domain.jsx
index e09fa4591..e09fa4591 100644
--- a/app/javascript/mastodon/components/domain.js
+++ b/app/javascript/mastodon/components/domain.jsx
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.jsx
index c04c513fb..c04c513fb 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.jsx
diff --git a/app/javascript/mastodon/components/edited_timestamp/index.js b/app/javascript/mastodon/components/edited_timestamp/index.jsx
index b30d88572..b30d88572 100644
--- a/app/javascript/mastodon/components/edited_timestamp/index.js
+++ b/app/javascript/mastodon/components/edited_timestamp/index.jsx
diff --git a/app/javascript/mastodon/components/error_boundary.js b/app/javascript/mastodon/components/error_boundary.jsx
index b711f1e46..b711f1e46 100644
--- a/app/javascript/mastodon/components/error_boundary.js
+++ b/app/javascript/mastodon/components/error_boundary.jsx
diff --git a/app/javascript/mastodon/components/gifv.js b/app/javascript/mastodon/components/gifv.jsx
index 1f0f99b46..1f0f99b46 100644
--- a/app/javascript/mastodon/components/gifv.js
+++ b/app/javascript/mastodon/components/gifv.jsx
diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.jsx
index e516fc086..e516fc086 100644
--- a/app/javascript/mastodon/components/hashtag.js
+++ b/app/javascript/mastodon/components/hashtag.jsx
diff --git a/app/javascript/mastodon/components/icon.js b/app/javascript/mastodon/components/icon.jsx
index d3d7c591d..d3d7c591d 100644
--- a/app/javascript/mastodon/components/icon.js
+++ b/app/javascript/mastodon/components/icon.jsx
diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.jsx
index 003692373..003692373 100644
--- a/app/javascript/mastodon/components/icon_button.js
+++ b/app/javascript/mastodon/components/icon_button.jsx
diff --git a/app/javascript/mastodon/components/icon_with_badge.js b/app/javascript/mastodon/components/icon_with_badge.jsx
index 4214eccfd..4214eccfd 100644
--- a/app/javascript/mastodon/components/icon_with_badge.js
+++ b/app/javascript/mastodon/components/icon_with_badge.jsx
diff --git a/app/javascript/mastodon/components/image.js b/app/javascript/mastodon/components/image.jsx
index 6e81ddf08..6e81ddf08 100644
--- a/app/javascript/mastodon/components/image.js
+++ b/app/javascript/mastodon/components/image.jsx
diff --git a/app/javascript/mastodon/components/inline_account.js b/app/javascript/mastodon/components/inline_account.jsx
index a1b495590..a1b495590 100644
--- a/app/javascript/mastodon/components/inline_account.js
+++ b/app/javascript/mastodon/components/inline_account.jsx
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.jsx
index c2feb003a..c2feb003a 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.jsx
diff --git a/app/javascript/mastodon/components/load_gap.js b/app/javascript/mastodon/components/load_gap.jsx
index c50b245fc..c50b245fc 100644
--- a/app/javascript/mastodon/components/load_gap.js
+++ b/app/javascript/mastodon/components/load_gap.jsx
diff --git a/app/javascript/mastodon/components/load_more.js b/app/javascript/mastodon/components/load_more.jsx
index 150525214..150525214 100644
--- a/app/javascript/mastodon/components/load_more.js
+++ b/app/javascript/mastodon/components/load_more.jsx
diff --git a/app/javascript/mastodon/components/load_pending.js b/app/javascript/mastodon/components/load_pending.jsx
index a75259146..a75259146 100644
--- a/app/javascript/mastodon/components/load_pending.js
+++ b/app/javascript/mastodon/components/load_pending.jsx
diff --git a/app/javascript/mastodon/components/loading_indicator.js b/app/javascript/mastodon/components/loading_indicator.jsx
index 33c59d94c..33c59d94c 100644
--- a/app/javascript/mastodon/components/loading_indicator.js
+++ b/app/javascript/mastodon/components/loading_indicator.jsx
diff --git a/app/javascript/mastodon/components/logo.js b/app/javascript/mastodon/components/logo.jsx
index ee5c22496..ee5c22496 100644
--- a/app/javascript/mastodon/components/logo.js
+++ b/app/javascript/mastodon/components/logo.jsx
diff --git a/app/javascript/mastodon/components/media_attachments.js b/app/javascript/mastodon/components/media_attachments.jsx
index 565a30330..565a30330 100644
--- a/app/javascript/mastodon/components/media_attachments.js
+++ b/app/javascript/mastodon/components/media_attachments.jsx
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.jsx
index 659a83375..659a83375 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.jsx
diff --git a/app/javascript/mastodon/components/missing_indicator.js b/app/javascript/mastodon/components/missing_indicator.jsx
index 05e0d653d..05e0d653d 100644
--- a/app/javascript/mastodon/components/missing_indicator.js
+++ b/app/javascript/mastodon/components/missing_indicator.jsx
diff --git a/app/javascript/mastodon/components/modal_root.js b/app/javascript/mastodon/components/modal_root.jsx
index c0525c221..c0525c221 100644
--- a/app/javascript/mastodon/components/modal_root.js
+++ b/app/javascript/mastodon/components/modal_root.jsx
diff --git a/app/javascript/mastodon/components/navigation_portal.js b/app/javascript/mastodon/components/navigation_portal.jsx
index 45407be43..45407be43 100644
--- a/app/javascript/mastodon/components/navigation_portal.js
+++ b/app/javascript/mastodon/components/navigation_portal.jsx
diff --git a/app/javascript/mastodon/components/not_signed_in_indicator.js b/app/javascript/mastodon/components/not_signed_in_indicator.jsx
index b440c6be2..b440c6be2 100644
--- a/app/javascript/mastodon/components/not_signed_in_indicator.js
+++ b/app/javascript/mastodon/components/not_signed_in_indicator.jsx
diff --git a/app/javascript/mastodon/components/picture_in_picture_placeholder.js b/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx
index 0effddef9..0effddef9 100644
--- a/app/javascript/mastodon/components/picture_in_picture_placeholder.js
+++ b/app/javascript/mastodon/components/picture_in_picture_placeholder.jsx
diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.jsx
index 95a900c49..95a900c49 100644
--- a/app/javascript/mastodon/components/poll.js
+++ b/app/javascript/mastodon/components/poll.jsx
diff --git a/app/javascript/mastodon/components/radio_button.js b/app/javascript/mastodon/components/radio_button.jsx
index 0496fa286..0496fa286 100644
--- a/app/javascript/mastodon/components/radio_button.js
+++ b/app/javascript/mastodon/components/radio_button.jsx
diff --git a/app/javascript/mastodon/components/regeneration_indicator.js b/app/javascript/mastodon/components/regeneration_indicator.jsx
index 52696a4a7..52696a4a7 100644
--- a/app/javascript/mastodon/components/regeneration_indicator.js
+++ b/app/javascript/mastodon/components/regeneration_indicator.jsx
diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.jsx
index 512480339..512480339 100644
--- a/app/javascript/mastodon/components/relative_timestamp.js
+++ b/app/javascript/mastodon/components/relative_timestamp.jsx
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.jsx
index 4a6ffb149..4a6ffb149 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.jsx
diff --git a/app/javascript/mastodon/components/server_banner.js b/app/javascript/mastodon/components/server_banner.jsx
index 617fdecdf..617fdecdf 100644
--- a/app/javascript/mastodon/components/server_banner.js
+++ b/app/javascript/mastodon/components/server_banner.jsx
diff --git a/app/javascript/mastodon/components/short_number.js b/app/javascript/mastodon/components/short_number.jsx
index 535c17727..535c17727 100644
--- a/app/javascript/mastodon/components/short_number.js
+++ b/app/javascript/mastodon/components/short_number.jsx
diff --git a/app/javascript/mastodon/components/skeleton.js b/app/javascript/mastodon/components/skeleton.jsx
index 6a17ffb26..6a17ffb26 100644
--- a/app/javascript/mastodon/components/skeleton.js
+++ b/app/javascript/mastodon/components/skeleton.jsx
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.jsx
index f02910f5a..2e2d96634 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.jsx
@@ -160,6 +160,7 @@ class Status extends ImmutablePureComponent {
 
     if (e) {
       e.preventDefault();
+      e.stopPropagation();
     }
 
     this._openProfile(proper);
@@ -510,8 +511,8 @@ class Status extends ImmutablePureComponent {
           {prepend}
 
           <div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted })} data-id={status.get('id')}>
-            <div className='status__info'>
-              <a onClick={this.handleClick} href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
+            <div onClick={this.handleClick} className='status__info'>
+              <a href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
                 <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span>
                 <RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
               </a>
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.jsx
index eeb376561..eeb376561 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.jsx
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.jsx
index ece54621f..ece54621f 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.jsx
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.jsx
index 3d513bbf8..3d513bbf8 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.jsx
diff --git a/app/javascript/mastodon/components/timeline_hint.js b/app/javascript/mastodon/components/timeline_hint.jsx
index ac9a79dcc..ac9a79dcc 100644
--- a/app/javascript/mastodon/components/timeline_hint.js
+++ b/app/javascript/mastodon/components/timeline_hint.jsx
diff --git a/app/javascript/mastodon/containers/account_container.js b/app/javascript/mastodon/containers/account_container.jsx
index 5a5136dd1..5a5136dd1 100644
--- a/app/javascript/mastodon/containers/account_container.js
+++ b/app/javascript/mastodon/containers/account_container.jsx
diff --git a/app/javascript/mastodon/containers/admin_component.js b/app/javascript/mastodon/containers/admin_component.jsx
index 816b44bd1..816b44bd1 100644
--- a/app/javascript/mastodon/containers/admin_component.js
+++ b/app/javascript/mastodon/containers/admin_component.jsx
diff --git a/app/javascript/mastodon/containers/compose_container.js b/app/javascript/mastodon/containers/compose_container.jsx
index 7bc7bbaa4..7bc7bbaa4 100644
--- a/app/javascript/mastodon/containers/compose_container.js
+++ b/app/javascript/mastodon/containers/compose_container.jsx
diff --git a/app/javascript/mastodon/containers/domain_container.js b/app/javascript/mastodon/containers/domain_container.jsx
index 8a8ba1df1..8a8ba1df1 100644
--- a/app/javascript/mastodon/containers/domain_container.js
+++ b/app/javascript/mastodon/containers/domain_container.jsx
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.jsx
index 002b71e93..002b71e93 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.jsx
diff --git a/app/javascript/mastodon/containers/media_container.js b/app/javascript/mastodon/containers/media_container.jsx
index 25dc17444..25dc17444 100644
--- a/app/javascript/mastodon/containers/media_container.js
+++ b/app/javascript/mastodon/containers/media_container.jsx
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.jsx
index 294105f25..294105f25 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.jsx
diff --git a/app/javascript/mastodon/features/about/index.js b/app/javascript/mastodon/features/about/index.jsx
index dc1942c63..dc1942c63 100644
--- a/app/javascript/mastodon/features/about/index.js
+++ b/app/javascript/mastodon/features/about/index.jsx
diff --git a/app/javascript/mastodon/features/account/components/account_note.js b/app/javascript/mastodon/features/account/components/account_note.jsx
index fdacc7583..fdacc7583 100644
--- a/app/javascript/mastodon/features/account/components/account_note.js
+++ b/app/javascript/mastodon/features/account/components/account_note.jsx
diff --git a/app/javascript/mastodon/features/account/components/featured_tags.js b/app/javascript/mastodon/features/account/components/featured_tags.jsx
index 24a3f2171..24a3f2171 100644
--- a/app/javascript/mastodon/features/account/components/featured_tags.js
+++ b/app/javascript/mastodon/features/account/components/featured_tags.jsx
diff --git a/app/javascript/mastodon/features/account/components/follow_request_note.js b/app/javascript/mastodon/features/account/components/follow_request_note.jsx
index 300ae4266..300ae4266 100644
--- a/app/javascript/mastodon/features/account/components/follow_request_note.js
+++ b/app/javascript/mastodon/features/account/components/follow_request_note.jsx
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.jsx
index 539d72574..539d72574 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.jsx
diff --git a/app/javascript/mastodon/features/account/navigation.js b/app/javascript/mastodon/features/account/navigation.jsx
index eb9ff9a95..eb9ff9a95 100644
--- a/app/javascript/mastodon/features/account/navigation.js
+++ b/app/javascript/mastodon/features/account/navigation.jsx
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.jsx
index d6d60ebda..d6d60ebda 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.jsx
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.jsx
index 3942b57cb..3942b57cb 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.jsx
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.jsx
index bffa5554b..bffa5554b 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.jsx
diff --git a/app/javascript/mastodon/features/account_timeline/components/limited_account_hint.js b/app/javascript/mastodon/features/account_timeline/components/limited_account_hint.jsx
index 9ee347bb5..9ee347bb5 100644
--- a/app/javascript/mastodon/features/account_timeline/components/limited_account_hint.js
+++ b/app/javascript/mastodon/features/account_timeline/components/limited_account_hint.jsx
diff --git a/app/javascript/mastodon/features/account_timeline/components/moved_note.js b/app/javascript/mastodon/features/account_timeline/components/moved_note.jsx
index daff47a9d..daff47a9d 100644
--- a/app/javascript/mastodon/features/account_timeline/components/moved_note.js
+++ b/app/javascript/mastodon/features/account_timeline/components/moved_note.jsx
diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx
index f53cd2480..f53cd2480 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.jsx
index 337977fde..337977fde 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.jsx
index bf954c06d..bf954c06d 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.jsx
diff --git a/app/javascript/mastodon/features/blocks/index.js b/app/javascript/mastodon/features/blocks/index.jsx
index e00f2b60e..e00f2b60e 100644
--- a/app/javascript/mastodon/features/blocks/index.js
+++ b/app/javascript/mastodon/features/blocks/index.jsx
diff --git a/app/javascript/mastodon/features/bookmarked_statuses/index.js b/app/javascript/mastodon/features/bookmarked_statuses/index.jsx
index 8ef7855c1..8ef7855c1 100644
--- a/app/javascript/mastodon/features/bookmarked_statuses/index.js
+++ b/app/javascript/mastodon/features/bookmarked_statuses/index.jsx
diff --git a/app/javascript/mastodon/features/closed_registrations_modal/index.js b/app/javascript/mastodon/features/closed_registrations_modal/index.jsx
index e6540e825..e6540e825 100644
--- a/app/javascript/mastodon/features/closed_registrations_modal/index.js
+++ b/app/javascript/mastodon/features/closed_registrations_modal/index.jsx
diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx
index 0cb6db883..0cb6db883 100644
--- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx
diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.jsx
index 4dbd55cf2..4dbd55cf2 100644
--- a/app/javascript/mastodon/features/community_timeline/index.js
+++ b/app/javascript/mastodon/features/community_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.jsx
index ee584cb1b..ee584cb1b 100644
--- a/app/javascript/mastodon/features/compose/components/action_bar.js
+++ b/app/javascript/mastodon/features/compose/components/action_bar.jsx
diff --git a/app/javascript/mastodon/features/compose/components/autosuggest_account.js b/app/javascript/mastodon/features/compose/components/autosuggest_account.jsx
index 1451be0e6..1451be0e6 100644
--- a/app/javascript/mastodon/features/compose/components/autosuggest_account.js
+++ b/app/javascript/mastodon/features/compose/components/autosuggest_account.jsx
diff --git a/app/javascript/mastodon/features/compose/components/character_counter.js b/app/javascript/mastodon/features/compose/components/character_counter.jsx
index 0ecfc9141..0ecfc9141 100644
--- a/app/javascript/mastodon/features/compose/components/character_counter.js
+++ b/app/javascript/mastodon/features/compose/components/character_counter.jsx
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.jsx
index 8df144dcc..8df144dcc 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx
index 79378454d..79378454d 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx
diff --git a/app/javascript/mastodon/features/compose/components/language_dropdown.js b/app/javascript/mastodon/features/compose/components/language_dropdown.jsx
index d96d39f23..82547e079 100644
--- a/app/javascript/mastodon/features/compose/components/language_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/language_dropdown.jsx
@@ -210,7 +210,7 @@ class LanguageDropdownMenu extends React.PureComponent {
 
     return (
       <div key={lang[0]} role='option' tabIndex='0' data-index={lang[0]} className={classNames('language-dropdown__dropdown__results__item', { active: lang[0] === value })} aria-selected={lang[0] === value} onClick={this.handleClick} onKeyDown={this.handleKeyDown}>
-        <span className='language-dropdown__dropdown__results__item__native-name'>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
+        <span className='language-dropdown__dropdown__results__item__native-name' lang={lang[0]}>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
       </div>
     );
   };
diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.jsx
index be979af50..be979af50 100644
--- a/app/javascript/mastodon/features/compose/components/navigation_bar.js
+++ b/app/javascript/mastodon/features/compose/components/navigation_bar.jsx
diff --git a/app/javascript/mastodon/features/compose/components/poll_button.js b/app/javascript/mastodon/features/compose/components/poll_button.jsx
index ff7a104aa..ff7a104aa 100644
--- a/app/javascript/mastodon/features/compose/components/poll_button.js
+++ b/app/javascript/mastodon/features/compose/components/poll_button.jsx
diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.jsx
index 379ae6821..379ae6821 100644
--- a/app/javascript/mastodon/features/compose/components/poll_form.js
+++ b/app/javascript/mastodon/features/compose/components/poll_form.jsx
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx
index ffd1094cd..ffd1094cd 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx
diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx
index 98b142ab8..98b142ab8 100644
--- a/app/javascript/mastodon/features/compose/components/reply_indicator.js
+++ b/app/javascript/mastodon/features/compose/components/reply_indicator.jsx
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.jsx
index 0539c6b80..0539c6b80 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.jsx
diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.jsx
index 44ab43638..44ab43638 100644
--- a/app/javascript/mastodon/features/compose/components/search_results.js
+++ b/app/javascript/mastodon/features/compose/components/search_results.jsx
diff --git a/app/javascript/mastodon/features/compose/components/text_icon_button.js b/app/javascript/mastodon/features/compose/components/text_icon_button.jsx
index 73da32ad5..73da32ad5 100644
--- a/app/javascript/mastodon/features/compose/components/text_icon_button.js
+++ b/app/javascript/mastodon/features/compose/components/text_icon_button.jsx
diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.jsx
index f114680b9..f114680b9 100644
--- a/app/javascript/mastodon/features/compose/components/upload.js
+++ b/app/javascript/mastodon/features/compose/components/upload.jsx
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.jsx
index 964340d82..964340d82 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.jsx
diff --git a/app/javascript/mastodon/features/compose/components/upload_form.js b/app/javascript/mastodon/features/compose/components/upload_form.jsx
index 9ff2aa0fa..9ff2aa0fa 100644
--- a/app/javascript/mastodon/features/compose/components/upload_form.js
+++ b/app/javascript/mastodon/features/compose/components/upload_form.jsx
diff --git a/app/javascript/mastodon/features/compose/components/upload_progress.js b/app/javascript/mastodon/features/compose/components/upload_progress.jsx
index cabf520fd..cabf520fd 100644
--- a/app/javascript/mastodon/features/compose/components/upload_progress.js
+++ b/app/javascript/mastodon/features/compose/components/upload_progress.jsx
diff --git a/app/javascript/mastodon/features/compose/components/warning.js b/app/javascript/mastodon/features/compose/components/warning.jsx
index 803b7f86a..803b7f86a 100644
--- a/app/javascript/mastodon/features/compose/components/warning.js
+++ b/app/javascript/mastodon/features/compose/components/warning.jsx
diff --git a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.jsx
index 1bcce5731..03f831d28 100644
--- a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
+++ b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.jsx
@@ -54,8 +54,6 @@ class SensitiveButton extends React.PureComponent {
             disabled={disabled}
           />
 
-          <span className={classNames('checkbox', { active })} />
-
           <FormattedMessage
             id='compose_form.sensitive.hide'
             defaultMessage='{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}'
diff --git a/app/javascript/mastodon/features/compose/containers/warning_container.js b/app/javascript/mastodon/features/compose/containers/warning_container.jsx
index 3c6ed483d..3c6ed483d 100644
--- a/app/javascript/mastodon/features/compose/containers/warning_container.js
+++ b/app/javascript/mastodon/features/compose/containers/warning_container.jsx
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.jsx
index 4b30d09ae..4b30d09ae 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.jsx
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx
index fbdff1bdd..fbdff1bdd 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/conversation.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.jsx
index 27e9a593f..27e9a593f 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/conversations_list.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversations_list.jsx
diff --git a/app/javascript/mastodon/features/direct_timeline/index.js b/app/javascript/mastodon/features/direct_timeline/index.jsx
index a45965bb2..a45965bb2 100644
--- a/app/javascript/mastodon/features/direct_timeline/index.js
+++ b/app/javascript/mastodon/features/direct_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/directory/components/account_card.js b/app/javascript/mastodon/features/directory/components/account_card.jsx
index 15c8ad303..15c8ad303 100644
--- a/app/javascript/mastodon/features/directory/components/account_card.js
+++ b/app/javascript/mastodon/features/directory/components/account_card.jsx
diff --git a/app/javascript/mastodon/features/directory/index.js b/app/javascript/mastodon/features/directory/index.jsx
index bb5e021cc..bb5e021cc 100644
--- a/app/javascript/mastodon/features/directory/index.js
+++ b/app/javascript/mastodon/features/directory/index.jsx
diff --git a/app/javascript/mastodon/features/domain_blocks/index.js b/app/javascript/mastodon/features/domain_blocks/index.jsx
index 43b275c2d..43b275c2d 100644
--- a/app/javascript/mastodon/features/domain_blocks/index.js
+++ b/app/javascript/mastodon/features/domain_blocks/index.jsx
diff --git a/app/javascript/mastodon/features/explore/components/story.js b/app/javascript/mastodon/features/explore/components/story.jsx
index 563128029..563128029 100644
--- a/app/javascript/mastodon/features/explore/components/story.js
+++ b/app/javascript/mastodon/features/explore/components/story.jsx
diff --git a/app/javascript/mastodon/features/explore/index.js b/app/javascript/mastodon/features/explore/index.jsx
index d91755ff6..d91755ff6 100644
--- a/app/javascript/mastodon/features/explore/index.js
+++ b/app/javascript/mastodon/features/explore/index.jsx
diff --git a/app/javascript/mastodon/features/explore/links.js b/app/javascript/mastodon/features/explore/links.jsx
index b47fc8fcf..b47fc8fcf 100644
--- a/app/javascript/mastodon/features/explore/links.js
+++ b/app/javascript/mastodon/features/explore/links.jsx
diff --git a/app/javascript/mastodon/features/explore/results.js b/app/javascript/mastodon/features/explore/results.jsx
index b2f6c72b7..b2f6c72b7 100644
--- a/app/javascript/mastodon/features/explore/results.js
+++ b/app/javascript/mastodon/features/explore/results.jsx
diff --git a/app/javascript/mastodon/features/explore/statuses.js b/app/javascript/mastodon/features/explore/statuses.jsx
index b027487d5..b027487d5 100644
--- a/app/javascript/mastodon/features/explore/statuses.js
+++ b/app/javascript/mastodon/features/explore/statuses.jsx
diff --git a/app/javascript/mastodon/features/explore/suggestions.js b/app/javascript/mastodon/features/explore/suggestions.jsx
index e6ad09974..e6ad09974 100644
--- a/app/javascript/mastodon/features/explore/suggestions.js
+++ b/app/javascript/mastodon/features/explore/suggestions.jsx
diff --git a/app/javascript/mastodon/features/explore/tags.js b/app/javascript/mastodon/features/explore/tags.jsx
index 258dc392f..258dc392f 100644
--- a/app/javascript/mastodon/features/explore/tags.js
+++ b/app/javascript/mastodon/features/explore/tags.jsx
diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.jsx
index 89093f682..89093f682 100644
--- a/app/javascript/mastodon/features/favourited_statuses/index.js
+++ b/app/javascript/mastodon/features/favourited_statuses/index.jsx
diff --git a/app/javascript/mastodon/features/favourites/index.js b/app/javascript/mastodon/features/favourites/index.jsx
index 7179e6470..7179e6470 100644
--- a/app/javascript/mastodon/features/favourites/index.js
+++ b/app/javascript/mastodon/features/favourites/index.jsx
diff --git a/app/javascript/mastodon/features/filters/added_to_filter.js b/app/javascript/mastodon/features/filters/added_to_filter.jsx
index 3785eb3c5..3785eb3c5 100644
--- a/app/javascript/mastodon/features/filters/added_to_filter.js
+++ b/app/javascript/mastodon/features/filters/added_to_filter.jsx
diff --git a/app/javascript/mastodon/features/filters/select_filter.js b/app/javascript/mastodon/features/filters/select_filter.jsx
index 8a21905d7..8a21905d7 100644
--- a/app/javascript/mastodon/features/filters/select_filter.js
+++ b/app/javascript/mastodon/features/filters/select_filter.jsx
diff --git a/app/javascript/mastodon/features/follow_recommendations/components/account.js b/app/javascript/mastodon/features/follow_recommendations/components/account.jsx
index ddd0c8baa..ddd0c8baa 100644
--- a/app/javascript/mastodon/features/follow_recommendations/components/account.js
+++ b/app/javascript/mastodon/features/follow_recommendations/components/account.jsx
diff --git a/app/javascript/mastodon/features/follow_recommendations/index.js b/app/javascript/mastodon/features/follow_recommendations/index.jsx
index 436cc582b..436cc582b 100644
--- a/app/javascript/mastodon/features/follow_recommendations/index.js
+++ b/app/javascript/mastodon/features/follow_recommendations/index.jsx
diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx
index d41f331e5..d41f331e5 100644
--- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
+++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx
diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.jsx
index 526ae4cde..526ae4cde 100644
--- a/app/javascript/mastodon/features/follow_requests/index.js
+++ b/app/javascript/mastodon/features/follow_requests/index.jsx
diff --git a/app/javascript/mastodon/features/followed_tags/index.js b/app/javascript/mastodon/features/followed_tags/index.jsx
index c2d0e4731..c2d0e4731 100644
--- a/app/javascript/mastodon/features/followed_tags/index.js
+++ b/app/javascript/mastodon/features/followed_tags/index.jsx
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.jsx
index 277eb702f..277eb702f 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.jsx
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.jsx
index e23d9b35c..e23d9b35c 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.jsx
diff --git a/app/javascript/mastodon/features/generic_not_found/index.js b/app/javascript/mastodon/features/generic_not_found/index.jsx
index 41cd61a5f..41cd61a5f 100644
--- a/app/javascript/mastodon/features/generic_not_found/index.js
+++ b/app/javascript/mastodon/features/generic_not_found/index.jsx
diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.jsx
index 0cae0bd1f..0cae0bd1f 100644
--- a/app/javascript/mastodon/features/getting_started/components/announcements.js
+++ b/app/javascript/mastodon/features/getting_started/components/announcements.jsx
diff --git a/app/javascript/mastodon/features/getting_started/components/trends.js b/app/javascript/mastodon/features/getting_started/components/trends.jsx
index 8dcdb4f61..8dcdb4f61 100644
--- a/app/javascript/mastodon/features/getting_started/components/trends.js
+++ b/app/javascript/mastodon/features/getting_started/components/trends.jsx
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.jsx
index fc91070d1..fc91070d1 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.jsx
diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx
index ac7863ed3..ac7863ed3 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.jsx
index e5262d70d..e5262d70d 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.jsx
index 455e21881..455e21881 100644
--- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.jsx
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.jsx
index 001de15d1..001de15d1 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/interaction_modal/index.js b/app/javascript/mastodon/features/interaction_modal/index.jsx
index c1d346fed..c1d346fed 100644
--- a/app/javascript/mastodon/features/interaction_modal/index.js
+++ b/app/javascript/mastodon/features/interaction_modal/index.jsx
diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.js b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx
index 9a870478d..9a870478d 100644
--- a/app/javascript/mastodon/features/keyboard_shortcuts/index.js
+++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx
diff --git a/app/javascript/mastodon/features/list_adder/components/account.js b/app/javascript/mastodon/features/list_adder/components/account.jsx
index 1369aac07..1369aac07 100644
--- a/app/javascript/mastodon/features/list_adder/components/account.js
+++ b/app/javascript/mastodon/features/list_adder/components/account.jsx
diff --git a/app/javascript/mastodon/features/list_adder/components/list.js b/app/javascript/mastodon/features/list_adder/components/list.jsx
index 60c8958a7..60c8958a7 100644
--- a/app/javascript/mastodon/features/list_adder/components/list.js
+++ b/app/javascript/mastodon/features/list_adder/components/list.jsx
diff --git a/app/javascript/mastodon/features/list_adder/index.js b/app/javascript/mastodon/features/list_adder/index.jsx
index cb8a15e8c..cb8a15e8c 100644
--- a/app/javascript/mastodon/features/list_adder/index.js
+++ b/app/javascript/mastodon/features/list_adder/index.jsx
diff --git a/app/javascript/mastodon/features/list_editor/components/account.js b/app/javascript/mastodon/features/list_editor/components/account.jsx
index 48085af43..48085af43 100644
--- a/app/javascript/mastodon/features/list_editor/components/account.js
+++ b/app/javascript/mastodon/features/list_editor/components/account.jsx
diff --git a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js b/app/javascript/mastodon/features/list_editor/components/edit_list_form.jsx
index 4d7e49ec0..4d7e49ec0 100644
--- a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js
+++ b/app/javascript/mastodon/features/list_editor/components/edit_list_form.jsx
diff --git a/app/javascript/mastodon/features/list_editor/components/search.js b/app/javascript/mastodon/features/list_editor/components/search.jsx
index 3ee26c8eb..3ee26c8eb 100644
--- a/app/javascript/mastodon/features/list_editor/components/search.js
+++ b/app/javascript/mastodon/features/list_editor/components/search.jsx
diff --git a/app/javascript/mastodon/features/list_editor/index.js b/app/javascript/mastodon/features/list_editor/index.jsx
index 48466604a..48466604a 100644
--- a/app/javascript/mastodon/features/list_editor/index.js
+++ b/app/javascript/mastodon/features/list_editor/index.jsx
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.jsx
index 25dbe311a..25dbe311a 100644
--- a/app/javascript/mastodon/features/list_timeline/index.js
+++ b/app/javascript/mastodon/features/list_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/lists/components/new_list_form.js b/app/javascript/mastodon/features/lists/components/new_list_form.jsx
index 4e00e5200..4e00e5200 100644
--- a/app/javascript/mastodon/features/lists/components/new_list_form.js
+++ b/app/javascript/mastodon/features/lists/components/new_list_form.jsx
diff --git a/app/javascript/mastodon/features/lists/index.js b/app/javascript/mastodon/features/lists/index.jsx
index 3a0b1373a..3a0b1373a 100644
--- a/app/javascript/mastodon/features/lists/index.js
+++ b/app/javascript/mastodon/features/lists/index.jsx
diff --git a/app/javascript/mastodon/features/mutes/index.js b/app/javascript/mastodon/features/mutes/index.jsx
index 65df6149f..65df6149f 100644
--- a/app/javascript/mastodon/features/mutes/index.js
+++ b/app/javascript/mastodon/features/mutes/index.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/clear_column_button.js b/app/javascript/mastodon/features/notifications/components/clear_column_button.jsx
index b82fd092f..b82fd092f 100644
--- a/app/javascript/mastodon/features/notifications/components/clear_column_button.js
+++ b/app/javascript/mastodon/features/notifications/components/clear_column_button.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.jsx
index 9251847ba..9251847ba 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.js b/app/javascript/mastodon/features/notifications/components/filter_bar.jsx
index 368eb0b7e..368eb0b7e 100644
--- a/app/javascript/mastodon/features/notifications/components/filter_bar.js
+++ b/app/javascript/mastodon/features/notifications/components/filter_bar.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/follow_request.js b/app/javascript/mastodon/features/notifications/components/follow_request.jsx
index 08de875e3..08de875e3 100644
--- a/app/javascript/mastodon/features/notifications/components/follow_request.js
+++ b/app/javascript/mastodon/features/notifications/components/follow_request.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/grant_permission_button.js b/app/javascript/mastodon/features/notifications/components/grant_permission_button.jsx
index 798e4c787..798e4c787 100644
--- a/app/javascript/mastodon/features/notifications/components/grant_permission_button.js
+++ b/app/javascript/mastodon/features/notifications/components/grant_permission_button.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.jsx
index 9e2517f08..9e2517f08 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.js b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx
index 3a7556c1d..3a7556c1d 100644
--- a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.js
+++ b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/report.js b/app/javascript/mastodon/features/notifications/components/report.jsx
index 3ce3eb9d3..3ce3eb9d3 100644
--- a/app/javascript/mastodon/features/notifications/components/report.js
+++ b/app/javascript/mastodon/features/notifications/components/report.jsx
diff --git a/app/javascript/mastodon/features/notifications/components/setting_toggle.js b/app/javascript/mastodon/features/notifications/components/setting_toggle.jsx
index c979e4383..c979e4383 100644
--- a/app/javascript/mastodon/features/notifications/components/setting_toggle.js
+++ b/app/javascript/mastodon/features/notifications/components/setting_toggle.jsx
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.jsx
index fee016a02..fee016a02 100644
--- a/app/javascript/mastodon/features/notifications/index.js
+++ b/app/javascript/mastodon/features/notifications/index.jsx
diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.js b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx
index 0ee6d06c7..0ee6d06c7 100644
--- a/app/javascript/mastodon/features/picture_in_picture/components/footer.js
+++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx
diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.js b/app/javascript/mastodon/features/picture_in_picture/components/header.jsx
index e05d8c62e..e05d8c62e 100644
--- a/app/javascript/mastodon/features/picture_in_picture/components/header.js
+++ b/app/javascript/mastodon/features/picture_in_picture/components/header.jsx
diff --git a/app/javascript/mastodon/features/picture_in_picture/index.js b/app/javascript/mastodon/features/picture_in_picture/index.jsx
index 01a7d43f2..01a7d43f2 100644
--- a/app/javascript/mastodon/features/picture_in_picture/index.js
+++ b/app/javascript/mastodon/features/picture_in_picture/index.jsx
diff --git a/app/javascript/mastodon/features/pinned_statuses/index.js b/app/javascript/mastodon/features/pinned_statuses/index.jsx
index 504fda415..504fda415 100644
--- a/app/javascript/mastodon/features/pinned_statuses/index.js
+++ b/app/javascript/mastodon/features/pinned_statuses/index.jsx
diff --git a/app/javascript/mastodon/features/privacy_policy/index.js b/app/javascript/mastodon/features/privacy_policy/index.jsx
index 3df487e8f..3df487e8f 100644
--- a/app/javascript/mastodon/features/privacy_policy/index.js
+++ b/app/javascript/mastodon/features/privacy_policy/index.jsx
diff --git a/app/javascript/mastodon/features/public_timeline/components/column_settings.js b/app/javascript/mastodon/features/public_timeline/components/column_settings.jsx
index 756b6fe06..756b6fe06 100644
--- a/app/javascript/mastodon/features/public_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/public_timeline/components/column_settings.jsx
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.jsx
index aaef45c86..aaef45c86 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.jsx
diff --git a/app/javascript/mastodon/features/reblogs/index.js b/app/javascript/mastodon/features/reblogs/index.jsx
index 31e5dc1d4..31e5dc1d4 100644
--- a/app/javascript/mastodon/features/reblogs/index.js
+++ b/app/javascript/mastodon/features/reblogs/index.jsx
diff --git a/app/javascript/mastodon/features/report/category.js b/app/javascript/mastodon/features/report/category.jsx
index c6c0a506f..c6c0a506f 100644
--- a/app/javascript/mastodon/features/report/category.js
+++ b/app/javascript/mastodon/features/report/category.jsx
diff --git a/app/javascript/mastodon/features/report/comment.js b/app/javascript/mastodon/features/report/comment.jsx
index cde156415..cde156415 100644
--- a/app/javascript/mastodon/features/report/comment.js
+++ b/app/javascript/mastodon/features/report/comment.jsx
diff --git a/app/javascript/mastodon/features/report/components/option.js b/app/javascript/mastodon/features/report/components/option.jsx
index 42c04b018..42c04b018 100644
--- a/app/javascript/mastodon/features/report/components/option.js
+++ b/app/javascript/mastodon/features/report/components/option.jsx
diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.jsx
index 5366da90b..5366da90b 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.jsx
diff --git a/app/javascript/mastodon/features/report/rules.js b/app/javascript/mastodon/features/report/rules.jsx
index 920da68d6..920da68d6 100644
--- a/app/javascript/mastodon/features/report/rules.js
+++ b/app/javascript/mastodon/features/report/rules.jsx
diff --git a/app/javascript/mastodon/features/report/statuses.js b/app/javascript/mastodon/features/report/statuses.jsx
index d5d86034f..d5d86034f 100644
--- a/app/javascript/mastodon/features/report/statuses.js
+++ b/app/javascript/mastodon/features/report/statuses.jsx
diff --git a/app/javascript/mastodon/features/report/thanks.js b/app/javascript/mastodon/features/report/thanks.jsx
index d169b1e32..d169b1e32 100644
--- a/app/javascript/mastodon/features/report/thanks.js
+++ b/app/javascript/mastodon/features/report/thanks.jsx
diff --git a/app/javascript/mastodon/features/standalone/compose/index.js b/app/javascript/mastodon/features/standalone/compose/index.jsx
index fbadef6f4..fbadef6f4 100644
--- a/app/javascript/mastodon/features/standalone/compose/index.js
+++ b/app/javascript/mastodon/features/standalone/compose/index.jsx
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.jsx
index 0d4767331..0d4767331 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.jsx
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.jsx
index 34fac1010..b588c83e4 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.jsx
@@ -196,11 +196,12 @@ export default class Card extends React.PureComponent {
     const interactive = card.get('type') !== 'link';
     const className   = classnames('status-card', { horizontal, compact, interactive });
     const title       = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
+    const language    = card.get('language') || '';
     const ratio       = card.get('width') / card.get('height');
     const height      = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
 
     const description = (
-      <div className='status-card__content'>
+      <div className='status-card__content' lang={language}>
         {title}
         {!(horizontal || compact) && <p className='status-card__description'>{trim(card.get('description') || '', maxDescription)}</p>}
         <span className='status-card__host'>{provider}</span>
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.jsx
index 064231ffe..064231ffe 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.jsx
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.jsx
index 2c6728fc0..2c6728fc0 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.jsx
diff --git a/app/javascript/mastodon/features/subscribed_languages_modal/index.js b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx
index f1360613e..f1360613e 100644
--- a/app/javascript/mastodon/features/subscribed_languages_modal/index.js
+++ b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx
diff --git a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js b/app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx
index a56859be0..a56859be0 100644
--- a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js
+++ b/app/javascript/mastodon/features/ui/components/__tests__/column-test.jsx
diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.js b/app/javascript/mastodon/features/ui/components/actions_modal.jsx
index fd59c1e20..fd59c1e20 100644
--- a/app/javascript/mastodon/features/ui/components/actions_modal.js
+++ b/app/javascript/mastodon/features/ui/components/actions_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/audio_modal.js b/app/javascript/mastodon/features/ui/components/audio_modal.jsx
index c46fefce8..c46fefce8 100644
--- a/app/javascript/mastodon/features/ui/components/audio_modal.js
+++ b/app/javascript/mastodon/features/ui/components/audio_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/block_modal.js b/app/javascript/mastodon/features/ui/components/block_modal.jsx
index 6c9d2043c..6c9d2043c 100644
--- a/app/javascript/mastodon/features/ui/components/block_modal.js
+++ b/app/javascript/mastodon/features/ui/components/block_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.jsx
index d6a6cea31..d6a6cea31 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.jsx
index 1b10a218b..1b10a218b 100644
--- a/app/javascript/mastodon/features/ui/components/bundle.js
+++ b/app/javascript/mastodon/features/ui/components/bundle.jsx
diff --git a/app/javascript/mastodon/features/ui/components/bundle_column_error.js b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx
index 9955173eb..9955173eb 100644
--- a/app/javascript/mastodon/features/ui/components/bundle_column_error.js
+++ b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx
diff --git a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js b/app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx
index d79d0ca4a..d79d0ca4a 100644
--- a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js
+++ b/app/javascript/mastodon/features/ui/components/bundle_modal_error.jsx
diff --git a/app/javascript/mastodon/features/ui/components/column.js b/app/javascript/mastodon/features/ui/components/column.jsx
index 7bc2f7e00..7bc2f7e00 100644
--- a/app/javascript/mastodon/features/ui/components/column.js
+++ b/app/javascript/mastodon/features/ui/components/column.jsx
diff --git a/app/javascript/mastodon/features/ui/components/column_header.js b/app/javascript/mastodon/features/ui/components/column_header.jsx
index 4ceef5957..4ceef5957 100644
--- a/app/javascript/mastodon/features/ui/components/column_header.js
+++ b/app/javascript/mastodon/features/ui/components/column_header.jsx
diff --git a/app/javascript/mastodon/features/ui/components/column_link.js b/app/javascript/mastodon/features/ui/components/column_link.jsx
index 8eebbf526..8eebbf526 100644
--- a/app/javascript/mastodon/features/ui/components/column_link.js
+++ b/app/javascript/mastodon/features/ui/components/column_link.jsx
diff --git a/app/javascript/mastodon/features/ui/components/column_loading.js b/app/javascript/mastodon/features/ui/components/column_loading.jsx
index e5ed22584..e5ed22584 100644
--- a/app/javascript/mastodon/features/ui/components/column_loading.js
+++ b/app/javascript/mastodon/features/ui/components/column_loading.jsx
diff --git a/app/javascript/mastodon/features/ui/components/column_subheading.js b/app/javascript/mastodon/features/ui/components/column_subheading.jsx
index 8160c4aa3..8160c4aa3 100644
--- a/app/javascript/mastodon/features/ui/components/column_subheading.js
+++ b/app/javascript/mastodon/features/ui/components/column_subheading.jsx
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.jsx
index 1dd6e34e8..1dd6e34e8 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.jsx
diff --git a/app/javascript/mastodon/features/ui/components/compare_history_modal.js b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx
index ecccc8f7d..ecccc8f7d 100644
--- a/app/javascript/mastodon/features/ui/components/compare_history_modal.js
+++ b/app/javascript/mastodon/features/ui/components/compare_history_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.js b/app/javascript/mastodon/features/ui/components/compose_panel.jsx
index 6cb352322..6cb352322 100644
--- a/app/javascript/mastodon/features/ui/components/compose_panel.js
+++ b/app/javascript/mastodon/features/ui/components/compose_panel.jsx
diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx
index b023b00b2..b023b00b2 100644
--- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js
+++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx
index 35520478b..35520478b 100644
--- a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js
+++ b/app/javascript/mastodon/features/ui/components/disabled_account_banner.jsx
diff --git a/app/javascript/mastodon/features/ui/components/drawer_loading.js b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx
index 08b0d2347..08b0d2347 100644
--- a/app/javascript/mastodon/features/ui/components/drawer_loading.js
+++ b/app/javascript/mastodon/features/ui/components/drawer_loading.jsx
diff --git a/app/javascript/mastodon/features/ui/components/embed_modal.js b/app/javascript/mastodon/features/ui/components/embed_modal.jsx
index a054dd3cf..a054dd3cf 100644
--- a/app/javascript/mastodon/features/ui/components/embed_modal.js
+++ b/app/javascript/mastodon/features/ui/components/embed_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/filter_modal.js b/app/javascript/mastodon/features/ui/components/filter_modal.jsx
index 376db961d..376db961d 100644
--- a/app/javascript/mastodon/features/ui/components/filter_modal.js
+++ b/app/javascript/mastodon/features/ui/components/filter_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx
index 6e8d017ee..6e8d017ee 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.js b/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx
index 8d4057782..8d4057782 100644
--- a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.js
+++ b/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx
diff --git a/app/javascript/mastodon/features/ui/components/header.js b/app/javascript/mastodon/features/ui/components/header.jsx
index 1384bebda..1384bebda 100644
--- a/app/javascript/mastodon/features/ui/components/header.js
+++ b/app/javascript/mastodon/features/ui/components/header.jsx
diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.jsx
index 92aeef5c4..92aeef5c4 100644
--- a/app/javascript/mastodon/features/ui/components/image_loader.js
+++ b/app/javascript/mastodon/features/ui/components/image_loader.jsx
diff --git a/app/javascript/mastodon/features/ui/components/image_modal.js b/app/javascript/mastodon/features/ui/components/image_modal.jsx
index 7522c3da5..7522c3da5 100644
--- a/app/javascript/mastodon/features/ui/components/image_modal.js
+++ b/app/javascript/mastodon/features/ui/components/image_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/link_footer.js b/app/javascript/mastodon/features/ui/components/link_footer.jsx
index be2111207..be2111207 100644
--- a/app/javascript/mastodon/features/ui/components/link_footer.js
+++ b/app/javascript/mastodon/features/ui/components/link_footer.jsx
diff --git a/app/javascript/mastodon/features/ui/components/list_panel.js b/app/javascript/mastodon/features/ui/components/list_panel.jsx
index 2f92a9254..2f92a9254 100644
--- a/app/javascript/mastodon/features/ui/components/list_panel.js
+++ b/app/javascript/mastodon/features/ui/components/list_panel.jsx
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.jsx
index 1cda8de04..1cda8de04 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/modal_loading.js b/app/javascript/mastodon/features/ui/components/modal_loading.jsx
index f403ca4c9..f403ca4c9 100644
--- a/app/javascript/mastodon/features/ui/components/modal_loading.js
+++ b/app/javascript/mastodon/features/ui/components/modal_loading.jsx
diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.jsx
index 5a1734977..5a1734977 100644
--- a/app/javascript/mastodon/features/ui/components/modal_root.js
+++ b/app/javascript/mastodon/features/ui/components/modal_root.jsx
diff --git a/app/javascript/mastodon/features/ui/components/mute_modal.js b/app/javascript/mastodon/features/ui/components/mute_modal.jsx
index b3e0ef56b..b3e0ef56b 100644
--- a/app/javascript/mastodon/features/ui/components/mute_modal.js
+++ b/app/javascript/mastodon/features/ui/components/mute_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx
index 9a9309be0..9a9309be0 100644
--- a/app/javascript/mastodon/features/ui/components/navigation_panel.js
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx
diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.jsx
index 22c31eb52..22c31eb52 100644
--- a/app/javascript/mastodon/features/ui/components/report_modal.js
+++ b/app/javascript/mastodon/features/ui/components/report_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/sign_in_banner.js b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx
index 86fcc11b5..86fcc11b5 100644
--- a/app/javascript/mastodon/features/ui/components/sign_in_banner.js
+++ b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx
diff --git a/app/javascript/mastodon/features/ui/components/upload_area.js b/app/javascript/mastodon/features/ui/components/upload_area.jsx
index 035fe7a26..035fe7a26 100644
--- a/app/javascript/mastodon/features/ui/components/upload_area.js
+++ b/app/javascript/mastodon/features/ui/components/upload_area.jsx
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.jsx
index abaccbe98..abaccbe98 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.jsx
diff --git a/app/javascript/mastodon/features/ui/components/zoomable_image.js b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx
index 3b2bb0286..3b2bb0286 100644
--- a/app/javascript/mastodon/features/ui/components/zoomable_image.js
+++ b/app/javascript/mastodon/features/ui/components/zoomable_image.jsx
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.jsx
index 4f0ea0450..4f0ea0450 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.jsx
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.js b/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx
index 21b352878..21b352878 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.js
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.jsx
diff --git a/app/javascript/mastodon/features/ui/util/reduced_motion.js b/app/javascript/mastodon/features/ui/util/reduced_motion.jsx
index 1123b80ed..1123b80ed 100644
--- a/app/javascript/mastodon/features/ui/util/reduced_motion.js
+++ b/app/javascript/mastodon/features/ui/util/reduced_motion.jsx
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.jsx
index 8d63394aa..8d63394aa 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.jsx
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index bedfd9138..54bab60d0 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -218,21 +218,21 @@
   "empty_column.domain_blocks": "Entá nun hai nengún dominiu bloquiáu.",
   "empty_column.explore_statuses": "Agora nun hai nada en tendencia. ¡Volvi equí dempués!",
   "empty_column.favourited_statuses": "Entá nun marquesti nengún artículu como favoritu. Cuando marques dalgún, apaez equí.",
-  "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
+  "empty_column.favourites": "Naide marcó esti artículu como favoritu. Cuando dalgún perfil lo faiga, apaez equí.",
   "empty_column.follow_recommendations": "Paez que nun se puen xenerar suxerencies pa ti. Pues tentar d'usar la busca p'atopar perfiles que pues conocer o esplorar les etiquetes en tendencia.",
   "empty_column.follow_requests": "Entá nun tienes nenguna solicitú de siguimientu. Cuando recibas dalguna, apaez equí.",
   "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
   "empty_column.hashtag": "Entá nun hai nada con esta etiqueta.",
   "empty_column.home": "¡La to llinia de tiempu ta balera! Sigui a cuentes pa enllenala. {suggestions}",
   "empty_column.home.suggestions": "Ver dalgunes suxerencies",
-  "empty_column.list": "Entá nun hai nada nesta llista. Cuando los miembros d'esta llista espublicen artículos nuevos, apaecen equí.",
+  "empty_column.list": "Entá nun hai nada nesta llista. Cuando perfiles d'esta llista espublicen artículos nuevos, apaecen equí.",
   "empty_column.lists": "Entá nun tienes nenguna llista. Cuando crees dalguna, apaez equí.",
   "empty_column.mutes": "Entá nun tienes nengún perfil colos avisos desactivaos.",
   "empty_column.notifications": "Entá nun tienes nengún avisu. Cuando otros perfiles interactúen contigo, apaez equí.",
   "empty_column.public": "¡Equí nun hai nada! Escribi daqué públicamente o sigui a perfiles d'otros sirvidores pa enllenar esta seición",
   "error.unexpected_crash.explanation": "Pola mor d'un fallu nel códigu o un problema de compatibilidá del restolador, esta páxina nun se pudo amosar correutamente.",
   "error.unexpected_crash.explanation_addons": "Esta páxina nun se pudo amosar correutamente. Ye probable que dalgún complementu del restolador o dalguna ferramienta de traducción automática produxere esti error.",
-  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
+  "error.unexpected_crash.next_steps": "Prueba a anovar la páxina. Si nun sirve, ye posible que tovía seyas a usar Mastodon pente otru restolador o una aplicación nativa.",
   "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
@@ -351,14 +351,14 @@
   "lists.account.remove": "Remove from list",
   "lists.delete": "Desaniciar la llista",
   "lists.edit": "Editar la llista",
-  "lists.edit.submit": "Change title",
+  "lists.edit.submit": "Camudar el títulu",
   "lists.new.create": "Amestar la llista",
   "lists.new.title_placeholder": "Títulu",
   "lists.replies_policy.followed": "Cualesquier perfil siguíu",
-  "lists.replies_policy.list": "Miembros de la llista",
+  "lists.replies_policy.list": "Perfiles de la llista",
   "lists.replies_policy.none": "Naide",
-  "lists.replies_policy.title": "Show replies to:",
-  "lists.search": "Search among people you follow",
+  "lists.replies_policy.title": "Amosar les rempuestes a:",
+  "lists.search": "Buscar ente los perfiles que sigues",
   "lists.subheading": "Les tos llistes",
   "load_pending": "{count, plural, one {# elementu nuevu} other {# elementos nuevos}}",
   "loading_indicator.label": "Cargando…",
@@ -463,15 +463,15 @@
   "privacy.unlisted.short": "Unlisted",
   "privacy_policy.last_updated": "Data del últimu anovamientu: {date}",
   "privacy_policy.title": "Política de privacidá",
-  "refresh": "Refresh",
+  "refresh": "Anovar",
   "regeneration_indicator.label": "Cargando…",
   "regeneration_indicator.sublabel": "Your home feed is being prepared!",
   "relative_time.days": "{number} d",
-  "relative_time.full.days": "Hai {number, plural, one {# día} other {# díes}}",
-  "relative_time.full.hours": "Hai {number, plural, one {# hora} other {# hores}}",
+  "relative_time.full.days": "hai {number, plural, one {# día} other {# díes}}",
+  "relative_time.full.hours": "hai {number, plural, one {# hora} other {# hores}}",
   "relative_time.full.just_now": "puramente agora",
-  "relative_time.full.minutes": "Hai {number, plural, one {# minutu} other {# minutos}}",
-  "relative_time.full.seconds": "Hai {number, plural, one {# segundu} other {# segundos}}",
+  "relative_time.full.minutes": "hai {number, plural, one {# minutu} other {# minutos}}",
+  "relative_time.full.seconds": "hai {number, plural, one {# segundu} other {# segundos}}",
   "relative_time.hours": "{number} h",
   "relative_time.just_now": "agora",
   "relative_time.minutes": "{number} m",
@@ -557,7 +557,7 @@
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Unviar un mensaxe direutu a @{name}",
   "status.edit": "Edit",
-  "status.edited": "Edited {date}",
+  "status.edited": "Editóse'l {date}",
   "status.edited_x_times": "Editóse {count, plural, one {{count} vegada} other {{count} vegaes}}",
   "status.embed": "Empotrar",
   "status.favourite": "Favourite",
@@ -613,7 +613,7 @@
   "time_remaining.minutes": "{number, plural, one {Queda # minutu} other {Queden # minutos}}",
   "time_remaining.moments": "Moments remaining",
   "time_remaining.seconds": "{number, plural, one {Queda # segundu} other {Queden # segundos}}",
-  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.remote_resource_not_displayed": "Nun s'amuesa'l recursu «{resource}» d'otros sirvidores.",
   "timeline_hint.resources.followers": "Siguidores",
   "timeline_hint.resources.follows": "Follows",
   "timeline_hint.resources.statuses": "Artículos antiguos",
@@ -647,7 +647,7 @@
   "upload_progress.label": "Xubiendo…",
   "upload_progress.processing": "Procesando…",
   "video.close": "Zarrar el videu",
-  "video.download": "Download file",
+  "video.download": "Baxar el ficheru",
   "video.exit_fullscreen": "Exit full screen",
   "video.expand": "Espander el videu",
   "video.fullscreen": "Pantalla completa",
diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json
index f4a10a795..08aa5ef3b 100644
--- a/app/javascript/mastodon/locales/be.json
+++ b/app/javascript/mastodon/locales/be.json
@@ -213,7 +213,7 @@
   "empty_column.account_unavailable": "Профіль недаступны",
   "empty_column.blocks": "Вы яшчэ нікога не заблакіравалі.",
   "empty_column.bookmarked_statuses": "У вас яшчэ няма паведамленняў з закладкамі. Калі вы дадасце закладку, яна з'явіцца тут.",
-  "empty_column.community": "Мясцовая шкала часу пустая. Напішыце што-небудзь публічна, каб зрушыць з месца",
+  "empty_column.community": "Мясцовая стужка пустая. Напішыце што-небудзь публічна, каб зрушыць з месца!",
   "empty_column.direct": "Пакуль у вас няма асабістых паведамленняў. Калі вы дашляце або атрымаеце штось, яно з'явіцца тут.",
   "empty_column.domain_blocks": "Заблакіраваных даменаў пакуль няма.",
   "empty_column.explore_statuses": "Зараз не ў трэндзе. Праверце пазней",
@@ -606,7 +606,7 @@
   "suggestions.header": "Гэта можа Вас зацікавіць…",
   "tabs_bar.federated_timeline": "Глабальнае",
   "tabs_bar.home": "Галоўная",
-  "tabs_bar.local_timeline": "Тутэйшыя",
+  "tabs_bar.local_timeline": "Мясцовае",
   "tabs_bar.notifications": "Апавяшчэнні",
   "time_remaining.days": "{number, plural, one {застаўся # дзень} few {засталося # дні} many {засталося # дзён} other {засталося # дня}}",
   "time_remaining.hours": "{number, plural, one {засталася # гадзіна} few {засталося # гадзіны} many {засталося # гадзін} other {засталося # гадзіны}}",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index f357ed67d..cd6baafac 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -101,7 +101,7 @@
   "column.about": "Относно",
   "column.blocks": "Блокирани потребители",
   "column.bookmarks": "Отметки",
-  "column.community": "Локален инфопоток",
+  "column.community": "Локална часова ос",
   "column.direct": "Директни съобщения",
   "column.directory": "Разглеждане на профили",
   "column.domain_blocks": "Блокирани домейни",
@@ -367,7 +367,7 @@
   "missing_indicator.sublabel": "Ресурсът не може да се намери",
   "moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
   "mute_modal.duration": "Времетраене",
-  "mute_modal.hide_notifications": "Скривате ли известията от този потребител?",
+  "mute_modal.hide_notifications": "Скривате ли известията от потребителя?",
   "mute_modal.indefinite": "Неопределено",
   "navigation_bar.about": "Относно",
   "navigation_bar.blocks": "Блокирани потребители",
@@ -382,7 +382,7 @@
   "navigation_bar.favourites": "Любими",
   "navigation_bar.filters": "Заглушени думи",
   "navigation_bar.follow_requests": "Заявки за последване",
-  "navigation_bar.followed_tags": "Последвани хештагове",
+  "navigation_bar.followed_tags": "Последвани хаштагове",
   "navigation_bar.follows_and_followers": "Последвания и последователи",
   "navigation_bar.lists": "Списъци",
   "navigation_bar.logout": "Излизане",
@@ -619,7 +619,7 @@
   "timeline_hint.resources.statuses": "По-стари публикации",
   "trends.counter_by_accounts": "{count, plural, one {{counter} човек} other {{counter} души}} {days, plural, one {за последния {days} ден} other {за последните {days} дни}}",
   "trends.trending_now": "Налагащи се сега",
-  "ui.beforeunload": "Черновата ви ще се загуби, ако излезете от Mastodon.",
+  "ui.beforeunload": "Черновата ви ще се загуби, излизайки от Mastodon.",
   "units.short.billion": "{count}млрд",
   "units.short.million": "{count}млн",
   "units.short.thousand": "{count}хил",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 8dba6bb2c..381deaa0c 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -27,7 +27,7 @@
   "account.enable_notifications": "Notifica'm els tuts de @{name}",
   "account.endorse": "Recomana en el perfil",
   "account.featured_tags.last_status_at": "Darrer tut el {date}",
-  "account.featured_tags.last_status_never": "No hi ha publicacions",
+  "account.featured_tags.last_status_never": "No hi ha tuts",
   "account.featured_tags.title": "etiquetes destacades de {name}",
   "account.follow": "Segueix",
   "account.followers": "Seguidors",
@@ -131,7 +131,7 @@
   "compose_form.hashtag_warning": "Aquest tut no apareixerà a les llistes d'etiquetes perquè no és públic. Només els tuts públics apareixen a les cerques per etiqueta.",
   "compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure els tuts de només per a seguidors.",
   "compose_form.lock_disclaimer.lock": "blocat",
-  "compose_form.placeholder": "Què et passa pel cap?",
+  "compose_form.placeholder": "En què penses?",
   "compose_form.poll.add_option": "Afegeix una opció",
   "compose_form.poll.duration": "Durada de l'enquesta",
   "compose_form.poll.option_placeholder": "Opció {number}",
@@ -139,7 +139,7 @@
   "compose_form.poll.switch_to_multiple": "Canvia l’enquesta per a permetre diverses opcions",
   "compose_form.poll.switch_to_single": "Canvia l’enquesta per a permetre una única opció",
   "compose_form.publish": "Tut",
-  "compose_form.publish_form": "Publica",
+  "compose_form.publish_form": "Tut",
   "compose_form.publish_loud": "Tut!",
   "compose_form.save_changes": "Desa els canvis",
   "compose_form.sensitive.hide": "{count, plural, one {Marca mèdia com a sensible} other {Marca mèdia com a sensible}}",
@@ -155,7 +155,7 @@
   "confirmations.cancel_follow_request.confirm": "Retirar la sol·licitud",
   "confirmations.cancel_follow_request.message": "Segur que vols retirar la sol·licitud de seguiment de {name}?",
   "confirmations.delete.confirm": "Elimina",
-  "confirmations.delete.message": "Segur que vols eliminar la publicació?",
+  "confirmations.delete.message": "Segur que vols eliminar aquest tut?",
   "confirmations.delete_list.confirm": "Elimina",
   "confirmations.delete_list.message": "Segur que vols suprimir permanentment aquesta llista?",
   "confirmations.discard_edit_media.confirm": "Descarta",
@@ -212,7 +212,7 @@
   "empty_column.account_timeline": "No hi ha tuts aquí!",
   "empty_column.account_unavailable": "Perfil no disponible",
   "empty_column.blocks": "Encara no has blocat cap usuari.",
-  "empty_column.bookmarked_statuses": "Encara no tens marcada cap publicació. Quan en marquis una apareixerà aquí.",
+  "empty_column.bookmarked_statuses": "Encara no has marcat cap tut. Quan en marquis un, apareixerà aquí.",
   "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per posar-ho tot en marxa!",
   "empty_column.direct": "Encara no tens missatges directes. Quan n'enviïs o en rebis un, sortirà aquí.",
   "empty_column.domain_blocks": "Encara no hi ha dominis blocats.",
@@ -242,21 +242,21 @@
   "explore.trending_links": "Notícies",
   "explore.trending_statuses": "Tuts",
   "explore.trending_tags": "Etiquetes",
-  "filter_modal.added.context_mismatch_explanation": "Aquesta categoria de filtre no s'aplica al context en què has accedit a aquesta publicació. Si també vols que la publicació es filtri en aquest context, hauràs d'editar el filtre.",
+  "filter_modal.added.context_mismatch_explanation": "Aquesta categoria de filtre no s'aplica al context en què has accedit a aquest tut. Si també vols que el tut es filtri en aquest context, hauràs d'editar el filtre.",
   "filter_modal.added.context_mismatch_title": "El context no coincideix!",
   "filter_modal.added.expired_explanation": "La categoria d'aquest filtre ha caducat, necessitaràs canviar la seva data de caducitat per a aplicar-la.",
   "filter_modal.added.expired_title": "Filtre caducat!",
   "filter_modal.added.review_and_configure": "Per a revisar i configurar aquesta categoria de filtre, ves a {settings_link}.",
   "filter_modal.added.review_and_configure_title": "Configuració del filtre",
   "filter_modal.added.settings_link": "pàgina de configuració",
-  "filter_modal.added.short_explanation": "Aquesta publicació s'ha afegit a la següent categoria de filtre: {title}.",
+  "filter_modal.added.short_explanation": "Aquest tut s'ha afegit a la següent categoria de filtre: {title}.",
   "filter_modal.added.title": "Filtre afegit!",
   "filter_modal.select_filter.context_mismatch": "no aplica en aquest context",
   "filter_modal.select_filter.expired": "caducat",
   "filter_modal.select_filter.prompt_new": "Nova categoria: {name}",
   "filter_modal.select_filter.search": "Cerca o crea",
   "filter_modal.select_filter.subtitle": "Usa una categoria existent o crea'n una de nova",
-  "filter_modal.select_filter.title": "Filtra aquesta publicació",
+  "filter_modal.select_filter.title": "Filtra aquest tut",
   "filter_modal.title.status": "Filtra un tut",
   "follow_recommendations.done": "Fet",
   "follow_recommendations.heading": "Segueix a la gent de la que t'agradaria veure els seus tuts! Aquí hi ha algunes recomanacions.",
@@ -293,29 +293,29 @@
   "home.show_announcements": "Mostra els anuncis",
   "interaction_modal.description.favourite": "Amb un compte a Mastodon pots afavorir aquest tut perquè l'autor sàpiga que t'ha agradat i desar-lo per a més endavant.",
   "interaction_modal.description.follow": "Amb un compte a Mastodon, pots seguir a {name} per a rebre els seus tuts en la teva línia de temps d'Inici.",
-  "interaction_modal.description.reblog": "Amb un compte a Mastodon, pots impulsar aquesta publicació per a compartir-la amb els teus seguidors.",
-  "interaction_modal.description.reply": "Amb un compte a Mastodon, pots respondre aquesta publicació.",
+  "interaction_modal.description.reblog": "Amb un compte a Mastodon, pots impulsar aquest tut per a compartir-lo amb els teus seguidors.",
+  "interaction_modal.description.reply": "Amb un compte a Mastodon, pots respondre aquest tut.",
   "interaction_modal.on_another_server": "En un servidor diferent",
   "interaction_modal.on_this_server": "En aquest servidor",
   "interaction_modal.other_server_instructions": "Copia i enganxa aquest URL en el camp de cerca de la teva aplicació Mastodon preferida o a la interfície web del teu servidor Mastodon.",
   "interaction_modal.preamble": "Com que Mastodon és descentralitzat, pots fer servir el teu compte existent en un altre servidor Mastodon o plataforma compatible si no tens compte en aquest.",
-  "interaction_modal.title.favourite": "Marca la publicació de {name}",
+  "interaction_modal.title.favourite": "Marca el tut de {name}",
   "interaction_modal.title.follow": "Segueix {name}",
   "interaction_modal.title.reblog": "Impulsa el tut de {name}",
-  "interaction_modal.title.reply": "Respon a la publicació de {name}",
+  "interaction_modal.title.reply": "Respon al tut de {name}",
   "intervals.full.days": "{number, plural, one {# dia} other {# dies}}",
   "intervals.full.hours": "{number, plural, one {# hora} other {# hores}}",
   "intervals.full.minutes": "{number, plural, one {# minut} other {# minuts}}",
   "keyboard_shortcuts.back": "Vés enrere",
   "keyboard_shortcuts.blocked": "Obre la llista d'usuaris blocats",
-  "keyboard_shortcuts.boost": "Impulsa la publicació",
+  "keyboard_shortcuts.boost": "Impulsa el tut",
   "keyboard_shortcuts.column": "Centra la columna",
   "keyboard_shortcuts.compose": "Centra l'àrea de composició de text",
   "keyboard_shortcuts.description": "Descripció",
   "keyboard_shortcuts.direct": "Obre la columna de missatges directes",
   "keyboard_shortcuts.down": "Abaixa a la llista",
   "keyboard_shortcuts.enter": "Obre el tut",
-  "keyboard_shortcuts.favourite": "Afavoreix la publicació",
+  "keyboard_shortcuts.favourite": "Afavoreix el tut",
   "keyboard_shortcuts.favourites": "Obre la llista de preferits",
   "keyboard_shortcuts.federated": "Obre la línia de temps federada",
   "keyboard_shortcuts.heading": "Dreceres de teclat",
@@ -330,14 +330,14 @@
   "keyboard_shortcuts.open_media": "Obre mèdia",
   "keyboard_shortcuts.pinned": "Obre la llista de tuts fixats",
   "keyboard_shortcuts.profile": "Obre el perfil de l'autor",
-  "keyboard_shortcuts.reply": "Respon a la publicació",
+  "keyboard_shortcuts.reply": "Respon al tut",
   "keyboard_shortcuts.requests": "Obre la llista de sol·licituds de seguiment",
   "keyboard_shortcuts.search": "Centra la barra de cerca",
   "keyboard_shortcuts.spoilers": "Mostra/amaga el camp CW",
   "keyboard_shortcuts.start": "Obre la columna \"Primeres passes\"",
   "keyboard_shortcuts.toggle_hidden": "Mostra/amaga el text marcat com a sensible",
   "keyboard_shortcuts.toggle_sensitivity": "Mostra/amaga contingut",
-  "keyboard_shortcuts.toot": "Inicia una nova publicació",
+  "keyboard_shortcuts.toot": "Escriu un nou tut",
   "keyboard_shortcuts.unfocus": "Descentra l'àrea de composició de text/cerca",
   "keyboard_shortcuts.up": "Apuja a la llista",
   "lightbox.close": "Tanca",
@@ -346,7 +346,7 @@
   "lightbox.next": "Següent",
   "lightbox.previous": "Anterior",
   "limited_account_hint.action": "Mostra el perfil de totes maneres",
-  "limited_account_hint.title": "Aquest perfil ha estat amagat pels moderadors de {domain}.",
+  "limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
   "lists.account.add": "Afegeix a la llista",
   "lists.account.remove": "Elimina de la llista",
   "lists.delete": "Elimina la llista",
@@ -396,7 +396,7 @@
   "not_signed_in_indicator.not_signed_in": "Necessites iniciar la sessió per a accedir aquest recurs.",
   "notification.admin.report": "{name} ha reportat {target}",
   "notification.admin.sign_up": "{name} s'ha registrat",
-  "notification.favourite": "a {name} li ha agradat la teva publicació",
+  "notification.favourite": "a {name} li ha agradat el teu tut",
   "notification.follow": "{name} et segueix",
   "notification.follow_request": "{name} ha sol·licitat seguir-te",
   "notification.mention": "{name} t'ha mencionat",
@@ -404,7 +404,7 @@
   "notification.poll": "Ha finalitzat una enquesta en què has votat",
   "notification.reblog": "{name} t'ha impulsat",
   "notification.status": "{name} acaba de publicar",
-  "notification.update": "{name} ha editat una publicació",
+  "notification.update": "{name} ha editat un tut",
   "notifications.clear": "Esborra les notificacions",
   "notifications.clear_confirmation": "Segur que vols esborrar permanentment totes les teves notificacions?",
   "notifications.column_settings.admin.report": "Nous informes:",
@@ -452,13 +452,13 @@
   "poll.votes": "{votes, plural, one {# vot} other {# vots}}",
   "poll_button.add_poll": "Afegeix una enquesta",
   "poll_button.remove_poll": "Elimina l'enquesta",
-  "privacy.change": "Canvia la privacitat de la publicació",
+  "privacy.change": "Canvia la privacitat del tut",
   "privacy.direct.long": "Visible només per als usuaris esmentats",
   "privacy.direct.short": "Només gent mencionada",
   "privacy.private.long": "Visible només per als seguidors",
   "privacy.private.short": "Només seguidors",
   "privacy.public.long": "Visible per a tothom",
-  "privacy.public.short": "Pública",
+  "privacy.public.short": "Públic",
   "privacy.unlisted.long": "Visible per a tothom però exclosa de les funcions de descobriment",
   "privacy.unlisted.short": "No llistada",
   "privacy_policy.last_updated": "Darrera actualització {date}",
@@ -466,16 +466,16 @@
   "refresh": "Actualitza",
   "regeneration_indicator.label": "Es carrega…",
   "regeneration_indicator.sublabel": "Es prepara la teva línia de temps d'Inici!",
-  "relative_time.days": "{number} d",
+  "relative_time.days": "{number}d",
   "relative_time.full.days": "fa {number, plural, one {# dia} other {# dies}}",
   "relative_time.full.hours": "fa {number, plural, one {# hora} other {# hores}}",
   "relative_time.full.just_now": "ara mateix",
   "relative_time.full.minutes": "fa {number, plural, one {# minut} other {# minuts}}",
   "relative_time.full.seconds": "fa {number, plural, one {# segon} other {# segons}}",
-  "relative_time.hours": "{number} h",
+  "relative_time.hours": "{number}h",
   "relative_time.just_now": "ara",
-  "relative_time.minutes": "{number} min",
-  "relative_time.seconds": "{number} s",
+  "relative_time.minutes": "{number}min",
+  "relative_time.seconds": "{number}s",
   "relative_time.today": "avui",
   "reply_indicator.cancel": "Cancel·la",
   "report.block": "Bloca",
@@ -486,7 +486,7 @@
   "report.category.subtitle": "Tria la millor coincidència",
   "report.category.title": "Explica'ns què passa amb això ({type})",
   "report.category.title_account": "perfil",
-  "report.category.title_status": "publicació",
+  "report.category.title_status": "tut",
   "report.close": "Fet",
   "report.comment.title": "Hi ha res més que creguis que hauríem de saber?",
   "report.forward": "Reenvia a {target}",
@@ -506,7 +506,7 @@
   "report.rules.subtitle": "Selecciona totes les aplicables",
   "report.rules.title": "Quines regles s'han violat?",
   "report.statuses.subtitle": "Selecciona totes les aplicables",
-  "report.statuses.title": "Hi ha cap publicació que doni suport a aquest informe?",
+  "report.statuses.title": "Hi ha cap tut que doni suport a aquest informe?",
   "report.submit": "Envia",
   "report.target": "Es denuncia {target}",
   "report.thanks.take_action": "Aquestes són les teves opcions per a controlar el que veus a Mastodon:",
@@ -525,7 +525,7 @@
   "search_popout.search_format": "Format de cerca avançada",
   "search_popout.tips.full_text": "Text simple recupera tuts que has escrit, els marcats com a favorits, els impulsats o en els que has estat esmentat, així com usuaris, noms d'usuari i etiquetes.",
   "search_popout.tips.hashtag": "etiqueta",
-  "search_popout.tips.status": "publicació",
+  "search_popout.tips.status": "tut",
   "search_popout.tips.text": "El text simple recupera coincidències amb els usuaris, els noms d'usuari i les etiquetes",
   "search_popout.tips.user": "usuari",
   "search_results.accounts": "Gent",
@@ -539,12 +539,12 @@
   "server_banner.about_active_users": "Gent que ha fet servir aquest servidor en els darrers 30 dies (Usuaris Actius Mensuals)",
   "server_banner.active_users": "usuaris actius",
   "server_banner.administered_by": "Administrat per:",
-  "server_banner.introduction": "{domain} és part de la xarxa social descentralitzada, potenciat per {mastodon}.",
+  "server_banner.introduction": "{domain} és part de la xarxa social descentralitzada impulsada per {mastodon}.",
   "server_banner.learn_more": "Més informació",
   "server_banner.server_stats": "Estadístiques del servidor:",
   "sign_in_banner.create_account": "Registra'm",
   "sign_in_banner.sign_in": "Inicia sessió",
-  "sign_in_banner.text": "Inicia la sessió per a seguir perfils o etiquetes, afavorir, compartir i respondre publicacions. També pots interactuar des del teu compte a un servidor diferent.",
+  "sign_in_banner.text": "Inicia la sessió per a seguir perfils o etiquetes, afavorir, compartir i respondre tuts. També pots interactuar des del teu compte a un servidor diferent.",
   "status.admin_account": "Obre la interfície de moderació per a @{name}",
   "status.admin_domain": "Obre la interfície de moderació per a @{domain}",
   "status.admin_status": "Obre aquest tut a la interfície de moderació",
@@ -552,7 +552,7 @@
   "status.bookmark": "Marca",
   "status.cancel_reblog_private": "Desfés l'impuls",
   "status.cannot_reblog": "No es pot impulsar aquest tut",
-  "status.copy": "Copia l'enllaç a la publicació",
+  "status.copy": "Copia l'enllaç al tut",
   "status.delete": "Elimina",
   "status.detailed_status": "Vista detallada de la conversa",
   "status.direct": "Missatge directe a @{name}",
@@ -563,7 +563,7 @@
   "status.favourite": "Favorit",
   "status.filter": "Filtra aquesta publicació",
   "status.filtered": "Filtrada",
-  "status.hide": "Amaga la publicació",
+  "status.hide": "Amaga el tut",
   "status.history.created": "creat per {name} {date}",
   "status.history.edited": "editat per {name} {date}",
   "status.load_more": "Carrega'n més",
@@ -572,9 +572,9 @@
   "status.more": "Més",
   "status.mute": "Silencia @{name}",
   "status.mute_conversation": "Silencia la conversa",
-  "status.open": "Amplia la publicació",
+  "status.open": "Amplia el tut",
   "status.pin": "Fixa en el perfil",
-  "status.pinned": "Publicació fixada",
+  "status.pinned": "Tut fixat",
   "status.read_more": "Més informació",
   "status.reblog": "Impulsa",
   "status.reblog_private": "Impulsa amb la visibilitat original",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index 84f8c70ac..c664046f0 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -1,7 +1,7 @@
 {
   "about.blocks": "Gweinyddion sy'n cael eu cymedroli",
   "about.contact": "Cysylltwch â:",
-  "about.disclaimer": "Mae Mastodon yn feddalwedd rhydd, cod agored ac o dan hawlfraint Mastodon gGmbH.",
+  "about.disclaimer": "Mae Mastodon yn feddalwedd cod agored rhydd ac o dan hawlfraint Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Nid yw'r rheswm ar gael",
   "about.domain_blocks.preamble": "Fel rheol, mae Mastodon yn caniatáu i chi weld cynnwys gan unrhyw weinyddwr arall yn y ffederasiwn a rhyngweithio â hi. Dyma'r eithriadau a wnaed ar y gweinydd penodol hwn.",
   "about.domain_blocks.silenced.explanation": "Fel rheol, fyddwch chi ddim yn gweld proffiliau a chynnwys o'r gweinydd hwn, oni bai eich bod yn chwilio'n benodol amdano neu yn ymuno drwy ei ddilyn.",
@@ -46,9 +46,9 @@
   "account.media": "Cyfryngau",
   "account.mention": "Crybwyll @{name}",
   "account.moved_to": "Mae {name} wedi nodi fod eu cyfrif newydd yn:",
-  "account.mute": "Tewi @{name}",
-  "account.mute_notifications": "Tewi hysbysiadau o @{name}",
-  "account.muted": "Wedi tewi",
+  "account.mute": "Anwybyddu @{name}",
+  "account.mute_notifications": "Diffodd hysbysiadau o @{name}",
+  "account.muted": "Wedi anwybyddu",
   "account.open_original_page": "Agor y dudalen wreiddiol",
   "account.posts": "Postiadau",
   "account.posts_with_replies": "Postiadau ac atebion",
@@ -491,8 +491,8 @@
   "report.comment.title": "Oes unrhyw beth arall y dylem ei wybod yn eich barn chi?",
   "report.forward": "Ymlaen i {target}",
   "report.forward_hint": "Mae'r cyfrif o weinydd arall. Anfon copi anhysbys o'r adroddiad yno hefyd?",
-  "report.mute": "Tewi",
-  "report.mute_explanation": "Ni fyddwch yn gweld eu postiadau. Gallant eich dilyn o hyd a gweld eich postiadau ac ni fyddant yn gwybod eu bod nhw wedi'u mudo.",
+  "report.mute": "Anwybyddu",
+  "report.mute_explanation": "Ni fyddwch yn gweld eu postiadau. Gallant eich dilyn o hyd a gweld eich postiadau ac ni fyddant yn gwybod eu bod nhw wedi'u hanwybyddu.",
   "report.next": "Nesaf",
   "report.placeholder": "Sylwadau ychwanegol",
   "report.reasons.dislike": "Dydw i ddim yn ei hoffi",
@@ -538,10 +538,10 @@
   "search_results.total": "{count, number} {count, plural, zero {canlyniad} one {canlyniad} two {ganlyniad} other {canlyniad}}",
   "server_banner.about_active_users": "Pobl sy'n defnyddio'r gweinydd hwn yn ystod y 30 diwrnod diwethaf (Defnyddwyr Gweithredol Misol)",
   "server_banner.active_users": "defnyddwyr gweithredol",
-  "server_banner.administered_by": "Yn cael ei weinyddu gan:",
+  "server_banner.administered_by": "Gweinyddir gan:",
   "server_banner.introduction": "Mae {domain} yn rhan o'r rhwydwaith cymdeithasol datganoledig a bwerir gan {mastodon}.",
   "server_banner.learn_more": "Dysgu mwy",
-  "server_banner.server_stats": "Ystagedau'r gweinydd:",
+  "server_banner.server_stats": "Ystadegau'r gweinydd:",
   "sign_in_banner.create_account": "Creu cyfrif",
   "sign_in_banner.sign_in": "Mewngofnodi",
   "sign_in_banner.text": "Mewngofnodwch i ddilyn proffiliau neu hashnodau, ffefrynnau, rhannu ac ateb postiadau. Gallwch hefyd ryngweithio o'ch cyfrif ar weinydd gwahanol.",
@@ -570,8 +570,8 @@
   "status.media_hidden": "Cyfryngau wedi'u cuddio",
   "status.mention": "Crybwyll @{name}",
   "status.more": "Rhagor",
-  "status.mute": "Tewi @{name}",
-  "status.mute_conversation": "Tewi sgwrs",
+  "status.mute": "Anwybyddu @{name}",
+  "status.mute_conversation": "Anwybyddu sgwrs",
   "status.open": "Ehangu'r post hwn",
   "status.pin": "Pinio ar y proffil",
   "status.pinned": "Postiad wedi'i binio",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index b34864cb0..7736877d9 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -403,7 +403,7 @@
   "notification.own_poll": "Deine Umfrage ist beendet",
   "notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet",
   "notification.reblog": "{name} teilte deinen Beitrag",
-  "notification.status": "{name} hat etwas mitgeteilt",
+  "notification.status": "{name} veröffentlichte gerade",
   "notification.update": "{name} bearbeitete einen Beitrag",
   "notifications.clear": "Mitteilungen löschen",
   "notifications.clear_confirmation": "Bist du dir sicher, dass du diese Mitteilungen für immer löschen möchtest?",
@@ -441,7 +441,7 @@
   "notifications.permission_required": "Desktop-Benachrichtigungen sind nicht verfügbar, da die erforderliche Berechtigung nicht erteilt wurde.",
   "notifications_permission_banner.enable": "Aktiviere Desktop-Benachrichtigungen",
   "notifications_permission_banner.how_to_control": "Um Benachrichtigungen zu erhalten, wenn Mastodon nicht geöffnet ist, aktiviere die Desktop-Benachrichtigungen. Du kannst genau bestimmen, welche Arten von Interaktionen Desktop-Benachrichtigungen über die {icon} -Taste erzeugen, sobald diese aktiviert sind.",
-  "notifications_permission_banner.title": "Verpasse nie etwas",
+  "notifications_permission_banner.title": "Nichts verpassen",
   "picture_in_picture.restore": "Zurücksetzen",
   "poll.closed": "Beendet",
   "poll.refresh": "Aktualisieren",
@@ -457,7 +457,7 @@
   "privacy.direct.short": "Nur erwähnte Profile",
   "privacy.private.long": "Nur für deine Follower sichtbar",
   "privacy.private.short": "Nur Follower",
-  "privacy.public.long": "Für alle sichtbar",
+  "privacy.public.long": "Für alle sichtbar, auch für nicht-registrierte bzw. nicht-angemeldete Nutzer*innen",
   "privacy.public.short": "Öffentlich",
   "privacy.unlisted.long": "Sichtbar für alle, aber nicht über Suchfunktion",
   "privacy.unlisted.short": "Nicht gelistet",
@@ -489,7 +489,7 @@
   "report.category.title_status": "Beitrag",
   "report.close": "Fertig",
   "report.comment.title": "Gibt es etwas anderes, was wir wissen sollten?",
-  "report.forward": "An {target} weiterleiten",
+  "report.forward": "Meldung zusätzlich an {target} weiterleiten",
   "report.forward_hint": "Dieses Konto gehört zu einem anderen Server. Soll eine anonymisierte Kopie der Meldung auch dorthin geschickt werden?",
   "report.mute": "Stummschalten",
   "report.mute_explanation": "Du wirst die Beiträge vom Konto nicht mehr sehen. Das Konto kann dir immer noch folgen, und die Person hinter dem Konto wird deine Beiträge sehen können und nicht wissen, dass du sie stummgeschaltet hast.",
@@ -501,18 +501,18 @@
   "report.reasons.other_description": "Der Vorfall passt zu keiner dieser Kategorien",
   "report.reasons.spam": "Das ist Spam",
   "report.reasons.spam_description": "Bösartige Links, gefälschtes Engagement oder wiederholte Antworten",
-  "report.reasons.violation": "Es verstößt gegen Serverregeln",
+  "report.reasons.violation": "Er verstößt gegen Serverregeln",
   "report.reasons.violation_description": "Du bist dir bewusst, dass es gegen bestimmte Regeln verstößt",
   "report.rules.subtitle": "Wähle alle zutreffenden Inhalte aus",
   "report.rules.title": "Welche Regeln werden verletzt?",
   "report.statuses.subtitle": "Wähle alle zutreffenden Inhalte aus",
-  "report.statuses.title": "Gibt es Beiträge, die diesen Bericht unterstützen?",
+  "report.statuses.title": "Gibt es Beiträge, die diesen Bericht untermauern?",
   "report.submit": "Abschicken",
   "report.target": "{target} melden",
   "report.thanks.take_action": "Das sind deine Möglichkeiten zu bestimmen, was du auf Mastodon sehen möchtest:",
   "report.thanks.take_action_actionable": "Während wir den Vorfall überprüfen, kannst du gegen @{name} weitere Maßnahmen ergreifen:",
   "report.thanks.title": "Möchtest du das nicht mehr sehen?",
-  "report.thanks.title_actionable": "Vielen Dank für die Meldung, wir werden uns das ansehen.",
+  "report.thanks.title_actionable": "Vielen Dank für die Meldung! Wir werden uns das ansehen.",
   "report.unfollow": "@{name} entfolgen",
   "report.unfollow_explanation": "Du folgst diesem Konto. Um die Beiträge nicht mehr auf deiner Startseite zu sehen, entfolge dem Konto.",
   "report_notification.attached_statuses": "{count, plural, one {{count} angehangener Beitrag} other {{count} angehängte Beiträge}}",
diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json
index b371e0e9e..0c6b49593 100644
--- a/app/javascript/mastodon/locales/es-MX.json
+++ b/app/javascript/mastodon/locales/es-MX.json
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "Atajos de teclado",
   "footer.privacy_policy": "Política de privacidad",
   "footer.source_code": "Ver código fuente",
-  "footer.status": "Status",
+  "footer.status": "Estado",
   "generic.saved": "Guardado",
   "getting_started.heading": "Primeros pasos",
   "hashtag.column_header.tag_mode.all": "y {additional}",
diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-QC.json
index 1ad8e9353..4b7258685 100644
--- a/app/javascript/mastodon/locales/fr-QC.json
+++ b/app/javascript/mastodon/locales/fr-QC.json
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "Raccourcis clavier",
   "footer.privacy_policy": "Politique de confidentialité",
   "footer.source_code": "Voir le code source",
-  "footer.status": "Status",
+  "footer.status": "État",
   "generic.saved": "Sauvegardé",
   "getting_started.heading": "Pour commencer",
   "hashtag.column_header.tag_mode.all": "et {additional}",
@@ -563,7 +563,7 @@
   "status.favourite": "Ajouter aux favoris",
   "status.filter": "Filtrer cette publication",
   "status.filtered": "Filtrée",
-  "status.hide": "Masquer la publication",
+  "status.hide": "Masquer le message",
   "status.history.created": "créé par {name} {date}",
   "status.history.edited": "modifié par {name} {date}",
   "status.load_more": "Charger plus",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 9ff4910ef..cf428b3d8 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -123,7 +123,7 @@
   "column_subheading.settings": "설정",
   "community.column_settings.local_only": "로컬만",
   "community.column_settings.media_only": "미디어만",
-  "community.column_settings.remote_only": "원격만",
+  "community.column_settings.remote_only": "원격지만",
   "compose.language.change": "언어 변경",
   "compose.language.search": "언어 검색...",
   "compose_form.direct_message_warning_learn_more": "더 알아보기",
@@ -170,7 +170,7 @@
   "confirmations.redraft.confirm": "삭제하고 다시 쓰기",
   "confirmations.redraft.message": "정말로 이 게시물을 삭제하고 다시 쓰시겠습니까? 해당 게시물에 대한 부스트와 좋아요를 잃게 되고 원본에 대한 답장은 연결 되지 않습니다.",
   "confirmations.reply.confirm": "답글",
-  "confirmations.reply.message": "답글을 달기 위해 현재 작성 중인 메시지가 덮어 씌워집니다. 진행하시겠습니까?",
+  "confirmations.reply.message": "지금 답장하면 작성 중인 메시지를 덮어쓰게 됩니다. 정말 진행합니까?",
   "confirmations.unfollow.confirm": "팔로우 해제",
   "confirmations.unfollow.message": "정말로 {name} 님을 팔로우 해제하시겠습니까?",
   "conversation.delete": "대화 삭제",
@@ -192,7 +192,7 @@
   "dismissable_banner.explore_tags": "이 해시태그들은 이 서버와 분산화된 네트워크의 다른 서버에서 사람들의 인기를 끌고 있는 것들입니다.",
   "dismissable_banner.public_timeline": "이 게시물들은 이 서버와 이 서버가 알고있는 분산화된 네트워크의 다른 서버에서 사람들이 게시한 최근 공개 게시물들입니다.",
   "embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 공유하세요.",
-  "embed.preview": "이렇게 표시됩니다:",
+  "embed.preview": "여기처럼 보여집니다.",
   "emoji_button.activity": "활동",
   "emoji_button.clear": "지우기",
   "emoji_button.custom": "사용자 지정",
@@ -355,9 +355,9 @@
   "lists.new.create": "리스트 추가",
   "lists.new.title_placeholder": "새 리스트의 이름",
   "lists.replies_policy.followed": "팔로우 한 사용자 누구나",
-  "lists.replies_policy.list": "리스트의 구성원들",
-  "lists.replies_policy.none": "아무도 없음",
-  "lists.replies_policy.title": "답글 표시:",
+  "lists.replies_policy.list": "리스트의 구성원",
+  "lists.replies_policy.none": "고르지 않음",
+  "lists.replies_policy.title": "답글을 볼 대상",
   "lists.search": "팔로우 중인 사람들 중에서 찾기",
   "lists.subheading": "리스트",
   "load_pending": "{count}개의 새 항목",
@@ -389,7 +389,7 @@
   "navigation_bar.mutes": "뮤트한 사용자",
   "navigation_bar.personal": "개인용",
   "navigation_bar.pins": "고정된 게시물",
-  "navigation_bar.preferences": "사용자 설정",
+  "navigation_bar.preferences": "환경설정",
   "navigation_bar.public_timeline": "연합 타임라인",
   "navigation_bar.search": "검색",
   "navigation_bar.security": "보안",
@@ -399,7 +399,7 @@
   "notification.favourite": "{name} 님이 당신의 게시물을 마음에 들어합니다",
   "notification.follow": "{name} 님이 나를 팔로우했습니다",
   "notification.follow_request": "{name} 님이 팔로우 요청을 보냈습니다",
-  "notification.mention": "{name} 님이 언급하였습니다",
+  "notification.mention": "{name}님의 멘션",
   "notification.own_poll": "내 투표가 끝났습니다",
   "notification.poll": "참여했던 투표가 끝났습니다.",
   "notification.reblog": "{name} 님이 부스트했습니다",
@@ -411,12 +411,12 @@
   "notifications.column_settings.admin.sign_up": "새로운 가입:",
   "notifications.column_settings.alert": "데스크탑 알림",
   "notifications.column_settings.favourite": "좋아요:",
-  "notifications.column_settings.filter_bar.advanced": "카테고리의 모든 종류를 표시",
-  "notifications.column_settings.filter_bar.category": "퀵 필터 바",
-  "notifications.column_settings.filter_bar.show_bar": "필터 막대 표시",
+  "notifications.column_settings.filter_bar.advanced": "모든 범주 표시하기",
+  "notifications.column_settings.filter_bar.category": "빠른 필터 막대",
+  "notifications.column_settings.filter_bar.show_bar": "필터 막대 보이기",
   "notifications.column_settings.follow": "새 팔로워:",
   "notifications.column_settings.follow_request": "새 팔로우 요청:",
-  "notifications.column_settings.mention": "답글:",
+  "notifications.column_settings.mention": "멘션:",
   "notifications.column_settings.poll": "투표 결과:",
   "notifications.column_settings.push": "푸시 알림",
   "notifications.column_settings.reblog": "부스트:",
@@ -523,7 +523,7 @@
   "search.placeholder": "검색",
   "search.search_or_paste": "검색하거나 URL 붙여넣기",
   "search_popout.search_format": "고급 검색 방법",
-  "search_popout.tips.full_text": "단순한 텍스트 검색은 당신이 작성했거나, 관심글로 지정했거나, 부스트했거나, 멘션을 받은 게시글, 그리고 사용자명, 표시되는 이름, 해시태그를 반환합니다.",
+  "search_popout.tips.full_text": "단순한 텍스트 검색은 작성한 게시물 그리고 좋아요, 부스트, 받은 멘션, 사용자명, 표시 이름, 해시태그를 반환합니다.",
   "search_popout.tips.hashtag": "해시태그",
   "search_popout.tips.status": "게시물",
   "search_popout.tips.text": "단순한 텍스트 검색은 관계된 프로필 이름, 사용자명 그리고 해시태그를 표시합니다",
@@ -568,7 +568,7 @@
   "status.history.edited": "{name} 님이 {date}에 수정함",
   "status.load_more": "더 보기",
   "status.media_hidden": "미디어 숨겨짐",
-  "status.mention": "@{name} 님에게 글 쓰기",
+  "status.mention": "@{name}님에게 멘션",
   "status.more": "자세히",
   "status.mute": "@{name} 님을 뮤트하기",
   "status.mute_conversation": "이 대화를 뮤트",
@@ -589,7 +589,7 @@
   "status.sensitive_warning": "민감한 내용",
   "status.share": "공유",
   "status.show_filter_reason": "그냥 표시하기",
-  "status.show_less": "숨기기",
+  "status.show_less": "적게 보기",
   "status.show_less_all": "모두 접기",
   "status.show_more": "더 보기",
   "status.show_more_all": "모두 펼치기",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index f54a92378..ba14ec5c0 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -258,7 +258,7 @@
   "filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu",
   "filter_modal.select_filter.title": "Filtrēt šo ziņu",
   "filter_modal.title.status": "Filtrēt ziņu",
-  "follow_recommendations.done": "Darīts",
+  "follow_recommendations.done": "Izpildīts",
   "follow_recommendations.heading": "Seko cilvēkiem, no kuriem vēlies redzēt ziņas! Šeit ir daži ieteikumi.",
   "follow_recommendations.lead": "Ziņas no cilvēkiem, kuriem seko, mājas plūsmā tiks parādītas hronoloģiskā secībā. Nebaidies kļūdīties, tu tikpat viegli vari pārtraukt sekot cilvēkiem jebkurā laikā!",
   "follow_request.authorize": "Autorizēt",
diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json
index d39ede21d..366544d2a 100644
--- a/app/javascript/mastodon/locales/my.json
+++ b/app/javascript/mastodon/locales/my.json
@@ -197,14 +197,14 @@
   "emoji_button.clear": "ရှင်းလင်းမည်",
   "emoji_button.custom": "Custom",
   "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
+  "emoji_button.food": "အစားအသောက်",
   "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
+  "emoji_button.nature": "သဘာဝ",
   "emoji_button.not_found": "No matching emojis found",
   "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
+  "emoji_button.people": "လူများ",
+  "emoji_button.recent": "မကြာခဏ အသုံးပြုသော",
+  "emoji_button.search": "ရှာရန်...",
   "emoji_button.search_results": "Search results",
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 75e6f7edf..32845ab64 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -168,7 +168,7 @@
   "confirmations.mute.explanation": "Это действие скроет посты данного пользователя и те, в которых он упоминается, но при этом он по-прежнему сможет подписаться и смотреть ваши посты.",
   "confirmations.mute.message": "Вы уверены, что хотите добавить {name} в список игнорируемых?",
   "confirmations.redraft.confirm": "Удалить и исправить",
-  "confirmations.redraft.message": "Вы уверены, что хотите отредактировать этот пост? Старый пост будет удалён, а вместе с ним пропадут отметки «В избранное», продвижения и ответы.",
+  "confirmations.redraft.message": "Вы уверены, что хотите удалить и переписать этот пост? Отметки «избранного», продвижения и ответы к оригинальному посту будут удалены.",
   "confirmations.reply.confirm": "Ответить",
   "confirmations.reply.message": "При ответе, текст набираемого поста будет очищен. Продолжить?",
   "confirmations.unfollow.confirm": "Отписаться",
@@ -200,10 +200,10 @@
   "emoji_button.food": "Еда и напитки",
   "emoji_button.label": "Вставить эмодзи",
   "emoji_button.nature": "Природа",
-  "emoji_button.not_found": "Нет эмодзи!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Подходящие эмодзи не найдены",
   "emoji_button.objects": "Предметы",
   "emoji_button.people": "Люди",
-  "emoji_button.recent": "Последние",
+  "emoji_button.recent": "Часто используемые",
   "emoji_button.search": "Найти...",
   "emoji_button.search_results": "Результаты поиска",
   "emoji_button.symbols": "Символы",
@@ -229,7 +229,7 @@
   "empty_column.lists": "У вас ещё нет списков. Созданные вами списки будут показаны здесь.",
   "empty_column.mutes": "Вы ещё никого не добавляли в список игнорируемых.",
   "empty_column.notifications": "У вас пока нет уведомлений. Взаимодействуйте с другими, чтобы завести разговор.",
-  "empty_column.public": "Здесь совсем пусто. Опубликуйте что-нибудь или подпишитесь на пользователей с других сообществ, чтобы заполнить ленту",
+  "empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту",
   "error.unexpected_crash.explanation": "Из-за несовместимого браузера или ошибки в нашем коде, эта страница не может быть корректно отображена.",
   "error.unexpected_crash.explanation_addons": "Эта страница не может быть корректно отображена. Скорее всего, эта ошибка вызвана расширением браузера или инструментом автоматического перевода.",
   "error.unexpected_crash.next_steps": "Попробуйте обновить страницу. Если проблема не исчезает, используйте Mastodon из-под другого браузера или приложения.",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index aaac5b784..e2db4627e 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -626,7 +626,7 @@
   "upload_area.title": "ลากแล้วปล่อยเพื่ออัปโหลด",
   "upload_button.label": "เพิ่มไฟล์ภาพ, วิดีโอ หรือเสียง",
   "upload_error.limit": "เกินขีดจำกัดการอัปโหลดไฟล์",
-  "upload_error.poll": "ไม่อนุญาตให้อัปโหลดไฟล์กับการลงคะแนน",
+  "upload_error.poll": "ไม่อนุญาตการอัปโหลดไฟล์โดยมีการสำรวจความคิดเห็น",
   "upload_form.audio_description": "อธิบายสำหรับผู้ที่สูญเสียการได้ยิน",
   "upload_form.description": "อธิบายสำหรับผู้บกพร่องทางการมองเห็น",
   "upload_form.description_missing": "ไม่มีการเพิ่มคำอธิบาย",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index f99a1c00c..5c6f539aa 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -128,7 +128,7 @@
   "compose.language.search": "搜尋語言...",
   "compose_form.direct_message_warning_learn_more": "了解更多",
   "compose_form.encryption_warning": "Mastodon 上的帖文並未端對端加密。請不要透過 Mastodon 分享任何敏感資訊。",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.hashtag_warning": "由於此帖文並非公開,因此它不會列在標籤下。只有公開帖文才可以經標籤搜尋。",
   "compose_form.lock_disclaimer": "你的用戶狀態沒有{locked},任何人都能立即關注你,然後看到「只有關注者能看」的文章。",
   "compose_form.lock_disclaimer.lock": "鎖定",
   "compose_form.placeholder": "你在想甚麼?",
@@ -221,7 +221,7 @@
   "empty_column.favourites": "還沒有人收藏這則文章。這裡將會顯示被收藏的嘟文。",
   "empty_column.follow_recommendations": "似乎未能替您產生任何建議。您可以試著搜尋您知道的帳戶或者探索熱門主題標籤",
   "empty_column.follow_requests": "您尚未收到任何追蹤請求。這裡將會顯示收到的追蹤請求。",
-  "empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
+  "empty_column.followed_tags": "你還沒有追蹤標籤。當你追蹤後,標籤將顯示在此處。",
   "empty_column.hashtag": "這個標籤暫時未有內容。",
   "empty_column.home": "你還沒有關注任何使用者。快看看{public},向其他使用者搭訕吧。",
   "empty_column.home.suggestions": "檢視部份建議",
@@ -264,7 +264,7 @@
   "follow_request.authorize": "批准",
   "follow_request.reject": "拒絕",
   "follow_requests.unlocked_explanation": "即使您的帳號未上鎖,{domain} 的工作人員認為您可能會想手動審核來自這些帳號的追蹤請求。",
-  "followed_tags": "Followed hashtags",
+  "followed_tags": "已追蹤標籤",
   "footer.about": "關於",
   "footer.directory": "個人檔案目錄",
   "footer.get_app": "取得應用程式",
@@ -272,7 +272,7 @@
   "footer.keyboard_shortcuts": "鍵盤快速鍵",
   "footer.privacy_policy": "私隱政策",
   "footer.source_code": "查看原始碼",
-  "footer.status": "Status",
+  "footer.status": "狀態",
   "generic.saved": "已儲存",
   "getting_started.heading": "開始使用",
   "hashtag.column_header.tag_mode.all": "以及{additional}",
@@ -382,7 +382,7 @@
   "navigation_bar.favourites": "最愛的內容",
   "navigation_bar.filters": "靜音詞彙",
   "navigation_bar.follow_requests": "追蹤請求",
-  "navigation_bar.followed_tags": "Followed hashtags",
+  "navigation_bar.followed_tags": "已追蹤標籤",
   "navigation_bar.follows_and_followers": "追蹤及追蹤者",
   "navigation_bar.lists": "列表",
   "navigation_bar.logout": "登出",
@@ -544,9 +544,9 @@
   "server_banner.server_stats": "伺服器統計:",
   "sign_in_banner.create_account": "建立帳號",
   "sign_in_banner.sign_in": "登入",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.",
+  "sign_in_banner.text": "登入以追蹤個人檔案和標籤,或最愛、分享和回覆帖文。你也可以使用帳戶在其他伺服器上互動。",
   "status.admin_account": "開啟 @{name} 的管理介面",
-  "status.admin_domain": "Open moderation interface for {domain}",
+  "status.admin_domain": "打開 {domain} 管理介面",
   "status.admin_status": "在管理介面開啟這篇文章",
   "status.block": "封鎖 @{name}",
   "status.bookmark": "書籤",
@@ -563,7 +563,7 @@
   "status.favourite": "最愛",
   "status.filter": "篩選此帖文",
   "status.filtered": "已過濾",
-  "status.hide": "Hide post",
+  "status.hide": "隱藏帖文",
   "status.history.created": "{name} 於 {date} 建立",
   "status.history.edited": "{name} 於 {date} 編輯",
   "status.load_more": "載入更多",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 405e526bb..3af82e86e 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,15 +1,15 @@
 {
-  "about.blocks": "受管制的伺服器",
+  "about.blocks": "被限制的伺服器",
   "about.contact": "聯絡我們:",
   "about.disclaimer": "Mastodon 是一個自由的開源軟體,是 Mastodon gGmbH 的註冊商標。",
-  "about.domain_blocks.no_reason_available": "無法存取之原因",
-  "about.domain_blocks.preamble": "Mastodon 一般來說允許您閱讀並和聯邦宇宙上任何伺服器的使用者互動。這些伺服器是這個站台設下的例外。",
-  "about.domain_blocks.silenced.explanation": "一般來說您不會看到來自這個伺服器的個人檔案和內容,除非您明確地打開或著跟隨此個人檔案。",
-  "about.domain_blocks.silenced.title": "受限的",
-  "about.domain_blocks.suspended.explanation": "來自此伺服器的資料都不會被處理、儲存或交換,也無法和此伺服器上的使用者互動與溝通。",
+  "about.domain_blocks.no_reason_available": "無法存取的原因",
+  "about.domain_blocks.preamble": "Mastodon 基本上允許您瀏覽聯邦宇宙中任何伺服器的內容並與使用者互動。以下是在本伺服器上設定的例外。",
+  "about.domain_blocks.silenced.explanation": "一般來說您不會看到來自這個伺服器的個人檔案和內容,除非您明確搜尋或主動跟隨對方。",
+  "about.domain_blocks.silenced.title": "已受限",
+  "about.domain_blocks.suspended.explanation": "來自此伺服器的資料都不會被處理、儲存或交換,也無法與此伺服器上的使用者互動或交流。",
   "about.domain_blocks.suspended.title": "已停權",
-  "about.not_available": "這個資料於此伺服器上不可存取。",
-  "about.powered_by": "由 {mastodon} 提供之去中心化社群媒體",
+  "about.not_available": "無法在本伺服器上使用此資訊。",
+  "about.powered_by": "由 {mastodon} 提供的去中心化社群媒體",
   "about.rules": "伺服器規則",
   "account.account_note_header": "備註",
   "account.add_or_remove_from_list": "從列表中新增或移除",
@@ -18,9 +18,9 @@
   "account.block": "封鎖 @{name}",
   "account.block_domain": "封鎖來自 {domain} 網域的所有內容",
   "account.blocked": "已封鎖",
-  "account.browse_more_on_origin_server": "於該伺服器的個人檔案頁上瀏覽更多",
+  "account.browse_more_on_origin_server": "在該伺服器上的個人檔案頁面瀏覽更多",
   "account.cancel_follow_request": "收回跟隨請求",
-  "account.direct": "傳私訊給 @{name}",
+  "account.direct": "私訊 @{name}",
   "account.disable_notifications": "取消來自 @{name} 嘟文的通知",
   "account.domain_blocked": "已封鎖網域",
   "account.edit_profile": "編輯個人檔案",
@@ -42,7 +42,7 @@
   "account.joined_short": "加入時間",
   "account.languages": "變更訂閱的語言",
   "account.link_verified_on": "已於 {date} 檢查此連結的擁有者權限",
-  "account.locked_info": "此帳號的隱私狀態被設為鎖定。該擁有者會手動審核能跟隨此帳號的人。",
+  "account.locked_info": "此帳號的隱私狀態設定為鎖定。該擁有者會手動審核能跟隨此帳號的人。",
   "account.media": "媒體",
   "account.mention": "提及 @{name}",
   "account.moved_to": "{name} 現在的新帳號為:",
@@ -58,15 +58,15 @@
   "account.share": "分享 @{name} 的個人檔案",
   "account.show_reblogs": "顯示來自 @{name} 的嘟文",
   "account.statuses_counter": "{count, plural,one {{counter} 則}other {{counter} 則}}嘟文",
-  "account.unblock": "取消封鎖 @{name}",
-  "account.unblock_domain": "取消封鎖域名 {domain}",
+  "account.unblock": "解除封鎖 @{name}",
+  "account.unblock_domain": "解除封鎖網域 {domain}",
   "account.unblock_short": "解除封鎖",
-  "account.unendorse": "不再於個人檔案頁面推薦對方",
+  "account.unendorse": "取消在個人檔案推薦對方",
   "account.unfollow": "取消跟隨",
-  "account.unmute": "取消靜音 @{name}",
+  "account.unmute": "解除靜音 @{name}",
   "account.unmute_notifications": "重新接收來自 @{name} 的通知",
   "account.unmute_short": "解除靜音",
-  "account_note.placeholder": "按此添加備注",
+  "account_note.placeholder": "按此新增備註",
   "admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
   "admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
   "admin.dashboard.retention.average": "平均",
@@ -93,10 +93,10 @@
   "bundle_modal_error.close": "關閉",
   "bundle_modal_error.message": "載入此元件時發生錯誤。",
   "bundle_modal_error.retry": "重試",
-  "closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。",
+  "closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,您可以在其他伺服器上也建立帳號,並繼續與這個伺服器互動。",
   "closed_registrations_modal.description": "目前無法在 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon 。",
   "closed_registrations_modal.find_another_server": "尋找另一個伺服器",
-  "closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您在哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架一個自己的伺服器!",
+  "closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您在哪個伺服器上建立帳號,都可以跟隨並與此伺服器上的任何人互動。您甚至能架一個自己的伺服器!",
   "closed_registrations_modal.title": "註冊 Mastodon",
   "column.about": "關於",
   "column.blocks": "已封鎖的使用者",
@@ -128,8 +128,8 @@
   "compose.language.search": "搜尋語言...",
   "compose_form.direct_message_warning_learn_more": "了解更多",
   "compose_form.encryption_warning": "Mastodon 上的嘟文並未進行端到端加密。請不要透過 Mastodon 分享任何敏感資訊。",
-  "compose_form.hashtag_warning": "由於這則嘟文設定為「不公開」,它將不被列於任何主題標籤下。只有公開的嘟文才能藉由主題標籤被找到。",
-  "compose_form.lock_disclaimer": "您的帳號尚未 {locked}。任何人皆能跟隨您並看到您設定成只有跟隨者能看的嘟文。",
+  "compose_form.hashtag_warning": "由於這則嘟文設定為非公開,將不會列於任何主題標籤下。只有公開的嘟文才能藉由主題標籤被找到。",
+  "compose_form.lock_disclaimer": "您的帳號尚未 {locked}。任何人皆能跟隨您並看到您設定成只對跟隨者顯示的嘟文。",
   "compose_form.lock_disclaimer.lock": "上鎖",
   "compose_form.placeholder": "正在想些什麼嗎?",
   "compose_form.poll.add_option": "新增選項",
@@ -151,22 +151,22 @@
   "confirmation_modal.cancel": "取消",
   "confirmations.block.block_and_report": "封鎖並檢舉",
   "confirmations.block.confirm": "封鎖",
-  "confirmations.block.message": "您確定要封鎖 {name} ?",
+  "confirmations.block.message": "您確定要封鎖 {name} 嗎?",
   "confirmations.cancel_follow_request.confirm": "收回跟隨請求",
   "confirmations.cancel_follow_request.message": "您確定要收回跟隨 {name} 的請求嗎?",
   "confirmations.delete.confirm": "刪除",
-  "confirmations.delete.message": "您確定要刪除這則嘟文?",
+  "confirmations.delete.message": "您確定要刪除這則嘟文嗎?",
   "confirmations.delete_list.confirm": "刪除",
-  "confirmations.delete_list.message": "您確定要永久刪除此列表?",
+  "confirmations.delete_list.message": "您確定要永久刪除此列表嗎?",
   "confirmations.discard_edit_media.confirm": "捨棄",
   "confirmations.discard_edit_media.message": "您在媒體描述或預覽區塊有未儲存的變更。是否要捨棄這些變更?",
-  "confirmations.domain_block.confirm": "封鎖整個域名",
-  "confirmations.domain_block.message": "真的非常確定封鎖整個 {domain} 網域嗎?大部分情況下,您只需要封鎖或靜音少數特定的帳號能滿足需求了。您將不能在任何公開的時間軸及通知中看到來自此網域的內容。您來自該網域的跟隨者也將被移除。",
+  "confirmations.domain_block.confirm": "封鎖整個網域",
+  "confirmations.domain_block.message": "您真的非常確定要封鎖整個 {domain} 網域嗎?大部分情況下,封鎖或靜音少數特定的帳號就能滿足需求了。您將不能在任何公開的時間軸及通知中看到來自此網域的內容。您來自該網域的跟隨者也將被移除。",
   "confirmations.logout.confirm": "登出",
   "confirmations.logout.message": "您確定要登出嗎?",
   "confirmations.mute.confirm": "靜音",
   "confirmations.mute.explanation": "這將會隱藏來自他們的嘟文與通知,但是他們還是可以查閱您的嘟文與跟隨您。",
-  "confirmations.mute.message": "您確定要靜音 {name} ?",
+  "confirmations.mute.message": "您確定要靜音 {name} 嗎?",
   "confirmations.redraft.confirm": "刪除並重新編輯",
   "confirmations.redraft.message": "您確定要刪掉這則嘟文並重新編輯嗎?將會失去這則嘟文的轉嘟及最愛,且回覆這則的嘟文將會變成獨立的嘟文。",
   "confirmations.reply.confirm": "回覆",
@@ -185,12 +185,12 @@
   "directory.recently_active": "最近活躍",
   "disabled_account_banner.account_settings": "帳號設定",
   "disabled_account_banner.text": "您的帳號 {disabledAccount} 目前已停用。",
-  "dismissable_banner.community_timeline": "這些是 {domain} 上面託管帳號之最新公開嘟文。",
+  "dismissable_banner.community_timeline": "這些是託管於 {domain} 上帳號之最新公開嘟文。",
   "dismissable_banner.dismiss": "關閉",
   "dismissable_banner.explore_links": "這些新聞故事正在被此伺服器以及去中心化網路上的人們熱烈討論著。",
-  "dismissable_banner.explore_statuses": "這些於這個伺服器以及去中心化網路中其他伺服器發出的嘟文正在被此伺服器上的人們熱烈討論著。",
+  "dismissable_banner.explore_statuses": "這些於此伺服器以及去中心化網路中其他伺服器發出的嘟文正在被此伺服器上的人們熱烈討論著。",
   "dismissable_banner.explore_tags": "這些主題標籤正在被此伺服器以及去中心化網路上的人們熱烈討論著。",
-  "dismissable_banner.public_timeline": "這些是來自這裡以及去中心化網路中其他已知伺服器之最新公開嘟文。",
+  "dismissable_banner.public_timeline": "這些是來自此伺服器以及去中心化網路中其他已知伺服器的最新公開嘟文。",
   "embed.instructions": "要在您的網站嵌入此嘟文,請複製以下程式碼。",
   "embed.preview": "它將顯示成這樣:",
   "emoji_button.activity": "活動",
@@ -208,10 +208,10 @@
   "emoji_button.search_results": "搜尋結果",
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊與地點",
-  "empty_column.account_suspended": "帳號被暫停",
+  "empty_column.account_suspended": "帳號已被停權",
   "empty_column.account_timeline": "這裡還沒有嘟文!",
   "empty_column.account_unavailable": "無法取得個人檔案",
-  "empty_column.blocks": "您還沒有封鎖任何使用者。",
+  "empty_column.blocks": "您尚未封鎖任何使用者。",
   "empty_column.bookmarked_statuses": "您還沒有建立任何書籤。當您建立書籤時,它將於此顯示。",
   "empty_column.community": "本站時間軸是空的。快公開嘟些文搶頭香啊!",
   "empty_column.direct": "您還沒有任何私訊。當您私訊別人或收到私訊時,它將於此顯示。",
@@ -227,9 +227,9 @@
   "empty_column.home.suggestions": "檢視部份建議",
   "empty_column.list": "這份列表下什麼也沒有。當此列表的成員嘟出了新的嘟文時,它們就會顯示於此。",
   "empty_column.lists": "您還沒有建立任何列表。當您建立列表時,它將於此顯示。",
-  "empty_column.mutes": "您還沒有靜音任何使用者。",
+  "empty_column.mutes": "您尚未靜音任何使用者。",
   "empty_column.notifications": "您還沒有收到任何通知,當您和別人開始互動時,它將於此顯示。",
-  "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或著自己跟隨其他伺服器的使用者後就會有嘟文出現了",
+  "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或者跟隨其他伺服器的使用者後,就會有嘟文出現了",
   "error.unexpected_crash.explanation": "由於發生系統故障或瀏覽器相容性問題,無法正常顯示此頁面。",
   "error.unexpected_crash.explanation_addons": "此頁面無法被正常顯示,這可能是由瀏覽器附加元件或網頁自動翻譯工具造成的。",
   "error.unexpected_crash.next_steps": "請嘗試重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式來檢視來使用 Mastodon。",
@@ -328,7 +328,7 @@
   "keyboard_shortcuts.my_profile": "開啟個人檔案頁面",
   "keyboard_shortcuts.notifications": "開啟通知欄",
   "keyboard_shortcuts.open_media": "開啟媒體",
-  "keyboard_shortcuts.pinned": "開啟釘選嘟文列表",
+  "keyboard_shortcuts.pinned": "開啟釘選的嘟文列表",
   "keyboard_shortcuts.profile": "開啟作者的個人檔案頁面",
   "keyboard_shortcuts.reply": "回應嘟文",
   "keyboard_shortcuts.requests": "開啟跟隨請求列表",
@@ -370,7 +370,7 @@
   "mute_modal.hide_notifications": "是否隱藏來自這位使用者的通知?",
   "mute_modal.indefinite": "無期限",
   "navigation_bar.about": "關於",
-  "navigation_bar.blocks": "封鎖使用者",
+  "navigation_bar.blocks": "已封鎖的使用者",
   "navigation_bar.bookmarks": "書籤",
   "navigation_bar.community_timeline": "本站時間軸",
   "navigation_bar.compose": "撰寫新嘟文",
@@ -380,13 +380,13 @@
   "navigation_bar.edit_profile": "編輯個人檔案",
   "navigation_bar.explore": "探索",
   "navigation_bar.favourites": "最愛",
-  "navigation_bar.filters": "靜音詞彙",
+  "navigation_bar.filters": "已靜音的關鍵字",
   "navigation_bar.follow_requests": "跟隨請求",
   "navigation_bar.followed_tags": "已跟隨主題標籤",
   "navigation_bar.follows_and_followers": "跟隨中與跟隨者",
   "navigation_bar.lists": "列表",
   "navigation_bar.logout": "登出",
-  "navigation_bar.mutes": "靜音的使用者",
+  "navigation_bar.mutes": "已靜音的使用者",
   "navigation_bar.personal": "個人",
   "navigation_bar.pins": "釘選嘟文",
   "navigation_bar.preferences": "偏好設定",
@@ -453,13 +453,13 @@
   "poll_button.add_poll": "建立投票",
   "poll_button.remove_poll": "移除投票",
   "privacy.change": "調整嘟文隱私狀態",
-  "privacy.direct.long": "只有被提及的使用者能看到",
+  "privacy.direct.long": "只對被提及的使用者顯示",
   "privacy.direct.short": "僅限提及的人",
-  "privacy.private.long": "只有跟隨您的使用者能看到",
+  "privacy.private.long": "只對跟隨者顯示",
   "privacy.private.short": "僅限跟隨者",
-  "privacy.public.long": "對所有人可見",
+  "privacy.public.long": "對所有人顯示",
   "privacy.public.short": "公開",
-  "privacy.unlisted.long": "對所有人可見,但選擇退出探索功能",
+  "privacy.unlisted.long": "對所有人顯示,但關閉探索功能",
   "privacy.unlisted.short": "不公開",
   "privacy_policy.last_updated": "最後更新:{date}",
   "privacy_policy.title": "隱私權政策",
@@ -567,7 +567,7 @@
   "status.history.created": "{name} 於 {date} 建立",
   "status.history.edited": "{name} 於 {date} 修改",
   "status.load_more": "載入更多",
-  "status.media_hidden": "隱藏媒體內容",
+  "status.media_hidden": "隱藏的媒體內容",
   "status.mention": "提及 @{name}",
   "status.more": "更多",
   "status.mute": "靜音 @{name}",
diff --git a/app/javascript/mastodon/main.js b/app/javascript/mastodon/main.jsx
index 69a7ee91f..69a7ee91f 100644
--- a/app/javascript/mastodon/main.js
+++ b/app/javascript/mastodon/main.jsx
diff --git a/app/javascript/mastodon/utils/icons.js b/app/javascript/mastodon/utils/icons.jsx
index c3e362e39..c3e362e39 100644
--- a/app/javascript/mastodon/utils/icons.js
+++ b/app/javascript/mastodon/utils/icons.jsx
diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.jsx
index 599015000..599015000 100644
--- a/app/javascript/packs/admin.js
+++ b/app/javascript/packs/admin.jsx
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.jsx
index 8017734d5..8017734d5 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.jsx
diff --git a/app/javascript/packs/share.js b/app/javascript/packs/share.jsx
index 1225d7b52..1225d7b52 100644
--- a/app/javascript/packs/share.js
+++ b/app/javascript/packs/share.jsx
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 01725cf96..58f161f81 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -258,6 +258,10 @@ html {
   border-color: $ui-base-color;
 }
 
+.upload-progress__backdrop {
+  background: $ui-base-color;
+}
+
 // Change the background colors of statuses
 .focusable:focus {
   background: $ui-base-color;
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 08a79c11e..240c90735 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -384,7 +384,7 @@ $content-width: 840px;
           position: fixed;
           z-index: 10;
           width: 100%;
-          height: calc(100vh - 56px);
+          height: calc(100% - 56px);
           left: 0;
           bottom: 0;
           overflow-y: auto;
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index dc1153073..13647b6fc 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -405,10 +405,7 @@ body > [data-popper-placement] {
     }
 
     input[type='checkbox'] {
-      display: none;
-    }
-
-    .checkbox {
+      appearance: none;
       display: inline-block;
       position: relative;
       border: 1px solid $ui-primary-color;
@@ -420,8 +417,9 @@ body > [data-popper-placement] {
       top: -1px;
       border-radius: 4px;
       vertical-align: middle;
+      cursor: inherit;
 
-      &.active {
+      &:checked {
         border-color: $highlight-text-color;
         background: $highlight-text-color
           url("data:image/svg+xml;utf8,<svg width='18' height='18' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M4.5 8.5L8 12l6-6' stroke='white' stroke-width='1.5'/></svg>")
@@ -1200,11 +1198,12 @@ body > [data-popper-placement] {
 
 .status__info {
   font-size: 15px;
-  margin-bottom: 10px;
+  padding-bottom: 10px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
+  cursor: pointer;
 }
 
 .status-check-box__status {
@@ -4544,7 +4543,7 @@ a.status-card.compact:hover {
   width: 100%;
   height: 6px;
   border-radius: 6px;
-  background: $ui-base-lighter-color;
+  background: darken($simple-background-color, 8%);
   position: relative;
   margin-top: 5px;
 }
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 900428e92..5d9596254 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -153,6 +153,7 @@ class ActivityPub::Activity
   def fetch_remote_original_status
     if object_uri.start_with?('http')
       return if ActivityPub::TagManager.instance.local_uri?(object_uri)
+
       ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first, request_id: @options[:request_id])
     elsif @object['url'].present?
       ::FetchRemoteStatusService.new.call(@object['url'], request_id: @options[:request_id])
diff --git a/app/lib/activitypub/case_transform.rb b/app/lib/activitypub/case_transform.rb
index 7f716f862..d36e01b8f 100644
--- a/app/lib/activitypub/case_transform.rb
+++ b/app/lib/activitypub/case_transform.rb
@@ -13,7 +13,7 @@ module ActivityPub::CaseTransform
       when Symbol then camel_lower(value.to_s).to_sym
       when String
         camel_lower_cache[value] ||= if value.start_with?('_:')
-                                       '_:' + value.gsub(/\A_:/, '').underscore.camelize(:lower)
+                                       "_:#{value.gsub(/\A_:/, '').underscore.camelize(:lower)}"
                                      else
                                        value.underscore.camelize(:lower)
                                      end
diff --git a/app/lib/activitypub/linked_data_signature.rb b/app/lib/activitypub/linked_data_signature.rb
index 61759649a..ea59879f3 100644
--- a/app/lib/activitypub/linked_data_signature.rb
+++ b/app/lib/activitypub/linked_data_signature.rb
@@ -32,7 +32,7 @@ class ActivityPub::LinkedDataSignature
 
   def sign!(creator, sign_with: nil)
     options = {
-      'type'    => 'RsaSignature2017',
+      'type' => 'RsaSignature2017',
       'creator' => ActivityPub::TagManager.instance.key_uri_for(creator),
       'created' => Time.now.utc.iso8601,
     }
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb
index 3d6b28ef5..a65a9565a 100644
--- a/app/lib/activitypub/tag_manager.rb
+++ b/app/lib/activitypub/tag_manager.rb
@@ -26,6 +26,7 @@ class ActivityPub::TagManager
       target.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(target)
     when :note, :comment, :activity
       return activity_account_status_url(target.account, target) if target.reblog?
+
       short_account_status_url(target.account, target)
     end
   end
@@ -38,6 +39,7 @@ class ActivityPub::TagManager
       target.instance_actor? ? instance_actor_url : account_url(target)
     when :note, :comment, :activity
       return activity_account_status_url(target.account, target) if target.reblog?
+
       account_status_url(target.account, target)
     when :emoji
       emoji_url(target)
diff --git a/app/lib/importer/base_importer.rb b/app/lib/importer/base_importer.rb
index ea522c600..0cd1d3422 100644
--- a/app/lib/importer/base_importer.rb
+++ b/app/lib/importer/base_importer.rb
@@ -45,7 +45,7 @@ class Importer::BaseImporter
   # Remove documents from the index that no longer exist in the database
   def clean_up!
     index.scroll_batches do |documents|
-      ids           = documents.map { |doc| doc['_id'] }
+      ids           = documents.pluck('_id')
       existence_map = index.adapter.target.where(id: ids).pluck(:id).each_with_object({}) { |id, map| map[id.to_s] = true }
       tmp           = ids.reject { |id| existence_map[id] }
 
diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb
index 74a7d0f3b..f8a0be636 100644
--- a/app/lib/link_details_extractor.rb
+++ b/app/lib/link_details_extractor.rb
@@ -188,7 +188,7 @@ class LinkDetailsExtractor
   end
 
   def language
-    valid_locale_or_nil(structured_data&.language || opengraph_tag('og:locale') || document.xpath('//html').map { |element| element['lang'] }.first)
+    valid_locale_or_nil(structured_data&.language || opengraph_tag('og:locale') || document.xpath('//html').pick('lang'))
   end
 
   def icon
@@ -220,15 +220,15 @@ class LinkDetailsExtractor
   end
 
   def link_tag(name)
-    document.xpath("//link[@rel=\"#{name}\"]").map { |link| link['href'] }.first
+    document.xpath("//link[@rel=\"#{name}\"]").pick('href')
   end
 
   def opengraph_tag(name)
-    document.xpath("//meta[@property=\"#{name}\" or @name=\"#{name}\"]").map { |meta| meta['content'] }.first
+    document.xpath("//meta[@property=\"#{name}\" or @name=\"#{name}\"]").pick('content')
   end
 
   def meta_tag(name)
-    document.xpath("//meta[@name=\"#{name}\"]").map { |meta| meta['content'] }.first
+    document.xpath("//meta[@name=\"#{name}\"]").pick('content')
   end
 
   def structured_data
diff --git a/app/lib/ostatus/tag_manager.rb b/app/lib/ostatus/tag_manager.rb
index 4f4501312..7d8131622 100644
--- a/app/lib/ostatus/tag_manager.rb
+++ b/app/lib/ostatus/tag_manager.rb
@@ -5,27 +5,27 @@ class OStatus::TagManager
   include RoutingHelper
 
   VERBS = {
-    post:           'http://activitystrea.ms/schema/1.0/post',
-    share:          'http://activitystrea.ms/schema/1.0/share',
-    favorite:       'http://activitystrea.ms/schema/1.0/favorite',
-    unfavorite:     'http://activitystrea.ms/schema/1.0/unfavorite',
-    delete:         'http://activitystrea.ms/schema/1.0/delete',
-    follow:         'http://activitystrea.ms/schema/1.0/follow',
+    post: 'http://activitystrea.ms/schema/1.0/post',
+    share: 'http://activitystrea.ms/schema/1.0/share',
+    favorite: 'http://activitystrea.ms/schema/1.0/favorite',
+    unfavorite: 'http://activitystrea.ms/schema/1.0/unfavorite',
+    delete: 'http://activitystrea.ms/schema/1.0/delete',
+    follow: 'http://activitystrea.ms/schema/1.0/follow',
     request_friend: 'http://activitystrea.ms/schema/1.0/request-friend',
-    authorize:      'http://activitystrea.ms/schema/1.0/authorize',
-    reject:         'http://activitystrea.ms/schema/1.0/reject',
-    unfollow:       'http://ostatus.org/schema/1.0/unfollow',
-    block:          'http://mastodon.social/schema/1.0/block',
-    unblock:        'http://mastodon.social/schema/1.0/unblock',
+    authorize: 'http://activitystrea.ms/schema/1.0/authorize',
+    reject: 'http://activitystrea.ms/schema/1.0/reject',
+    unfollow: 'http://ostatus.org/schema/1.0/unfollow',
+    block: 'http://mastodon.social/schema/1.0/block',
+    unblock: 'http://mastodon.social/schema/1.0/unblock',
   }.freeze
 
   TYPES = {
-    activity:   'http://activitystrea.ms/schema/1.0/activity',
-    note:       'http://activitystrea.ms/schema/1.0/note',
-    comment:    'http://activitystrea.ms/schema/1.0/comment',
-    person:     'http://activitystrea.ms/schema/1.0/person',
+    activity: 'http://activitystrea.ms/schema/1.0/activity',
+    note: 'http://activitystrea.ms/schema/1.0/note',
+    comment: 'http://activitystrea.ms/schema/1.0/comment',
+    person: 'http://activitystrea.ms/schema/1.0/person',
     collection: 'http://activitystrea.ms/schema/1.0/collection',
-    group:      'http://activitystrea.ms/schema/1.0/group',
+    group: 'http://activitystrea.ms/schema/1.0/group',
   }.freeze
 
   COLLECTIONS = {
diff --git a/app/lib/request.rb b/app/lib/request.rb
index be6a69b3f..85716f999 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -182,6 +182,7 @@ class Request
 
       contents = truncated_body(limit)
       raise Mastodon::LengthValidationError if contents.bytesize > limit
+
       contents
     end
   end
diff --git a/app/lib/request_pool.rb b/app/lib/request_pool.rb
index e5899a79a..6be172286 100644
--- a/app/lib/request_pool.rb
+++ b/app/lib/request_pool.rb
@@ -64,7 +64,7 @@ class RequestPool
           retries     += 1
           retry
         end
-      rescue StandardError
+      rescue
         # If this connection raises errors of any kind, it's
         # better if it gets reaped as soon as possible
 
diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb
index 796de1113..983865a68 100644
--- a/app/lib/settings/scoped_settings.rb
+++ b/app/lib/settings/scoped_settings.rb
@@ -35,6 +35,7 @@ module Settings
 
       Setting.default_settings.each do |key, default_value|
         next if records.key?(key) || default_value.is_a?(Hash)
+
         records[key] = Setting.new(var: key, value: default_value)
       end
 
@@ -55,6 +56,7 @@ module Settings
         if db_val
           default_value = ScopedSettings.default_settings[key]
           return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash)
+
           db_val.value
         else
           ScopedSettings.default_settings[key]
diff --git a/app/lib/status_filter.rb b/app/lib/status_filter.rb
index b6c80b801..c0e6f3331 100644
--- a/app/lib/status_filter.rb
+++ b/app/lib/status_filter.rb
@@ -11,6 +11,7 @@ class StatusFilter
 
   def filtered?
     return false if !account.nil? && account.id == status.account_id
+
     blocked_by_policy? || (account_present? && filtered_status?) || silenced_account?
   end
 
diff --git a/app/lib/tag_manager.rb b/app/lib/tag_manager.rb
index a1d12a654..7fbf4437d 100644
--- a/app/lib/tag_manager.rb
+++ b/app/lib/tag_manager.rb
@@ -25,6 +25,7 @@ class TagManager
   def local_url?(url)
     uri    = Addressable::URI.parse(url).normalize
     return false unless uri.host
+
     domain = uri.host + (uri.port ? ":#{uri.port}" : '')
 
     TagManager.instance.web_domain?(domain)
diff --git a/app/lib/validation_error_formatter.rb b/app/lib/validation_error_formatter.rb
index 3f964f739..1d3e8955b 100644
--- a/app/lib/validation_error_formatter.rb
+++ b/app/lib/validation_error_formatter.rb
@@ -19,7 +19,7 @@ class ValidationErrorFormatter
       messages = errors.messages[attribute_name]
 
       h[@aliases[attribute_name] || attribute_name] = attribute_errors.map.with_index do |error, index|
-        { error: 'ERR_' + error[:error].to_s.upcase, description: messages[index] }
+        { error: "ERR_#{error[:error].to_s.upcase}", description: messages[index] }
       end
     end
 
diff --git a/app/lib/webfinger.rb b/app/lib/webfinger.rb
index 42ddef47b..ae8a3b1ea 100644
--- a/app/lib/webfinger.rb
+++ b/app/lib/webfinger.rb
@@ -57,6 +57,7 @@ class Webfinger
       if res.code == 200
         body = res.body_with_limit
         raise Webfinger::Error, "Request for #{@uri} returned empty response" if body.empty?
+
         body
       elsif res.code == 404 && use_fallback
         body_from_host_meta
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index a37682eca..73b623576 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -9,9 +9,7 @@ class ApplicationMailer < ActionMailer::Base
 
   protected
 
-  def locale_for_account(account)
-    I18n.with_locale(account.user_locale || I18n.default_locale) do
-      yield
-    end
+  def locale_for_account(account, &block)
+    I18n.with_locale(account.user_locale || I18n.default_locale, &block)
   end
 end
diff --git a/app/models/account.rb b/app/models/account.rb
index bd623cff9..2a5a33ca7 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: accounts
@@ -82,8 +83,8 @@ class Account < ApplicationRecord
   MAX_NOTE_LENGTH = (ENV['MAX_BIO_CHARS'] || 500).to_i
   DEFAULT_FIELDS_SIZE = (ENV['MAX_PROFILE_FIELDS'] || 4).to_i
 
-  enum protocol: [:ostatus, :activitypub]
-  enum suspension_origin: [:local, :remote], _prefix: true
+  enum protocol: { ostatus: 0, activitypub: 1 }
+  enum suspension_origin: { local: 0, remote: 1 }, _prefix: true
 
   validates :username, presence: true
   validates_with UniqueUsernameValidator, if: -> { will_save_change_to_username? }
@@ -111,7 +112,7 @@ class Account < ApplicationRecord
   scope :bots, -> { where(actor_type: %w(Application Service)) }
   scope :groups, -> { where(actor_type: 'Group') }
   scope :alphabetic, -> { order(domain: :asc, username: :asc) }
-  scope :matches_username, ->(value) { where(arel_table[:username].matches("#{value}%")) }
+  scope :matches_username, ->(value) { where('lower((username)::text) LIKE lower(?)', "#{value}%") }
   scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) }
   scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
   scope :without_unapproved, -> { left_outer_joins(:user).remote.or(left_outer_joins(:user).merge(User.approved.confirmed)) }
@@ -537,6 +538,7 @@ class Account < ApplicationRecord
 
   def ensure_keys!
     return unless local? && private_key.blank? && public_key.blank?
+
     generate_keys
     save!
   end
diff --git a/app/models/account/field.rb b/app/models/account/field.rb
index 98c29726d..2bada6954 100644
--- a/app/models/account/field.rb
+++ b/app/models/account/field.rb
@@ -14,8 +14,8 @@ class Account::Field < ActiveModelSerializers::Model
     @account        = account
 
     super(
-      name:        sanitize(attributes['name']),
-      value:       sanitize(attributes['value']),
+      name: sanitize(attributes['name']),
+      value: sanitize(attributes['value']),
       verified_at: attributes['verified_at']&.to_datetime,
     )
   end
diff --git a/app/models/account_conversation.rb b/app/models/account_conversation.rb
index 45e74bbeb..b3ddc04c1 100644
--- a/app/models/account_conversation.rb
+++ b/app/models/account_conversation.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_conversations
@@ -107,6 +108,7 @@ class AccountConversation < ApplicationRecord
 
   def push_to_streaming_api
     return if destroyed? || !subscribed_to_timeline?
+
     PushConversationWorker.perform_async(id)
   end
 
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index 3aaffde9a..af1e6a68d 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_domain_blocks
diff --git a/app/models/account_moderation_note.rb b/app/models/account_moderation_note.rb
index 22e312bb2..ff399bab0 100644
--- a/app/models/account_moderation_note.rb
+++ b/app/models/account_moderation_note.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_moderation_notes
diff --git a/app/models/account_note.rb b/app/models/account_note.rb
index b338bc92f..9bc704d98 100644
--- a/app/models/account_note.rb
+++ b/app/models/account_note.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_notes
diff --git a/app/models/account_pin.rb b/app/models/account_pin.rb
index b51d3d4cd..6c78e8c44 100644
--- a/app/models/account_pin.rb
+++ b/app/models/account_pin.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_pins
diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb
index a5d71a5b8..834f8ba4c 100644
--- a/app/models/account_stat.rb
+++ b/app/models/account_stat.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_stats
diff --git a/app/models/account_summary.rb b/app/models/account_summary.rb
index 3a3cebc55..0d8835b83 100644
--- a/app/models/account_summary.rb
+++ b/app/models/account_summary.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_summaries
diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb
index a181cd18d..4f8cc5320 100644
--- a/app/models/account_warning.rb
+++ b/app/models/account_warning.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: account_warnings
@@ -17,13 +18,13 @@
 
 class AccountWarning < ApplicationRecord
   enum action: {
-    none:                       0,
-    disable:                    1_000,
+    none: 0,
+    disable: 1_000,
     mark_statuses_as_sensitive: 1_250,
-    delete_statuses:            1_500,
-    sensitive:                  2_000,
-    silence:                    3_000,
-    suspend:                    4_000,
+    delete_statuses: 1_500,
+    sensitive: 2_000,
+    silence: 3_000,
+    suspend: 4_000,
   }, _suffix: :action
 
   before_validation :before_validate
diff --git a/app/models/admin/import.rb b/app/models/admin/import.rb
index fecde4878..0fd4bdb82 100644
--- a/app/models/admin/import.rb
+++ b/app/models/admin/import.rb
@@ -56,6 +56,7 @@ class Admin::Import
 
   def validate_data
     return if data.nil?
+
     errors.add(:data, I18n.t('imports.errors.over_rows_processing_limit', count: ROWS_PROCESSING_LIMIT)) if csv_row_count > ROWS_PROCESSING_LIMIT
   rescue CSV::MalformedCSVError => e
     errors.add(:data, I18n.t('imports.errors.invalid_csv_file', error: e.message))
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index 898bf3efa..339f5ae70 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -20,7 +20,7 @@
 class Announcement < ApplicationRecord
   scope :unpublished, -> { where(published: false) }
   scope :published, -> { where(published: true) }
-  scope :without_muted, ->(account) { joins("LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{account.id}").where('announcement_mutes.id IS NULL') }
+  scope :without_muted, ->(account) { joins("LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{account.id}").where(announcement_mutes: { id: nil }) }
   scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC')) }
   scope :reverse_chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) DESC')) }
 
diff --git a/app/models/backup.rb b/app/models/backup.rb
index 277b9395b..bec3cbfe5 100644
--- a/app/models/backup.rb
+++ b/app/models/backup.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: backups
diff --git a/app/models/block.rb b/app/models/block.rb
index bf3e07600..b42c1569b 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: blocks
diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb
index 6334ef0df..04b660372 100644
--- a/app/models/bookmark.rb
+++ b/app/models/bookmark.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: bookmarks
diff --git a/app/models/canonical_email_block.rb b/app/models/canonical_email_block.rb
index 1eb69ac67..d09df6f5e 100644
--- a/app/models/canonical_email_block.rb
+++ b/app/models/canonical_email_block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: canonical_email_blocks
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index 325619774..1898516b0 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -278,7 +278,7 @@ module AccountInteractions
       followers.where(Account.arel_table[:uri].matches("#{Account.sanitize_sql_like(url_prefix)}/%", false, true)).or(followers.where(uri: url_prefix)).pluck_each(:uri) do |uri|
         Xorcist.xor!(digest, Digest::SHA256.digest(uri))
       end
-      digest.unpack('H*')[0]
+      digest.unpack1('H*')
     end
   end
 
@@ -288,7 +288,7 @@ module AccountInteractions
       followers.where(domain: nil).pluck_each(:username) do |username|
         Xorcist.xor!(digest, Digest::SHA256.digest(ActivityPub::TagManager.instance.uri_for_username(username)))
       end
-      digest.unpack('H*')[0]
+      digest.unpack1('H*')
     end
   end
 
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index 4dfaea889..5de259962 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: conversations
diff --git a/app/models/conversation_mute.rb b/app/models/conversation_mute.rb
index 52c1a33e0..31f8e1966 100644
--- a/app/models/conversation_mute.rb
+++ b/app/models/conversation_mute.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: conversation_mutes
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index fc8d3aed3..b5a07a5a0 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: custom_emojis
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb
index 5a4a974be..d85e196e9 100644
--- a/app/models/custom_filter.rb
+++ b/app/models/custom_filter.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: custom_filters
@@ -30,11 +31,11 @@ class CustomFilter < ApplicationRecord
   include Expireable
   include Redisable
 
-  enum action: [:warn, :hide], _suffix: :action
+  enum action: { warn: 0, hide: 1 }, _suffix: :action
 
   belongs_to :account
-  has_many :keywords, class_name: 'CustomFilterKeyword', foreign_key: :custom_filter_id, inverse_of: :custom_filter, dependent: :destroy
-  has_many :statuses, class_name: 'CustomFilterStatus', foreign_key: :custom_filter_id, inverse_of: :custom_filter, dependent: :destroy
+  has_many :keywords, class_name: 'CustomFilterKeyword', inverse_of: :custom_filter, dependent: :destroy
+  has_many :statuses, class_name: 'CustomFilterStatus', inverse_of: :custom_filter, dependent: :destroy
   accepts_nested_attributes_for :keywords, reject_if: :all_blank, allow_destroy: true
 
   validates :title, :context, presence: true
@@ -101,6 +102,7 @@ class CustomFilter < ApplicationRecord
       status_matches = [status.id, status.reblog_of_id].compact & rules[:status_ids] if rules[:status_ids].present?
 
       next if keyword_matches.blank? && status_matches.blank?
+
       FilterResultPresenter.new(filter: filter, keyword_matches: keyword_matches, status_matches: status_matches)
     end
   end
@@ -111,6 +113,7 @@ class CustomFilter < ApplicationRecord
 
   def invalidate_cache!
     return unless @should_invalidate_cache
+
     @should_invalidate_cache = false
 
     Rails.cache.delete("filters:v3:#{account_id}")
diff --git a/app/models/custom_filter_keyword.rb b/app/models/custom_filter_keyword.rb
index e0d0289ae..3158b3b79 100644
--- a/app/models/custom_filter_keyword.rb
+++ b/app/models/custom_filter_keyword.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: custom_filter_keywords
diff --git a/app/models/custom_filter_status.rb b/app/models/custom_filter_status.rb
index e748d6963..0a5650204 100644
--- a/app/models/custom_filter_status.rb
+++ b/app/models/custom_filter_status.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: custom_filter_statuses
diff --git a/app/models/device.rb b/app/models/device.rb
index 97d0d2774..5dc6cf1e6 100644
--- a/app/models/device.rb
+++ b/app/models/device.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: devices
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index 8e298ac9d..fbb045416 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: domain_blocks
@@ -20,7 +21,7 @@ class DomainBlock < ApplicationRecord
   include DomainNormalizable
   include DomainMaterializable
 
-  enum severity: [:silence, :suspend, :noop]
+  enum severity: { silence: 0, suspend: 1, noop: 2 }
 
   validates :domain, presence: true, uniqueness: true, domain: true
 
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 3a56e4f2a..276e7d31a 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: email_domain_blocks
diff --git a/app/models/encrypted_message.rb b/app/models/encrypted_message.rb
index 7b4e32283..3e7e95594 100644
--- a/app/models/encrypted_message.rb
+++ b/app/models/encrypted_message.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: encrypted_messages
diff --git a/app/models/favourite.rb b/app/models/favourite.rb
index 2f355739a..042f72bea 100644
--- a/app/models/favourite.rb
+++ b/app/models/favourite.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: favourites
@@ -38,6 +39,7 @@ class Favourite < ApplicationRecord
 
   def decrement_cache_counters
     return if association(:status).loaded? && status.marked_for_destruction?
+
     status&.decrement_count!(:favourites_count)
   end
 
diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb
index 70f949b6a..587dcf991 100644
--- a/app/models/featured_tag.rb
+++ b/app/models/featured_tag.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: featured_tags
diff --git a/app/models/follow.rb b/app/models/follow.rb
index e5cecbbc1..108f5c5d5 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: follows
diff --git a/app/models/follow_recommendation.rb b/app/models/follow_recommendation.rb
index e552b5a88..602d32985 100644
--- a/app/models/follow_recommendation.rb
+++ b/app/models/follow_recommendation.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: follow_recommendations
@@ -12,7 +13,7 @@ class FollowRecommendation < ApplicationRecord
   self.primary_key = :account_id
 
   belongs_to :account_summary, foreign_key: :account_id
-  belongs_to :account, foreign_key: :account_id
+  belongs_to :account
 
   scope :localized, ->(locale) { joins(:account_summary).merge(AccountSummary.localized(locale)) }
 
diff --git a/app/models/follow_recommendation_suppression.rb b/app/models/follow_recommendation_suppression.rb
index 170506b85..a9dbbfc18 100644
--- a/app/models/follow_recommendation_suppression.rb
+++ b/app/models/follow_recommendation_suppression.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: follow_recommendation_suppressions
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 9034250c0..78f79c18f 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: follow_requests
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index d692891d8..eaee142fa 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -153,6 +153,7 @@ class Form::AdminSettings
   def validate_site_uploads
     UPLOAD_KEYS.each do |key|
       next unless instance_variable_defined?("@#{key}")
+
       upload = instance_variable_get("@#{key}")
       next if upload.valid?
 
diff --git a/app/models/identity.rb b/app/models/identity.rb
index 8cc65aef4..6f10fed4d 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: identities
diff --git a/app/models/import.rb b/app/models/import.rb
index 00a54892e..21634005e 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: imports
@@ -24,7 +25,7 @@ class Import < ApplicationRecord
 
   belongs_to :account
 
-  enum type: [:following, :blocking, :muting, :domain_blocking, :bookmarks]
+  enum type: { following: 0, blocking: 1, muting: 2, domain_blocking: 3, bookmarks: 4 }
 
   validates :type, presence: true
   validates_with ImportValidator, on: :create
diff --git a/app/models/instance.rb b/app/models/instance.rb
index edbf02a6d..1f96d3728 100644
--- a/app/models/instance.rb
+++ b/app/models/instance.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: instances
diff --git a/app/models/invite.rb b/app/models/invite.rb
index 7ea4e2f98..8e816cef0 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: invites
diff --git a/app/models/ip_block.rb b/app/models/ip_block.rb
index 31343f0e1..99783050b 100644
--- a/app/models/ip_block.rb
+++ b/app/models/ip_block.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: ip_blocks
diff --git a/app/models/list.rb b/app/models/list.rb
index cdc6ebdb3..bd1bdbd24 100644
--- a/app/models/list.rb
+++ b/app/models/list.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: lists
@@ -16,7 +17,7 @@ class List < ApplicationRecord
 
   PER_ACCOUNT_LIMIT = 50
 
-  enum replies_policy: [:list, :followed, :none], _prefix: :show
+  enum replies_policy: { list: 0, followed: 1, none: 2 }, _prefix: :show
 
   belongs_to :account, optional: true
 
diff --git a/app/models/list_account.rb b/app/models/list_account.rb
index 785923c4c..a5767d3d8 100644
--- a/app/models/list_account.rb
+++ b/app/models/list_account.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: list_accounts
diff --git a/app/models/login_activity.rb b/app/models/login_activity.rb
index 52a0fd01d..2b7b37f8e 100644
--- a/app/models/login_activity.rb
+++ b/app/models/login_activity.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: login_activities
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 4dd3042ab..62c9828c6 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: media_attachments
@@ -33,8 +34,8 @@ class MediaAttachment < ApplicationRecord
 
   include Attachmentable
 
-  enum type: [:image, :gifv, :video, :unknown, :audio]
-  enum processing: [:queued, :in_progress, :complete, :failed], _prefix: true
+  enum type: { :image => 0, :gifv => 1, :video => 2, :unknown => 3, :audio => 4 }
+  enum processing: { :queued => 0, :in_progress => 1, :complete => 2, :failed => 3 }, _prefix: true
 
   MAX_DESCRIPTION_LENGTH = 1_500
 
@@ -372,7 +373,7 @@ class MediaAttachment < ApplicationRecord
     return {} if width.nil?
 
     {
-      width:  width,
+      width: width,
       height: height,
       size: "#{width}x#{height}",
       aspect: width.to_f / height,
diff --git a/app/models/mention.rb b/app/models/mention.rb
index d01a88e32..2348b2905 100644
--- a/app/models/mention.rb
+++ b/app/models/mention.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: mentions
diff --git a/app/models/mute.rb b/app/models/mute.rb
index 578345ef6..8fc542262 100644
--- a/app/models/mute.rb
+++ b/app/models/mute.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: mutes
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 01155c363..3eaf557b0 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: notifications
@@ -19,12 +20,12 @@ class Notification < ApplicationRecord
   include Paginable
 
   LEGACY_TYPE_CLASS_MAP = {
-    'Mention'       => :mention,
-    'Status'        => :reblog,
-    'Follow'        => :follow,
+    'Mention' => :mention,
+    'Status' => :reblog,
+    'Follow' => :follow,
     'FollowRequest' => :follow_request,
-    'Favourite'     => :favourite,
-    'Poll'          => :poll,
+    'Favourite' => :favourite,
+    'Poll' => :poll,
   }.freeze
 
   TYPES = %i(
diff --git a/app/models/one_time_key.rb b/app/models/one_time_key.rb
index 8ada34824..23604e2f7 100644
--- a/app/models/one_time_key.rb
+++ b/app/models/one_time_key.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: one_time_keys
diff --git a/app/models/poll.rb b/app/models/poll.rb
index af3b09315..dd35e953b 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: polls
@@ -74,9 +75,9 @@ class Poll < ApplicationRecord
 
     def initialize(poll, id, title, votes_count)
       super(
-        poll:        poll,
-        id:          id,
-        title:       title,
+        poll: poll,
+        id: id,
+        title: title,
         votes_count: votes_count,
       )
     end
@@ -105,6 +106,7 @@ class Poll < ApplicationRecord
 
   def reset_parent_cache
     return if status_id.nil?
+
     Rails.cache.delete("statuses/#{status_id}")
   end
 
diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb
index ad24eb691..00eaedd12 100644
--- a/app/models/poll_vote.rb
+++ b/app/models/poll_vote.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: poll_votes
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index 56ca62d5e..6bce16562 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: preview_cards
@@ -44,8 +45,8 @@ class PreviewCard < ApplicationRecord
 
   self.inheritance_column = false
 
-  enum type: [:link, :photo, :video, :rich]
-  enum link_type: [:unknown, :article]
+  enum type: { link: 0, photo: 1, video: 2, rich: 3 }
+  enum link_type: { unknown: 0, article: 1 }
 
   has_and_belongs_to_many :statuses
   has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy
diff --git a/app/models/preview_card_provider.rb b/app/models/preview_card_provider.rb
index d61fe6020..1dd95fc91 100644
--- a/app/models/preview_card_provider.rb
+++ b/app/models/preview_card_provider.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: preview_card_providers
diff --git a/app/models/relay.rb b/app/models/relay.rb
index c66bfe4ff..a5fa03a99 100644
--- a/app/models/relay.rb
+++ b/app/models/relay.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: relays
@@ -14,7 +15,7 @@
 class Relay < ApplicationRecord
   validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url?
 
-  enum state: [:idle, :pending, :accepted, :rejected]
+  enum state: { idle: 0, pending: 1, accepted: 2, rejected: 3 }
 
   scope :enabled, -> { accepted }
 
diff --git a/app/models/report.rb b/app/models/report.rb
index 525d22ad5..a9940459d 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: reports
@@ -32,7 +33,7 @@ class Report < ApplicationRecord
   belongs_to :action_taken_by_account, class_name: 'Account', optional: true
   belongs_to :assigned_account, class_name: 'Account', optional: true
 
-  has_many :notes, class_name: 'ReportNote', foreign_key: :report_id, inverse_of: :report, dependent: :destroy
+  has_many :notes, class_name: 'ReportNote', inverse_of: :report, dependent: :destroy
   has_many :notifications, as: :activity, dependent: :destroy
 
   scope :unresolved, -> { where(action_taken_at: nil) }
diff --git a/app/models/report_note.rb b/app/models/report_note.rb
index 6d7167e0e..74b46027e 100644
--- a/app/models/report_note.rb
+++ b/app/models/report_note.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: report_notes
diff --git a/app/models/session_activation.rb b/app/models/session_activation.rb
index 0b7fa6fe4..10c3a6c25 100644
--- a/app/models/session_activation.rb
+++ b/app/models/session_activation.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: session_activations
@@ -51,6 +52,7 @@ class SessionActivation < ApplicationRecord
 
     def deactivate(id)
       return unless id
+
       where(session_id: id).destroy_all
     end
 
diff --git a/app/models/setting.rb b/app/models/setting.rb
index c6558d692..3bdc6ffb4 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: settings
@@ -30,6 +31,7 @@ class Setting < RailsSettings::Base
           default_value = default_settings[key]
 
           return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash)
+
           db_val.value
         else
           default_settings[key]
@@ -43,6 +45,7 @@ class Setting < RailsSettings::Base
 
       default_settings.each do |key, default_value|
         next if records.key?(key) || default_value.is_a?(Hash)
+
         records[key] = Setting.new(var: key, value: default_value)
       end
 
@@ -51,6 +54,7 @@ class Setting < RailsSettings::Base
 
     def default_settings
       return {} unless RailsSettings::Default.enabled?
+
       RailsSettings::Default.instance
     end
   end
diff --git a/app/models/site_upload.rb b/app/models/site_upload.rb
index 167131fdd..e17668110 100644
--- a/app/models/site_upload.rb
+++ b/app/models/site_upload.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: site_uploads
diff --git a/app/models/status.rb b/app/models/status.rb
index c17921333..bf102120e 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: statuses
@@ -50,12 +51,12 @@ class Status < ApplicationRecord
 
   update_index('statuses', :proper)
 
-  enum visibility: [:public, :unlisted, :private, :direct, :limited], _suffix: :visibility
+  enum visibility: { public: 0, unlisted: 1, private: 2, direct: 3, limited: 4 }, _suffix: :visibility
 
   belongs_to :application, class_name: 'Doorkeeper::Application', optional: true
 
   belongs_to :account, inverse_of: :statuses
-  belongs_to :in_reply_to_account, foreign_key: 'in_reply_to_account_id', class_name: 'Account', optional: true
+  belongs_to :in_reply_to_account, class_name: 'Account', optional: true
   belongs_to :conversation, optional: true
   belongs_to :preloadable_poll, class_name: 'Poll', foreign_key: 'poll_id', optional: true
 
@@ -97,7 +98,7 @@ class Status < ApplicationRecord
   scope :local,  -> { where(local: true).or(where(uri: nil)) }
   scope :with_accounts, ->(ids) { where(id: ids).includes(:account) }
   scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') }
-  scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
+  scope :without_reblogs, -> { where(statuses: { reblog_of_id: nil }) }
   scope :with_public_visibility, -> { where(visibility: :public) }
   scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) }
   scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) }
diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb
index 18095b4e6..653a04252 100644
--- a/app/models/status_edit.rb
+++ b/app/models/status_edit.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: status_edits
@@ -46,6 +47,7 @@ class StatusEdit < ApplicationRecord
 
   def emojis
     return @emojis if defined?(@emojis)
+
     @emojis = CustomEmoji.from_text([spoiler_text, text].join(' '), status.account.domain)
   end
 
diff --git a/app/models/status_pin.rb b/app/models/status_pin.rb
index 93a0ea1c0..dae4a5b4e 100644
--- a/app/models/status_pin.rb
+++ b/app/models/status_pin.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: status_pins
diff --git a/app/models/status_stat.rb b/app/models/status_stat.rb
index 437861d1c..d101cc178 100644
--- a/app/models/status_stat.rb
+++ b/app/models/status_stat.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: status_stats
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 98001d60a..554a92d90 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: tags
diff --git a/app/models/unavailable_domain.rb b/app/models/unavailable_domain.rb
index dfc0ef14e..c3f2f20e9 100644
--- a/app/models/unavailable_domain.rb
+++ b/app/models/unavailable_domain.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: unavailable_domains
diff --git a/app/models/user.rb b/app/models/user.rb
index 5ac1f663c..a90f43eda 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: users
@@ -501,12 +502,14 @@ class User < ApplicationRecord
 
   def sanitize_languages
     return if chosen_languages.nil?
+
     chosen_languages.reject!(&:blank?)
     self.chosen_languages = nil if chosen_languages.empty?
   end
 
   def sanitize_role
     return if role.nil?
+
     self.role = nil if role.everyone?
   end
 
@@ -525,6 +528,7 @@ class User < ApplicationRecord
   def notify_staff_about_pending_account!
     User.those_who_can(:manage_users).includes(:account).find_each do |u|
       next unless u.allows_pending_account_emails?
+
       AdminMailer.new_pending_account(u.account, self).deliver_later
     end
   end
diff --git a/app/models/user_ip.rb b/app/models/user_ip.rb
index a8e802e13..38287c2a6 100644
--- a/app/models/user_ip.rb
+++ b/app/models/user_ip.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: user_ips
@@ -11,7 +12,7 @@
 class UserIp < ApplicationRecord
   self.primary_key = :user_id
 
-  belongs_to :user, foreign_key: :user_id
+  belongs_to :user
 
   def readonly?
     true
diff --git a/app/models/user_role.rb b/app/models/user_role.rb
index 74dfdc220..a1b91dc0f 100644
--- a/app/models/user_role.rb
+++ b/app/models/user_role.rb
@@ -163,6 +163,7 @@ class UserRole < ApplicationRecord
 
   def in_permissions?(privilege)
     raise ArgumentError, "Unknown privilege: #{privilege}" unless FLAGS.key?(privilege)
+
     computed_permissions & FLAGS[privilege] == FLAGS[privilege]
   end
 
@@ -172,6 +173,7 @@ class UserRole < ApplicationRecord
 
   def validate_own_role_edition
     return unless defined?(@current_account) && @current_account.user_role.id == id
+
     errors.add(:permissions_as_keys, :own_role) if permissions_changed?
     errors.add(:position, :own_role) if position_changed?
   end
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index dfaadf5cc..0ffbe068e 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: web_push_subscriptions
diff --git a/app/models/web/setting.rb b/app/models/web/setting.rb
index 99588d26c..3d5efe664 100644
--- a/app/models/web/setting.rb
+++ b/app/models/web/setting.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: web_settings
diff --git a/app/models/webauthn_credential.rb b/app/models/webauthn_credential.rb
index 48abfc1d4..4fa31ece5 100644
--- a/app/models/webauthn_credential.rb
+++ b/app/models/webauthn_credential.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 # == Schema Information
 #
 # Table name: webauthn_credentials
diff --git a/app/presenters/account_relationships_presenter.rb b/app/presenters/account_relationships_presenter.rb
index ab8bac412..5d2b5435d 100644
--- a/app/presenters/account_relationships_presenter.rb
+++ b/app/presenters/account_relationships_presenter.rb
@@ -70,16 +70,16 @@ class AccountRelationshipsPresenter
   def cache_uncached!
     @uncached_account_ids.each do |account_id|
       maps_for_account = {
-        following:       { account_id => following[account_id] },
-        followed_by:     { account_id => followed_by[account_id] },
-        blocking:        { account_id => blocking[account_id] },
-        blocked_by:      { account_id => blocked_by[account_id] },
-        muting:          { account_id => muting[account_id] },
-        requested:       { account_id => requested[account_id] },
-        requested_by:    { account_id => requested_by[account_id] },
+        following: { account_id => following[account_id] },
+        followed_by: { account_id => followed_by[account_id] },
+        blocking: { account_id => blocking[account_id] },
+        blocked_by: { account_id => blocked_by[account_id] },
+        muting: { account_id => muting[account_id] },
+        requested: { account_id => requested[account_id] },
+        requested_by: { account_id => requested_by[account_id] },
         domain_blocking: { account_id => domain_blocking[account_id] },
-        endorsed:        { account_id => endorsed[account_id] },
-        account_note:    { account_id => account_note[account_id] },
+        endorsed: { account_id => endorsed[account_id] },
+        account_note: { account_id => account_note[account_id] },
       }
 
       Rails.cache.write("relationship:#{@current_account_id}:#{account_id}", maps_for_account, expires_in: 1.day)
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 938ede6bb..2cac42e8d 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -82,7 +82,6 @@ class InitialStateSerializer < ActiveModel::Serializer
 
     store
   end
-  # rubocop:enable Metrics/AbcSize
 
   def compose
     store = {}
diff --git a/app/serializers/rest/preview_card_serializer.rb b/app/serializers/rest/preview_card_serializer.rb
index 66ff47d22..8413b23d8 100644
--- a/app/serializers/rest/preview_card_serializer.rb
+++ b/app/serializers/rest/preview_card_serializer.rb
@@ -3,7 +3,7 @@
 class REST::PreviewCardSerializer < ActiveModel::Serializer
   include RoutingHelper
 
-  attributes :url, :title, :description, :type,
+  attributes :url, :title, :description, :language, :type,
              :author_name, :author_url, :provider_name,
              :provider_url, :html, :width, :height,
              :image, :embed_url, :blurhash
diff --git a/app/serializers/rest/privacy_policy_serializer.rb b/app/serializers/rest/privacy_policy_serializer.rb
index f0572e714..57a67abf3 100644
--- a/app/serializers/rest/privacy_policy_serializer.rb
+++ b/app/serializers/rest/privacy_policy_serializer.rb
@@ -8,7 +8,7 @@ class REST::PrivacyPolicySerializer < ActiveModel::Serializer
   end
 
   def content
-    markdown.render(object.text % { domain: Rails.configuration.x.local_domain })
+    markdown.render(format(object.text, domain: Rails.configuration.x.local_domain))
   end
 
   private
diff --git a/app/services/activitypub/fetch_remote_actor_service.rb b/app/services/activitypub/fetch_remote_actor_service.rb
index e8992b845..c29570086 100644
--- a/app/services/activitypub/fetch_remote_actor_service.rb
+++ b/app/services/activitypub/fetch_remote_actor_service.rb
@@ -28,7 +28,7 @@ class ActivityPub::FetchRemoteActorService < BaseService
     raise Error, "Unsupported JSON-LD context for document #{uri}" unless supported_context?
     raise Error, "Unexpected object type for actor #{uri} (expected any of: #{SUPPORTED_TYPES})" unless expected_type?
     raise Error, "Actor #{uri} has moved to #{@json['movedTo']}" if break_on_redirect && @json['movedTo'].present?
-    raise Error, "Actor #{uri} has no 'preferredUsername', which is a requirement for Mastodon compatibility" unless @json['preferredUsername'].present?
+    raise Error, "Actor #{uri} has no 'preferredUsername', which is a requirement for Mastodon compatibility" if @json['preferredUsername'].blank?
 
     @uri      = @json['id']
     @username = @json['preferredUsername']
@@ -50,6 +50,7 @@ class ActivityPub::FetchRemoteActorService < BaseService
 
     if @username.casecmp(confirmed_username).zero? && @domain.casecmp(confirmed_domain).zero?
       raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.link('self', 'href') != @uri
+
       return
     end
 
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb
index aea80f078..ab0acf7f0 100644
--- a/app/services/activitypub/fetch_remote_status_service.rb
+++ b/app/services/activitypub/fetch_remote_status_service.rb
@@ -56,6 +56,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService
 
   def trustworthy_attribution?(uri, attributed_to)
     return false if uri.nil? || attributed_to.nil?
+
     Addressable::URI.parse(uri).normalized_host.casecmp(Addressable::URI.parse(attributed_to).normalized_host).zero?
   end
 
diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb
index 4128df9ca..3fe150ba2 100644
--- a/app/services/activitypub/fetch_replies_service.rb
+++ b/app/services/activitypub/fetch_replies_service.rb
@@ -36,6 +36,7 @@ class ActivityPub::FetchRepliesService < BaseService
     return collection_or_uri if collection_or_uri.is_a?(Hash)
     return unless @allow_synchronous_requests
     return if invalid_origin?(collection_or_uri)
+
     fetch_resource_without_id_validation(collection_or_uri, nil, true)
   end
 
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 2da9096c7..603e4cf48 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -226,6 +226,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def property_values
     return unless @json['attachment'].is_a?(Array)
+
     as_array(@json['attachment']).select { |attachment| attachment['type'] == 'PropertyValue' }.map { |attachment| attachment.slice('name', 'value') }
   end
 
@@ -289,6 +290,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
   def domain_block
     return @domain_block if defined?(@domain_block)
+
     @domain_block = DomainBlock.rule_for(@domain)
   end
 
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb
index 68ccffc97..a9d740211 100644
--- a/app/services/backup_service.rb
+++ b/app/services/backup_service.rb
@@ -53,7 +53,7 @@ class BackupService < BaseService
       end
     end
 
-    archive_filename = ['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(16)].join('-') + '.tar.gz'
+    archive_filename = "#{['archive', Time.now.utc.strftime('%Y%m%d%H%M%S'), SecureRandom.hex(16)].join('-')}.tar.gz"
 
     @backup.dump      = ActionDispatch::Http::UploadedFile.new(tempfile: tmp_file, filename: archive_filename)
     @backup.processed = true
@@ -86,14 +86,14 @@ class BackupService < BaseService
   def dump_actor!(tar)
     actor = serialize(account, ActivityPub::ActorSerializer)
 
-    actor[:icon][:url]  = 'avatar' + File.extname(actor[:icon][:url])  if actor[:icon]
-    actor[:image][:url] = 'header' + File.extname(actor[:image][:url]) if actor[:image]
+    actor[:icon][:url]  = "avatar#{File.extname(actor[:icon][:url])}"  if actor[:icon]
+    actor[:image][:url] = "header#{File.extname(actor[:image][:url])}" if actor[:image]
     actor[:outbox]      = 'outbox.json'
     actor[:likes]       = 'likes.json'
     actor[:bookmarks]   = 'bookmarks.json'
 
-    download_to_tar(tar, account.avatar, 'avatar' + File.extname(account.avatar.path)) if account.avatar.exists?
-    download_to_tar(tar, account.header, 'header' + File.extname(account.header.path)) if account.header.exists?
+    download_to_tar(tar, account.avatar, "avatar#{File.extname(account.avatar.path)}") if account.avatar.exists?
+    download_to_tar(tar, account.header, "header#{File.extname(account.header.path)}") if account.header.exists?
 
     json = Oj.dump(actor)
 
diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb
index dc7fe8855..6fdc92a17 100644
--- a/app/services/favourite_service.rb
+++ b/app/services/favourite_service.rb
@@ -40,6 +40,7 @@ class FavouriteService < BaseService
   def bump_potential_friendship(account, status)
     ActivityTracker.increment('activity:interactions')
     return if account.following?(status.account_id)
+
     PotentialFriendshipTracker.record(account.id, status.account_id, :favourite)
   end
 
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index d5fa9af54..8d07958b7 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -45,7 +45,7 @@ class FetchLinkCardService < BaseService
   def html
     return @html if defined?(@html)
 
-    Request.new(:get, @url).add_headers('Accept' => 'text/html', 'User-Agent' => Mastodon::Version.user_agent + ' Bot').perform do |res|
+    Request.new(:get, @url).add_headers('Accept' => 'text/html', 'User-Agent' => "#{Mastodon::Version.user_agent} Bot").perform do |res|
       # We follow redirects, and ideally we want to save the preview card for
       # the destination URL and not any link shortener in-between, so here
       # we set the URL to the one of the last response in the redirect chain
diff --git a/app/services/import_service.rb b/app/services/import_service.rb
index 2f48abc36..7a68e4ca3 100644
--- a/app/services/import_service.rb
+++ b/app/services/import_service.rb
@@ -114,7 +114,7 @@ class ImportService < BaseService
       status || ActivityPub::FetchRemoteStatusService.new.call(uri)
     rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::UnexpectedResponseError
       nil
-    rescue StandardError => e
+    rescue => e
       Rails.logger.warn "Unexpected error when importing bookmark: #{e}"
       nil
     end
diff --git a/app/services/keys/claim_service.rb b/app/services/keys/claim_service.rb
index 0451c3cb1..ebce9cce7 100644
--- a/app/services/keys/claim_service.rb
+++ b/app/services/keys/claim_service.rb
@@ -9,10 +9,10 @@ class Keys::ClaimService < BaseService
 
     def initialize(account, device_id, key_attributes = {})
       super(
-        account:   account,
+        account: account,
         device_id: device_id,
-        key_id:    key_attributes[:key_id],
-        key:       key_attributes[:key],
+        key_id: key_attributes[:key_id],
+        key: key_attributes[:key],
         signature: key_attributes[:signature],
       )
     end
diff --git a/app/services/keys/query_service.rb b/app/services/keys/query_service.rb
index 404854c9f..14c9d9205 100644
--- a/app/services/keys/query_service.rb
+++ b/app/services/keys/query_service.rb
@@ -23,9 +23,9 @@ class Keys::QueryService < BaseService
 
     def initialize(attributes = {})
       super(
-        device_id:       attributes[:device_id],
-        name:            attributes[:name],
-        identity_key:    attributes[:identity_key],
+        device_id: attributes[:device_id],
+        name: attributes[:name],
+        identity_key: attributes[:identity_key],
         fingerprint_key: attributes[:fingerprint_key],
       )
       @claim_url = attributes[:claim_url]
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index c7454fc60..4c7acbcac 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -31,6 +31,7 @@ class NotifyService < BaseService
 
   def following_sender?
     return @following_sender if defined?(@following_sender)
+
     @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
   end
 
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 77527f2db..bca3b3ff7 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -95,6 +95,7 @@ class PostStatusService < BaseService
 
   def safeguard_mentions!(status)
     return if @options[:allowed_mentions].nil?
+
     expected_account_ids = @options[:allowed_mentions].map(&:to_i)
 
     unexpected_accounts = status.mentions.map(&:account).to_a.reject { |mentioned_account| expected_account_ids.include?(mentioned_account.id) }
@@ -184,8 +185,10 @@ class PostStatusService < BaseService
 
   def bump_potential_friendship!
     return if !@status.reply? || @account.id == @status.in_reply_to_account_id
+
     ActivityTracker.increment('activity:interactions')
     return if @account.following?(@status.in_reply_to_account_id)
+
     PotentialFriendshipTracker.record(@account.id, @status.in_reply_to_account_id, :reply)
   end
 
diff --git a/app/services/vote_service.rb b/app/services/vote_service.rb
index 114ec285c..9ebf5a98d 100644
--- a/app/services/vote_service.rb
+++ b/app/services/vote_service.rb
@@ -44,11 +44,13 @@ class VoteService < BaseService
 
   def distribute_poll!
     return if @poll.hide_totals?
+
     ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, @poll.status.id)
   end
 
   def queue_final_poll_check!
     return unless @poll.expires?
+
     PollExpirationNotifyWorker.perform_at(@poll.expires_at + 5.minutes, @poll.id)
   end
 
diff --git a/app/validators/follow_limit_validator.rb b/app/validators/follow_limit_validator.rb
index 409bf0176..c619cb9a3 100644
--- a/app/validators/follow_limit_validator.rb
+++ b/app/validators/follow_limit_validator.rb
@@ -6,6 +6,7 @@ class FollowLimitValidator < ActiveModel::Validator
 
   def validate(follow)
     return if follow.account.nil? || !follow.account.local?
+
     follow.errors.add(:base, I18n.t('users.follow_limit_reached', limit: self.class.limit_for_account(follow.account))) if limit_reached?(follow.account)
   end
 
diff --git a/app/validators/html_validator.rb b/app/validators/html_validator.rb
deleted file mode 100644
index b85b9769f..000000000
--- a/app/validators/html_validator.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class HtmlValidator < ActiveModel::EachValidator
-  ERROR_RE = /Opening and ending tag mismatch|Unexpected end tag/
-
-  def validate_each(record, attribute, value)
-    return if value.blank?
-
-    errors = html_errors(value)
-
-    record.errors.add(attribute, I18n.t('html_validator.invalid_markup', error: errors.first.to_s)) unless errors.empty?
-  end
-
-  private
-
-  def html_errors(str)
-    fragment = Nokogiri::HTML.fragment(options[:wrap_with] ? "<#{options[:wrap_with]}>#{str}</#{options[:wrap_with]}>" : str)
-    fragment.errors.select { |error| ERROR_RE.match?(error.message) }
-  end
-end
diff --git a/app/validators/unreserved_username_validator.rb b/app/validators/unreserved_username_validator.rb
index 974f3ba62..f82f4b91d 100644
--- a/app/validators/unreserved_username_validator.rb
+++ b/app/validators/unreserved_username_validator.rb
@@ -13,12 +13,14 @@ class UnreservedUsernameValidator < ActiveModel::Validator
 
   def pam_controlled?
     return false unless Devise.pam_authentication && Devise.pam_controlled_service
+
     Rpam2.account(Devise.pam_controlled_service, @username).present?
   end
 
   def reserved_username?
     return true if pam_controlled?
     return false unless Setting.reserved_usernames
+
     Setting.reserved_usernames.include?(@username.downcase)
   end
 end
diff --git a/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb b/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb
index bd92fe32c..f237f1dc9 100644
--- a/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb
+++ b/app/workers/scheduler/accounts_statuses_cleanup_scheduler.rb
@@ -7,7 +7,7 @@ class Scheduler::AccountsStatusesCleanupScheduler
   # This limit is mostly to be nice to the fediverse at large and not
   # generate too much traffic.
   # This also helps limiting the running time of the scheduler itself.
-  MAX_BUDGET         = 50
+  MAX_BUDGET         = 150
 
   # This is an attempt to spread the load across instances, as various
   # accounts are likely to have various followers.
@@ -15,28 +15,22 @@ class Scheduler::AccountsStatusesCleanupScheduler
 
   # This is an attempt to limit the workload generated by status removal
   # jobs to something the particular instance can handle.
-  PER_THREAD_BUDGET  = 5
+  PER_THREAD_BUDGET  = 6
 
   # Those avoid loading an instance that is already under load
-  MAX_DEFAULT_SIZE    = 2
+  MAX_DEFAULT_SIZE    = 200
   MAX_DEFAULT_LATENCY = 5
-  MAX_PUSH_SIZE       = 5
+  MAX_PUSH_SIZE       = 500
   MAX_PUSH_LATENCY    = 10
+
   # 'pull' queue has lower priority jobs, and it's unlikely that pushing
   # deletes would cause much issues with this queue if it didn't cause issues
   # with default and push. Yet, do not enqueue deletes if the instance is
   # lagging behind too much.
-  MAX_PULL_SIZE       = 500
-  MAX_PULL_LATENCY    = 300
-
-  # This is less of an issue in general, but deleting old statuses is likely
-  # to cause delivery errors, and thus increase the number of jobs to be retried.
-  # This doesn't directly translate to load, but connection errors and a high
-  # number of dead instances may lead to this spiraling out of control if
-  # unchecked.
-  MAX_RETRY_SIZE = 50_000
+  MAX_PULL_SIZE       = 10_000
+  MAX_PULL_LATENCY    = 5.minutes.to_i
 
-  sidekiq_options retry: 0, lock: :until_executed
+  sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i
 
   def perform
     return if under_load?
@@ -62,17 +56,17 @@ class Scheduler::AccountsStatusesCleanupScheduler
       # The idea here is to loop through all policies at least once until the budget is exhausted
       # and start back after the last processed account otherwise
       break if budget.zero? || (num_processed_accounts.zero? && first_policy_id.nil?)
+
       first_policy_id = nil
     end
   end
 
   def compute_budget
-    threads = Sidekiq::ProcessSet.new.select { |x| x['queues'].include?('push') }.map { |x| x['concurrency'] }.sum
+    threads = Sidekiq::ProcessSet.new.select { |x| x['queues'].include?('push') }.pluck('concurrency').sum
     [PER_THREAD_BUDGET * threads, MAX_BUDGET].min
   end
 
   def under_load?
-    return true if Sidekiq::Stats.new.retry_size > MAX_RETRY_SIZE
     queue_under_load?('default', MAX_DEFAULT_SIZE, MAX_DEFAULT_LATENCY) || queue_under_load?('push', MAX_PUSH_SIZE, MAX_PUSH_LATENCY) || queue_under_load?('pull', MAX_PULL_SIZE, MAX_PULL_LATENCY)
   end
 
diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb
index 1ed5bb9e0..7e9691aab 100644
--- a/app/workers/web/push_notification_worker.rb
+++ b/app/workers/web/push_notification_worker.rb
@@ -22,13 +22,13 @@ class Web::PushNotificationWorker
       request = Request.new(:post, @subscription.endpoint, body: payload.fetch(:ciphertext), http_client: http_client)
 
       request.add_headers(
-        'Content-Type'     => 'application/octet-stream',
-        'Ttl'              => TTL,
-        'Urgency'          => URGENCY,
+        'Content-Type' => 'application/octet-stream',
+        'Ttl' => TTL,
+        'Urgency' => URGENCY,
         'Content-Encoding' => 'aesgcm',
-        'Encryption'       => "salt=#{Webpush.encode64(payload.fetch(:salt)).delete('=')}",
-        'Crypto-Key'       => "dh=#{Webpush.encode64(payload.fetch(:server_public_key)).delete('=')};#{@subscription.crypto_key_header}",
-        'Authorization'    => @subscription.authorization_header
+        'Encryption' => "salt=#{Webpush.encode64(payload.fetch(:salt)).delete('=')}",
+        'Crypto-Key' => "dh=#{Webpush.encode64(payload.fetch(:server_public_key)).delete('=')};#{@subscription.crypto_key_header}",
+        'Authorization' => @subscription.authorization_header
       )
 
       request.perform do |response|