about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/helpers/application_helper.rb15
-rw-r--r--app/javascript/core/admin.js7
-rw-r--r--app/javascript/mastodon/components/extended_video_player.js1
-rw-r--r--app/javascript/mastodon/components/media_gallery.js1
-rw-r--r--app/javascript/mastodon/components/status.js1
-rw-r--r--app/javascript/mastodon/containers/status_container.js2
-rw-r--r--app/javascript/mastodon/features/account/components/header.js4
-rw-r--r--app/javascript/mastodon/features/compose/components/upload_button.js2
-rw-r--r--app/javascript/mastodon/features/report/components/status_check_box.js1
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js1
-rw-r--r--app/javascript/mastodon/features/status/index.js2
-rw-r--r--app/javascript/mastodon/features/video/index.js1
-rw-r--r--app/javascript/mastodon/locales/ar.json2
-rw-r--r--app/javascript/mastodon/locales/ast.json2
-rw-r--r--app/javascript/mastodon/locales/bg.json2
-rw-r--r--app/javascript/mastodon/locales/ca.json2
-rw-r--r--app/javascript/mastodon/locales/co.json2
-rw-r--r--app/javascript/mastodon/locales/cs.json4
-rw-r--r--app/javascript/mastodon/locales/da.json16
-rw-r--r--app/javascript/mastodon/locales/de.json2
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json12
-rw-r--r--app/javascript/mastodon/locales/el.json2
-rw-r--r--app/javascript/mastodon/locales/en.json6
-rw-r--r--app/javascript/mastodon/locales/eo.json2
-rw-r--r--app/javascript/mastodon/locales/es.json2
-rw-r--r--app/javascript/mastodon/locales/eu.json2
-rw-r--r--app/javascript/mastodon/locales/fa.json2
-rw-r--r--app/javascript/mastodon/locales/fi.json2
-rw-r--r--app/javascript/mastodon/locales/fr.json6
-rw-r--r--app/javascript/mastodon/locales/gl.json2
-rw-r--r--app/javascript/mastodon/locales/he.json2
-rw-r--r--app/javascript/mastodon/locales/hr.json2
-rw-r--r--app/javascript/mastodon/locales/hu.json2
-rw-r--r--app/javascript/mastodon/locales/hy.json2
-rw-r--r--app/javascript/mastodon/locales/id.json2
-rw-r--r--app/javascript/mastodon/locales/io.json2
-rw-r--r--app/javascript/mastodon/locales/it.json2
-rw-r--r--app/javascript/mastodon/locales/ja.json4
-rw-r--r--app/javascript/mastodon/locales/ka.json2
-rw-r--r--app/javascript/mastodon/locales/ko.json8
-rw-r--r--app/javascript/mastodon/locales/nl.json2
-rw-r--r--app/javascript/mastodon/locales/no.json2
-rw-r--r--app/javascript/mastodon/locales/oc.json10
-rw-r--r--app/javascript/mastodon/locales/pl.json2
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json8
-rw-r--r--app/javascript/mastodon/locales/pt.json2
-rw-r--r--app/javascript/mastodon/locales/ru.json2
-rw-r--r--app/javascript/mastodon/locales/sk.json2
-rw-r--r--app/javascript/mastodon/locales/sl.json2
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json2
-rw-r--r--app/javascript/mastodon/locales/sr.json2
-rw-r--r--app/javascript/mastodon/locales/sv.json2
-rw-r--r--app/javascript/mastodon/locales/te.json2
-rw-r--r--app/javascript/mastodon/locales/th.json2
-rw-r--r--app/javascript/mastodon/locales/tr.json2
-rw-r--r--app/javascript/mastodon/locales/uk.json2
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json2
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json2
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json2
-rw-r--r--app/javascript/packs/public.js5
-rw-r--r--app/lib/activitypub/activity.rb4
-rw-r--r--app/lib/activitypub/activity/create.rb16
-rw-r--r--app/views/admin/reports/_status.html.haml2
-rwxr-xr-xapp/views/layouts/application.html.haml6
-rw-r--r--app/views/stream_entries/_detailed_status.html.haml2
-rw-r--r--app/views/stream_entries/_simple_status.html.haml2
-rw-r--r--app/workers/maintenance/destroy_media_worker.rb2
-rw-r--r--app/workers/maintenance/redownload_account_media_worker.rb2
-rw-r--r--app/workers/maintenance/uncache_media_worker.rb2
-rw-r--r--app/workers/scheduler/backup_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/doorkeeper_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/email_scheduler.rb2
-rw-r--r--app/workers/scheduler/feed_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/ip_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/media_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/subscriptions_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/subscriptions_scheduler.rb2
-rw-r--r--app/workers/scheduler/user_cleanup_scheduler.rb2
78 files changed, 192 insertions, 57 deletions
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 327901e4e..cf6f8aa70 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -27,11 +27,6 @@ module ApplicationHelper
     Setting.open_deletion
   end
 
-  def add_rtl_body_class(other_classes)
-    other_classes = "#{other_classes} rtl" if locale_direction == 'rtl'
-    other_classes
-  end
-
   def locale_direction
     if [:ar, :fa, :he].include?(I18n.locale)
       'rtl'
@@ -77,4 +72,14 @@ module ApplicationHelper
   def react_component(name, props = {})
     content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
   end
+
+  def body_classes
+    output = (@body_classes || '').split(' ')
+    output << "flavour-#{current_flavour.parameterize}"
+    output << "skin-#{current_skin.parameterize}"
+    output << 'system-font' if current_account&.user&.setting_system_font_ui
+    output << current_account&.user&.setting_reduce_motion ? 'reduce-motion' : 'no-reduce-motion'
+    output << 'rtl' if locale_direction == 'rtl'
+    output.reject(&:blank?).join(' ')
+  end
 end
diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js
index 28f27fbc6..0c26dc18d 100644
--- a/app/javascript/core/admin.js
+++ b/app/javascript/core/admin.js
@@ -41,3 +41,10 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => {
     element.click();
   });
 });
+
+delegate(document, '#domain_block_severity', 'change', ({ target }) => {
+  const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media');
+  if (rejectMediaDiv) {
+    rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
+  }
+});
diff --git a/app/javascript/mastodon/components/extended_video_player.js b/app/javascript/mastodon/components/extended_video_player.js
index 9e2f6835a..009c0d559 100644
--- a/app/javascript/mastodon/components/extended_video_player.js
+++ b/app/javascript/mastodon/components/extended_video_player.js
@@ -50,6 +50,7 @@ export default class ExtendedVideoPlayer extends React.PureComponent {
           role='button'
           tabIndex='0'
           aria-label={alt}
+          title={alt}
           muted={muted}
           controls={controls}
           loop={!controls}
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index 63bc4a59b..6e1310cd6 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -154,6 +154,7 @@ class Item extends React.PureComponent {
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
+            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onClick={this.handleClick}
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 9a3fd3576..9809a9a32 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -230,6 +230,7 @@ export default class Status extends ImmutablePureComponent {
               <Component
                 preview={video.get('preview_url')}
                 src={video.get('url')}
+                alt={video.get('description')}
                 width={239}
                 height={110}
                 inline
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index ed375c3e5..bbc0d5e96 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -34,7 +34,7 @@ const messages = defineMessages({
   deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
   deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
   redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
-  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' },
+  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
 });
 
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index dd2cd406b..eb9236aeb 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -104,7 +104,9 @@ export default class Header extends ImmutablePureComponent {
     }
 
     if (me !== account.get('id')) {
-      if (account.getIn(['relationship', 'requested'])) {
+      if (!account.get('relationship')) { // Wait until the relationship is loaded
+        actionBtn = '';
+      } else if (account.getIn(['relationship', 'requested'])) {
         actionBtn = (
           <div className='account--action-button'>
             <IconButton size={26} active icon='hourglass' title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js
index 70b28a2ba..2f38f5148 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.js
@@ -7,7 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 
 const messages = defineMessages({
-  upload: { id: 'upload_button.label', defaultMessage: 'Add media' },
+  upload: { id: 'upload_button.label', defaultMessage: 'Add media (JPEG, PNG, GIF, WebM, MP4)' },
 });
 
 const makeMapStateToProps = () => {
diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.js
index 9ff75a082..2552d94d8 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.js
@@ -36,6 +36,7 @@ export default class StatusCheckBox extends React.PureComponent {
               <Component
                 preview={video.get('preview_url')}
                 src={video.get('url')}
+                alt={video.get('description')}
                 width={239}
                 height={110}
                 inline
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 12ffb7579..b4bbda161 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -60,6 +60,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
           <Video
             preview={video.get('preview_url')}
             src={video.get('url')}
+            alt={video.get('description')}
             width={300}
             height={150}
             inline
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index 45e36e3eb..48931b2d6 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -49,7 +49,7 @@ const messages = defineMessages({
   deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
   deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
   redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
-  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' },
+  redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
   blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
   revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
   hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 55ea32acb..52b395f88 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -315,6 +315,7 @@ export default class Video extends React.PureComponent {
           role='button'
           tabIndex='0'
           aria-label={alt}
+          title={alt}
           width={width}
           height={height}
           onClick={this.togglePlay}
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index b38dbcf73..bf0701094 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "الحسابات المحجوبة",
   "navigation_bar.community_timeline": "الخيط العام المحلي",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "الرسائل المباشِرة",
   "navigation_bar.discover": "إكتشف",
   "navigation_bar.domain_blocks": "النطاقات المخفية",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "إلغاء الترقية",
   "status.cannot_reblog": "تعذرت ترقية هذا المنشور",
   "status.delete": "إحذف",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "رسالة خاصة إلى @{name}",
   "status.embed": "إدماج",
   "status.favourite": "أضف إلى المفضلة",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index 96e3a14d9..a6d951626 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blocked users",
   "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index b41045fb8..ae8222db5 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blocked users",
   "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Изтриване",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Предпочитани",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 7378b703b..216e5d0f2 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Usuaris bloquejats",
   "navigation_bar.community_timeline": "Línia de temps Local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Missatges directes",
   "navigation_bar.discover": "Descobreix",
   "navigation_bar.domain_blocks": "Dominis ocults",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Desfer l'impuls",
   "status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
   "status.delete": "Esborrar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Missatge directe @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorit",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 717397d41..91cdb541c 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Utilizatori bluccati",
   "navigation_bar.community_timeline": "Linea pubblica lucale",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Missaghji diretti",
   "navigation_bar.discover": "Scopre",
   "navigation_bar.domain_blocks": "Duminii piattati",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Ùn sparte più",
   "status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu",
   "status.delete": "Toglie",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Mandà un missaghju @{name}",
   "status.embed": "Integrà",
   "status.favourite": "Aghjunghje à i favuriti",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index b71179ca0..2b19628a5 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -162,9 +162,10 @@
   "missing_indicator.label": "Nenalezeno",
   "missing_indicator.sublabel": "Tento zdroj se nepodařilo najít",
   "mute_modal.hide_notifications": "Skrýt oznámení před tímto uživatelem?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Mobilní aplikace",
   "navigation_bar.blocks": "Blokovaní uživatelé",
   "navigation_bar.community_timeline": "Místní časová osa",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Přímé zprávy",
   "navigation_bar.discover": "Objevujte",
   "navigation_bar.domain_blocks": "Skryté domény",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Zrušit boost",
   "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
   "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Poslat přímou zprávu uživateli @{name}",
   "status.embed": "Vložit",
   "status.favourite": "Oblíbit",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 4c38b8eb2..92a09602c 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -20,7 +20,7 @@
   "account.mute_notifications": "Dæmp notifikationer fra @{name}",
   "account.muted": "Dæmpet",
   "account.posts": "Trut",
-  "account.posts_with_replies": "Trut samt svar",
+  "account.posts_with_replies": "Trut og svar",
   "account.report": "Rapporter @{name}",
   "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
   "account.share": "Del @{name}s profil",
@@ -51,7 +51,7 @@
   "column.lists": "Lister",
   "column.mutes": "Dæmpede brugere",
   "column.notifications": "Notifikationer",
-  "column.pins": "Fastgjorte toots",
+  "column.pins": "Fastgjorte trut",
   "column.public": "Fælles tidslinje",
   "column_back_button.label": "Tilbage",
   "column_header.hide_settings": "Skjul indstillinger",
@@ -61,7 +61,7 @@
   "column_header.show_settings": "Vis indstillinger",
   "column_header.unpin": "Fastgør ikke længere",
   "column_subheading.settings": "Indstillinger",
-  "community.column_settings.media_only": "Kun multimedier",
+  "community.column_settings.media_only": "Kun medie",
   "compose_form.direct_message_warning": "Dette trut vil kun blive sendt til de nævnte brugere.",
   "compose_form.direct_message_warning_learn_more": "Lær mere",
   "compose_form.hashtag_warning": "Dette trut vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige trut kan blive vist under søgninger med hashtags.",
@@ -70,8 +70,8 @@
   "compose_form.placeholder": "Hvad har du på hjertet?",
   "compose_form.publish": "Trut",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Multimedie er markeret som værende følsomt",
-  "compose_form.sensitive.unmarked": "Multimediet er ikke markeret som værende følsomt",
+  "compose_form.sensitive.marked": "Medie er markeret som værende følsomt",
+  "compose_form.sensitive.unmarked": "Mediet er ikke markeret som værende følsomt",
   "compose_form.spoiler.marked": "Teksten er skjult bag en advarsel",
   "compose_form.spoiler.unmarked": "Teksten er ikke skjult",
   "compose_form.spoiler_placeholder": "Skriv din advarsel her",
@@ -162,9 +162,10 @@
   "missing_indicator.label": "Ikke fundet",
   "missing_indicator.sublabel": "Denne ressource kunne ikke blive fundet",
   "mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Mobil apps",
   "navigation_bar.blocks": "Blokerede brugere",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direkte beskeder",
   "navigation_bar.discover": "Opdag",
   "navigation_bar.domain_blocks": "Skjulte domæner",
@@ -258,12 +259,13 @@
   "status.cancel_reblog_private": "Fremhæv ikke længere",
   "status.cannot_reblog": "Denne post kan ikke fremhæves",
   "status.delete": "Slet",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Send direkte besked til @{name}",
   "status.embed": "Indlejre",
   "status.favourite": "Favorit",
   "status.filtered": "Filtreret",
   "status.load_more": "Indlæs mere",
-  "status.media_hidden": "Multimedia skjult",
+  "status.media_hidden": "Medie skjult",
   "status.mention": "Nævn @{name}",
   "status.more": "Mere",
   "status.mute": "Dæmp @{name}",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 3427b322b..e6139b218 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blockierte Profile",
   "navigation_bar.community_timeline": "Lokale Zeitleiste",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direktnachrichten",
   "navigation_bar.discover": "Entdecken",
   "navigation_bar.domain_blocks": "Versteckte Domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Nicht mehr teilen",
   "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
   "status.delete": "Löschen",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direktnachricht @{name}",
   "status.embed": "Einbetten",
   "status.favourite": "Favorisieren",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 2d836be90..98974bf47 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -390,7 +390,7 @@
         "id": "confirmations.redraft.confirm"
       },
       {
-        "defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+        "defaultMessage": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
         "id": "confirmations.redraft.message"
       },
       {
@@ -1019,6 +1019,10 @@
       {
         "defaultMessage": "Logout",
         "id": "navigation_bar.logout"
+      },
+      {
+        "defaultMessage": "Compose new toot",
+        "id": "navigation_bar.compose"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/index.json"
@@ -1636,7 +1640,7 @@
         "id": "confirmations.redraft.confirm"
       },
       {
-        "defaultMessage": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+        "defaultMessage": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
         "id": "confirmations.redraft.message"
       },
       {
@@ -1652,6 +1656,10 @@
         "id": "status.show_less_all"
       },
       {
+        "defaultMessage": "Detailed conversation view",
+        "id": "status.detailed_status"
+      },
+      {
         "defaultMessage": "Are you sure you want to block {name}?",
         "id": "confirmations.block.message"
       }
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 76a003f65..fad0aa9bc 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Αποκλεισμένοι χρήστες",
   "navigation_bar.community_timeline": "Τοπική ροή",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Προσωπικά μηνύματα",
   "navigation_bar.discover": "Ανακάλυψη",
   "navigation_bar.domain_blocks": "Κρυμμένοι τομείς",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Ακύρωσε την προώθηση",
   "status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
   "status.delete": "Διαγραφή",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Προσωπικό μήνυμα προς @{name}",
   "status.embed": "Ενσωμάτωσε",
   "status.favourite": "Σημείωσε ως αγαπημένο",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 27b2cb45e..52d501780 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -91,7 +91,7 @@
   "confirmations.mute.confirm": "Mute",
   "confirmations.mute.message": "Are you sure you want to mute {name}?",
   "confirmations.redraft.confirm": "Delete & redraft",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
   "confirmations.unfollow.confirm": "Unfollow",
   "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
   "embed.instructions": "Embed this status on your website by copying the code below.",
@@ -169,6 +169,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blocked users",
   "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -263,6 +264,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
@@ -300,7 +302,7 @@
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media",
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4)",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
   "upload_form.undo": "Delete",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index f4c316441..cfeef55bb 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokitaj uzantoj",
   "navigation_bar.community_timeline": "Loka tempolinio",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Rektaj mesaĝoj",
   "navigation_bar.discover": "Esplori",
   "navigation_bar.domain_blocks": "Kaŝitaj domajnoj",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Eksdiskonigi",
   "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
   "status.delete": "Forigi",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Rekte mesaĝi @{name}",
   "status.embed": "Enkorpigi",
   "status.favourite": "Stelumi",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index b17e1411e..7e835cd65 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Usuarios bloqueados",
   "navigation_bar.community_timeline": "Historia local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Este toot no puede retootearse",
   "status.delete": "Borrar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Incrustado",
   "status.favourite": "Favorito",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index ec27fe425..c5cf627e8 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokeatutako erabiltzaileak",
   "navigation_bar.community_timeline": "Denbora-lerro lokala",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Mezu zuzenak",
   "navigation_bar.discover": "Aurkitu",
   "navigation_bar.domain_blocks": "Ezkutatutako domeinuak",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Kendu bultzada",
   "status.cannot_reblog": "Mezu honi ezin zaio bultzada eman",
   "status.delete": "Ezabatu",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Mezu zuzena @{name}(r)i",
   "status.embed": "Txertatu",
   "status.favourite": "Gogokoa",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 03c6bb7ce..55615baa3 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "کاربران مسدودشده",
   "navigation_bar.community_timeline": "نوشته‌های محلی",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "پیغام‌های خصوصی",
   "navigation_bar.discover": "گشت و گذار",
   "navigation_bar.domain_blocks": "دامین‌های پنهان‌شده",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "حذف بازبوق",
   "status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",
   "status.delete": "پاک‌کردن",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "پیغام مستقیم به @{name}",
   "status.embed": "جاگذاری",
   "status.favourite": "پسندیدن",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index 0861c42fc..fcf08a9b9 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Estetyt käyttäjät",
   "navigation_bar.community_timeline": "Paikallinen aikajana",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Viestit",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Piilotetut verkkotunnukset",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Peru buustaus",
   "status.cannot_reblog": "Tätä julkaisua ei voi buustata",
   "status.delete": "Poista",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Viesti käyttäjälle @{name}",
   "status.embed": "Upota",
   "status.favourite": "Tykkää",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 835b1af65..79d318d1b 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -87,7 +87,7 @@
   "confirmations.mute.confirm": "Masquer",
   "confirmations.mute.message": "Confirmez-vous le masquage de {name} ?",
   "confirmations.redraft.confirm": "Effacer et ré-écrire",
-  "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire ? Vous perdrez toutes ses réponses, ses repartages et ses mises en favori.",
+  "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire ? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
   "confirmations.unfollow.confirm": "Ne plus suivre",
   "confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name} ?",
   "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.",
@@ -162,9 +162,10 @@
   "missing_indicator.label": "Non trouvé",
   "missing_indicator.sublabel": "Ressource introuvable",
   "mute_modal.hide_notifications": "Masquer les notifications de cette personne ?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Applications mobiles",
   "navigation_bar.blocks": "Comptes bloqués",
   "navigation_bar.community_timeline": "Fil public local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Messages directs",
   "navigation_bar.discover": "Découvrir",
   "navigation_bar.domain_blocks": "Domaines cachés",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Dé-booster",
   "status.cannot_reblog": "Cette publication ne peut être boostée",
   "status.delete": "Effacer",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Envoyer un message direct à @{name}",
   "status.embed": "Intégrer",
   "status.favourite": "Ajouter aux favoris",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index d83b11d74..e8b598263 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Usuarias bloqueadas",
   "navigation_bar.community_timeline": "Liña temporal local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Mensaxes directas",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Dominios agochados",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Non promover",
   "status.cannot_reblog": "Esta mensaxe non pode ser promovida",
   "status.delete": "Eliminar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Mensaxe directa @{name}",
   "status.embed": "Incrustar",
   "status.favourite": "Favorita",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index d20adce11..5f5e396b4 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "חסימות",
   "navigation_bar.community_timeline": "ציר זמן מקומי",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "לא ניתן להדהד הודעה זו",
   "status.delete": "מחיקה",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "הטמעה",
   "status.favourite": "חיבוב",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index e6ce3359d..d0bea84d6 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokirani korisnici",
   "navigation_bar.community_timeline": "Lokalni timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ovaj post ne može biti boostan",
   "status.delete": "Obriši",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Označi omiljenim",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 80c3a1de8..4dae46bb1 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Tiltott felhasználók",
   "navigation_bar.community_timeline": "Helyi idővonal",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ezen státusz nem rebloggolható",
   "status.delete": "Törlés",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Beágyaz",
   "status.favourite": "Kedvenc",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index e5ad93fd8..e9f60b727 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Արգելափակված օգտատերեր",
   "navigation_bar.community_timeline": "Տեղական հոսք",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Այս թութը չի կարող տարածվել",
   "status.delete": "Ջնջել",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Ներդնել",
   "status.favourite": "Հավանել",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 010d35b73..1dd30f2f7 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Pengguna diblokir",
   "navigation_bar.community_timeline": "Linimasa lokal",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Hapus",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Difavoritkan",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index 06e6b02d7..385313df3 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokusita uzeri",
   "navigation_bar.community_timeline": "Lokala tempolineo",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Efacar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorizar",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index c9ac57c74..0f460b3f6 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Utenti bloccati",
   "navigation_bar.community_timeline": "Timeline locale",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Messaggi diretti",
   "navigation_bar.discover": "Scopri",
   "navigation_bar.domain_blocks": "Domini nascosti",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Annulla condivisione",
   "status.cannot_reblog": "Questo post non può essere condiviso",
   "status.delete": "Elimina",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Messaggio diretto @{name}",
   "status.embed": "Incorpora",
   "status.favourite": "Apprezzato",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index d8ec6e934..dd755f1ca 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -166,9 +166,10 @@
   "missing_indicator.label": "見つかりません",
   "missing_indicator.sublabel": "見つかりませんでした",
   "mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "アプリ",
   "navigation_bar.blocks": "ブロックしたユーザー",
   "navigation_bar.community_timeline": "ローカルタイムライン",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "ダイレクトメッセージ",
   "navigation_bar.discover": "見つける",
   "navigation_bar.domain_blocks": "非表示にしたドメイン",
@@ -263,6 +264,7 @@
   "status.cancel_reblog_private": "ブースト解除",
   "status.cannot_reblog": "この投稿はブーストできません",
   "status.delete": "削除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "@{name}さんにダイレクトメッセージ",
   "status.embed": "埋め込み",
   "status.favourite": "お気に入り",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index d2a915c60..1ded84143 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
   "navigation_bar.community_timeline": "ლოკალური თაიმლაინი",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "პირდაპირი წერილები",
   "navigation_bar.discover": "აღმოაჩინე",
   "navigation_bar.domain_blocks": "დამალული დომენები",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "ბუსტის მოშორება",
   "status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება",
   "status.delete": "წაშლა",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "პირდაპირი წერილი @{name}-ს",
   "status.embed": "ჩართვა",
   "status.favourite": "ფავორიტი",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 18150d17c..dd9079878 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -7,7 +7,7 @@
   "account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.",
   "account.domain_blocked": "도메인 숨겨짐",
   "account.edit_profile": "프로필 편집",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "프로필에 나타내기",
   "account.follow": "팔로우",
   "account.followers": "팔로워",
   "account.follows": "팔로우",
@@ -27,7 +27,7 @@
   "account.show_reblogs": "@{name}의 부스트 보기",
   "account.unblock": "차단 해제",
   "account.unblock_domain": "{domain} 숨김 해제",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "프로필에 나타내지 않기",
   "account.unfollow": "팔로우 해제",
   "account.unmute": "뮤트 해제",
   "account.unmute_notifications": "@{name}의 알림 뮤트 해제",
@@ -162,9 +162,10 @@
   "missing_indicator.label": "찾을 수 없습니다",
   "missing_indicator.sublabel": "이 리소스를 찾을 수 없었습니다",
   "mute_modal.hide_notifications": "이 사용자로부터의 알림을 뮤트하시겠습니까?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "모바일 앱",
   "navigation_bar.blocks": "차단한 사용자",
   "navigation_bar.community_timeline": "로컬 타임라인",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "다이렉트 메시지",
   "navigation_bar.discover": "발견하기",
   "navigation_bar.domain_blocks": "숨겨진 도메인",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "부스트 취소",
   "status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
   "status.delete": "삭제",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "@{name}에게 다이렉트 메시지",
   "status.embed": "공유하기",
   "status.favourite": "즐겨찾기",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 72ffbdc6e..7259ba49a 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Geblokkeerde gebruikers",
   "navigation_bar.community_timeline": "Lokale tijdlijn",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Directe berichten",
   "navigation_bar.discover": "Ontdekken",
   "navigation_bar.domain_blocks": "Verborgen domeinen",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Niet langer boosten",
   "status.cannot_reblog": "Deze toot kan niet geboost worden",
   "status.delete": "Verwijderen",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Directe toot @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favoriet",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 3e9612edb..520c9ec25 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokkerte brukere",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Denne posten kan ikke fremheves",
   "status.delete": "Slett",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Bygge inn",
   "status.favourite": "Lik",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 6aaf4cc63..a198a0d93 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -7,7 +7,7 @@
   "account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.",
   "account.domain_blocked": "Domeni amagat",
   "account.edit_profile": "Modificar lo perfil",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "Mostrar pel perfil",
   "account.follow": "Sègre",
   "account.followers": "Seguidors",
   "account.follows": "Abonaments",
@@ -27,7 +27,7 @@
   "account.show_reblogs": "Mostrar los partatges de @{name}",
   "account.unblock": "Desblocar @{name}",
   "account.unblock_domain": "Desblocar {domain}",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "Mostrar pas pel perfil",
   "account.unfollow": "Quitar de sègre",
   "account.unmute": "Quitar de rescondre @{name}",
   "account.unmute_notifications": "Mostrar las notificacions de @{name}",
@@ -139,7 +139,7 @@
   "keyboard_shortcuts.hotkey": "Acorchis",
   "keyboard_shortcuts.legend": "mostrar aquesta legenda",
   "keyboard_shortcuts.mention": "mencionar l’autor",
-  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.profile": "per dobrir lo perfil de l’autor",
   "keyboard_shortcuts.reply": "respondre",
   "keyboard_shortcuts.search": "anar a la recèrca",
   "keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments",
@@ -162,9 +162,10 @@
   "missing_indicator.label": "Pas trobat",
   "missing_indicator.sublabel": "Aquesta ressorsa es pas estada trobada",
   "mute_modal.hide_notifications": "Rescondre las notificacions d’aquesta persona ?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Aplicacions mobil",
   "navigation_bar.blocks": "Personas blocadas",
   "navigation_bar.community_timeline": "Flux public local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Messatges dirèctes",
   "navigation_bar.discover": "Trobar",
   "navigation_bar.domain_blocks": "Domenis resconduts",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Quitar de partejar",
   "status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat",
   "status.delete": "Escafar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Messatge per @{name}",
   "status.embed": "Embarcar",
   "status.favourite": "Apondre als favorits",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 595e5d57b..b8eceb1cf 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -169,6 +169,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Zablokowani użytkownicy",
   "navigation_bar.community_timeline": "Lokalna oś czasu",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Wiadomości bezpośrednie",
   "navigation_bar.discover": "Odkrywaj",
   "navigation_bar.domain_blocks": "Ukryte domeny",
@@ -263,6 +264,7 @@
   "status.cancel_reblog_private": "Cofnij podbicie",
   "status.cannot_reblog": "Ten wpis nie może zostać podbity",
   "status.delete": "Usuń",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Wyślij wiadomość bezpośrednią do @{name}",
   "status.embed": "Osadź",
   "status.favourite": "Dodaj do ulubionych",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index bdfdd46e5..d40e6d6a2 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -7,7 +7,7 @@
   "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de maneira incompleta.",
   "account.domain_blocked": "Domínio escondido",
   "account.edit_profile": "Editar perfil",
-  "account.endorse": "Feature on profile",
+  "account.endorse": "Destacar no perfil",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.follows": "Segue",
@@ -27,7 +27,7 @@
   "account.show_reblogs": "Mostra compartilhamentos de @{name}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Desbloquear {domain}",
-  "account.unendorse": "Don't feature on profile",
+  "account.unendorse": "Não destacar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Retirar silêncio das notificações vindas de @{name}",
@@ -162,9 +162,10 @@
   "missing_indicator.label": "Não encontrado",
   "missing_indicator.sublabel": "Esse recurso não pôde ser encontrado",
   "mute_modal.hide_notifications": "Esconder notificações deste usuário?",
-  "navigation_bar.apps": "Mobile apps",
+  "navigation_bar.apps": "Apps",
   "navigation_bar.blocks": "Usuários bloqueados",
   "navigation_bar.community_timeline": "Local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Mensagens diretas",
   "navigation_bar.discover": "Descobrir",
   "navigation_bar.domain_blocks": "Domínios escondidos",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Desfazer compartilhamento",
   "status.cannot_reblog": "Esta postagem não pode ser compartilhada",
   "status.delete": "Excluir",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Enviar mensagem direta a @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index b3c4c3ad9..92c7343cc 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Utilizadores bloqueados",
   "navigation_bar.community_timeline": "Local",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Este post não pode ser partilhado",
   "status.delete": "Eliminar",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Incorporar",
   "status.favourite": "Adicionar aos favoritos",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 8ba26a3c8..7d964859b 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Список блокировки",
   "navigation_bar.community_timeline": "Локальная лента",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Личные сообщения",
   "navigation_bar.discover": "Изучайте",
   "navigation_bar.domain_blocks": "Скрытые домены",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Не продвигать",
   "status.cannot_reblog": "Этот статус не может быть продвинут",
   "status.delete": "Удалить",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Написать @{name}",
   "status.embed": "Встроить",
   "status.favourite": "Нравится",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 8c36f866d..e51bb1d48 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokovaní užívatelia",
   "navigation_bar.community_timeline": "Lokálna časová os",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Súkromné správy",
   "navigation_bar.discover": "Objavuj",
   "navigation_bar.domain_blocks": "Skryté domény",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Nezdieľaj",
   "status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
   "status.delete": "Zmazať",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Súkromná správa @{name}",
   "status.embed": "Vložiť",
   "status.favourite": "Páči sa mi",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 01617f790..ca0f7a53f 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blocked users",
   "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index 96b46077a..b76710419 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blokirani korisnici",
   "navigation_bar.community_timeline": "Lokalna lajna",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ovaj status ne može da se podrži",
   "status.delete": "Obriši",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Ugradi na sajt",
   "status.favourite": "Omiljeno",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 681337947..e31618f66 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Блокирани корисници",
   "navigation_bar.community_timeline": "Локална лајна",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Овај статус не може да се подржи",
   "status.delete": "Обриши",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Угради на сајт",
   "status.favourite": "Омиљено",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 5c11e72d9..813bf45df 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blockerade användare",
   "navigation_bar.community_timeline": "Lokal tidslinje",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direktmeddelanden",
   "navigation_bar.discover": "Upptäck",
   "navigation_bar.domain_blocks": "Dolda domäner",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Ta bort knuff",
   "status.cannot_reblog": "Detta inlägg kan inte knuffas",
   "status.delete": "Ta bort",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direktmeddela @{name}",
   "status.embed": "Bädda in",
   "status.favourite": "Favorit",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 8aeebd048..2556b0ecb 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు",
   "navigation_bar.community_timeline": "స్థానిక కాలక్రమం",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "ప్రత్యక్ష సందేశాలు",
   "navigation_bar.discover": "కనుగొను",
   "navigation_bar.domain_blocks": "దాచిన డొమైన్లు",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "బూస్ట్ను తొలగించు",
   "status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు",
   "status.delete": "తొలగించు",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "@{name}కు నేరుగా సందేశం పంపు",
   "status.embed": "ఎంబెడ్",
   "status.favourite": "ఇష్టపడు",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 5e4995b71..c02d40d97 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Blocked users",
   "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.delete": "Delete",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favourite",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index be7ad47e4..e3193c99f 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Engellenen kullanıcılar",
   "navigation_bar.community_timeline": "Yerel zaman tüneli",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
   "navigation_bar.domain_blocks": "Hidden domains",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Bu gönderi boost edilemez",
   "status.delete": "Sil",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Favorilere ekle",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index 5f7e5c266..c1a47b307 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "Заблоковані користувачі",
   "navigation_bar.community_timeline": "Локальна стрічка",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Прямі повідомлення",
   "navigation_bar.discover": "Знайти",
   "navigation_bar.domain_blocks": "Приховані домени",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Цей допис не може бути передмухнутий",
   "status.delete": "Видалити",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
   "status.embed": "Embed",
   "status.favourite": "Подобається",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 378a1a45b..329a95084 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "已屏蔽的用户",
   "navigation_bar.community_timeline": "本站时间轴",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "私信",
   "navigation_bar.discover": "发现",
   "navigation_bar.domain_blocks": "已屏蔽的网站",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "取消转嘟",
   "status.cannot_reblog": "无法转嘟这条嘟文",
   "status.delete": "删除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "发送私信给 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "收藏",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index f0718468a..df32369e7 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "被你封鎖的用戶",
   "navigation_bar.community_timeline": "本站時間軸",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "個人訊息",
   "navigation_bar.discover": "探索",
   "navigation_bar.domain_blocks": "隱藏的服務站",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "取消轉推",
   "status.cannot_reblog": "這篇文章無法被轉推",
   "status.delete": "刪除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "私訊 @{name}",
   "status.embed": "鑲嵌",
   "status.favourite": "收藏",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index ca5919e30..dd7c84b32 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -165,6 +165,7 @@
   "navigation_bar.apps": "Mobile apps",
   "navigation_bar.blocks": "封鎖的使用者",
   "navigation_bar.community_timeline": "本地時間軸",
+  "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "私訊",
   "navigation_bar.discover": "探索",
   "navigation_bar.domain_blocks": "隱藏的站點",
@@ -258,6 +259,7 @@
   "status.cancel_reblog_private": "取消轉嘟",
   "status.cannot_reblog": "這篇嘟文無法被轉嘟",
   "status.delete": "刪除",
+  "status.detailed_status": "Detailed conversation view",
   "status.direct": "發送私訊給 @{name}",
   "status.embed": "嵌入",
   "status.favourite": "最愛",
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index e5fdc7f83..1cb491e17 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -63,7 +63,10 @@ function main() {
         .catch(error => console.error(error));
     }
 
-    new Rellax('.parallax', { speed: -1 });
+    const parallaxComponents = document.querySelectorAll('.parallax');
+    if (parallaxComponents.length > 0 ) {
+      new Rellax('.parallax', { speed: -1 });
+    }
 
     const history = createHistory();
     const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index 03476920b..3a39b723e 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -104,7 +104,9 @@ class ActivityPub::Activity
 
   def crawl_links(status)
     return if status.spoiler_text?
-    LinkCrawlWorker.perform_async(status.id)
+
+    # Spread out crawling randomly to avoid DDoSing the link
+    LinkCrawlWorker.perform_in(rand(1..59).seconds, status.id)
   end
 
   def distribute_to_followers(status)
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 79efc95d3..f40e1fa3e 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -48,7 +48,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       account: @account,
       text: text_from_content || '',
       language: detected_language,
-      spoiler_text: @object['summary'] || '',
+      spoiler_text: text_from_summary || '',
       created_at: @object['published'],
       override_timestamps: @options[:override_timestamps],
       reply: @object['inReplyTo'].present?,
@@ -193,6 +193,14 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def text_from_summary
+    if @object['summary'].present?
+      @object['summary']
+    elsif summary_language_map?
+      @object['summaryMap'].values.first
+    end
+  end
+
   def text_from_name
     if @object['name'].present?
       @object['name']
@@ -206,6 +214,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       @object['contentMap'].keys.first
     elsif name_language_map?
       @object['nameMap'].keys.first
+    elsif summary_language_map?
+      @object['summaryMap'].keys.first
     elsif supported_object_type?
       LanguageDetector.instance.detect(text_from_content, @account)
     end
@@ -223,6 +233,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def summary_language_map?
+    @object['summaryMap'].is_a?(Hash) && !@object['summaryMap'].empty?
+  end
+
   def content_language_map?
     @object['contentMap'].is_a?(Hash) && !@object['contentMap'].empty?
   end
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index 5b410ec84..4d557b071 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -14,7 +14,7 @@
     - unless status.proper.media_attachments.empty?
       - if status.proper.media_attachments.first.video?
         - video = status.proper.media_attachments.first
-        = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
+        = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true, alt: video.description
       - else
         = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 21713f72e..36b4e9cae 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -30,9 +30,5 @@
     = render partial: 'layouts/theme', object: @core
     = render partial: 'layouts/theme', object: @theme
 
-  - body_classes ||= @body_classes || ''
-  - body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
-  - body_classes += current_account&.user&.setting_reduce_motion ? ' reduce-motion' : ' no-reduce-motion'
-
-  %body{ class: add_rtl_body_class(body_classes) }
+  %body{ class: body_classes }
     = content_for?(:content) ? yield(:content) : yield
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index a7c767816..7843005c1 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -21,7 +21,7 @@
   - if !status.media_attachments.empty?
     - if status.media_attachments.first.video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true
+      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true, alt: video.description
     - else
       = react_component :media_gallery, height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
   - elsif status.preview_cards.first
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index 1d61684ab..effd4826e 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -25,7 +25,7 @@
   - unless status.media_attachments.empty?
     - if status.media_attachments.first.video?
       - video = status.media_attachments.first
-      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true
+      = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true, alt: video.description
     - else
       = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 
diff --git a/app/workers/maintenance/destroy_media_worker.rb b/app/workers/maintenance/destroy_media_worker.rb
index 5f052983b..cde33d6d7 100644
--- a/app/workers/maintenance/destroy_media_worker.rb
+++ b/app/workers/maintenance/destroy_media_worker.rb
@@ -6,7 +6,7 @@ class Maintenance::DestroyMediaWorker
   sidekiq_options queue: 'pull'
 
   def perform(media_attachment_id)
-    media = MediaAttachment.find(media_attachment_id)
+    media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
     media.destroy
   rescue ActiveRecord::RecordNotFound
     true
diff --git a/app/workers/maintenance/redownload_account_media_worker.rb b/app/workers/maintenance/redownload_account_media_worker.rb
index fc26815f2..6afbe6e19 100644
--- a/app/workers/maintenance/redownload_account_media_worker.rb
+++ b/app/workers/maintenance/redownload_account_media_worker.rb
@@ -6,7 +6,7 @@ class Maintenance::RedownloadAccountMediaWorker
   sidekiq_options queue: 'pull', retry: false
 
   def perform(account_id)
-    account = Account.find(account_id)
+    account = account_id.is_a?(Account) ? account_id : Account.find(account_id)
     account.reset_avatar!
     account.reset_header!
     account.save
diff --git a/app/workers/maintenance/uncache_media_worker.rb b/app/workers/maintenance/uncache_media_worker.rb
index 2d1a670a7..4bc62ef75 100644
--- a/app/workers/maintenance/uncache_media_worker.rb
+++ b/app/workers/maintenance/uncache_media_worker.rb
@@ -6,7 +6,7 @@ class Maintenance::UncacheMediaWorker
   sidekiq_options queue: 'pull'
 
   def perform(media_attachment_id)
-    media = MediaAttachment.find(media_attachment_id)
+    media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id)
 
     return if media.file.blank?
 
diff --git a/app/workers/scheduler/backup_cleanup_scheduler.rb b/app/workers/scheduler/backup_cleanup_scheduler.rb
index 023a77307..d43660699 100644
--- a/app/workers/scheduler/backup_cleanup_scheduler.rb
+++ b/app/workers/scheduler/backup_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::BackupCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     old_backups.reorder(nil).find_each(&:destroy!)
diff --git a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
index fec08c6bc..e5e5f6bc4 100644
--- a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
+++ b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::DoorkeeperCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb
index 24117e424..24ec89b29 100644
--- a/app/workers/scheduler/email_scheduler.rb
+++ b/app/workers/scheduler/email_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::EmailScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     eligible_users.reorder(nil).find_each do |user|
diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb
index b02bac883..cd2273418 100644
--- a/app/workers/scheduler/feed_cleanup_scheduler.rb
+++ b/app/workers/scheduler/feed_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::FeedCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     clean_home_feeds!
diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb
index 6bb93df7d..42620332e 100644
--- a/app/workers/scheduler/ip_cleanup_scheduler.rb
+++ b/app/workers/scheduler/ip_cleanup_scheduler.rb
@@ -5,7 +5,7 @@ class Scheduler::IpCleanupScheduler
 
   RETENTION_PERIOD = 1.year
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     time_ago = RETENTION_PERIOD.ago
diff --git a/app/workers/scheduler/media_cleanup_scheduler.rb b/app/workers/scheduler/media_cleanup_scheduler.rb
index a27e02953..fb01aa70c 100644
--- a/app/workers/scheduler/media_cleanup_scheduler.rb
+++ b/app/workers/scheduler/media_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::MediaCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     unattached_media.find_each(&:destroy)
diff --git a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
index 06ba66205..5fba120f6 100644
--- a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
+++ b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::SubscriptionsCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     Subscription.expired.in_batches.delete_all
diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb
index 4b0959af2..d5873bccb 100644
--- a/app/workers/scheduler/subscriptions_scheduler.rb
+++ b/app/workers/scheduler/subscriptions_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::SubscriptionsScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     Pubsubhubbub::SubscribeWorker.push_bulk(expiring_accounts.pluck(:id))
diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb
index 626fb1652..881b911be 100644
--- a/app/workers/scheduler/user_cleanup_scheduler.rb
+++ b/app/workers/scheduler/user_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::UserCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options unique: :until_executed, retry: 0
 
   def perform
     User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|