about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/chewy/statuses_index.rb2
-rw-r--r--app/controllers/admin/domain_blocks_controller.rb4
-rw-r--r--app/controllers/admin/instances_controller.rb26
-rw-r--r--app/controllers/api/v1/statuses_controller.rb1
-rw-r--r--app/controllers/auth/omniauth_callbacks_controller.rb6
-rw-r--r--app/helpers/languages_helper.rb9
-rw-r--r--app/helpers/statuses_helper.rb12
-rw-r--r--app/javascript/mastodon/components/admin/Counter.js6
-rw-r--r--app/javascript/mastodon/components/media_attachments.js116
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js12
-rw-r--r--app/javascript/mastodon/features/report/components/status_check_box.js52
-rw-r--r--app/javascript/mastodon/features/ui/components/compare_history_modal.js20
-rw-r--r--app/javascript/mastodon/locales/af.json5
-rw-r--r--app/javascript/mastodon/locales/ar.json5
-rw-r--r--app/javascript/mastodon/locales/ast.json5
-rw-r--r--app/javascript/mastodon/locales/bg.json5
-rw-r--r--app/javascript/mastodon/locales/bn.json5
-rw-r--r--app/javascript/mastodon/locales/br.json5
-rw-r--r--app/javascript/mastodon/locales/ca.json5
-rw-r--r--app/javascript/mastodon/locales/co.json5
-rw-r--r--app/javascript/mastodon/locales/cs.json5
-rw-r--r--app/javascript/mastodon/locales/cy.json5
-rw-r--r--app/javascript/mastodon/locales/da.json5
-rw-r--r--app/javascript/mastodon/locales/de.json5
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json44
-rw-r--r--app/javascript/mastodon/locales/el.json5
-rw-r--r--app/javascript/mastodon/locales/en.json5
-rw-r--r--app/javascript/mastodon/locales/eo.json5
-rw-r--r--app/javascript/mastodon/locales/es-AR.json5
-rw-r--r--app/javascript/mastodon/locales/es-MX.json5
-rw-r--r--app/javascript/mastodon/locales/es.json5
-rw-r--r--app/javascript/mastodon/locales/et.json5
-rw-r--r--app/javascript/mastodon/locales/eu.json5
-rw-r--r--app/javascript/mastodon/locales/fa.json5
-rw-r--r--app/javascript/mastodon/locales/fi.json5
-rw-r--r--app/javascript/mastodon/locales/fr.json5
-rw-r--r--app/javascript/mastodon/locales/ga.json5
-rw-r--r--app/javascript/mastodon/locales/gd.json5
-rw-r--r--app/javascript/mastodon/locales/gl.json5
-rw-r--r--app/javascript/mastodon/locales/he.json5
-rw-r--r--app/javascript/mastodon/locales/hi.json5
-rw-r--r--app/javascript/mastodon/locales/hr.json5
-rw-r--r--app/javascript/mastodon/locales/hu.json5
-rw-r--r--app/javascript/mastodon/locales/hy.json5
-rw-r--r--app/javascript/mastodon/locales/id.json5
-rw-r--r--app/javascript/mastodon/locales/io.json5
-rw-r--r--app/javascript/mastodon/locales/is.json5
-rw-r--r--app/javascript/mastodon/locales/it.json5
-rw-r--r--app/javascript/mastodon/locales/ja.json5
-rw-r--r--app/javascript/mastodon/locales/ka.json5
-rw-r--r--app/javascript/mastodon/locales/kab.json5
-rw-r--r--app/javascript/mastodon/locales/kk.json5
-rw-r--r--app/javascript/mastodon/locales/kmr.json5
-rw-r--r--app/javascript/mastodon/locales/kn.json5
-rw-r--r--app/javascript/mastodon/locales/ko.json5
-rw-r--r--app/javascript/mastodon/locales/ku.json5
-rw-r--r--app/javascript/mastodon/locales/kw.json5
-rw-r--r--app/javascript/mastodon/locales/lt.json5
-rw-r--r--app/javascript/mastodon/locales/lv.json5
-rw-r--r--app/javascript/mastodon/locales/mk.json5
-rw-r--r--app/javascript/mastodon/locales/ml.json5
-rw-r--r--app/javascript/mastodon/locales/mr.json5
-rw-r--r--app/javascript/mastodon/locales/ms.json5
-rw-r--r--app/javascript/mastodon/locales/nl.json5
-rw-r--r--app/javascript/mastodon/locales/nn.json5
-rw-r--r--app/javascript/mastodon/locales/no.json5
-rw-r--r--app/javascript/mastodon/locales/oc.json5
-rw-r--r--app/javascript/mastodon/locales/pa.json5
-rw-r--r--app/javascript/mastodon/locales/pl.json5
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json5
-rw-r--r--app/javascript/mastodon/locales/pt-PT.json5
-rw-r--r--app/javascript/mastodon/locales/ro.json5
-rw-r--r--app/javascript/mastodon/locales/ru.json5
-rw-r--r--app/javascript/mastodon/locales/sa.json5
-rw-r--r--app/javascript/mastodon/locales/sc.json5
-rw-r--r--app/javascript/mastodon/locales/si.json5
-rw-r--r--app/javascript/mastodon/locales/sk.json5
-rw-r--r--app/javascript/mastodon/locales/sl.json5
-rw-r--r--app/javascript/mastodon/locales/sq.json5
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json5
-rw-r--r--app/javascript/mastodon/locales/sr.json5
-rw-r--r--app/javascript/mastodon/locales/sv.json5
-rw-r--r--app/javascript/mastodon/locales/szl.json5
-rw-r--r--app/javascript/mastodon/locales/ta.json5
-rw-r--r--app/javascript/mastodon/locales/tai.json5
-rw-r--r--app/javascript/mastodon/locales/te.json5
-rw-r--r--app/javascript/mastodon/locales/th.json5
-rw-r--r--app/javascript/mastodon/locales/tr.json5
-rw-r--r--app/javascript/mastodon/locales/tt.json5
-rw-r--r--app/javascript/mastodon/locales/ug.json5
-rw-r--r--app/javascript/mastodon/locales/uk.json5
-rw-r--r--app/javascript/mastodon/locales/ur.json5
-rw-r--r--app/javascript/mastodon/locales/vi.json5
-rw-r--r--app/javascript/mastodon/locales/zgh.json5
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json5
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json5
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json5
-rw-r--r--app/javascript/styles/mastodon-light/diff.scss6
-rw-r--r--app/javascript/styles/mastodon/admin.scss50
-rw-r--r--app/javascript/styles/mastodon/components.scss8
-rw-r--r--app/javascript/styles/mastodon/tables.scss18
-rw-r--r--app/lib/admin/metrics/dimension.rb2
-rw-r--r--app/lib/admin/metrics/dimension/instance_accounts_dimension.rb35
-rw-r--r--app/lib/admin/metrics/dimension/instance_languages_dimension.rb37
-rw-r--r--app/lib/admin/metrics/measure.rb6
-rw-r--r--app/lib/admin/metrics/measure/base_measure.rb8
-rw-r--r--app/lib/admin/metrics/measure/instance_accounts_measure.rb58
-rw-r--r--app/lib/admin/metrics/measure/instance_followers_measure.rb59
-rw-r--r--app/lib/admin/metrics/measure/instance_follows_measure.rb59
-rw-r--r--app/lib/admin/metrics/measure/instance_media_attachments_measure.rb69
-rw-r--r--app/lib/admin/metrics/measure/instance_reports_measure.rb59
-rw-r--r--app/lib/admin/metrics/measure/instance_statuses_measure.rb60
-rw-r--r--app/lib/delivery_failure_tracker.rb2
-rw-r--r--app/lib/feed_manager.rb2
-rw-r--r--app/lib/rss/serializer.rb2
-rw-r--r--app/models/concerns/omniauthable.rb23
-rw-r--r--app/models/domain_block.rb8
-rw-r--r--app/models/featured_tag.rb4
-rw-r--r--app/models/instance.rb36
-rw-r--r--app/models/instance_filter.rb16
-rw-r--r--app/models/report.rb16
-rw-r--r--app/models/status.rb128
-rw-r--r--app/models/status_edit.rb52
-rw-r--r--app/serializers/activitypub/note_serializer.rb6
-rw-r--r--app/serializers/rest/admin/measure_serializer.rb10
-rw-r--r--app/serializers/rest/status_edit_serializer.rb10
-rw-r--r--app/serializers/rest/status_serializer.rb2
-rw-r--r--app/services/activitypub/process_status_update_service.rb19
-rw-r--r--app/services/fan_out_on_write_service.rb2
-rw-r--r--app/services/post_status_service.rb8
-rw-r--r--app/services/remove_status_service.rb2
-rw-r--r--app/services/update_status_service.rb23
-rw-r--r--app/views/admin/domain_blocks/edit.html.haml4
-rw-r--r--app/views/admin/domain_blocks/new.html.haml4
-rw-r--r--app/views/admin/domain_blocks/show.html.haml25
-rw-r--r--app/views/admin/instances/_exhausted_deliveries_days.haml2
-rw-r--r--app/views/admin/instances/_instance.html.haml28
-rw-r--r--app/views/admin/instances/index.html.haml19
-rw-r--r--app/views/admin/instances/show.html.haml169
-rw-r--r--app/views/admin/reports/_status.html.haml12
-rw-r--r--app/views/admin/reports/index.html.haml4
-rw-r--r--app/views/admin/trends/statuses/_status.html.haml2
-rw-r--r--app/views/disputes/strikes/show.html.haml2
-rw-r--r--app/views/notification_mailer/_status.html.haml4
-rw-r--r--app/views/statuses/_detailed_status.html.haml6
-rw-r--r--app/views/statuses/_og_image.html.haml2
-rw-r--r--app/views/statuses/_simple_status.html.haml6
-rw-r--r--app/views/user_mailer/warning.text.erb3
-rw-r--r--app/workers/admin/domain_purge_worker.rb2
149 files changed, 1366 insertions, 563 deletions
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
index 1903c2ea3..65cbb6fcd 100644
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -57,7 +57,7 @@ class StatusesIndex < Chewy::Index
     field :id, type: 'long'
     field :account_id, type: 'long'
 
-    field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do
+    field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do
       field :stemmed, type: 'text', analyzer: 'content'
     end
 
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
index b140c454c..16defc1ea 100644
--- a/app/controllers/admin/domain_blocks_controller.rb
+++ b/app/controllers/admin/domain_blocks_controller.rb
@@ -56,10 +56,6 @@ module Admin
       end
     end
 
-    def show
-      authorize @domain_block, :show?
-    end
-
     def destroy
       authorize @domain_block, :destroy?
       UnblockDomainService.new.call(@domain_block)
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index 306ec1f53..5c82331de 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -4,28 +4,26 @@ module Admin
   class InstancesController < BaseController
     before_action :set_instances, only: :index
     before_action :set_instance, except: :index
-    before_action :set_exhausted_deliveries_days, only: :show
 
     def index
       authorize :instance, :index?
+      preload_delivery_failures!
     end
 
     def show
       authorize :instance, :show?
+      @time_period = (6.days.ago.to_date...Time.now.utc.to_date)
     end
 
     def destroy
       authorize :instance, :destroy?
-
       Admin::DomainPurgeWorker.perform_async(@instance.domain)
-
       log_action :destroy, @instance
       redirect_to admin_instances_path, notice: I18n.t('admin.instances.destroyed_msg', domain: @instance.domain)
     end
 
     def clear_delivery_errors
       authorize :delivery, :clear_delivery_errors?
-
       @instance.delivery_failure_tracker.clear_failures!
       redirect_to admin_instance_path(@instance.domain)
     end
@@ -33,11 +31,9 @@ module Admin
     def restart_delivery
       authorize :delivery, :restart_delivery?
 
-      last_unavailable_domain = unavailable_domain
-
-      if last_unavailable_domain.present?
+      if @instance.unavailable?
         @instance.delivery_failure_tracker.track_success!
-        log_action :destroy, last_unavailable_domain
+        log_action :destroy, @instance.unavailable_domain
       end
 
       redirect_to admin_instance_path(@instance.domain)
@@ -45,8 +41,7 @@ module Admin
 
     def stop_delivery
       authorize :delivery, :stop_delivery?
-
-      UnavailableDomain.create(domain: @instance.domain)
+      unavailable_domain = UnavailableDomain.create!(domain: @instance.domain)
       log_action :create, unavailable_domain
       redirect_to admin_instance_path(@instance.domain)
     end
@@ -57,12 +52,11 @@ module Admin
       @instance = Instance.find(params[:id])
     end
 
-    def set_exhausted_deliveries_days
-      @exhausted_deliveries_days = @instance.delivery_failure_tracker.exhausted_deliveries_days
-    end
-
     def set_instances
       @instances = filtered_instances.page(params[:page])
+    end
+
+    def preload_delivery_failures!
       warning_domains_map = DeliveryFailureTracker.warning_domains_map
 
       @instances.each do |instance|
@@ -70,10 +64,6 @@ module Admin
       end
     end
 
-    def unavailable_domain
-      UnavailableDomain.find_by(domain: @instance.domain)
-    end
-
     def filtered_instances
       InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
     end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index ddd7c33ae..7de446ac4 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -10,6 +10,7 @@ class Api::V1::StatusesController < Api::BaseController
   before_action :set_thread, only:       [:create]
 
   override_rate_limit_headers :create, family: :statuses
+  override_rate_limit_headers :update, family: :statuses
 
   # This API was originally unlimited, pagination cannot be introduced without
   # breaking backwards-compatibility. Arbitrarily high number to cover most
diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb
index 991a50b03..f9cf6d655 100644
--- a/app/controllers/auth/omniauth_callbacks_controller.rb
+++ b/app/controllers/auth/omniauth_callbacks_controller.rb
@@ -4,8 +4,6 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   skip_before_action :verify_authenticity_token
 
   def self.provides_callback_for(provider)
-    provider_id = provider.to_s.chomp '_oauth2'
-
     define_method provider do
       @user = User.find_for_oauth(request.env['omniauth.auth'], current_user)
 
@@ -20,7 +18,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
         )
 
         sign_in_and_redirect @user, event: :authentication
-        set_flash_message(:notice, :success, kind: provider_id.capitalize) if is_navigational_format?
+        set_flash_message(:notice, :success, kind: Devise.omniauth_configs[provider].strategy.display_name.capitalize) if is_navigational_format?
       else
         session["devise.#{provider}_data"] = request.env['omniauth.auth']
         redirect_to new_user_registration_url
@@ -33,7 +31,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   end
 
   def after_sign_in_path_for(resource)
-    if resource.email_verified?
+    if resource.email_present?
       root_path
     else
       auth_setup_path(missing_email: '1')
diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb
index f22cc6d28..9be35ad8e 100644
--- a/app/helpers/languages_helper.rb
+++ b/app/helpers/languages_helper.rb
@@ -241,6 +241,15 @@ module LanguagesHelper
     code
   end
 
+  def valid_locale_cascade(*arr)
+    arr.each do |str|
+      locale = valid_locale_or_nil(str)
+      return locale if locale.present?
+    end
+
+    nil
+  end
+
   def valid_locale?(locale)
     locale.present? && SUPPORTED_LOCALES.key?(locale.to_sym)
   end
diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb
index 25f079e9d..d328f89b7 100644
--- a/app/helpers/statuses_helper.rb
+++ b/app/helpers/statuses_helper.rb
@@ -132,7 +132,7 @@ module StatusesHelper
   end
 
   def render_video_component(status, **options)
-    video = status.media_attachments.first
+    video = status.ordered_media_attachments.first
 
     meta = video.file.meta || {}
 
@@ -150,12 +150,12 @@ module StatusesHelper
     }.merge(**options)
 
     react_component :video, component_params do
-      render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
+      render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
     end
   end
 
   def render_audio_component(status, **options)
-    audio = status.media_attachments.first
+    audio = status.ordered_media_attachments.first
 
     meta = audio.file.meta || {}
 
@@ -170,7 +170,7 @@ module StatusesHelper
     }.merge(**options)
 
     react_component :audio, component_params do
-      render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
+      render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
     end
   end
 
@@ -178,11 +178,11 @@ module StatusesHelper
     component_params = {
       sensitive: sensitized?(status, current_account),
       autoplay: prefers_autoplay?,
-      media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json },
+      media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json },
     }.merge(**options)
 
     react_component :media_gallery, component_params do
-      render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
+      render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
     end
   end
 
diff --git a/app/javascript/mastodon/components/admin/Counter.js b/app/javascript/mastodon/components/admin/Counter.js
index 047e864b2..6edb7bcfc 100644
--- a/app/javascript/mastodon/components/admin/Counter.js
+++ b/app/javascript/mastodon/components/admin/Counter.js
@@ -68,12 +68,12 @@ export default class Counter extends React.PureComponent {
       );
     } else {
       const measure = data[0];
-      const percentChange = percIncrease(measure.previous_total * 1, measure.total * 1);
+      const percentChange = measure.previous_total && percIncrease(measure.previous_total * 1, measure.total * 1);
 
       content = (
         <React.Fragment>
-          <span className='sparkline__value__total'><FormattedNumber value={measure.total} /></span>
-          <span className={classNames('sparkline__value__change', { positive: percentChange > 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'}<FormattedNumber value={percentChange} style='percent' /></span>
+          <span className='sparkline__value__total'>{measure.human_value || <FormattedNumber value={measure.total} />}</span>
+          {measure.previous_total && (<span className={classNames('sparkline__value__change', { positive: percentChange > 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'}<FormattedNumber value={percentChange} style='percent' /></span>)}
         </React.Fragment>
       );
     }
diff --git a/app/javascript/mastodon/components/media_attachments.js b/app/javascript/mastodon/components/media_attachments.js
new file mode 100644
index 000000000..d27720de4
--- /dev/null
+++ b/app/javascript/mastodon/components/media_attachments.js
@@ -0,0 +1,116 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { MediaGallery, Video, Audio } from 'mastodon/features/ui/util/async-components';
+import Bundle from 'mastodon/features/ui/components/bundle';
+import noop from 'lodash/noop';
+
+export default class MediaAttachments extends ImmutablePureComponent {
+
+  static propTypes = {
+    status: ImmutablePropTypes.map.isRequired,
+    height: PropTypes.number,
+    width: PropTypes.number,
+  };
+
+  static defaultProps = {
+    height: 110,
+    width: 239,
+  };
+
+  updateOnProps = [
+    'status',
+  ];
+
+  renderLoadingMediaGallery = () => {
+    const { height, width } = this.props;
+
+    return (
+      <div className='media-gallery' style={{ height, width }} />
+    );
+  }
+
+  renderLoadingVideoPlayer = () => {
+    const { height, width } = this.props;
+
+    return (
+      <div className='video-player' style={{ height, width }} />
+    );
+  }
+
+  renderLoadingAudioPlayer = () => {
+    const { height, width } = this.props;
+
+    return (
+      <div className='audio-player' style={{ height, width }} />
+    );
+  }
+
+  render () {
+    const { status, width, height } = this.props;
+    const mediaAttachments = status.get('media_attachments');
+
+    if (mediaAttachments.size === 0) {
+      return null;
+    }
+
+    if (mediaAttachments.getIn([0, 'type']) === 'audio') {
+      const audio = mediaAttachments.get(0);
+
+      return (
+        <Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
+          {Component => (
+            <Component
+              src={audio.get('url')}
+              alt={audio.get('description')}
+              width={width}
+              height={height}
+              poster={audio.get('preview_url') || status.getIn(['account', 'avatar_static'])}
+              backgroundColor={audio.getIn(['meta', 'colors', 'background'])}
+              foregroundColor={audio.getIn(['meta', 'colors', 'foreground'])}
+              accentColor={audio.getIn(['meta', 'colors', 'accent'])}
+              duration={audio.getIn(['meta', 'original', 'duration'], 0)}
+            />
+          )}
+        </Bundle>
+      );
+    } else if (mediaAttachments.getIn([0, 'type']) === 'video') {
+      const video = mediaAttachments.get(0);
+
+      return (
+        <Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
+          {Component => (
+            <Component
+              preview={video.get('preview_url')}
+              frameRate={video.getIn(['meta', 'original', 'frame_rate'])}
+              blurhash={video.get('blurhash')}
+              src={video.get('url')}
+              alt={video.get('description')}
+              width={width}
+              height={height}
+              inline
+              sensitive={status.get('sensitive')}
+              onOpenVideo={noop}
+            />
+          )}
+        </Bundle>
+      );
+    } else {
+      return (
+        <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
+          {Component => (
+            <Component
+              media={mediaAttachments}
+              sensitive={status.get('sensitive')}
+              defaultWidth={width}
+              height={height}
+              onOpenMedia={noop}
+            />
+          )}
+        </Bundle>
+      );
+    }
+  }
+
+}
diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
index 142118cef..ede8907e5 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
@@ -40,7 +40,17 @@ class ColumnSettings extends React.PureComponent {
     }
   };
 
-  onSelect = mode => value => this.props.onChange(['tags', mode], value);
+  onSelect = mode => value => {
+    const oldValue = this.tags(mode);
+
+    // Prevent changes that add more than 4 tags, but allow removing
+    // tags that were already added before
+    if ((value.length > 4) && !(value < oldValue)) {
+      return;
+    }
+
+    this.props.onChange(['tags', mode], value);
+  };
 
   onToggle = () => {
     if (this.state.open && this.hasTags()) {
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 a2eb3d6f5..373c60e21 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.js
@@ -1,14 +1,12 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
-import noop from 'lodash/noop';
 import StatusContent from 'mastodon/components/status_content';
-import { MediaGallery, Video } from 'mastodon/features/ui/util/async-components';
-import Bundle from 'mastodon/features/ui/components/bundle';
 import Avatar from 'mastodon/components/avatar';
 import DisplayName from 'mastodon/components/display_name';
 import RelativeTimestamp from 'mastodon/components/relative_timestamp';
 import Option from './option';
+import MediaAttachments from 'mastodon/components/media_attachments';
 
 export default class StatusCheckBox extends React.PureComponent {
 
@@ -27,51 +25,10 @@ export default class StatusCheckBox extends React.PureComponent {
   render () {
     const { status, checked } = this.props;
 
-    let media = null;
-
     if (status.get('reblog')) {
       return null;
     }
 
-    if (status.get('media_attachments').size > 0) {
-      if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
-
-      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
-        const video = status.getIn(['media_attachments', 0]);
-
-        media = (
-          <Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
-            {Component => (
-              <Component
-                preview={video.get('preview_url')}
-                blurhash={video.get('blurhash')}
-                src={video.get('url')}
-                alt={video.get('description')}
-                width={239}
-                height={110}
-                inline
-                sensitive={status.get('sensitive')}
-                onOpenVideo={noop}
-              />
-            )}
-          </Bundle>
-        );
-      } else {
-        media = (
-          <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
-            {Component => (
-              <Component
-                media={status.get('media_attachments')}
-                sensitive={status.get('sensitive')}
-                height={110}
-                onOpenMedia={noop}
-              />
-            )}
-          </Bundle>
-        );
-      }
-    }
-
     const labelComponent = (
       <div className='status-check-box__status poll__option__text'>
         <div className='detailed-status__display-name'>
@@ -79,12 +36,13 @@ export default class StatusCheckBox extends React.PureComponent {
             <Avatar account={status.get('account')} size={46} />
           </div>
 
-          <div><DisplayName account={status.get('account')} /> · <RelativeTimestamp timestamp={status.get('created_at')} /></div>
+          <div>
+            <DisplayName account={status.get('account')} /> · <RelativeTimestamp timestamp={status.get('created_at')} />
+          </div>
         </div>
 
         <StatusContent status={status} />
-
-        {media}
+        <MediaAttachments status={status} />
       </div>
     );
 
diff --git a/app/javascript/mastodon/features/ui/components/compare_history_modal.js b/app/javascript/mastodon/features/ui/components/compare_history_modal.js
index 40cfba335..ecccc8f7d 100644
--- a/app/javascript/mastodon/features/ui/components/compare_history_modal.js
+++ b/app/javascript/mastodon/features/ui/components/compare_history_modal.js
@@ -9,6 +9,7 @@ import escapeTextContentForBrowser from 'escape-html';
 import InlineAccount from 'mastodon/components/inline_account';
 import IconButton from 'mastodon/components/icon_button';
 import RelativeTimestamp from 'mastodon/components/relative_timestamp';
+import MediaAttachments from 'mastodon/components/media_attachments';
 
 const mapStateToProps = (state, { statusId }) => ({
   versions: state.getIn(['history', statusId, 'items']),
@@ -70,6 +71,25 @@ class CompareHistoryModal extends React.PureComponent {
             )}
 
             <div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} />
+
+            {!!currentVersion.get('poll') && (
+              <div className='poll'>
+                <ul>
+                  {currentVersion.getIn(['poll', 'options']).map(option => (
+                    <li key={option.get('title')}>
+                      <span className='poll__input disabled' />
+
+                      <span
+                        className='poll__option__text translate'
+                        dangerouslySetInnerHTML={{ __html: emojify(escapeTextContentForBrowser(option.get('title')), emojiMap) }}
+                      />
+                    </li>
+                  ))}
+                </ul>
+              </div>
+            )}
+
+            <MediaAttachments status={currentVersion} />
           </div>
         </div>
       </div>
diff --git a/app/javascript/mastodon/locales/af.json b/app/javascript/mastodon/locales/af.json
index a7e5313a3..d31ed3fe9 100644
--- a/app/javascript/mastodon/locales/af.json
+++ b/app/javascript/mastodon/locales/af.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 84708b1e2..5fd1ab9e5 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -18,12 +18,12 @@
   "account.followers": "المُتابِعون",
   "account.followers.empty": "لا أحدَ يُتابع هذا المُستخدم حتى الآن.",
   "account.followers_counter": "{count, plural, zero{لا مُتابع} one {مُتابعٌ واحِد} two{مُتابعانِ اِثنان} few{{counter} مُتابِعين} many{{counter}  مُتابِعًا} other {{counter}  مُتابع}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, zero{لا يُتابِع} one {يُتابِعُ واحد} two{يُتابِعُ اِثنان} few{يُتابِعُ {counter}} many{يُتابِعُ {counter}} other {يُتابِعُ {counter}}}",
   "account.follows.empty": "لا يُتابع هذا المُستخدمُ أيَّ أحدٍ حتى الآن.",
   "account.follows_you": "يُتابِعُك",
   "account.hide_reblogs": "إخفاء مشاركات @{name}",
   "account.joined": "انضم في {date}",
-  "account.last_status": "آخر نشاط",
   "account.link_verified_on": "تمَّ التَّحقق مِن مِلْكيّة هذا الرابط بتاريخ {date}",
   "account.locked_info": "تمَّ تعيين حالة خصوصية هذا الحساب إلى مُقفَل. يُراجع المالك يدويًا من يمكنه متابعته.",
   "account.media": "وسائط",
@@ -32,7 +32,6 @@
   "account.mute": "كَتم @{name}",
   "account.mute_notifications": "كَتم الإشعارات من @{name}",
   "account.muted": "مَكتوم",
-  "account.never_active": "أبدًا",
   "account.posts": "منشورات",
   "account.posts_with_replies": "المنشورات والرُدود",
   "account.report": "الإبلاغ عن @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, zero {لَا تَبويقات} one {تَبويقةٌ واحدة} two {تَبويقَتانِ اِثنتان} few {{counter} تَبويقات} many {{counter} تَبويقتًا} other {{counter} تَبويقة}}",
   "account.unblock": "إلغاء الحَظر عن @{name}",
   "account.unblock_domain": "إلغاء الحَظر عن النِّطاق {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "لا تُرَوِّج لهُ في الملف الشخصي",
   "account.unfollow": "إلغاء المُتابعة",
   "account.unmute": "إلغاء الكَتم عن @{name}",
   "account.unmute_notifications": "إلغاء كَتم الإشعارات عن @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "اضغط لإضافة مُلاحظة",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index 0627f57e1..4ca5f0123 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -18,12 +18,12 @@
   "account.followers": "Siguidores",
   "account.followers.empty": "Naide sigue a esti usuariu entá.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "Esti usuariu entá nun sigue a naide.",
   "account.follows_you": "Síguete",
   "account.hide_reblogs": "Anubrir les comparticiones de @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Cabera actividá",
   "account.link_verified_on": "La propiedá d'esti enllaz foi comprobada'l {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar a @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Enxamás",
   "account.posts": "Barritos",
   "account.posts_with_replies": "Barritos y rempuestes",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquiar a @{name}",
   "account.unblock_domain": "Amosar {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Nun destacar nel perfil",
   "account.unfollow": "Dexar de siguir",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index f037444d6..2e7038aa9 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -18,12 +18,12 @@
   "account.followers": "Последователи",
   "account.followers.empty": "Все още никой не следва този потребител.",
   "account.followers_counter": "{count, plural, one {{counter} Последовател} other {{counter} Последователи}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Последван} other {{counter} Последвани}}",
   "account.follows.empty": "Този потребител все още не следва никого.",
   "account.follows_you": "Твой последовател",
   "account.hide_reblogs": "Скриване на споделяния от @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Последно активен/а",
   "account.link_verified_on": "Собствеността върху тази връзка е проверена на {date}",
   "account.locked_info": "Този акаунт е поверително заключен. Собственикът преглежда ръчно кой може да го следва.",
   "account.media": "Мултимедия",
@@ -32,7 +32,6 @@
   "account.mute": "Заглушаване на @{name}",
   "account.mute_notifications": "Заглушаване на известия от @{name}",
   "account.muted": "Заглушено",
-  "account.never_active": "Никога",
   "account.posts": "Публикации",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "Докладване на @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Публикация} other {{counter} Публикации}}",
   "account.unblock": "Не блокирай",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Не включвайте в профила",
   "account.unfollow": "Не следвай",
   "account.unmute": "Раззаглушаване на @{name}",
   "account.unmute_notifications": "Раззаглушаване на известия от @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json
index 3387289a4..38d70853e 100644
--- a/app/javascript/mastodon/locales/bn.json
+++ b/app/javascript/mastodon/locales/bn.json
@@ -18,12 +18,12 @@
   "account.followers": "অনুসরণকারী",
   "account.followers.empty": "এই ব্যক্তিকে এখনো কেউ অনুসরণ করে না।",
   "account.followers_counter": "{count, plural,one {{counter} জন অনুসরণকারী } other {{counter} জন অনুসরণকারী}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural,one {{counter} জনকে অনুসরণ} other {{counter} জনকে অনুসরণ}}",
   "account.follows.empty": "এই সদস্য কাওকে এখনো অনুসরণ করেন না.",
   "account.follows_you": "তোমাকে অনুসরণ করে",
   "account.hide_reblogs": "@{name}'র সমর্থনগুলি লুকিয়ে ফেলুন",
   "account.joined": "Joined {date}",
-  "account.last_status": "শেষ সক্রিয় ছিল",
   "account.link_verified_on": "এই লিংকের মালিকানা চেক করা হয়েছে {date} তারিখে",
   "account.locked_info": "এই নিবন্ধনের গোপনীয়তার ক্ষেত্র তালা দেওয়া আছে। নিবন্ধনকারী অনুসরণ করার অনুমতি যাদেরকে দেবেন, শুধু তারাই অনুসরণ করতে পারবেন।",
   "account.media": "মিডিয়া",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} কে নিঃশব্দ করুন",
   "account.mute_notifications": "@{name} র প্রজ্ঞাপন আপনার কাছে নিঃশব্দ করুন",
   "account.muted": "নিঃশব্দ",
-  "account.never_active": "কখনও নয়",
   "account.posts": "টুট",
   "account.posts_with_replies": "টুট এবং মতামত",
   "account.report": "@{name} কে রিপোর্ট করুন",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural,one {{counter} টুট} other {{counter} টুট}}",
   "account.unblock": "@{name} র কার্যকলাপ দেখুন",
   "account.unblock_domain": "{domain} কে আবার দেখুন",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "আপনার নিজের পাতায় এটা দেখবেন না",
   "account.unfollow": "অনুসরণ করো না",
   "account.unmute": "@{name} র কার্যকলাপ আবার দেখুন",
   "account.unmute_notifications": "@{name} র প্রজ্ঞাপন দেখুন",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "নোট যোগ করতে ক্লিক করুন",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json
index 9a78feaab..a07b21c78 100644
--- a/app/javascript/mastodon/locales/br.json
+++ b/app/javascript/mastodon/locales/br.json
@@ -18,12 +18,12 @@
   "account.followers": "Heulier·ezed·ien",
   "account.followers.empty": "Den na heul an implijer-mañ c'hoazh.",
   "account.followers_counter": "{count, plural, other{{counter} Heulier}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Heuliañ}}",
   "account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
   "account.follows_you": "Ho heul",
   "account.hide_reblogs": "Kuzh toudoù rannet gant @{name}",
   "account.joined": "Amañ abaoe {date}",
-  "account.last_status": "Oberiantiz zivezhañ",
   "account.link_verified_on": "Gwiriet eo bet perc'hennidigezh al liamm d'an deiziad-mañ : {date}",
   "account.locked_info": "Prennet eo ar gont-mañ. Dibab a ra ar perc'henn ar re a c'hall heuliañ anezhi pe anezhañ.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Kuzhat @{name}",
   "account.mute_notifications": "Kuzh kemennoù eus @{name}",
   "account.muted": "Kuzhet",
-  "account.never_active": "Birviken",
   "account.posts": "a doudoù",
   "account.posts_with_replies": "Toudoù ha respontoù",
   "account.report": "Disklêriañ @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toud} other {{counter} Toud}}",
   "account.unblock": "Diverzañ @{name}",
   "account.unblock_domain": "Diverzañ an domani {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Paouez da lakaat war-wel war ar profil",
   "account.unfollow": "Diheuliañ",
   "account.unmute": "Diguzhat @{name}",
   "account.unmute_notifications": "Diguzhat kemennoù a @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikit evit ouzhpenniñ un notenn",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 915278f95..0182170fd 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidors",
   "account.followers.empty": "Encara ningú no segueix aquest usuari.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Seguint}}",
   "account.follows.empty": "Aquest usuari encara no segueix a ningú.",
   "account.follows_you": "Et segueix",
   "account.hide_reblogs": "Amaga els impulsos de @{name}",
   "account.joined": "Unit des de {date}",
-  "account.last_status": "Darrer actiu",
   "account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}",
   "account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.",
   "account.media": "Mèdia",
@@ -32,7 +32,6 @@
   "account.mute": "Silencia @{name}",
   "account.mute_notifications": "Notificacions desactivades de @{name}",
   "account.muted": "Silenciat",
-  "account.never_active": "Mai",
   "account.posts": "Tuts",
   "account.posts_with_replies": "Tuts i respostes",
   "account.report": "Informar sobre @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
   "account.unblock": "Desbloqueja @{name}",
   "account.unblock_domain": "Mostra {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "No recomanar en el perfil",
   "account.unfollow": "Deixa de seguir",
   "account.unmute": "Treure silenci de @{name}",
   "account.unmute_notifications": "Activar notificacions de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Fes clic per afegir una nota",
   "admin.dashboard.daily_retention": "Ràtio de retenció per dia després del registre",
   "admin.dashboard.monthly_retention": "Ràtio de retenció per mes després del registre",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 799fc877d..4d75dbb08 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -18,12 +18,12 @@
   "account.followers": "Abbunati",
   "account.followers.empty": "Nisunu hè abbunatu à st'utilizatore.",
   "account.followers_counter": "{count, plural, one {{counter} Abbunatu} other {{counter} Abbunati}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Abbunamentu} other {{counter} Abbunamenti}}",
   "account.follows.empty": "St'utilizatore ùn seguita nisunu.",
   "account.follows_you": "Vi seguita",
   "account.hide_reblogs": "Piattà spartere da @{name}",
   "account.joined": "Quì dapoi {date}",
-  "account.last_status": "Ultima attività",
   "account.link_verified_on": "A prupietà di stu ligame hè stata verificata u {date}",
   "account.locked_info": "U statutu di vita privata di u contu hè chjosu. U pruprietariu esamina manualmente e dumande d'abbunamentu.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Piattà @{name}",
   "account.mute_notifications": "Piattà nutificazione da @{name}",
   "account.muted": "Piattatu",
-  "account.never_active": "Mai",
   "account.posts": "Statuti",
   "account.posts_with_replies": "Statuti è risposte",
   "account.report": "Palisà @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Statutu} other {{counter} Statuti}}",
   "account.unblock": "Sbluccà @{name}",
   "account.unblock_domain": "Ùn piattà più {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ùn fà figurà nant'à u prufilu",
   "account.unfollow": "Ùn siguità più",
   "account.unmute": "Ùn piattà più @{name}",
   "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Senza cummentariu",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index 65043cc0e..97f4674ba 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -18,12 +18,12 @@
   "account.followers": "Sledující",
   "account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
   "account.followers_counter": "{count, plural, one {{counter} Sledující} few {{counter} Sledující} many {{counter} Sledujících} other {{counter} Sledujících}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Sledovaný} few {{counter} Sledovaní} many {{counter} Sledovaných} other {{counter} Sledovaných}}",
   "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
   "account.follows_you": "Sleduje vás",
   "account.hide_reblogs": "Skrýt boosty od @{name}",
   "account.joined": "Založen {date}",
-  "account.last_status": "Naposledy aktivní",
   "account.link_verified_on": "Vlastnictví tohoto odkazu bylo zkontrolováno {date}",
   "account.locked_info": "Stav soukromí tohoto účtu je nastaven na zamčeno. Jeho vlastník ručně posuzuje, kdo ho může sledovat.",
   "account.media": "Média",
@@ -32,7 +32,6 @@
   "account.mute": "Skrýt @{name}",
   "account.mute_notifications": "Skrýt oznámení od @{name}",
   "account.muted": "Skryt",
-  "account.never_active": "Nikdy",
   "account.posts": "Příspěvky",
   "account.posts_with_replies": "Příspěvky a odpovědi",
   "account.report": "Nahlásit @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Příspěvek} few {{counter} Příspěvky} many {{counter} Příspěvků} other {{counter} Příspěvků}}",
   "account.unblock": "Odblokovat @{name}",
   "account.unblock_domain": "Odblokovat doménu {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Nezvýrazňovat na profilu",
   "account.unfollow": "Přestat sledovat",
   "account.unmute": "Zrušit skrytí @{name}",
   "account.unmute_notifications": "Zrušit skrytí oznámení od @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikněte pro přidání poznámky",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index ad7316865..79ef2dfc6 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -18,12 +18,12 @@
   "account.followers": "Dilynwyr",
   "account.followers.empty": "Nid oes neb yn dilyn y defnyddiwr hwn eto.",
   "account.followers_counter": "{count, plural, one {{counter} Ddilynwr} other {{counter} o Ddilynwyr}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} yn Dilyn} other {{counter} yn Dilyn}}",
   "account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
   "account.follows_you": "Yn eich dilyn chi",
   "account.hide_reblogs": "Cuddio bwstiau o @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Gweithredol olaf",
   "account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}",
   "account.locked_info": "Mae'r statws preifatrwydd cyfrif hwn wedi'i osod i gloi. Mae'r perchennog yn adolygu'r sawl sy'n gallu eu dilyn.",
   "account.media": "Cyfryngau",
@@ -32,7 +32,6 @@
   "account.mute": "Tawelu @{name}",
   "account.mute_notifications": "Cuddio hysbysiadau o @{name}",
   "account.muted": "Distewyd",
-  "account.never_active": "Byth",
   "account.posts": "Tŵtiau",
   "account.posts_with_replies": "Tŵtiau ac atebion",
   "account.report": "Adrodd @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Dŵt} other {{counter} o Dŵtiau}}",
   "account.unblock": "Dadflocio @{name}",
   "account.unblock_domain": "Dadguddio {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Peidio a'i arddangos ar fy mhroffil",
   "account.unfollow": "Dad-ddilyn",
   "account.unmute": "Dad-dawelu @{name}",
   "account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clicio i ychwanegu nodyn",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 3c7a658a3..5861bac50 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -18,12 +18,12 @@
   "account.followers": "Følgere",
   "account.followers.empty": "Ingen følger brugeren endnu.",
   "account.followers_counter": "{count, plural, one {{counter} Følger} other {{counter} Følgere}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Følges} other {{counter} Følges}}",
   "account.follows.empty": "Denne bruger følger ikke nogen endnu.",
   "account.follows_you": "Følger dig",
   "account.hide_reblogs": "Skjul fremhævelser fra @{name}",
   "account.joined": "Tilmeldt {date}",
-  "account.last_status": "Senest aktiv",
   "account.link_verified_on": "Ejerskab af dette link blev tjekket {date}",
   "account.locked_info": "Denne kontos fortrolighedsstatus er sat til låst. Ejeren bedømmer manuelt, hvem der kan følge vedkommende.",
   "account.media": "Medier",
@@ -32,7 +32,6 @@
   "account.mute": "Skjul @{name}",
   "account.mute_notifications": "Skjul notifikationer fra @{name}",
   "account.muted": "Tystnet",
-  "account.never_active": "Aldrig",
   "account.posts": "Indlæg",
   "account.posts_with_replies": "Indlæg og svar",
   "account.report": "Anmeld @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Indlæg} other {{counter} Indlæg}}",
   "account.unblock": "Fjern blokeringen af @{name}",
   "account.unblock_domain": "Afblokér domænet {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Fjern visning på din profil",
   "account.unfollow": "Følg ikke længere",
   "account.unmute": "Fjern tavsgjort for @{name}",
   "account.unmute_notifications": "Slå notifikationer om @{name} til igen",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klik for at tilføje notat",
   "admin.dashboard.daily_retention": "Brugerfastholdelsesrate efter dag efter tilmelding",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 46bd3e07e..5344a444e 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -18,12 +18,12 @@
   "account.followers": "Follower",
   "account.followers.empty": "Diesem Profil folgt noch niemand.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Folgender} other {{counter} Folgende}}",
   "account.follows.empty": "Dieses Profil folgt noch niemandem.",
   "account.follows_you": "Folgt dir",
   "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
   "account.joined": "Beigetreten am {date}",
-  "account.last_status": "Zuletzt aktiv",
   "account.link_verified_on": "Besitz dieses Links wurde geprüft am {date}",
   "account.locked_info": "Der Privatsphärenstatus dieses Accounts wurde auf gesperrt gesetzt. Die Person bestimmt manuell wer ihm/ihr folgen darf.",
   "account.media": "Medien",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} stummschalten",
   "account.mute_notifications": "Benachrichtigungen von @{name} stummschalten",
   "account.muted": "Stummgeschaltet",
-  "account.never_active": "Nie",
   "account.posts": "Beiträge",
   "account.posts_with_replies": "Beiträge und Antworten",
   "account.report": "@{name} melden",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
   "account.unblock": "@{name} entblocken",
   "account.unblock_domain": "{domain} wieder anzeigen",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Nicht auf Profil hervorheben",
   "account.unfollow": "Entfolgen",
   "account.unmute": "@{name} nicht mehr stummschalten",
   "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Notiz durch Klicken hinzufügen",
   "admin.dashboard.daily_retention": "Benutzerverbleibrate nach Tag nach Anmeldung",
   "admin.dashboard.monthly_retention": "Benutzerverbleibrate nach Monat nach Anmeldung",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index cb999a9ef..370765f9f 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -1625,30 +1625,38 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Unfollow",
+        "id": "account.unfollow"
+      },
+      {
         "defaultMessage": "Follow",
         "id": "account.follow"
       },
       {
-        "defaultMessage": "Unfollow",
-        "id": "account.unfollow"
+        "defaultMessage": "Cancel follow request",
+        "id": "account.cancel_follow_request"
       },
       {
-        "defaultMessage": "Awaiting approval",
+        "defaultMessage": "Awaiting approval. Click to cancel follow request",
         "id": "account.requested"
       },
       {
-        "defaultMessage": "Unblock @{name}",
-        "id": "account.unblock"
+        "defaultMessage": "Unblock",
+        "id": "account.unblock_short"
       },
       {
-        "defaultMessage": "Unmute @{name}",
-        "id": "account.unmute"
+        "defaultMessage": "Unmute",
+        "id": "account.unmute_short"
       },
       {
         "defaultMessage": "Unfollow",
         "id": "confirmations.unfollow.confirm"
       },
       {
+        "defaultMessage": "Edit profile",
+        "id": "account.edit_profile"
+      },
+      {
         "defaultMessage": "Are you sure you want to unfollow {name}?",
         "id": "confirmations.unfollow.message"
       },
@@ -1661,12 +1669,8 @@
         "id": "account.followers"
       },
       {
-        "defaultMessage": "Never",
-        "id": "account.never_active"
-      },
-      {
-        "defaultMessage": "Last active",
-        "id": "account.last_status"
+        "defaultMessage": "Following",
+        "id": "account.following"
       }
     ],
     "path": "app/javascript/mastodon/features/directory/components/account_card.json"
@@ -2007,10 +2011,6 @@
       {
         "defaultMessage": "Getting started",
         "id": "getting_started.heading"
-      },
-      {
-        "defaultMessage": "Profile directory",
-        "id": "getting_started.directory"
       }
     ],
     "path": "app/javascript/mastodon/features/getting_started/index.json"
@@ -2742,7 +2742,7 @@
         "id": "report.reasons.spam"
       },
       {
-        "defaultMessage": "Malicious links, fake engagement, or repetetive replies",
+        "defaultMessage": "Malicious links, fake engagement, or repetitive replies",
         "id": "report.reasons.spam_description"
       },
       {
@@ -3403,6 +3403,10 @@
         "id": "navigation_bar.info"
       },
       {
+        "defaultMessage": "Profile directory",
+        "id": "getting_started.directory"
+      },
+      {
         "defaultMessage": "Mobile apps",
         "id": "navigation_bar.apps"
       },
@@ -3530,10 +3534,6 @@
         "id": "navigation_bar.lists"
       },
       {
-        "defaultMessage": "Profile directory",
-        "id": "getting_started.directory"
-      },
-      {
         "defaultMessage": "Preferences",
         "id": "navigation_bar.preferences"
       },
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 96fe6c609..4e8765d13 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -18,12 +18,12 @@
   "account.followers": "Ακόλουθοι",
   "account.followers.empty": "Κανείς δεν ακολουθεί αυτό τον χρήστη ακόμα.",
   "account.followers_counter": "{count, plural, one {{counter} Ακόλουθος} other {{counter} Ακόλουθοι}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Ακολουθεί}}",
   "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμα.",
   "account.follows_you": "Σε ακολουθεί",
   "account.hide_reblogs": "Απόκρυψη προωθήσεων από @{name}",
   "account.joined": "Μέλος από τις {date}",
-  "account.last_status": "Τελευταία δραστηριότητα",
   "account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε την {date}",
   "account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού είναι κλειδωμένη. Ο ιδιοκτήτης επιβεβαιώνει χειροκίνητα ποιος μπορεί να τον ακολουθήσει.",
   "account.media": "Πολυμέσα",
@@ -32,7 +32,6 @@
   "account.mute": "Σώπασε @{name}",
   "account.mute_notifications": "Σώπασε τις ειδοποιήσεις από @{name}",
   "account.muted": "Αποσιωπημένος/η",
-  "account.never_active": "Ποτέ",
   "account.posts": "Τουτ",
   "account.posts_with_replies": "Τουτ και απαντήσεις",
   "account.report": "Κατάγγειλε @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Τουτ} other {{counter} Τουτ}}",
   "account.unblock": "Ξεμπλόκαρε @{name}",
   "account.unblock_domain": "Αποκάλυψε το {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Άνευ προβολής στο προφίλ",
   "account.unfollow": "Διακοπή παρακολούθησης",
   "account.unmute": "Διακοπή αποσιώπησης @{name}",
   "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Κλικ για να βάλεις σημείωση",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 06c2b679c..2afc1b75f 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Posts",
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 8ef35c03b..0628392ae 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -18,12 +18,12 @@
   "account.followers": "Sekvantoj",
   "account.followers.empty": "Ankoraŭ neniu sekvas tiun uzanton.",
   "account.followers_counter": "{count, plural, one{{counter} Sekvanto} other {{counter} Sekvantoj}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Sekvato} other {{counter} Sekvatoj}}",
   "account.follows.empty": "Tiu uzanto ankoraŭ ne sekvas iun.",
   "account.follows_you": "Sekvas vin",
   "account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
   "account.joined": "Kuniĝis {date}",
-  "account.last_status": "Laste aktiva",
   "account.link_verified_on": "La posedanto de tiu ligilo estis kontrolita je {date}",
   "account.locked_info": "La privateco de tiu konto estas elektita kiel fermita. La posedanto povas mane akcepti tiun, kiu povas sekvi rin.",
   "account.media": "Amaskomunikiloj",
@@ -32,7 +32,6 @@
   "account.mute": "Silentigi @{name}",
   "account.mute_notifications": "Silentigi sciigojn de @{name}",
   "account.muted": "Silentigita",
-  "account.never_active": "Neniam",
   "account.posts": "Mesaĝoj",
   "account.posts_with_replies": "Kun respondoj",
   "account.report": "Signali @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Mesaĝo} other {{counter} Mesaĝoj}}",
   "account.unblock": "Malbloki @{name}",
   "account.unblock_domain": "Malbloki {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ne montri en profilo",
   "account.unfollow": "Ne plu sekvi",
   "account.unmute": "Malsilentigi @{name}",
   "account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Alklaku por aldoni noton",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index cfda3360f..811f814be 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidores",
   "account.followers.empty": "Todavía nadie sigue a este usuario.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Siguiendo}}",
   "account.follows.empty": "Todavía este usuario no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar adhesiones de @{name}",
   "account.joined": "En este servidor desde {date}",
-  "account.last_status": "Última actividad",
   "account.link_verified_on": "La propiedad de este enlace fue verificada el {date}",
   "account.locked_info": "Esta cuenta es privada. El propietario manualmente revisa quién puede seguirle.",
   "account.media": "Medios",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar a @{name}",
   "account.mute_notifications": "Silenciar notificaciones de @{name}",
   "account.muted": "Silenciado",
-  "account.never_active": "Nunca",
   "account.posts": "Mensajes",
   "account.posts_with_replies": "Mensajes y respuestas públicas",
   "account.report": "Denunciar a @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Mensaje} other {{counter} Mensajes}}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Desbloquear dominio {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "No destacar en el perfil",
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Hacé clic par agregar una nota",
   "admin.dashboard.daily_retention": "Tasa de retención de usuarios por día, después del registro",
   "admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes, después del registro",
diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json
index e243bb8d8..cb5d740fb 100644
--- a/app/javascript/mastodon/locales/es-MX.json
+++ b/app/javascript/mastodon/locales/es-MX.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidores",
   "account.followers.empty": "Todavía nadie sigue a este usuario.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Siguiendo}}",
   "account.follows.empty": "Este usuario todavía no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
   "account.joined": "Se unió el {date}",
-  "account.last_status": "Última actividad",
   "account.link_verified_on": "El proprietario de este link fue comprobado el {date}",
   "account.locked_info": "El estado de privacidad de esta cuenta està configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.",
   "account.media": "Multimedia",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar a @{name}",
   "account.mute_notifications": "Silenciar notificaciones de @{name}",
   "account.muted": "Silenciado",
-  "account.never_active": "Nunca",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots con respuestas",
   "account.report": "Reportar a @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Mostrar a {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "No mostrar en el perfil",
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clic para añadir nota",
   "admin.dashboard.daily_retention": "Tasa de retención de usuarios por día después del registro",
   "admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes después del registro",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 5725a0637..d36798e7b 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidores",
   "account.followers.empty": "Todavía nadie sigue a este usuario.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Siguiendo}}",
   "account.follows.empty": "Este usuario todavía no sigue a nadie.",
   "account.follows_you": "Te sigue",
   "account.hide_reblogs": "Ocultar retoots de @{name}",
   "account.joined": "Se unió el {date}",
-  "account.last_status": "Última actividad",
   "account.link_verified_on": "El proprietario de este link fue comprobado el {date}",
   "account.locked_info": "El estado de privacidad de esta cuenta està configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.",
   "account.media": "Multimedia",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar a @{name}",
   "account.mute_notifications": "Silenciar notificaciones de @{name}",
   "account.muted": "Silenciado",
-  "account.never_active": "Nunca",
   "account.posts": "Publicaciones",
   "account.posts_with_replies": "Publicaciones y respuestas",
   "account.report": "Reportar a @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicaciones}}",
   "account.unblock": "Desbloquear a @{name}",
   "account.unblock_domain": "Mostrar a {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "No mostrar en el perfil",
   "account.unfollow": "Dejar de seguir",
   "account.unmute": "Dejar de silenciar a @{name}",
   "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clic para añadir nota",
   "admin.dashboard.daily_retention": "Tasa de retención de usuarios por día después del registro",
   "admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes después del registro",
diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json
index 2eca42e09..4b57f4b81 100644
--- a/app/javascript/mastodon/locales/et.json
+++ b/app/javascript/mastodon/locales/et.json
@@ -18,12 +18,12 @@
   "account.followers": "Jälgijad",
   "account.followers.empty": "Keegi ei jälgi seda kasutajat veel.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "See kasutaja ei jälgi veel kedagi.",
   "account.follows_you": "Jälgib Teid",
   "account.hide_reblogs": "Peida upitused kasutajalt @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Viimati aktiivne",
   "account.link_verified_on": "Selle lingi autorsust kontrolliti {date}",
   "account.locked_info": "Selle konto privaatsussätteks on lukustatud. Omanik vaatab manuaalselt üle, kes teda jägida saab.",
   "account.media": "Meedia",
@@ -32,7 +32,6 @@
   "account.mute": "Vaigista @{name}",
   "account.mute_notifications": "Vaigista teated kasutajalt @{name}",
   "account.muted": "Vaigistatud",
-  "account.never_active": "Mitte kunagi",
   "account.posts": "Tuututused",
   "account.posts_with_replies": "Tuututused ja vastused",
   "account.report": "Raporteeri @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Eemalda blokeering @{name}",
   "account.unblock_domain": "Tee {domain} nähtavaks",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ära kuva profiilil",
   "account.unfollow": "Ära jälgi",
   "account.unmute": "Ära vaigista @{name}",
   "account.unmute_notifications": "Ära vaigista teateid kasutajalt @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 0d3eec701..0b25e8e95 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -18,12 +18,12 @@
   "account.followers": "Jarraitzaileak",
   "account.followers.empty": "Ez du inork erabiltzaile hau jarraitzen oraindik.",
   "account.followers_counter": "{count, plural, one {Jarraitzaile {counter}} other {{counter} jarraitzaile}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} jarraitzen} other {{counter} jarraitzen}}",
   "account.follows.empty": "Erabiltzaile honek ez du inor jarraitzen oraindik.",
   "account.follows_you": "Jarraitzen dizu",
   "account.hide_reblogs": "Ezkutatu @{name}(r)en bultzadak",
   "account.joined": "{date}(e)an elkartua",
-  "account.last_status": "Azkenekoz aktiboa",
   "account.link_verified_on": "Esteka honen jabetzaren egiaztaketa data: {date}",
   "account.locked_info": "Kontu honen pribatutasun egoera blokeatuta gisa ezarri da. Jabeak eskuz erabakitzen du nork jarraitu diezaioken.",
   "account.media": "Multimedia",
@@ -32,7 +32,6 @@
   "account.mute": "Mututu @{name}",
   "account.mute_notifications": "Mututu @{name}(r)en jakinarazpenak",
   "account.muted": "Mutututa",
-  "account.never_active": "Inoiz ez",
   "account.posts": "Bidalketa",
   "account.posts_with_replies": "Bidalketak eta erantzunak",
   "account.report": "Salatu @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {Bidalketa {counter}} other {{counter} bidalketa}}",
   "account.unblock": "Desblokeatu @{name}",
   "account.unblock_domain": "Berriz erakutsi {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ez nabarmendu profilean",
   "account.unfollow": "Utzi jarraitzeari",
   "account.unmute": "Desmututu @{name}",
   "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "Erabiltzaile atxikitze-tasa izena eman ondorengo eguneko",
   "admin.dashboard.monthly_retention": "Erabiltzaile atxikitze-tasa izena eman ondorengo hilabeteko",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 2024903d0..a81efacbb 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -18,12 +18,12 @@
   "account.followers": "پی‌گیرندگان",
   "account.followers.empty": "هنوز کسی این کاربر را پی‌گیری نمی‌کند.",
   "account.followers_counter": "{count, plural, one {{counter} پی‌گیرنده} other {{counter} پی‌گیرنده}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} پی‌گرفته} other {{counter} پی‌گرفته}}",
   "account.follows.empty": "این کاربر هنوز پی‌گیر کسی نیست.",
   "account.follows_you": "پی می‌گیردتان",
   "account.hide_reblogs": "نهفتن تقویت‌های @{name}",
   "account.joined": "پیوسته از {date}",
-  "account.last_status": "آخرین فعّالیت",
   "account.link_verified_on": "مالکیت این پیوند در {date} بررسی شد",
   "account.locked_info": "این حساب خصوصی است. صاحبش تصمیم می‌گیرد که چه کسی پی‌گیرش باشد.",
   "account.media": "رسانه",
@@ -32,7 +32,6 @@
   "account.mute": "خموشاندن @{name}",
   "account.mute_notifications": "خموشاندن آگاهی‌ها از @{name}",
   "account.muted": "خموش",
-  "account.never_active": "هرگز",
   "account.posts": "فرسته",
   "account.posts_with_replies": "فرسته‌ها و پاسخ‌ها",
   "account.report": "گزارش @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}}",
   "account.unblock": "رفع مسدودیت @{name}",
   "account.unblock_domain": "رفع مسدودیت دامنهٔ {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "معرّفی نکردن در نمایه",
   "account.unfollow": "ناپی‌گیری",
   "account.unmute": "ناخموشی @{name}",
   "account.unmute_notifications": "ناخموشی آگاهی‌ها از @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "برای افزودن یادداشت کلیک کنید",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index eaad6e358..e6407b79e 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -18,12 +18,12 @@
   "account.followers": "Seuraajat",
   "account.followers.empty": "Kukaan ei seuraa tätä käyttäjää vielä.",
   "account.followers_counter": "{count, plural, one {{counter} seuraaja} other {{counter} seuraajat}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} seuraa} other {{counter} seuraa}}",
   "account.follows.empty": "Tämä käyttäjä ei vielä seuraa ketään.",
   "account.follows_you": "Seuraa sinua",
   "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}",
   "account.joined": "Liittynyt {date}",
-  "account.last_status": "Aktiivinen viimeksi",
   "account.link_verified_on": "Tämän linkin omistaja tarkistettiin {date}",
   "account.locked_info": "Tämän tilin yksityisyyden tila on asetettu lukituksi. Omistaja arvioi manuaalisesti, kuka voi seurata niitä.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mykistä @{name}",
   "account.mute_notifications": "Mykistä ilmoitukset käyttäjältä @{name}",
   "account.muted": "Mykistetty",
-  "account.never_active": "Ei koskaan",
   "account.posts": "Viestit",
   "account.posts_with_replies": "Viestit ja vastaukset",
   "account.report": "Raportoi @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Salli @{name}",
   "account.unblock_domain": "Salli {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lopeta seuraaminen",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
   "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Lisää muistiinpano napsauttamalla",
   "admin.dashboard.daily_retention": "Käyttäjän säilyminen rekisteröitymisen jälkeiseen päivään mennessä",
   "admin.dashboard.monthly_retention": "Käyttäjän säilyminen rekisteröitymisen jälkeiseen kuukauteen mennessä",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index f85662775..d5fdcebdd 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -18,12 +18,12 @@
   "account.followers": "Abonnés",
   "account.followers.empty": "Personne ne suit cet·te utilisateur·rice pour l’instant.",
   "account.followers_counter": "{count, plural, one {{counter} Abonné·e} other {{counter} Abonné·e·s}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Abonnements}}",
   "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.",
   "account.follows_you": "Vous suit",
   "account.hide_reblogs": "Masquer les partages de @{name}",
   "account.joined": "Ici depuis {date}",
-  "account.last_status": "Dernière activité",
   "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}",
   "account.locked_info": "Ce compte est privé. Son ou sa propriétaire approuve manuellement qui peut le suivre.",
   "account.media": "Médias",
@@ -32,7 +32,6 @@
   "account.mute": "Masquer @{name}",
   "account.mute_notifications": "Ignorer les notifications de @{name}",
   "account.muted": "Masqué·e",
-  "account.never_active": "Jamais",
   "account.posts": "Messages",
   "account.posts_with_replies": "Messages et réponses",
   "account.report": "Signaler @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Message} other {{counter} Messages}}",
   "account.unblock": "Débloquer @{name}",
   "account.unblock_domain": "Débloquer le domaine {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ne plus recommander sur le profil",
   "account.unfollow": "Ne plus suivre",
   "account.unmute": "Ne plus masquer @{name}",
   "account.unmute_notifications": "Ne plus masquer les notifications de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Cliquez pour ajouter une note",
   "admin.dashboard.daily_retention": "Taux de maintien des utilisateur·rice·s par jour après inscription",
   "admin.dashboard.monthly_retention": "Brugerfastholdelsesrate efter måned efter tilmelding",
diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json
index 06a6bca5b..aeb152e56 100644
--- a/app/javascript/mastodon/locales/ga.json
+++ b/app/javascript/mastodon/locales/ga.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "No comment provided",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json
index 35ab5e83e..d71705c5c 100644
--- a/app/javascript/mastodon/locales/gd.json
+++ b/app/javascript/mastodon/locales/gd.json
@@ -18,12 +18,12 @@
   "account.followers": "Luchd-leantainn",
   "account.followers.empty": "Chan eil neach sam bith a’ leantainn air a’ chleachdaiche seo fhathast.",
   "account.followers_counter": "{count, plural, one {{counter} neach-leantainn} two {{counter} neach-leantainn} few {{counter} luchd-leantainn} other {{counter} luchd-leantainn}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {A’ leantainn air {counter}} two {A’ leantainn air {counter}} few {A’ leantainn air {counter}} other {A’ leantainn air {counter}}}",
   "account.follows.empty": "Chan eil an cleachdaiche seo a’ leantainn air neach sam bith fhathast.",
   "account.follows_you": "’Gad leantainn",
   "account.hide_reblogs": "Falaich na brosnachaidhean o @{name}",
   "account.joined": "Air ballrachd fhaighinn {date}",
-  "account.last_status": "An gnìomh mu dheireadh",
   "account.link_verified_on": "Chaidh dearbhadh cò leis a tha an ceangal seo {date}",
   "account.locked_info": "Tha prìobhaideachd ghlaiste aig a’ chunntais seo. Nì an sealbhadair lèirmheas a làimh air cò dh’fhaodas leantainn orra.",
   "account.media": "Meadhanan",
@@ -32,7 +32,6 @@
   "account.mute": "Mùch @{name}",
   "account.mute_notifications": "Mùch na brathan o @{name}",
   "account.muted": "’Ga mhùchadh",
-  "account.never_active": "Chan ann idir",
   "account.posts": "Postaichean",
   "account.posts_with_replies": "Postaichean ’s freagairtean",
   "account.report": "Dèan gearan mu @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} phost} two {{counter} phost} few {{counter} postaichean} other {{counter} post}}",
   "account.unblock": "Dì-bhac @{name}",
   "account.unblock_domain": "Dì-bhac an àrainn {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Na brosnaich air a’ phròifil",
   "account.unfollow": "Na lean tuilleadh",
   "account.unmute": "Dì-mhùch @{name}",
   "account.unmute_notifications": "Dì-mhùch na brathan o @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Briog airson nòta a chur ris",
   "admin.dashboard.daily_retention": "Reat glèidheadh nan cleachdaichean às dèidh an clàradh a-rèir latha",
   "admin.dashboard.monthly_retention": "Reat glèidheadh nan cleachdaichean às dèidh an clàradh a-rèir mìos",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 63d4d7dbc..6db991aac 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidoras",
   "account.followers.empty": "Aínda ninguén segue esta usuaria.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidora} other {{counter} Seguidoras}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Seguindo} other {{counter} Seguindo}}",
   "account.follows.empty": "Esta usuaria aínda non segue a ninguén.",
   "account.follows_you": "Séguete",
   "account.hide_reblogs": "Agochar repeticións de @{name}",
   "account.joined": "Uníuse {date}",
-  "account.last_status": "Última actividade",
   "account.link_verified_on": "A propiedade desta ligazón foi verificada o {date}",
   "account.locked_info": "Esta é unha conta privada. A propietaria revisa de xeito manual quen pode seguila.",
   "account.media": "Multimedia",
@@ -32,7 +32,6 @@
   "account.mute": "Acalar @{name}",
   "account.mute_notifications": "Acalar as notificacións de @{name}",
   "account.muted": "Acalada",
-  "account.never_active": "Nunca",
   "account.posts": "Publicacións",
   "account.posts_with_replies": "Publicacións e respostas",
   "account.report": "Informar sobre @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicacións}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Amosar {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Non amosar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Deixar de silenciar a @{name}",
   "account.unmute_notifications": "Deixar de silenciar as notificacións de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Preme para engadir nota",
   "admin.dashboard.daily_retention": "Ratio de retención de usuarias após rexistrarse",
   "admin.dashboard.monthly_retention": "Ratio de retención de usuarias após un mes do rexistro",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index fd97ce53c..452b64d9e 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -18,12 +18,12 @@
   "account.followers": "עוקבים",
   "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.",
   "account.followers_counter": "{count, plural,one {עוקב אחד} other {{counter} עוקבים}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural,one {עוקב אחרי {counter}}other {עוקב אחרי {counter}}}",
   "account.follows.empty": "משתמש זה לא עוקב אחר אף אחד עדיין.",
   "account.follows_you": "במעקב אחריך",
   "account.hide_reblogs": "להסתיר הידהודים מאת @{name}",
   "account.joined": "הצטרפו ב{date}",
-  "account.last_status": "פעילות אחרונה",
   "account.link_verified_on": "בעלות על הקישור הזה נבדקה לאחרונה ב{date}",
   "account.locked_info": "מצב הפרטיות של החשבון הנוכחי הוגדר כנעול. בעל החשבון קובע באופן פרטני מי יכול לעקוב אחריו.",
   "account.media": "מדיה",
@@ -32,7 +32,6 @@
   "account.mute": "להשתיק את @{name}",
   "account.mute_notifications": "להסתיר התראות מאת @{name}",
   "account.muted": "מושתק",
-  "account.never_active": "אף פעם",
   "account.posts": "הודעות",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "לדווח על @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "הסרת חסימה מעל @{name}",
   "account.unblock_domain": "הסר חסימה מקהילת {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "לא להציג בפרופיל",
   "account.unfollow": "הפסקת מעקב",
   "account.unmute": "הפסקת השתקת @{name}",
   "account.unmute_notifications": "להפסיק הסתרת הודעות מעם @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "ללא הערה",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json
index b5d731ac4..bb08cc92e 100644
--- a/app/javascript/mastodon/locales/hi.json
+++ b/app/javascript/mastodon/locales/hi.json
@@ -18,12 +18,12 @@
   "account.followers": "फॉलोवर",
   "account.followers.empty": "कोई भी इस यूज़र् को फ़ॉलो नहीं करता है",
   "account.followers_counter": "{count, plural, one {{counter} अनुगामी} other {{counter} समर्थक}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} निम्नलिखित} other {{counter} निम्नलिखित}}",
   "account.follows.empty": "यह यूज़र् अभी तक किसी को फॉलो नहीं करता है।",
   "account.follows_you": "आपको फॉलो करता है",
   "account.hide_reblogs": "@{name} के बूस्ट छुपाएं",
   "account.joined": "Joined {date}",
-  "account.last_status": "अंतिम सक्रिय",
   "account.link_verified_on": "इस लिंक का स्वामित्व {date} को चेक किया गया था",
   "account.locked_info": "यह खाता गोपनीयता स्थिति लॉक करने के लिए सेट है। मालिक मैन्युअल रूप से समीक्षा करता है कि कौन उनको फॉलो कर सकता है।",
   "account.media": "मीडिया",
@@ -32,7 +32,6 @@
   "account.mute": "म्यूट @{name}",
   "account.mute_notifications": "@{name} के नोटिफिकेशन म्यूट करे",
   "account.muted": "म्यूट है",
-  "account.never_active": "कभी नहीं दिखे",
   "account.posts": "टूट्स",
   "account.posts_with_replies": "टूट्स एवं जवाब",
   "account.report": "रिपोर्ट @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} भोंपू} other {{counter} भोंपू}}",
   "account.unblock": "@{name} को अनब्लॉक करें",
   "account.unblock_domain": "{domain} दिखाए",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "प्रोफ़ाइल पर न दिखाए",
   "account.unfollow": "अनफॉलो करें",
   "account.unmute": "अनम्यूट @{name}",
   "account.unmute_notifications": "@{name} के नोटिफिकेशन अनम्यूट करे",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "नोट्स जोड़ने के लिए क्लिक करें",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index e8798aaba..a74c819c0 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -18,12 +18,12 @@
   "account.followers": "Pratitelji",
   "account.followers.empty": "Nitko još ne prati korisnika/cu.",
   "account.followers_counter": "{count, plural, one {{counter} pratitelj} other {{counter} pratitelja}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} praćeni} few{{counter} praćena} other {{counter} praćenih}}",
   "account.follows.empty": "Korisnik/ca još ne prati nikoga.",
   "account.follows_you": "Prati te",
   "account.hide_reblogs": "Sakrij boostove od @{name}",
   "account.joined": "Pridružio se {date}",
-  "account.last_status": "Posljednja aktivnost",
   "account.link_verified_on": "Vlasništvo ove poveznice provjereno je {date}",
   "account.locked_info": "Status privatnosti ovog računa postavljen je na zaključano. Vlasnik ručno pregledava tko ih može pratiti.",
   "account.media": "Medijski sadržaj",
@@ -32,7 +32,6 @@
   "account.mute": "Utišaj @{name}",
   "account.mute_notifications": "Utišaj obavijesti od @{name}",
   "account.muted": "Utišano",
-  "account.never_active": "Nikad",
   "account.posts": "Tootovi",
   "account.posts_with_replies": "Tootovi i odgovori",
   "account.report": "Prijavi @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} toot} other {{counter} toota}}",
   "account.unblock": "Deblokiraj @{name}",
   "account.unblock_domain": "Deblokiraj domenu {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ne ističi na profilu",
   "account.unfollow": "Prestani pratiti",
   "account.unmute": "Poništi utišavanje @{name}",
   "account.unmute_notifications": "Ne utišavaj obavijesti od @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Kliknite za dodavanje bilješke",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 107b47b73..494ca5f62 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -18,12 +18,12 @@
   "account.followers": "Követő",
   "account.followers.empty": "Ezt a felhasználót még senki sem követi.",
   "account.followers_counter": "{count, plural, one {{counter} Követő} other {{counter} Követő}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Követett}}",
   "account.follows.empty": "Ez a felhasználó még senkit sem követ.",
   "account.follows_you": "Követ téged",
   "account.hide_reblogs": "@{name} megtolásainak elrejtése",
   "account.joined": "Csatlakozott {date}",
-  "account.last_status": "Utoljára aktív",
   "account.link_verified_on": "A linket eredetiségét ebben az időpontban ellenőriztük: {date}",
   "account.locked_info": "Ennek a fióknak zárolt a láthatósága. A tulajdonos kézzel engedélyezi, hogy ki követheti őt.",
   "account.media": "Média",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} némítása",
   "account.mute_notifications": "@{name} értesítéseinek némítása",
   "account.muted": "Némítva",
-  "account.never_active": "Soha",
   "account.posts": "Bejegyzések",
   "account.posts_with_replies": "Bejegyzések és válaszok",
   "account.report": "@{name} jelentése",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Bejegyzés} other {{counter} Bejegyzés}}",
   "account.unblock": "@{name} letiltásának feloldása",
   "account.unblock_domain": "{domain} elrejtésének feloldása",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ne jelenjen meg a profilodon",
   "account.unfollow": "Követés megszüntetése",
   "account.unmute": "@{name} némítás feloldása",
   "account.unmute_notifications": "@{name} némított értesítéseinek feloldása",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikk a feljegyzéshez",
   "admin.dashboard.daily_retention": "Napi regisztráció utáni felhasználómegtartási arány",
   "admin.dashboard.monthly_retention": "Havi regisztráció utáni felhasználómegtartási arány",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 0f984b0bc..934d41a41 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -18,12 +18,12 @@
   "account.followers": "Հետեւողներ",
   "account.followers.empty": "Այս օգտատիրոջը դեռ ոչ մէկ չի հետեւում։",
   "account.followers_counter": "{count, plural, one {{counter} Հետեւորդ} other {{counter} Հետեւորդ}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} հետեւած} other {{counter} հետեւած}}",
   "account.follows.empty": "Այս օգտատէրը դեռ ոչ մէկի չի հետեւում։",
   "account.follows_you": "Հետեւում է քեզ",
   "account.hide_reblogs": "Թաքցնել @{name}֊ի տարածածները",
   "account.joined": "Միացել է {date}-ից",
-  "account.last_status": "Վերջին այցը",
   "account.link_verified_on": "Սոյն յղման տիրապետումը ստուգուած է՝ {date}֊ին",
   "account.locked_info": "Սոյն հաշուի գաղտնիութեան մակարդակը նշուած է որպէս՝ փակ։ Հաշուի տէրն ընտրում է, թէ ով կարող է հետեւել իրեն։",
   "account.media": "Մեդիա",
@@ -32,7 +32,6 @@
   "account.mute": "Լռեցնել @{name}֊ին",
   "account.mute_notifications": "Անջատել ծանուցումները @{name}֊ից",
   "account.muted": "Լռեցուած",
-  "account.never_active": "Երբեք",
   "account.posts": "Գրառումներ",
   "account.posts_with_replies": "Գրառումներ եւ պատասխաններ",
   "account.report": "Բողոքել @{name}֊ի մասին",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Գրառում} other {{counter} Գրառումներ}}",
   "account.unblock": "Ապաարգելափակել @{name}֊ին",
   "account.unblock_domain": "Ցուցադրել {domain} թաքցուած տիրոյթի գրառումները",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Չցուցադրել անձնական էջում",
   "account.unfollow": "Ապահետեւել",
   "account.unmute": "Ապալռեցնել @{name}֊ին",
   "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Սեղմէ՛ք գրառելու համար\n",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index d9a66373a..bc0b3c087 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -18,12 +18,12 @@
   "account.followers": "Pengikut",
   "account.followers.empty": "Pengguna ini belum ada pengikut.",
   "account.followers_counter": "{count, plural, other {{counter} Pengikut}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Mengikuti}}",
   "account.follows.empty": "Pengguna ini belum mengikuti siapapun.",
   "account.follows_you": "Mengikuti anda",
   "account.hide_reblogs": "Sembunyikan boosts dari @{name}",
   "account.joined": "Bergabung {date}",
-  "account.last_status": "Terakhir aktif",
   "account.link_verified_on": "Kepemilikan tautan ini telah dicek pada {date}",
   "account.locked_info": "Status privasi akun ini disetel untuk dikunci. Pemilik secara manual meninjau siapa yang dapat mengikutinya.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Bisukan @{name}",
   "account.mute_notifications": "Bisukan pemberitahuan dari @{name}",
   "account.muted": "Dibisukan",
-  "account.never_active": "Tak pernah",
   "account.posts": "Kiriman",
   "account.posts_with_replies": "Postingan dengan balasan",
   "account.report": "Laporkan @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, other {{counter} Toot}}",
   "account.unblock": "Hapus blokir @{name}",
   "account.unblock_domain": "Buka blokir domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Jangan tampilkan di profil",
   "account.unfollow": "Berhenti mengikuti",
   "account.unmute": "Berhenti membisukan @{name}",
   "account.unmute_notifications": "Berhenti bisukan pemberitahuan dari @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klik untuk menambah catatan",
   "admin.dashboard.daily_retention": "Tingkat retensi pengguna perhari setelah mendaftar",
   "admin.dashboard.monthly_retention": "Tingkat retensi pengguna perbulan setelah mendaftar",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index ef4a489ad..a60f68fba 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -18,12 +18,12 @@
   "account.followers": "Sequanti",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Sequas tu",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Celar @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Mesaji",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "Denuncar @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desblokusar @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Ne plus sequar",
   "account.unmute": "Ne plus celar @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json
index 34e539360..ab8c55d1e 100644
--- a/app/javascript/mastodon/locales/is.json
+++ b/app/javascript/mastodon/locales/is.json
@@ -18,12 +18,12 @@
   "account.followers": "Fylgjendur",
   "account.followers.empty": "Ennþá fylgist enginn með þessum notanda.",
   "account.followers_counter": "{count, plural, one {{counter} fylgjandi} other {{counter} fylgjendur}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} fylgist með} other {{counter} fylgjast með}}",
   "account.follows.empty": "Þessi notandi fylgist ennþá ekki með neinum.",
   "account.follows_you": "Fylgir þér",
   "account.hide_reblogs": "Fela endurbirtingar fyrir @{name}",
   "account.joined": "Gerðist þátttakandi {date}",
-  "account.last_status": "Síðasta virkni",
   "account.link_verified_on": "Eignarhald á þessum tengli var athugað þann {date}",
   "account.locked_info": "Staða gagnaleyndar á þessum aðgangi er stillt á læsingu. Eigandinn yfirfer handvirkt hverjir geti fylgst með honum.",
   "account.media": "Myndskrár",
@@ -32,7 +32,6 @@
   "account.mute": "Þagga niður í @{name}",
   "account.mute_notifications": "Þagga tilkynningar frá @{name}",
   "account.muted": "Þaggað",
-  "account.never_active": "Aldrei",
   "account.posts": "Færslur",
   "account.posts_with_replies": "Færslur og svör",
   "account.report": "Kæra @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} færsla} other {{counter} færslur}}",
   "account.unblock": "Aflétta útilokun af @{name}",
   "account.unblock_domain": "Aflétta útilokun lénsins {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ekki birta á notandasniði",
   "account.unfollow": "Hætta að fylgja",
   "account.unmute": "Hætta að þagga niður í @{name}",
   "account.unmute_notifications": "Hætta að þagga tilkynningar frá @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Smelltu til að bæta við minnispunkti",
   "admin.dashboard.daily_retention": "Hlutfall virkra notenda eftir nýskráningu eftir dögum",
   "admin.dashboard.monthly_retention": "Hlutfall virkra notenda eftir nýskráningu eftir mánuðum",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 5530c5abf..389986ef5 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -18,12 +18,12 @@
   "account.followers": "Follower",
   "account.followers.empty": "Nessuno segue ancora questo utente.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} Seguiti}}",
   "account.follows.empty": "Questo utente non segue nessuno ancora.",
   "account.follows_you": "Ti segue",
   "account.hide_reblogs": "Nascondi condivisioni da @{name}",
   "account.joined": "Su questa istanza dal {date}",
-  "account.last_status": "Ultima attività",
   "account.link_verified_on": "La proprietà di questo link è stata controllata il {date}",
   "account.locked_info": "Questo è un account privato. Il proprietario approva manualmente chi può seguirlo.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Silenzia @{name}",
   "account.mute_notifications": "Silenzia notifiche da @{name}",
   "account.muted": "Silenziato",
-  "account.never_active": "Mai",
   "account.posts": "Post",
   "account.posts_with_replies": "Post e risposte",
   "account.report": "Segnala @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Post}}",
   "account.unblock": "Sblocca @{name}",
   "account.unblock_domain": "Sblocca il dominio {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Non mostrare sul profilo",
   "account.unfollow": "Smetti di seguire",
   "account.unmute": "Riattiva @{name}",
   "account.unmute_notifications": "Riattiva le notifiche da @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clicca per aggiungere una nota",
   "admin.dashboard.daily_retention": "Tasso di ritenzione utente per giorno dopo la registrazione",
   "admin.dashboard.monthly_retention": "Tasso di ritenzione utente per mese dopo la registrazione",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index f120df2ae..19b8cb705 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -18,12 +18,12 @@
   "account.followers": "フォロワー",
   "account.followers.empty": "まだ誰もフォローしていません。",
   "account.followers_counter": "{counter} フォロワー",
+  "account.following": "Following",
   "account.following_counter": "{counter} フォロー",
   "account.follows.empty": "まだ誰もフォローしていません。",
   "account.follows_you": "フォローされています",
   "account.hide_reblogs": "@{name}さんからのブーストを非表示",
   "account.joined": "{date} に登録",
-  "account.last_status": "最後の活動",
   "account.link_verified_on": "このリンクの所有権は{date}に確認されました",
   "account.locked_info": "このアカウントは承認制アカウントです。相手が承認するまでフォローは完了しません。",
   "account.media": "メディア",
@@ -32,7 +32,6 @@
   "account.mute": "@{name}さんをミュート",
   "account.mute_notifications": "@{name}さんからの通知を受け取らない",
   "account.muted": "ミュート済み",
-  "account.never_active": "活動なし",
   "account.posts": "投稿",
   "account.posts_with_replies": "投稿と返信",
   "account.report": "@{name}さんを通報",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{counter} 投稿",
   "account.unblock": "@{name}さんのブロックを解除",
   "account.unblock_domain": "{domain}のブロックを解除",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "プロフィールから外す",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
   "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "クリックしてメモを追加",
   "admin.dashboard.daily_retention": "サインアップ後の日ごとのユーザー継続率",
   "admin.dashboard.monthly_retention": "サインアップ後の月ごとのユーザー継続率",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index 561770060..fd848a164 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -18,12 +18,12 @@
   "account.followers": "მიმდევრები",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "მოგყვებათ",
   "account.hide_reblogs": "დაიმალოს ბუსტები @{name}-სგან",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "მედია",
@@ -32,7 +32,6 @@
   "account.mute": "გააჩუმე @{name}",
   "account.mute_notifications": "გააჩუმე შეტყობინებები @{name}-სგან",
   "account.muted": "გაჩუმებული",
-  "account.never_active": "Never",
   "account.posts": "ტუტები",
   "account.posts_with_replies": "ტუტები და პასუხები",
   "account.report": "დაარეპორტე @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "განბლოკე @{name}",
   "account.unblock_domain": "გამოაჩინე {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "არ გამოირჩეს პროფილზე",
   "account.unfollow": "ნუღარ მიჰყვები",
   "account.unmute": "ნუღარ აჩუმებ @{name}-ს",
   "account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json
index 0f0880100..213f529e3 100644
--- a/app/javascript/mastodon/locales/kab.json
+++ b/app/javascript/mastodon/locales/kab.json
@@ -18,12 +18,12 @@
   "account.followers": "Imeḍfaren",
   "account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.",
   "account.followers_counter": "{count, plural, one {{count} n umeḍfar} other {{count} n imeḍfaren}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} yeṭṭafaren} aḍfar {{counter} wayeḍ}}",
   "account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
   "account.follows_you": "Yeṭṭafaṛ-ik",
   "account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}",
   "account.joined": "Yerna-d {date}",
-  "account.last_status": "Armud aneggaru",
   "account.link_verified_on": "Taɣara n useɣwen-a tettwasenqed ass n {date}",
   "account.locked_info": "Amiḍan-agi uslig isekweṛ. D bab-is kan i izemren ad yeǧǧ, s ufus-is, win ara t-iḍefṛen.",
   "account.media": "Amidya",
@@ -32,7 +32,6 @@
   "account.mute": "Sgugem @{name}",
   "account.mute_notifications": "Sgugem tilɣa sγur @{name}",
   "account.muted": "Yettwasgugem",
-  "account.never_active": "Werǧin",
   "account.posts": "Tijewwaqin",
   "account.posts_with_replies": "Tijewwaqin akked tririyin",
   "account.report": "Cetki ɣef @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} ajewwaq} other {{counter} ijewwaqen}}",
   "account.unblock": "Serreḥ i @{name}",
   "account.unblock_domain": "Ssken-d {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
   "account.unfollow": "Ur ṭṭafaṛ ara",
   "account.unmute": "Kkes asgugem ɣef @{name}",
   "account.unmute_notifications": "Serreḥ ilɣa sɣur @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Ulac iwenniten",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json
index 3bd56653c..1802d5fdf 100644
--- a/app/javascript/mastodon/locales/kk.json
+++ b/app/javascript/mastodon/locales/kk.json
@@ -18,12 +18,12 @@
   "account.followers": "Оқырмандар",
   "account.followers.empty": "Әлі ешкім жазылмаған.",
   "account.followers_counter": "{count, plural, one {{counter} Оқырман} other {{counter} Оқырман}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Жазылым} other {{counter} Жазылым}}",
   "account.follows.empty": "Ешкімге жазылмапты.",
   "account.follows_you": "Сізге жазылыпты",
   "account.hide_reblogs": "@{name} атты қолданушының әрекеттерін жасыру",
   "account.joined": "Joined {date}",
-  "account.last_status": "Соңғы белсенділік",
   "account.link_verified_on": "Сілтеме меншігі расталған күн {date}",
   "account.locked_info": "Бұл қолданушы өзі туралы мәліметтерді жасырған. Тек жазылғандар ғана көре алады.",
   "account.media": "Медиа",
@@ -32,7 +32,6 @@
   "account.mute": "Үнсіз қылу @{name}",
   "account.mute_notifications": "@{name} туралы ескертпелерді жасыру",
   "account.muted": "Үнсіз",
-  "account.never_active": "Ешқашан",
   "account.posts": "Жазбалар",
   "account.posts_with_replies": "Жазбалар мен жауаптар",
   "account.report": "Шағымдану @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Пост} other {{counter} Пост}}",
   "account.unblock": "Бұғаттан шығару @{name}",
   "account.unblock_domain": "Бұғаттан шығару {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Профильде рекомендемеу",
   "account.unfollow": "Оқымау",
   "account.unmute": "@{name} ескертпелерін қосу",
   "account.unmute_notifications": "@{name} ескертпелерін көрсету",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Жазба қалдыру үшін бас",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/kmr.json b/app/javascript/mastodon/locales/kmr.json
index 84c8978a4..43468eee4 100644
--- a/app/javascript/mastodon/locales/kmr.json
+++ b/app/javascript/mastodon/locales/kmr.json
@@ -18,12 +18,12 @@
   "account.followers": "Şopîner",
   "account.followers.empty": "Kesekî hin ev bikarhêner neşopandiye.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Dişopîne} other {{counter} Dişopîne}}",
   "account.follows.empty": "Ev bikarhêner hin kesekî heya niha neşopandiye.",
   "account.follows_you": "Te dişopîne",
   "account.hide_reblogs": "Bilindkirinên ji @{name} veşêre",
   "account.joined": "Tevlîbû di {date} de",
-  "account.last_status": "Çalakiya dawî",
   "account.link_verified_on": "Xwedaniya li vê girêdanê di {date} de hatiye kontrolkirin",
   "account.locked_info": "Rewşa vê ajimêrê wek kilît kirî hatiye saz kirin. Xwedî yê ajimêrê, kesên vê bişopîne bi dest vekolin dike.",
   "account.media": "Medya",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} Bêdeng bike",
   "account.mute_notifications": "Agahdariyan ji @{name} bêdeng bike",
   "account.muted": "Bêdengkirî",
-  "account.never_active": "Tu car",
   "account.posts": "Şandî",
   "account.posts_with_replies": "Şandî û bersiv",
   "account.report": "@{name} Ragihîne",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural,one {{counter} şandî}other {{counter} şandî}}",
   "account.unblock": "Astengê li ser @{name} rake",
   "account.unblock_domain": "Astengê li ser navperê {domain} rake",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Li ser profîl nîşan neke",
   "account.unfollow": "Neşopîne",
   "account.unmute": "@{name} Bêdeng bike",
   "account.unmute_notifications": "Agahdariyan ji @{name} bêdeng bike",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Bitikîne bo nîşeyekê tevlî bikî",
   "admin.dashboard.daily_retention": "Rêjeya ragirtina bikarhêner bi roj piştî tomarkirinê",
   "admin.dashboard.monthly_retention": "Rêjeya ragirtina bikarhêner bi meh piştî tomarkirinê",
diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json
index 9da0f8c57..133ad1848 100644
--- a/app/javascript/mastodon/locales/kn.json
+++ b/app/javascript/mastodon/locales/kn.json
@@ -18,12 +18,12 @@
   "account.followers": "ಹಿಂಬಾಲಕರು",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "ಟೂಟ್‌ಗಳು",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 767fd8d46..79f6de035 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -18,12 +18,12 @@
   "account.followers": "팔로워",
   "account.followers.empty": "아직 아무도 이 유저를 팔로우하고 있지 않습니다.",
   "account.followers_counter": "{counter} 팔로워",
+  "account.following": "Following",
   "account.following_counter": "{counter} 팔로잉",
   "account.follows.empty": "이 유저는 아직 아무도 팔로우하고 있지 않습니다.",
   "account.follows_you": "날 팔로우합니다",
   "account.hide_reblogs": "@{name}의 부스트를 숨기기",
   "account.joined": "{date}에 가입함",
-  "account.last_status": "마지막 활동",
   "account.link_verified_on": "{date}에 이 링크의 소유권이 확인 됨",
   "account.locked_info": "이 계정의 프라이버시 설정은 잠금으로 설정되어 있습니다. 계정 소유자가 수동으로 팔로워를 승인합니다.",
   "account.media": "미디어",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} 뮤트",
   "account.mute_notifications": "@{name}의 알림을 뮤트",
   "account.muted": "뮤트 됨",
-  "account.never_active": "없음",
   "account.posts": "게시물",
   "account.posts_with_replies": "게시물과 답장",
   "account.report": "@{name} 신고",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{counter} 게시물",
   "account.unblock": "차단 해제",
   "account.unblock_domain": "도메인 {domain} 차단 해제",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "프로필에 추천하지 않기",
   "account.unfollow": "팔로우 해제",
   "account.unmute": "@{name} 뮤트 해제",
   "account.unmute_notifications": "@{name}의 알림 뮤트 해제",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "클릭해서 노트 추가",
   "admin.dashboard.daily_retention": "가입 후 일별 사용자 유지율",
   "admin.dashboard.monthly_retention": "가입 후 월별 사용자 유지율",
diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json
index a71702171..5a3e5a1f2 100644
--- a/app/javascript/mastodon/locales/ku.json
+++ b/app/javascript/mastodon/locales/ku.json
@@ -18,12 +18,12 @@
   "account.followers": "شوێنکەوتووان",
   "account.followers.empty": "کەسێک شوێن ئەم بەکارهێنەرە نەکەوتووە",
   "account.followers_counter": "{count, plural, one {{counter} شوێنکەوتوو} other {{counter} شوێنکەوتوو}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "ئەم بەکارهێنەرە تا ئێستا شوێن کەس نەکەوتووە.",
   "account.follows_you": "شوێنکەوتووەکانت",
   "account.hide_reblogs": "داشاردنی بووستەکان لە @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "دوایین چالاکی",
   "account.link_verified_on": "خاوەنداریەتی ئەم لینکە لە {date} چێک کراوە",
   "account.locked_info": "تایبەتمەندی ئەم هەژمارەیە ڕیکخراوە بۆ قوفڵدراوە. خاوەنەکە بە دەستی پێداچوونەوە دەکات کە کێ دەتوانێت شوێنیان بکەوێت.",
   "account.media": "میدیا",
@@ -32,7 +32,6 @@
   "account.mute": "بێدەنگکردن @{name}",
   "account.mute_notifications": "هۆشیارکەرەوەکان لاببە لە @{name}",
   "account.muted": "بێ دەنگ",
-  "account.never_active": "هەرگیز",
   "account.posts": "توتس",
   "account.posts_with_replies": "توتس و وەڵامەکان",
   "account.report": "گوزارشت @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.unblock": "@{name} لاببە",
   "account.unblock_domain": "کردنەوەی دۆمەینی {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "تایبەتمەندی لەسەر پرۆفایلەکە نیە",
   "account.unfollow": "بەدوادانەچو",
   "account.unmute": "بێدەنگکردنی @{name}",
   "account.unmute_notifications": "بێدەنگکردنی هۆشیارییەکان لە @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "کرتەبکە بۆ زیادکردنی تێبینی",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json
index 0e8aa9cf8..068732610 100644
--- a/app/javascript/mastodon/locales/kw.json
+++ b/app/javascript/mastodon/locales/kw.json
@@ -18,12 +18,12 @@
   "account.followers": "Holyoryon",
   "account.followers.empty": "Ny wra nagonan holya'n devnydhyer ma hwath.",
   "account.followers_counter": "{count, plural, one {{counter} Holyer} other {{counter} Holyer}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {Ow holya {counter}} other {Ow holya {counter}}}",
   "account.follows.empty": "Ny wra'n devnydhyer ma holya nagonan hwath.",
   "account.follows_you": "Y'th hol",
   "account.hide_reblogs": "Kudha kenerthow a @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Bew diwettha",
   "account.link_verified_on": "Perghenogeth an kolm ma a veu checkys dhe {date}",
   "account.locked_info": "Studh privetter an akont ma yw alhwedhys. An perghen a wra dasweles dre leuv piw a yll aga holya.",
   "account.media": "Myski",
@@ -32,7 +32,6 @@
   "account.mute": "Tawhe @{name}",
   "account.mute_notifications": "Tawhe gwarnyansow a @{name}",
   "account.muted": "Tawhes",
-  "account.never_active": "Nevra",
   "account.posts": "Postow",
   "account.posts_with_replies": "Postow ha gorthebow",
   "account.report": "Reportya @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Tout} other {{counter} Tout}}",
   "account.unblock": "Anlettya @{name}",
   "account.unblock_domain": "Anlettya gorfarth {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Na wra diskwedhes yn profil",
   "account.unfollow": "Anholya",
   "account.unmute": "Antawhe @{name}",
   "account.unmute_notifications": "Antawhe gwarnyansow a @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klyckya dhe geworra noten",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index 600f4249e..57f6c6216 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Užtildytas",
-  "account.never_active": "Niekada",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Nebesekti",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 07d93f563..aa3c6de3d 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -18,12 +18,12 @@
   "account.followers": "Sekotāji",
   "account.followers.empty": "Šim lietotājam patreiz nav sekotāju.",
   "account.followers_counter": "{count, plural, one {{counter} Sekotājs} other {{counter} Sekotāji}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Sekojošs} other {{counter} Sekojoši}}",
   "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
   "account.follows_you": "Seko tev",
   "account.hide_reblogs": "Paslēpt paceltos ierakstus no lietotāja @{name}",
   "account.joined": "Pievienojās {date}",
-  "account.last_status": "Pēdējā aktivitāte",
   "account.link_verified_on": "Šīs saites piederība ir pārbaudīta {date}",
   "account.locked_info": "Šī konta privātuma statuss ir slēgts. Īpašnieks izskatīs, kurš viņam drīkst sekot.",
   "account.media": "Mediji",
@@ -32,7 +32,6 @@
   "account.mute": "Apklusināt @{name}",
   "account.mute_notifications": "Nerādīt paziņojumus no @{name}",
   "account.muted": "Apklusināts",
-  "account.never_active": "Nekad",
   "account.posts": "Ziņas",
   "account.posts_with_replies": "Ziņas un atbildes",
   "account.report": "Ziņot par lietotāju @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} ziņa} other {{counter} ziņas}}",
   "account.unblock": "Atbloķēt lietotāju @{name}",
   "account.unblock_domain": "Atbloķēt domēnu {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Neattēlot profilā",
   "account.unfollow": "Pārstāt sekot",
   "account.unmute": "Noņemt apklusinājumu @{name}",
   "account.unmute_notifications": "Rādīt paziņojumus no lietotāja @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Noklikšķiniet, lai pievienotu piezīmi",
   "admin.dashboard.daily_retention": "Lietotāju saglabāšanas rādītājs dienā pēc reģistrēšanās",
   "admin.dashboard.monthly_retention": "Lietotāju saglabāšanas rādītājs mēnesī pēc reģistrēšanās",
diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json
index 54eae6e6d..a263d407b 100644
--- a/app/javascript/mastodon/locales/mk.json
+++ b/app/javascript/mastodon/locales/mk.json
@@ -18,12 +18,12 @@
   "account.followers": "Следбеници",
   "account.followers.empty": "Никој не го следи овој корисник сеуште.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "Корисникот не следи никој сеуште.",
   "account.follows_you": "Те следи тебе",
   "account.hide_reblogs": "Сокриј буст од @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Последно активен",
   "account.link_verified_on": "Сопстевноста на овај линк беше проверен на {date}",
   "account.locked_info": "Статусот на приватност на овај корисник е сетиран како заклучен. Корисникот одлучува кој можи да го следи него.",
   "account.media": "Медија",
@@ -32,7 +32,6 @@
   "account.mute": "Зачути го @{name}",
   "account.mute_notifications": "Исклучи известувања од @{name}",
   "account.muted": "Зачутено",
-  "account.never_active": "Никогаш",
   "account.posts": "Тутови",
   "account.posts_with_replies": "Тутови и реплики",
   "account.report": "Пријави @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Одблокирај @{name}",
   "account.unblock_domain": "Прикажи {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Не прикажувај на профил",
   "account.unfollow": "Одследи",
   "account.unmute": "Зачути го @{name}",
   "account.unmute_notifications": "Исклучи известувања од @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json
index 766bdfafd..f20de5554 100644
--- a/app/javascript/mastodon/locales/ml.json
+++ b/app/javascript/mastodon/locales/ml.json
@@ -18,12 +18,12 @@
   "account.followers": "പിന്തുടരുന്നവർ",
   "account.followers.empty": "ഈ ഉപയോക്താവിനെ ആരും ഇതുവരെ പിന്തുടരുന്നില്ല.",
   "account.followers_counter": "{count, plural, one {{counter} പിന്തുടരുന്നവർ} other {{counter} പിന്തുടരുന്നവർ}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} പിന്തുടരുന്നു} other {{counter} പിന്തുടരുന്നു}}",
   "account.follows.empty": "ഈ ഉപയോക്താവ് ആരേയും ഇതുവരെ പിന്തുടരുന്നില്ല.",
   "account.follows_you": "നിങ്ങളെ പിന്തുടരുന്നു",
   "account.hide_reblogs": "@{name} ബൂസ്റ്റ് ചെയ്തവ മറയ്കുക",
   "account.joined": "{date} ൽ ചേർന്നു",
-  "account.last_status": "അവസാനം കണ്ടത്",
   "account.link_verified_on": "ഈ ലിങ്കിന്റെ ഉടമസ്തത {date} ഇൽ ഉറപ്പാക്കിയതാണ്",
   "account.locked_info": "ഈ അംഗത്വത്തിന്റെ സ്വകാര്യതാ നിലപാട് അനുസരിച്ച് പിന്തുടരുന്നവരെ തിരഞ്ഞെടുക്കാനുള്ള വിവേചനാധികാരം ഉടമസ്ഥനിൽ നിഷിപ്തമായിരിക്കുന്നു.",
   "account.media": "മീഡിയ",
@@ -32,7 +32,6 @@
   "account.mute": "@{name}-നെ(യെ) നിശ്ശബ്ദമാക്കൂ",
   "account.mute_notifications": "@{name} യിൽ നിന്നുള്ള അറിയിപ്പുകൾ നിശബ്ദമാക്കുക",
   "account.muted": "നിശ്ശബ്ദമാക്കിയിരിക്കുന്നു",
-  "account.never_active": "ഒരിക്കലും ഇല്ല",
   "account.posts": "പോസ്റ്റുകൾ",
   "account.posts_with_replies": "പോസ്റ്റുകളും മറുപടികളും",
   "account.report": "റിപ്പോർട്ട് ചെയ്യുക @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} ടൂട്ട്} other {{counter} ടൂട്ടുകൾ}}",
   "account.unblock": "@{name} തടഞ്ഞത് മാറ്റുക",
   "account.unblock_domain": "{domain} എന്ന മേഖല വെളിപ്പെടുത്തുക",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "പ്രൊഫൈലിൽ പ്രകടമാക്കരുത്",
   "account.unfollow": "പിന്തുടരുന്നത് നിര്‍ത്തുക",
   "account.unmute": "നിശ്ശബ്ദമാക്കുന്നത് നിർത്തുക @{name}",
   "account.unmute_notifications": "@{name} യിൽ നിന്നുള്ള അറിയിപ്പുകൾ പ്രസിദ്ധപ്പെടുത്തുക",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "കുറിപ്പ് ചേർക്കാൻ ക്ലിക്കുചെയ്യുക",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json
index 9bbd24777..213c6c80d 100644
--- a/app/javascript/mastodon/locales/mr.json
+++ b/app/javascript/mastodon/locales/mr.json
@@ -18,12 +18,12 @@
   "account.followers": "अनुयायी",
   "account.followers.empty": "ह्या वापरकर्त्याचा आतापर्यंत कोणी अनुयायी नाही.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "हा वापरकर्ता अजूनपर्यंत कोणाचा अनुयायी नाही.",
   "account.follows_you": "तुमचा अनुयायी आहे",
   "account.hide_reblogs": "@{name} पासून सर्व बूस्ट लपवा",
   "account.joined": "Joined {date}",
-  "account.last_status": "शेवटचे सक्रिय",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "दृक्‌‌श्राव्य मजकूर",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} ला मूक कारा",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} ला ब्लॉक करा",
   "account.unblock_domain": "उघड करा {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "अनुयायी असणे थांबवा",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index 42dd34131..7b79d38a5 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -18,12 +18,12 @@
   "account.followers": "Pengikut",
   "account.followers.empty": "Belum ada yang mengikuti pengguna ini.",
   "account.followers_counter": "{count, plural, one {{counter} Pengikut} other {{counter} Pengikut}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Diikuti} other {{counter} Diikuti}}",
   "account.follows.empty": "Pengguna ini belum mengikuti sesiapa.",
   "account.follows_you": "Mengikuti anda",
   "account.hide_reblogs": "Sembunyikan galakan daripada @{name}",
   "account.joined": "Sertai pada {date}",
-  "account.last_status": "Terakhir aktif",
   "account.link_verified_on": "Pemilikan pautan ini telah disemak pada {date}",
   "account.locked_info": "Status privasi akaun ini dikunci. Pemiliknya menyaring sendiri siapa yang boleh mengikutinya.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Bisukan @{name}",
   "account.mute_notifications": "Bisukan pemberitahuan daripada @{name}",
   "account.muted": "Dibisukan",
-  "account.never_active": "Jangan sesekali",
   "account.posts": "Hantaran",
   "account.posts_with_replies": "Hantaran dan balasan",
   "account.report": "Laporkan @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Hantaran} other {{counter} Hantaran}}",
   "account.unblock": "Nyahsekat @{name}",
   "account.unblock_domain": "Nyahsekat domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Jangan tampilkan di profil",
   "account.unfollow": "Nyahikut",
   "account.unmute": "Nyahbisukan @{name}",
   "account.unmute_notifications": "Nyahbisukan pemberitahuan daripada @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klik untuk tambah catatan",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 4ad3335a3..4ab0d3b64 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -18,12 +18,12 @@
   "account.followers": "Volgers",
   "account.followers.empty": "Niemand volgt nog deze gebruiker.",
   "account.followers_counter": "{count, plural, one {{counter} volger} other {{counter} volgers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} volgend} other {{counter} volgend}}",
   "account.follows.empty": "Deze gebruiker volgt nog niemand.",
   "account.follows_you": "Volgt jou",
   "account.hide_reblogs": "Boosts van @{name} verbergen",
   "account.joined": "Geregistreerd in {date}",
-  "account.last_status": "Laatst actief",
   "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}",
   "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} negeren",
   "account.mute_notifications": "Meldingen van @{name} negeren",
   "account.muted": "Genegeerd",
-  "account.never_active": "Nooit",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots en reacties",
   "account.report": "@{name} rapporteren",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} toot} other {{counter} toots}}",
   "account.unblock": "@{name} deblokkeren",
   "account.unblock_domain": "{domain} niet langer verbergen",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Niet op profiel weergeven",
   "account.unfollow": "Ontvolgen",
   "account.unmute": "@{name} niet langer negeren",
   "account.unmute_notifications": "Meldingen van @{name} niet langer negeren",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klik om een opmerking toe te voegen",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index 5fdbfd25d..ddfeb2a97 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -18,12 +18,12 @@
   "account.followers": "Fylgjarar",
   "account.followers.empty": "Ingen fylgjer denne brukaren enno.",
   "account.followers_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjarar}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjar}}",
   "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.",
   "account.follows_you": "Fylgjer deg",
   "account.hide_reblogs": "Gøym fremhevingar frå @{name}",
   "account.joined": "Vart med {date}",
-  "account.last_status": "Sist aktiv",
   "account.link_verified_on": "Eigarskap for denne lenkja vart sist sjekka {date}",
   "account.locked_info": "Denne kontoen er privat. Eigaren kan sjølv velja kven som kan fylgja han.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Målbind @{name}",
   "account.mute_notifications": "Målbind varsel frå @{name}",
   "account.muted": "Målbunden",
-  "account.never_active": "Aldri",
   "account.posts": "Tut",
   "account.posts_with_replies": "Tut og svar",
   "account.report": "Rapporter @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} tut} other {{counter} tut}}",
   "account.unblock": "Slutt å blokera @{name}",
   "account.unblock_domain": "Vis {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ikkje framhev på profil",
   "account.unfollow": "Slutt å fylgja",
   "account.unmute": "Av-demp @{name}",
   "account.unmute_notifications": "Vis varsel frå @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikk for å leggja til merknad",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 2b90414f0..896989b14 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -18,12 +18,12 @@
   "account.followers": "Følgere",
   "account.followers.empty": "Ingen følger denne brukeren ennå.",
   "account.followers_counter": "{count, plural, one {{counter} følger} other {{counter} følgere}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} som følges} other {{counter} som følges}}",
   "account.follows.empty": "Denne brukeren følger ikke noen enda.",
   "account.follows_you": "Følger deg",
   "account.hide_reblogs": "Skjul fremhevinger fra @{name}",
   "account.joined": "Ble med den {date}",
-  "account.last_status": "Sist aktiv",
   "account.link_verified_on": "Eierskap av denne lenken ble sjekket {date}",
   "account.locked_info": "Denne kontoens personvernstatus er satt til låst. Eieren vurderer manuelt hvem som kan følge dem.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Demp @{name}",
   "account.mute_notifications": "Ignorer varsler fra @{name}",
   "account.muted": "Dempet",
-  "account.never_active": "Aldri",
   "account.posts": "Innlegg",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "Rapportér @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} tut} other {{counter} tuter}}",
   "account.unblock": "Avblokker @{name}",
   "account.unblock_domain": "Vis {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ikke vis frem på profilen",
   "account.unfollow": "Avfølg",
   "account.unmute": "Avdemp @{name}",
   "account.unmute_notifications": "Vis varsler fra @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikk for å legge til et notat",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 282a0aa59..b1ee0a977 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidors",
   "account.followers.empty": "Degun sèc pas aqueste utilizaire pel moment.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Abonaments} other {{counter} Abonaments}}",
   "account.follows.empty": "Aqueste utilizaire sèc pas degun pel moment.",
   "account.follows_you": "Vos sèc",
   "account.hide_reblogs": "Rescondre los partatges de @{name}",
   "account.joined": "Arribèt en {date}",
-  "account.last_status": "Darrièra activitat",
   "account.link_verified_on": "La proprietat d’aqueste ligam foguèt verificada lo {date}",
   "account.locked_info": "L’estatut de privacitat del compte es configurat sus clavat. Lo proprietari causís qual pòt sègre son compte.",
   "account.media": "Mèdias",
@@ -32,7 +32,6 @@
   "account.mute": "Rescondre @{name}",
   "account.mute_notifications": "Rescondre las notificacions de @{name}",
   "account.muted": "Mes en silenci",
-  "account.never_active": "Jamai",
   "account.posts": "Tuts",
   "account.posts_with_replies": "Tuts e responsas",
   "account.report": "Senhalar @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
   "account.unblock": "Desblocar @{name}",
   "account.unblock_domain": "Desblocar {domain}",
+  "account.unblock_short": "Unblock",
   "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}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clicar per ajustar una nòta",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json
index a7e5313a3..d31ed3fe9 100644
--- a/app/javascript/mastodon/locales/pa.json
+++ b/app/javascript/mastodon/locales/pa.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 07e88ead2..481675f5c 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -18,12 +18,12 @@
   "account.followers": "Śledzący",
   "account.followers.empty": "Nikt jeszcze nie śledzi tego użytkownika.",
   "account.followers_counter": "{count, plural, one {{counter} śledzący} few {{counter} śledzących} many {{counter} śledzących} other {{counter} śledzących}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} śledzony} few {{counter} śledzonych} many {{counter} śledzonych} other {{counter} śledzonych}}",
   "account.follows.empty": "Ten użytkownik nie śledzi jeszcze nikogo.",
   "account.follows_you": "Śledzi Cię",
   "account.hide_reblogs": "Ukryj podbicia od @{name}",
   "account.joined": "Dołączył(a) {date}",
-  "account.last_status": "Ostatnia aktywność",
   "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}",
   "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go śledzić.",
   "account.media": "Zawartość multimedialna",
@@ -32,7 +32,6 @@
   "account.mute": "Wycisz @{name}",
   "account.mute_notifications": "Wycisz powiadomienia o @{name}",
   "account.muted": "Wyciszony",
-  "account.never_active": "Nigdy",
   "account.posts": "Wpisy",
   "account.posts_with_replies": "Wpisy i odpowiedzi",
   "account.report": "Zgłoś @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} wpis} few {{counter} wpisy} many {{counter} wpisów} other {{counter} wpisów}}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Odblokuj domenę {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Przestań polecać",
   "account.unfollow": "Przestań śledzić",
   "account.unmute": "Cofnij wyciszenie @{name}",
   "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Naciśnij aby dodać notatkę",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 66410b252..d23b5bfda 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidores",
   "account.followers.empty": "Nada aqui.",
   "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {segue {counter}} other {segue {counter}}}",
   "account.follows.empty": "Nada aqui.",
   "account.follows_you": "te segue",
   "account.hide_reblogs": "Ocultar boosts de @{name}",
   "account.joined": "Entrou em {date}",
-  "account.last_status": "Ativo pela última vez",
   "account.link_verified_on": "link verificado em {date}",
   "account.locked_info": "Trancado. Seguir requer aprovação manual do perfil.",
   "account.media": "Mídia",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar @{name}",
   "account.mute_notifications": "Ocultar notificações de @{name}",
   "account.muted": "Silenciado",
-  "account.never_active": "Nunca",
   "account.posts": "Toots",
   "account.posts_with_replies": "Com respostas",
   "account.report": "Denunciar @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Desbloquear domínio {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Remover",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Dessilenciar @{name}",
   "account.unmute_notifications": "Mostrar notificações de @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Nota pessoal sobre este perfil aqui",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "Taxa de retenção de usuários por mês, após a inscrição",
diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json
index 48e1fb044..d36e2d0ef 100644
--- a/app/javascript/mastodon/locales/pt-PT.json
+++ b/app/javascript/mastodon/locales/pt-PT.json
@@ -18,12 +18,12 @@
   "account.followers": "Seguidores",
   "account.followers.empty": "Ainda ninguém segue este utilizador.",
   "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidores}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {A seguir {counter}}}",
   "account.follows.empty": "Este utilizador ainda não segue ninguém.",
   "account.follows_you": "Segue-te",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
   "account.joined": "Ingressou em {date}",
-  "account.last_status": "Última atividade",
   "account.link_verified_on": "A posse deste link foi verificada em {date}",
   "account.locked_info": "Esta conta é privada. O proprietário revê manualmente quem a pode seguir.",
   "account.media": "Média",
@@ -32,7 +32,6 @@
   "account.mute": "Silenciar @{name}",
   "account.mute_notifications": "Silenciar notificações de @{name}",
   "account.muted": "Silenciada",
-  "account.never_active": "Nunca",
   "account.posts": "Toots",
   "account.posts_with_replies": "Publicações e respostas",
   "account.report": "Denunciar @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
   "account.unblock_domain": "Mostrar {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Não mostrar no perfil",
   "account.unfollow": "Deixar de seguir",
   "account.unmute": "Não silenciar @{name}",
   "account.unmute_notifications": "Deixar de silenciar @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Clique para adicionar nota",
   "admin.dashboard.daily_retention": "Taxa de retenção de utilizadores por dia após a inscrição",
   "admin.dashboard.monthly_retention": "Taxa de retenção de utilizadores por mês após a inscrição",
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index 6e3ee6c2f..aed16677e 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -18,12 +18,12 @@
   "account.followers": "Abonați",
   "account.followers.empty": "Acest utilizator încă nu are abonați.",
   "account.followers_counter": "{count, plural, one {{counter} Abonat} few {{counter} Abonați} other {{counter} Abonați}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Abonament} few {{counter} Abonamente} other {{counter} Abonamente}}",
   "account.follows.empty": "Momentan acest utilizator nu are niciun abonament.",
   "account.follows_you": "Este abonat la tine",
   "account.hide_reblogs": "Ascunde distribuirile de la @{name}",
   "account.joined": "S-a înscris în {date}",
-  "account.last_status": "Ultima activitate",
   "account.link_verified_on": "Proprietatea acestui link a fost verificată pe {date}",
   "account.locked_info": "Acest profil este privat. Această persoană aprobă manual conturile care se abonează la ea.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Ignoră pe @{name}",
   "account.mute_notifications": "Ignoră notificările de la @{name}",
   "account.muted": "Ignorat",
-  "account.never_active": "Niciodată",
   "account.posts": "Postări",
   "account.posts_with_replies": "Postări și răspunsuri",
   "account.report": "Raportează pe @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Deblochează pe @{name}",
   "account.unblock_domain": "Deblochează domeniul {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Nu promova pe profil",
   "account.unfollow": "Nu mai urmări",
   "account.unmute": "Nu mai ignora pe @{name}",
   "account.unmute_notifications": "Activează notificările de la @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 9cbd82f5c..cacfac23a 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -18,12 +18,12 @@
   "account.followers": "Подписчики",
   "account.followers.empty": "На этого пользователя пока никто не подписан.",
   "account.followers_counter": "{count, plural, one {{counter} подписчик} many {{counter} подписчиков} other {{counter} подписчика}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} подписка} many {{counter} подписок} other {{counter} подписки}}",
   "account.follows.empty": "Этот пользователь пока ни на кого не подписался.",
   "account.follows_you": "Подписан(а) на вас",
   "account.hide_reblogs": "Скрыть продвижения от @{name}",
   "account.joined": "Зарегистрирован(а) с {date}",
-  "account.last_status": "Последняя активность",
   "account.link_verified_on": "Владение этой ссылкой было проверено {date}",
   "account.locked_info": "Это закрытый аккаунт. Его владелец вручную одобряет подписчиков.",
   "account.media": "Медиа",
@@ -32,7 +32,6 @@
   "account.mute": "Игнорировать @{name}",
   "account.mute_notifications": "Скрыть уведомления от @{name}",
   "account.muted": "Игнорируется",
-  "account.never_active": "Никогда",
   "account.posts": "Посты",
   "account.posts_with_replies": "Посты и ответы",
   "account.report": "Пожаловаться на @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} пост} many {{counter} постов} other {{counter} поста}}",
   "account.unblock": "Разблокировать @{name}",
   "account.unblock_domain": "Разблокировать {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Не рекомендовать в профиле",
   "account.unfollow": "Отписаться",
   "account.unmute": "Убрать {name} из игнорируемых",
   "account.unmute_notifications": "Показывать уведомления от @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Текст заметки",
   "admin.dashboard.daily_retention": "Уровень удержания пользователей после регистрации, в днях",
   "admin.dashboard.monthly_retention": "Уровень удержания пользователей после регистрации, в месяцах",
diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json
index 3be5b5012..d94bf8c31 100644
--- a/app/javascript/mastodon/locales/sa.json
+++ b/app/javascript/mastodon/locales/sa.json
@@ -18,12 +18,12 @@
   "account.followers": "अनुसर्तारः",
   "account.followers.empty": "नाऽनुसर्तारो वर्तन्ते",
   "account.followers_counter": "{count, plural, one {{counter} अनुसर्ता} two {{counter} अनुसर्तारौ} other {{counter} अनुसर्तारः}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} अनुसृतः} two {{counter} अनुसृतौ} other {{counter} अनुसृताः}}",
   "account.follows.empty": "न कोऽप्यनुसृतो वर्तते",
   "account.follows_you": "त्वामनुसरति",
   "account.hide_reblogs": "@{name} मित्रस्य प्रकाशनानि छिद्यन्ताम्",
   "account.joined": "Joined {date}",
-  "account.last_status": "गतसक्रियता",
   "account.link_verified_on": "अन्तर्जालस्थानस्यास्य स्वामित्वं परीक्षितमासीत् {date} दिने",
   "account.locked_info": "एतस्या लेखायाः गुह्यता \"निषिद्ध\"इति वर्तते । स्वामी स्वयञ्चिनोति कोऽनुसर्ता भवितुमर्हतीति ।",
   "account.media": "सामग्री",
@@ -32,7 +32,6 @@
   "account.mute": "निःशब्दम् @{name}",
   "account.mute_notifications": "@{name} सूचनाः निष्क्रियन्ताम्",
   "account.muted": "निःशब्दम्",
-  "account.never_active": "नैव कदापि",
   "account.posts": "दौत्यानि",
   "account.posts_with_replies": "दौत्यानि प्रत्युत्तराणि च",
   "account.report": "आविद्यताम् @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} दौत्यम्} two {{counter} दौत्ये} other {{counter} दौत्यानि}}",
   "account.unblock": "निषेधता नश्यताम् @{name}",
   "account.unblock_domain": "प्रदेशनिषेधता नश्यताम् {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "व्यक्तिगतविवरणे मा प्रकाश्यताम्",
   "account.unfollow": "नश्यतामनुसरणम्",
   "account.unmute": "सशब्दम् @{name}",
   "account.unmute_notifications": "@{name} सूचनाः सक्रियन्ताम्",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "टीकायोजनार्थं नुद्यताम्",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json
index cdc001ba8..0f77e776b 100644
--- a/app/javascript/mastodon/locales/sc.json
+++ b/app/javascript/mastodon/locales/sc.json
@@ -18,12 +18,12 @@
   "account.followers": "Sighiduras",
   "account.followers.empty": "Nemos sighit ancora custa persone.",
   "account.followers_counter": "{count, plural, one {{counter} sighidura} other {{counter} sighiduras}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {Sighende a {counter}} other {Sighende a {counter}}}",
   "account.follows.empty": "Custa persone non sighit ancora a nemos.",
   "account.follows_you": "Ti sighit",
   "account.hide_reblogs": "Cua is cumpartziduras de @{name}",
   "account.joined": "At aderidu su {date}",
-  "account.last_status": "Ùrtima atividade",
   "account.link_verified_on": "Sa propiedade de custu ligòngiu est istada controllada su {date}",
   "account.locked_info": "S'istadu de riservadesa de custu contu est istadu cunfiguradu comente blocadu. Sa persone chi tenet sa propiedade revisionat a manu chie dda podet sighire.",
   "account.media": "Cuntenutu multimediale",
@@ -32,7 +32,6 @@
   "account.mute": "Pone a @{name} a sa muda",
   "account.mute_notifications": "Disativa is notìficas de @{name}",
   "account.muted": "A sa muda",
-  "account.never_active": "Mai",
   "account.posts": "Publicatziones",
   "account.posts_with_replies": "Publicatziones e rispostas",
   "account.report": "Signala @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} publicatzione} other {{counter} publicatziones}}",
   "account.unblock": "Isbloca a @{name}",
   "account.unblock_domain": "Isbloca su domìniu {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Non cussiges in su profilu",
   "account.unfollow": "Non sigas prus",
   "account.unmute": "Torra a ativare a @{name}",
   "account.unmute_notifications": "Ativa notìficas pro @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Incarca pro agiùnghere una nota",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json
index dc513c8a1..bec751ac7 100644
--- a/app/javascript/mastodon/locales/si.json
+++ b/app/javascript/mastodon/locales/si.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "{date} එක් වී ඇත",
-  "account.last_status": "අවසන් වරට සක්‍රීය",
   "account.link_verified_on": "මෙම සබැඳියේ හිමිකාරිත්වය {date} දින පරීක්ෂා කරන ලදි",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "මාධ්‍යය",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} නිහඬ කරන්න",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "@{name} වාර්තා කරන්න",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} අනවහිර කරන්න",
   "account.unblock_domain": "{domain} වසම අනවහිර කරන්න",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "පැතිකඩෙහි විශේෂාංග නොකරන්න",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "සටහන එකතු කිරීමට ක්ලික් කරන්න",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 3c3ca14b4..deb9ffafc 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -18,12 +18,12 @@
   "account.followers": "Sledujúci",
   "account.followers.empty": "Tohto používateľa ešte nikto nenásleduje.",
   "account.followers_counter": "{count, plural, one {{counter} Sledujúci} few {{counter} Sledujúci} many {{counter} Sledujúci} other {{counter} Sledujúci}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "Tento používateľ ešte nikoho nenasleduje.",
   "account.follows_you": "Nasleduje ťa",
   "account.hide_reblogs": "Skry vyzdvihnutia od @{name}",
   "account.joined": "Pridal/a sa v {date}",
-  "account.last_status": "Naposledy aktívny",
   "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}",
   "account.locked_info": "Stav súkromia pre tento účet je nastavený na zamknutý. Jeho vlastník sám prehodnocuje, kto ho môže sledovať.",
   "account.media": "Médiá",
@@ -32,7 +32,6 @@
   "account.mute": "Nevšímaj si @{name}",
   "account.mute_notifications": "Stĺm oboznámenia od @{name}",
   "account.muted": "Utíšený/á",
-  "account.never_active": "Nikdy",
   "account.posts": "Príspevky",
   "account.posts_with_replies": "Príspevky, aj s odpoveďami",
   "account.report": "Nahlás @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokuj @{name}",
   "account.unblock_domain": "Prestaň skrývať {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Nezobrazuj na profile",
   "account.unfollow": "Prestaň následovať",
   "account.unmute": "Prestaň ignorovať @{name}",
   "account.unmute_notifications": "Zruš stĺmenie oboznámení od @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikni pre vloženie poznámky",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index d4475760b..a9c68d8cd 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -18,12 +18,12 @@
   "account.followers": "Sledilci",
   "account.followers.empty": "Nihče ne sledi temu uporabniku.",
   "account.followers_counter": "{count, plural, one {ima {count} sledilca} two {ima {count} sledilca} few {ima {count} sledilcev} other {ima {count} sledilce}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {sledi {count} osebi} two {sledi {count} osebama} few {sledi {count} osebam} other {sledi {count} osebam}}",
   "account.follows.empty": "Ta uporabnik še ne sledi nikomur.",
   "account.follows_you": "Vam sledi",
   "account.hide_reblogs": "Skrij spodbude od @{name}",
   "account.joined": "Pridružen/a {date}",
-  "account.last_status": "Zadnja dejavnost",
   "account.link_verified_on": "Lastništvo te povezave je bilo preverjeno {date}",
   "account.locked_info": "Stanje zasebnosti računa je nastavljeno na zaklenjeno. Lastnik ročno pregleda, kdo ga lahko spremlja.",
   "account.media": "Mediji",
@@ -32,7 +32,6 @@
   "account.mute": "Utišaj @{name}",
   "account.mute_notifications": "Utišaj obvestila od @{name}",
   "account.muted": "Utišan",
-  "account.never_active": "Nikoli",
   "account.posts": "Tuti",
   "account.posts_with_replies": "Tuti in odgovori",
   "account.report": "Prijavi @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokiraj @{name}",
   "account.unblock_domain": "Razkrij {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ne vključi v profil",
   "account.unfollow": "Prenehaj slediti",
   "account.unmute": "Odtišaj @{name}",
   "account.unmute_notifications": "Vklopi obvestila od @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
index b3a70dd27..2ce035323 100644
--- a/app/javascript/mastodon/locales/sq.json
+++ b/app/javascript/mastodon/locales/sq.json
@@ -18,12 +18,12 @@
   "account.followers": "Ndjekës",
   "account.followers.empty": "Këtë përdorues ende s’e ndjek kush.",
   "account.followers_counter": "{count, plural, one {{counter} Ndjekës} other {{counter} Ndjekës}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} i Ndjekur} other {{counter} të Ndjekur}}",
   "account.follows.empty": "Ky përdorues ende s’ndjek kënd.",
   "account.follows_you": "Ju ndjek",
   "account.hide_reblogs": "Fshih përforcime nga @{name}",
   "account.joined": "U bë pjesë më {date}",
-  "account.last_status": "Aktiv së fundi më",
   "account.link_verified_on": "Pronësia e kësaj lidhjeje qe kontrolluar më {date}",
   "account.locked_info": "Gjendja e privatësisë së kësaj llogarie është caktuar si e kyçur. I zoti merr dorazi në shqyrtim cilët mund ta ndjekin.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Heshtoni @{name}",
   "account.mute_notifications": "Heshtoji njoftimet prej @{name}",
   "account.muted": "Heshtuar",
-  "account.never_active": "Kurrë",
   "account.posts": "Mesazhe",
   "account.posts_with_replies": "Mesazhe dhe përgjigje",
   "account.report": "Raportojeni @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Mesazh} other {{counter} Mesazhe}}",
   "account.unblock": "Zhbllokoje @{name}",
   "account.unblock_domain": "Zhblloko përkatësinë {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Mos e përfshi në profil",
   "account.unfollow": "Resht së ndjekuri",
   "account.unmute": "Ktheji zërin @{name}",
   "account.unmute_notifications": "Hiqua ndalimin e shfaqjes njoftimeve nga @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klikoni për të shtuar shënim",
   "admin.dashboard.daily_retention": "Shkallë mbajtjeje përdoruesi, në ditë, pas regjistrimit",
   "admin.dashboard.monthly_retention": "Shkallë mbajtjeje përdoruesi, në muaj, pas regjistrimit",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index 67a21e94d..fff26e8a4 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -18,12 +18,12 @@
   "account.followers": "Pratioca",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Prati Vas",
   "account.hide_reblogs": "Sakrij podrške koje daje korisnika @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Mediji",
@@ -32,7 +32,6 @@
   "account.mute": "Ućutkaj korisnika @{name}",
   "account.mute_notifications": "Isključi obaveštenja od korisnika @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Statusa",
   "account.posts_with_replies": "Toots with replies",
   "account.report": "Prijavi @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Odblokiraj korisnika @{name}",
   "account.unblock_domain": "Odblokiraj domen {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Otprati",
   "account.unmute": "Ukloni ućutkavanje korisniku @{name}",
   "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 8eae28d93..064a2dac8 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -18,12 +18,12 @@
   "account.followers": "Пратиоци",
   "account.followers.empty": "Тренутно нико не прати овог корисника.",
   "account.followers_counter": "{count, plural, one {{counter} пратилац} few {{counter} пратиоца} other {{counter} пратилаца}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} прати} few {{counter} прати} other {{counter} прати}}",
   "account.follows.empty": "Корисник тренутно не прати никога.",
   "account.follows_you": "Прати Вас",
   "account.hide_reblogs": "Сакриј подршке које даје корисника @{name}",
   "account.joined": "Придружио/ла се {date}",
-  "account.last_status": "Последњи пут активан/на",
   "account.link_verified_on": "Власништво над овом везом је проверено {date}",
   "account.locked_info": "Статус приватности овог налога је подешен на закључано. Власник ручно прегледа ко га може пратити.",
   "account.media": "Медији",
@@ -32,7 +32,6 @@
   "account.mute": "Ућуткај корисника @{name}",
   "account.mute_notifications": "Искључи обавештења од корисника @{name}",
   "account.muted": "Ућуткан",
-  "account.never_active": "Никада",
   "account.posts": "Трубе",
   "account.posts_with_replies": "Трубе и одговори",
   "account.report": "Пријави @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} објава} few {{counter} објаве} other {{counter} објава}}",
   "account.unblock": "Одблокирај корисника @{name}",
   "account.unblock_domain": "Одблокирај домен {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Не истичи на налогу",
   "account.unfollow": "Отпрати",
   "account.unmute": "Уклони ућуткавање кориснику @{name}",
   "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 09a2f5176..fed4e7bca 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -18,12 +18,12 @@
   "account.followers": "Följare",
   "account.followers.empty": "Ingen följer denna användare än.",
   "account.followers_counter": "{count, plural, one {{counter} Följare} other {{counter} Följare}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Följer} other {{counter} Följer}}",
   "account.follows.empty": "Denna användare följer inte någon än.",
   "account.follows_you": "Följer dig",
   "account.hide_reblogs": "Dölj knuffar från @{name}",
   "account.joined": "Gick med {date}",
-  "account.last_status": "Senast aktiv",
   "account.link_verified_on": "Ägarskap för detta konto kontrollerades den {date}",
   "account.locked_info": "Detta konto har låst integritetsstatus. Ägaren väljer manuellt vem som kan följa.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Tysta @{name}",
   "account.mute_notifications": "Stäng av notifieringar från @{name}",
   "account.muted": "Tystad",
-  "account.never_active": "Aldrig",
   "account.posts": "Tutningar",
   "account.posts_with_replies": "Tutningar och svar",
   "account.report": "Rapportera @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural,one {{counter} Tuta} other {{counter} Tutor}}",
   "account.unblock": "Avblockera @{name}",
   "account.unblock_domain": "Sluta dölja {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Visa inte på profil",
   "account.unfollow": "Sluta följ",
   "account.unmute": "Sluta tysta @{name}",
   "account.unmute_notifications": "Återaktivera aviseringar från @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Klicka för att lägga till anteckning",
   "admin.dashboard.daily_retention": "Användarlojalitet per dag efter registrering",
   "admin.dashboard.monthly_retention": "Användarlojalitet per månad efter registrering",
diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json
index a7e5313a3..d31ed3fe9 100644
--- a/app/javascript/mastodon/locales/szl.json
+++ b/app/javascript/mastodon/locales/szl.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
index 8ea28b965..bd59ddda8 100644
--- a/app/javascript/mastodon/locales/ta.json
+++ b/app/javascript/mastodon/locales/ta.json
@@ -18,12 +18,12 @@
   "account.followers": "பின்தொடர்பவர்கள்",
   "account.followers.empty": "இதுவரை யாரும் இந்த பயனரைப் பின்தொடரவில்லை.",
   "account.followers_counter": "{count, plural, one {{counter} வாசகர்} other {{counter} வாசகர்கள்}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural,one {{counter} சந்தா} other {{counter} சந்தாக்கள்}}",
   "account.follows.empty": "இந்த பயனர் இதுவரை யாரையும் பின்தொடரவில்லை.",
   "account.follows_you": "உங்களைப் பின்தொடர்கிறார்",
   "account.hide_reblogs": "இருந்து ஊக்கியாக மறை @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "கடைசி செயல்பாடு",
   "account.link_verified_on": "இந்த இணைப்பை உரிமையாளர் சரிபார்க்கப்பட்டது {date}",
   "account.locked_info": "இந்தக் கணக்கு தனியுரிமை நிலை பூட்டப்பட்டுள்ளது. அவர்களைப் பின்தொடர்பவர் யார் என்பதை உரிமையாளர் கைமுறையாக மதிப்பாய்வு செய்கிறார்.",
   "account.media": "ஊடகங்கள்",
@@ -32,7 +32,6 @@
   "account.mute": "ஊமையான @{name}",
   "account.mute_notifications": "அறிவிப்புகளை முடக்கு @{name}",
   "account.muted": "முடக்கியது",
-  "account.never_active": "எப்போதுமில்லை",
   "account.posts": "டூட்டுகள்",
   "account.posts_with_replies": "Toots மற்றும் பதில்கள்",
   "account.report": "@{name} -ஐப் புகாரளி",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} டூட்} other {{counter} டூட்டுகள்}}",
   "account.unblock": "@{name} மீது தடை நீக்குக",
   "account.unblock_domain": "{domain} ஐ காண்பி",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "சுயவிவரத்தில் இடம்பெற வேண்டாம்",
   "account.unfollow": "பின்தொடர்வதை நிறுத்துக",
   "account.unmute": "@{name} இன் மீது மௌனத் தடையை நீக்குக",
   "account.unmute_notifications": "@{name} இலிருந்து அறிவிப்புகளின் மீது மௌனத் தடையை நீக்குக",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "குறிப்பு ஒன்றை சேர்க்க சொடுக்கவும்",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json
index 55a62bb55..9c0074184 100644
--- a/app/javascript/mastodon/locales/tai.json
+++ b/app/javascript/mastodon/locales/tai.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Mûi-thé",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 40e37d497..6ac4f1d9b 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -18,12 +18,12 @@
   "account.followers": "అనుచరులు",
   "account.followers.empty": "ఈ వినియోగదారుడిని ఇంకా ఎవరూ అనుసరించడంలేదు.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "ఈ వినియోగదారి ఇంకా ఎవరినీ అనుసరించడంలేదు.",
   "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు",
   "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "ఈ లంకె యొక్క యాజమాన్యం {date}న పరీక్షించబడింది",
   "account.locked_info": "ఈ ఖాతా యొక్క గోప్యత స్థితి లాక్ చేయబడి వుంది. ఈ ఖాతాను ఎవరు అనుసరించవచ్చో యజమానే నిర్ణయం తీసుకుంటారు.",
   "account.media": "మీడియా",
@@ -32,7 +32,6 @@
   "account.mute": "@{name}ను మ్యూట్ చెయ్యి",
   "account.mute_notifications": "@{name}నుంచి ప్రకటనలను మ్యూట్ చెయ్యి",
   "account.muted": "మ్యూట్ అయినవి",
-  "account.never_active": "Never",
   "account.posts": "టూట్లు",
   "account.posts_with_replies": "టూట్లు మరియు ప్రత్యుత్తరములు",
   "account.report": "@{name}పై ఫిర్యాదుచేయు",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name}పై బ్లాక్ ను తొలగించు",
   "account.unblock_domain": "{domain}ను దాచవద్దు",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "ప్రొఫైల్లో చూపించవద్దు",
   "account.unfollow": "అనుసరించవద్దు",
   "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు",
   "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 1b276c467..c4e9a3f6f 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -18,12 +18,12 @@
   "account.followers": "ผู้ติดตาม",
   "account.followers.empty": "ยังไม่มีใครติดตามผู้ใช้นี้",
   "account.followers_counter": "{count, plural, other {{counter} ผู้ติดตาม}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, other {{counter} กำลังติดตาม}}",
   "account.follows.empty": "ผู้ใช้นี้ยังไม่ได้ติดตามใคร",
   "account.follows_you": "ติดตามคุณ",
   "account.hide_reblogs": "ซ่อนการดันจาก @{name}",
   "account.joined": "เข้าร่วมเมื่อ {date}",
-  "account.last_status": "ใช้งานล่าสุด",
   "account.link_verified_on": "ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ {date}",
   "account.locked_info": "มีการตั้งสถานะความเป็นส่วนตัวของบัญชีนี้เป็นล็อคอยู่ เจ้าของตรวจทานผู้ที่สามารถติดตามเขาด้วยตนเอง",
   "account.media": "สื่อ",
@@ -32,7 +32,6 @@
   "account.mute": "ซ่อน @{name}",
   "account.mute_notifications": "ซ่อนการแจ้งเตือนจาก @{name}",
   "account.muted": "ซ่อนอยู่",
-  "account.never_active": "ไม่เลย",
   "account.posts": "โพสต์",
   "account.posts_with_replies": "โพสต์และการตอบกลับ",
   "account.report": "รายงาน @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, other {{counter} โพสต์}}",
   "account.unblock": "เลิกปิดกั้น @{name}",
   "account.unblock_domain": "เลิกปิดกั้นโดเมน {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "ไม่แนะนำในโปรไฟล์",
   "account.unfollow": "เลิกติดตาม",
   "account.unmute": "เลิกซ่อน @{name}",
   "account.unmute_notifications": "เลิกซ่อนการแจ้งเตือนจาก @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "คลิกเพื่อเพิ่มหมายเหตุ",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index 0d7c92f05..d4cee1569 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -18,12 +18,12 @@
   "account.followers": "Takipçi",
   "account.followers.empty": "Henüz kimse bu kullanıcıyı takip etmiyor.",
   "account.followers_counter": "{count, plural, one {{counter} Takipçi} other {{counter} Takipçi}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Takip Edilen} other {{counter} Takip Edilen}}",
   "account.follows.empty": "Bu kullanıcı henüz kimseyi takip etmiyor.",
   "account.follows_you": "Seni takip ediyor",
   "account.hide_reblogs": "@{name} kişisinin boostlarını gizle",
   "account.joined": "{date} tarihinde katıldı",
-  "account.last_status": "Son etkinlik",
   "account.link_verified_on": "Bu bağlantının sahipliği {date} tarihinde kontrol edildi",
   "account.locked_info": "Bu hesabın gizlilik durumu kilitli olarak ayarlanmış. Sahibi, onu kimin takip edebileceğini elle inceliyor.",
   "account.media": "Medya",
@@ -32,7 +32,6 @@
   "account.mute": "@{name} adlı kişiyi sessize al",
   "account.mute_notifications": "@{name} adlı kişinin bildirimlerini kapat",
   "account.muted": "Susturuldu",
-  "account.never_active": "Asla",
   "account.posts": "Gönderiler",
   "account.posts_with_replies": "Gönderiler ve yanıtlar",
   "account.report": "@{name} adlı kişiyi bildir",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Gönderi} other {{counter} Gönderi}}",
   "account.unblock": "@{name} adlı kişinin engelini kaldır",
   "account.unblock_domain": "{domain} alan adının engelini kaldır",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Profilde gösterme",
   "account.unfollow": "Takibi bırak",
   "account.unmute": "@{name} adlı kişinin sesini aç",
   "account.unmute_notifications": "@{name} adlı kişinin bildirimlerini aç",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Not eklemek için tıklayın",
   "admin.dashboard.daily_retention": "Kayıttan sonra günlük kullanıcı saklama oranı",
   "admin.dashboard.monthly_retention": "Kayıttan sonra aylık kullanıcı saklama oranı",
diff --git a/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json
index ebdbdbd6e..20a4b2ecd 100644
--- a/app/javascript/mastodon/locales/tt.json
+++ b/app/javascript/mastodon/locales/tt.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Сезгә язылган",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Медиа",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Беркайчан да",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Язылынмау",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json
index a7e5313a3..d31ed3fe9 100644
--- a/app/javascript/mastodon/locales/ug.json
+++ b/app/javascript/mastodon/locales/ug.json
@@ -18,12 +18,12 @@
   "account.followers": "Followers",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "Follows you",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
   "account.muted": "Muted",
-  "account.never_active": "Never",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index e27eb5c21..b1f335a84 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -18,12 +18,12 @@
   "account.followers": "Підписники",
   "account.followers.empty": "Ніхто ще не підписався на цього користувача.",
   "account.followers_counter": "{count, plural, one {{counter} Підписник} few {{counter} Підписники} many {{counter} Підписників} other {{counter} Підписники}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Підписка} few {{counter} Підписки} many {{counter} Підписок} other {{counter} Підписки}}",
   "account.follows.empty": "Цей користувач ще ні на кого не підписався.",
   "account.follows_you": "Підписаний(-а) на вас",
   "account.hide_reblogs": "Сховати передмухи від @{name}",
   "account.joined": "Долучення {date}",
-  "account.last_status": "Крайня активність",
   "account.link_verified_on": "Права власності на це посилання були перевірені {date}",
   "account.locked_info": "Статус конфіденційності цього облікового запису встановлено у заблокований. Власник вручну переглядає, хто може за ним стежити.",
   "account.media": "Медіа",
@@ -32,7 +32,6 @@
   "account.mute": "Заглушити @{name}",
   "account.mute_notifications": "Не показувати сповіщення від @{name}",
   "account.muted": "Заглушений",
-  "account.never_active": "Ніколи",
   "account.posts": "Дмухи",
   "account.posts_with_replies": "Дмухи й відповіді",
   "account.report": "Поскаржитися на @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Пост} few {{counter} Пости} many {{counter} Постів} other {{counter} Пости}}",
   "account.unblock": "Розблокувати @{name}",
   "account.unblock_domain": "Розблокувати {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Не публікувати у профілі",
   "account.unfollow": "Відписатися",
   "account.unmute": "Зняти глушення з @{name}",
   "account.unmute_notifications": "Показувати сповіщення від @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Коментарі відсутні",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json
index 3e71bcc06..9a40cdd47 100644
--- a/app/javascript/mastodon/locales/ur.json
+++ b/app/javascript/mastodon/locales/ur.json
@@ -18,12 +18,12 @@
   "account.followers": "پیروکار",
   "account.followers.empty": "\"ہنوز اس صارف کی کوئی پیروی نہیں کرتا\".",
   "account.followers_counter": "{count, plural,one {{counter} پیروکار} other {{counter} پیروکار}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} پیروی کر رہے ہیں} other {{counter} پیروی کر رہے ہیں}}",
   "account.follows.empty": "\"یہ صارف ہنوز کسی کی پیروی نہیں کرتا ہے\".",
   "account.follows_you": "آپ کا پیروکار ہے",
   "account.hide_reblogs": "@{name} سے فروغ چھپائیں",
   "account.joined": "{date} شامل ہوئے",
-  "account.last_status": "آخری فعال",
   "account.link_verified_on": "اس لنک کی ملکیت کی توثیق {date} پر کی گئی تھی",
   "account.locked_info": "اس اکاونٹ کا اخفائی ضابطہ مقفل ہے۔ صارف کی پیروی کون کر سکتا ہے اس کا جائزہ وہ خود لیتا ہے.",
   "account.media": "وسائل",
@@ -32,7 +32,6 @@
   "account.mute": "خاموش @{name}",
   "account.mute_notifications": "@{name} سے اطلاعات خاموش کریں",
   "account.muted": "خاموش کردہ",
-  "account.never_active": "کبھی نہیں",
   "account.posts": "ٹوٹ",
   "account.posts_with_replies": "ٹوٹ اور جوابات",
   "account.report": "@{name} اطلاع کریں",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} کو بحال کریں",
   "account.unblock_domain": "{domain} کو نہ چھپائیں",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "مشخص پر نمایاں نہ کریں",
   "account.unfollow": "پیروی ترک کریں",
   "account.unmute": "@{name} کو با آواز کریں",
   "account.unmute_notifications": "@{name} سے اطلاعات کو با آواز کریں",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json
index ab777e31e..217cd3861 100644
--- a/app/javascript/mastodon/locales/vi.json
+++ b/app/javascript/mastodon/locales/vi.json
@@ -18,12 +18,12 @@
   "account.followers": "Người theo dõi",
   "account.followers.empty": "Chưa có người theo dõi nào.",
   "account.followers_counter": "{count, plural, one {{counter} Người theo dõi} other {{counter} Người theo dõi}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Theo dõi} other {{counter} Theo dõi}}",
   "account.follows.empty": "Người này chưa theo dõi ai.",
   "account.follows_you": "Đang theo dõi bạn",
   "account.hide_reblogs": "Ẩn chia sẻ từ @{name}",
   "account.joined": "Đã tham gia {date}",
-  "account.last_status": "Online",
   "account.link_verified_on": "Liên kết này đã được xác thực vào {date}",
   "account.locked_info": "Đây là tài khoản riêng tư. Họ sẽ tự mình xét duyệt các yêu cầu theo dõi.",
   "account.media": "Media",
@@ -32,7 +32,6 @@
   "account.mute": "Ẩn @{name}",
   "account.mute_notifications": "Tắt thông báo từ @{name}",
   "account.muted": "Đã ẩn",
-  "account.never_active": "Chưa có bất cứ hoạt động nào",
   "account.posts": "Tút",
   "account.posts_with_replies": "Trả lời",
   "account.report": "Báo cáo @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Tút} other {{counter} Tút}}",
   "account.unblock": "Bỏ chặn @{name}",
   "account.unblock_domain": "Bỏ ẩn {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Ngưng tôn vinh người này",
   "account.unfollow": "Ngưng theo dõi",
   "account.unmute": "Bỏ ẩn @{name}",
   "account.unmute_notifications": "Mở lại thông báo từ @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Nhấn để thêm",
   "admin.dashboard.daily_retention": "Tỉ lệ người dùng sau đăng ký ở lại theo ngày",
   "admin.dashboard.monthly_retention": "Tỉ lệ người dùng sau đăng ký ở lại theo tháng",
diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json
index df307d439..0fc7c56da 100644
--- a/app/javascript/mastodon/locales/zgh.json
+++ b/app/javascript/mastodon/locales/zgh.json
@@ -18,12 +18,12 @@
   "account.followers": "ⵉⵎⴹⴼⴰⵕⵏ",
   "account.followers.empty": "No one follows this user yet.",
   "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
   "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
   "account.follows.empty": "This user doesn't follow anyone yet.",
   "account.follows_you": "ⴹⴼⵕⵏ ⴽⵯⵏ",
   "account.hide_reblogs": "Hide boosts from @{name}",
   "account.joined": "Joined {date}",
-  "account.last_status": "Last active",
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "ⴰⵙⵏⵖⵎⵉⵙ",
@@ -32,7 +32,6 @@
   "account.mute": "ⵥⵥⵉⵥⵏ @{name}",
   "account.mute_notifications": "ⵥⵥⵉⵥⵏ ⵜⵉⵏⵖⵎⵉⵙⵉⵏ ⵙⴳ @{name}",
   "account.muted": "ⵉⵜⵜⵓⵥⵉⵥⵏ",
-  "account.never_active": "ⵓⵙⴰⵔ",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Unblock @{name}",
   "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "ⴽⴽⵙ ⴰⴹⴼⴼⵓⵕ",
   "account.unmute": "Unmute @{name}",
   "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "Click to add a note",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 7f6743e62..1be5f796f 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -18,12 +18,12 @@
   "account.followers": "关注者",
   "account.followers.empty": "目前无人关注此用户。",
   "account.followers_counter": "被 {counter} 人关注",
+  "account.following": "Following",
   "account.following_counter": "正在关注 {counter} 人",
   "account.follows.empty": "此用户目前尚未关注任何人。",
   "account.follows_you": "关注了你",
   "account.hide_reblogs": "隐藏来自 @{name} 的转嘟",
   "account.joined": "加入于 {date}",
-  "account.last_status": "最近活动",
   "account.link_verified_on": "此链接的所有权已在 {date} 检查",
   "account.locked_info": "此账户已锁嘟。账户的主人会手动审核关注者。",
   "account.media": "媒体",
@@ -32,7 +32,6 @@
   "account.mute": "隐藏 @{name}",
   "account.mute_notifications": "隐藏来自 @{name} 的通知",
   "account.muted": "已隐藏",
-  "account.never_active": "从未活跃",
   "account.posts": "嘟文",
   "account.posts_with_replies": "嘟文和回复",
   "account.report": "举报 @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{counter} 条嘟文",
   "account.unblock": "解除屏蔽 @{name}",
   "account.unblock_domain": "不再屏蔽 {domain} 实例",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "不在个人资料中推荐此用户",
   "account.unfollow": "取消关注",
   "account.unmute": "不再隐藏 @{name}",
   "account.unmute_notifications": "不再隐藏来自 @{name} 的通知",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "点击添加备注",
   "admin.dashboard.daily_retention": "注册后用户留存率(按日计算)",
   "admin.dashboard.monthly_retention": "注册后用户留存率(按月计算)",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 292b64042..823fb37fb 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -18,12 +18,12 @@
   "account.followers": "關注者",
   "account.followers.empty": "尚未有人關注這位使用者。",
   "account.followers_counter": "有 {count, plural,one {{counter} 個} other {{counter} 個}}關注者",
+  "account.following": "Following",
   "account.following_counter": "正在關注 {count, plural,one {{counter}}other {{counter} 人}}",
   "account.follows.empty": "這位使用者尚未關注任何人。",
   "account.follows_you": "關注你",
   "account.hide_reblogs": "隱藏 @{name} 的轉推",
   "account.joined": "於 {date} 加入",
-  "account.last_status": "上次活躍時間",
   "account.link_verified_on": "此連結的所有權已在 {date} 檢查過",
   "account.locked_info": "這位使用者將私隱設定為「不公開」,會手動審批誰能關注他/她。",
   "account.media": "媒體",
@@ -32,7 +32,6 @@
   "account.mute": "將 @{name} 靜音",
   "account.mute_notifications": "將來自 @{name} 的通知靜音",
   "account.muted": "靜音",
-  "account.never_active": "永不",
   "account.posts": "文章",
   "account.posts_with_replies": "包含回覆的文章",
   "account.report": "舉報 @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural,one {{counter} 篇}other {{counter} 篇}}文章",
   "account.unblock": "解除對 @{name} 的封鎖",
   "account.unblock_domain": "解除對域名 {domain} 的封鎖",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "不再於個人資料頁面推薦對方",
   "account.unfollow": "取消關注",
   "account.unmute": "取消 @{name} 的靜音",
   "account.unmute_notifications": "取消來自 @{name} 通知的靜音",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "按此添加備注",
   "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 4da14a475..a53f59ddf 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -18,12 +18,12 @@
   "account.followers": "跟隨者",
   "account.followers.empty": "尚未有人跟隨這位使用者。",
   "account.followers_counter": "被 {count, plural,one {{counter} 人}other {{counter} 人}} 跟隨",
+  "account.following": "Following",
   "account.following_counter": "正在跟隨 {count, plural,one {{counter}}other {{counter} 人}}",
   "account.follows.empty": "這位使用者尚未跟隨任何人。",
   "account.follows_you": "跟隨了您",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉嘟",
   "account.joined": "加入於 {date}",
-  "account.last_status": "上次活躍時間",
   "account.link_verified_on": "已在 {date} 檢查此連結的擁有者權限",
   "account.locked_info": "此帳戶的隱私狀態被設為鎖定。該擁有者會手動審核能跟隨此帳戶的人。",
   "account.media": "媒體",
@@ -32,7 +32,6 @@
   "account.mute": "靜音 @{name}",
   "account.mute_notifications": "靜音來自 @{name} 的通知",
   "account.muted": "已靜音",
-  "account.never_active": "永不",
   "account.posts": "嘟文",
   "account.posts_with_replies": "嘟文與回覆",
   "account.report": "檢舉 @{name}",
@@ -42,10 +41,12 @@
   "account.statuses_counter": "{count, plural,one {{counter} 則}other {{counter} 則}}嘟文",
   "account.unblock": "取消封鎖 @{name}",
   "account.unblock_domain": "取消封鎖域名 {domain}",
+  "account.unblock_short": "Unblock",
   "account.unendorse": "不再於個人資料頁面推薦對方",
   "account.unfollow": "取消跟隨",
   "account.unmute": "取消靜音 @{name}",
   "account.unmute_notifications": "重新接收來自 @{name} 的通知",
+  "account.unmute_short": "Unmute",
   "account_note.placeholder": "按此添加備注",
   "admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
   "admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index eb6bdea99..7a2dd0330 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -143,10 +143,15 @@ html {
 .box-widget input[type="password"],
 .box-widget textarea,
 .statuses-grid .detailed-status,
+.report-dialog-modal__textarea,
 .audio-player {
   border: 1px solid lighten($ui-base-color, 8%);
 }
 
+.report-dialog-modal .dialog-option .poll__input {
+  color: $white;
+}
+
 .search__input {
   @media screen and (max-width: $no-gap-breakpoint) {
     border-top: 0;
@@ -342,6 +347,7 @@ html {
 .mute-modal,
 .block-modal,
 .report-modal,
+.report-dialog-modal,
 .embed-modal,
 .error-modal,
 .onboarding-modal,
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 0873ac300..40cd899b3 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -367,6 +367,21 @@ body,
     }
   }
 
+  .positive-hint,
+  .negative-hint,
+  .neutral-hint {
+    a {
+      color: inherit;
+      text-decoration: underline;
+
+      &:focus,
+      &:hover,
+      &:active {
+        text-decoration: none;
+      }
+    }
+  }
+
   .positive-hint {
     color: $valid-value-color;
     font-weight: 500;
@@ -1612,3 +1627,38 @@ a.sparkline {
     }
   }
 }
+
+.availability-indicator {
+  display: flex;
+  align-items: center;
+  margin-bottom: 30px;
+  font-size: 14px;
+  line-height: 21px;
+
+  &__hint {
+    padding: 0 15px;
+  }
+
+  &__graphic {
+    display: flex;
+    margin: 0 -2px;
+
+    &__item {
+      display: block;
+      flex: 0 0 auto;
+      width: 4px;
+      height: 21px;
+      background: lighten($ui-base-color, 8%);
+      margin: 0 2px;
+      border-radius: 2px;
+
+      &.positive {
+        background: $valid-value-color;
+      }
+
+      &.negative {
+        background: $error-value-color;
+      }
+    }
+  }
+}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index d1d679ac2..295b0ddfb 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -1127,7 +1127,7 @@
   .media-gallery,
   .audio-player,
   .video-player {
-    margin-top: 8px;
+    margin-top: 15px;
     max-width: 250px;
   }
 
@@ -5609,6 +5609,12 @@ a.status-card.compact:hover {
       margin: 20px 0;
     }
   }
+
+  .media-gallery,
+  .audio-player,
+  .video-player {
+    margin-top: 15px;
+  }
 }
 
 .loading-bar {
diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss
index 1f7e71776..431b8a73a 100644
--- a/app/javascript/styles/mastodon/tables.scss
+++ b/app/javascript/styles/mastodon/tables.scss
@@ -65,6 +65,24 @@
     }
   }
 
+  &.horizontal-table {
+    border-collapse: collapse;
+    border-style: hidden;
+
+    & > tbody > tr > th,
+    & > tbody > tr > td {
+      padding: 11px 10px;
+      background: transparent;
+      border: 1px solid lighten($ui-base-color, 8%);
+      color: $secondary-text-color;
+    }
+
+    & > tbody > tr > th {
+      color: $darker-text-color;
+      font-weight: 600;
+    }
+  }
+
   &.batch-table {
     & > thead > tr > th {
       background: $ui-base-color;
diff --git a/app/lib/admin/metrics/dimension.rb b/app/lib/admin/metrics/dimension.rb
index d8392ddfc..81b89d9b3 100644
--- a/app/lib/admin/metrics/dimension.rb
+++ b/app/lib/admin/metrics/dimension.rb
@@ -9,6 +9,8 @@ class Admin::Metrics::Dimension
     software_versions: Admin::Metrics::Dimension::SoftwareVersionsDimension,
     tag_servers: Admin::Metrics::Dimension::TagServersDimension,
     tag_languages: Admin::Metrics::Dimension::TagLanguagesDimension,
+    instance_accounts: Admin::Metrics::Dimension::InstanceAccountsDimension,
+    instance_languages: Admin::Metrics::Dimension::InstanceLanguagesDimension,
   }.freeze
 
   def self.retrieve(dimension_keys, start_at, end_at, limit, params)
diff --git a/app/lib/admin/metrics/dimension/instance_accounts_dimension.rb b/app/lib/admin/metrics/dimension/instance_accounts_dimension.rb
new file mode 100644
index 000000000..4eac8e611
--- /dev/null
+++ b/app/lib/admin/metrics/dimension/instance_accounts_dimension.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Dimension::InstanceAccountsDimension < Admin::Metrics::Dimension::BaseDimension
+  include LanguagesHelper
+
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_accounts'
+  end
+
+  protected
+
+  def perform_query
+    sql = <<-SQL.squish
+      SELECT accounts.username, count(follows.*) AS value
+      FROM accounts
+      LEFT JOIN follows ON follows.target_account_id = accounts.id
+      WHERE accounts.domain = $1
+      GROUP BY accounts.id, follows.target_account_id
+      ORDER BY value DESC
+      LIMIT $2
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, params[:domain]], [nil, @limit]])
+
+    rows.map { |row| { key: row['username'], human_key: row['username'], value: row['value'].to_s } }
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/dimension/instance_languages_dimension.rb b/app/lib/admin/metrics/dimension/instance_languages_dimension.rb
new file mode 100644
index 000000000..1ede1a56e
--- /dev/null
+++ b/app/lib/admin/metrics/dimension/instance_languages_dimension.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Dimension::InstanceLanguagesDimension < Admin::Metrics::Dimension::BaseDimension
+  include LanguagesHelper
+
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_languages'
+  end
+
+  protected
+
+  def perform_query
+    sql = <<-SQL.squish
+      SELECT COALESCE(statuses.language, 'und') AS language, count(*) AS value
+      FROM statuses
+      INNER JOIN accounts ON accounts.id = statuses.account_id
+      WHERE accounts.domain = $1
+        AND statuses.id BETWEEN $2 AND $3
+        AND statuses.reblog_of_id IS NULL
+      GROUP BY COALESCE(statuses.language, 'und')
+      ORDER BY count(*) DESC
+      LIMIT $4
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, params[:domain]], [nil, Mastodon::Snowflake.id_at(@start_at, with_random: false)], [nil, Mastodon::Snowflake.id_at(@end_at, with_random: false)], [nil, @limit]])
+
+    rows.map { |row| { key: row['language'], human_key: standard_locale_name(row['language']), value: row['value'].to_s } }
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure.rb b/app/lib/admin/metrics/measure.rb
index a839498a1..0b510eb25 100644
--- a/app/lib/admin/metrics/measure.rb
+++ b/app/lib/admin/metrics/measure.rb
@@ -10,6 +10,12 @@ class Admin::Metrics::Measure
     tag_accounts: Admin::Metrics::Measure::TagAccountsMeasure,
     tag_uses: Admin::Metrics::Measure::TagUsesMeasure,
     tag_servers: Admin::Metrics::Measure::TagServersMeasure,
+    instance_accounts: Admin::Metrics::Measure::InstanceAccountsMeasure,
+    instance_media_attachments: Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure,
+    instance_reports: Admin::Metrics::Measure::InstanceReportsMeasure,
+    instance_statuses: Admin::Metrics::Measure::InstanceStatusesMeasure,
+    instance_follows: Admin::Metrics::Measure::InstanceFollowsMeasure,
+    instance_followers: Admin::Metrics::Measure::InstanceFollowersMeasure,
   }.freeze
 
   def self.retrieve(measure_keys, start_at, end_at, params)
diff --git a/app/lib/admin/metrics/measure/base_measure.rb b/app/lib/admin/metrics/measure/base_measure.rb
index ed1df9c7d..e33a6c494 100644
--- a/app/lib/admin/metrics/measure/base_measure.rb
+++ b/app/lib/admin/metrics/measure/base_measure.rb
@@ -26,6 +26,14 @@ class Admin::Metrics::Measure::BaseMeasure
     raise NotImplementedError
   end
 
+  def unit
+    nil
+  end
+
+  def total_in_time_range?
+    true
+  end
+
   def total
     load[:total]
   end
diff --git a/app/lib/admin/metrics/measure/instance_accounts_measure.rb b/app/lib/admin/metrics/measure/instance_accounts_measure.rb
new file mode 100644
index 000000000..4c61a064a
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_accounts_measure.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceAccountsMeasure < Admin::Metrics::Measure::BaseMeasure
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_accounts'
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    Account.where(domain: params[:domain]).count
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_accounts AS (
+          SELECT accounts.id
+          FROM accounts
+          WHERE date_trunc('day', accounts.created_at)::date = axis.period
+            AND accounts.domain = $3::text
+        )
+        SELECT count(*) FROM new_accounts
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure/instance_followers_measure.rb b/app/lib/admin/metrics/measure/instance_followers_measure.rb
new file mode 100644
index 000000000..caa60013b
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_followers_measure.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceFollowersMeasure < Admin::Metrics::Measure::BaseMeasure
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_followers'
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    Follow.joins(:account).merge(Account.where(domain: params[:domain])).count
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_followers AS (
+          SELECT follows.id
+          FROM follows
+          INNER JOIN accounts ON follows.account_id = accounts.id
+          WHERE date_trunc('day', follows.created_at)::date = axis.period
+            AND accounts.domain = $3::text
+        )
+        SELECT count(*) FROM new_followers
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure/instance_follows_measure.rb b/app/lib/admin/metrics/measure/instance_follows_measure.rb
new file mode 100644
index 000000000..b026c7e6d
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_follows_measure.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceFollowsMeasure < Admin::Metrics::Measure::BaseMeasure
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_follows'
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    Follow.joins(:target_account).merge(Account.where(domain: params[:domain])).count
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_follows AS (
+          SELECT follows.id
+          FROM follows
+          INNER JOIN accounts ON follows.target_account_id = accounts.id
+          WHERE date_trunc('day', follows.created_at)::date = axis.period
+            AND accounts.domain = $3::text
+        )
+        SELECT count(*) FROM new_follows
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb
new file mode 100644
index 000000000..2e2154c92
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics::Measure::BaseMeasure
+  include ActionView::Helpers::NumberHelper
+
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_media_attachments'
+  end
+
+  def unit
+    'bytes'
+  end
+
+  def value_to_human_value(value)
+    number_to_human_size(value)
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    MediaAttachment.joins(:account).merge(Account.where(domain: params[:domain])).sum('COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0)')
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_media_attachments AS (
+          SELECT COALESCE(media_attachments.file_file_size, 0) + COALESCE(media_attachments.thumbnail_file_size, 0) AS size
+          FROM media_attachments
+          INNER JOIN accounts ON accounts.id = media_attachments.account_id
+          WHERE date_trunc('day', media_attachments.created_at)::date = axis.period
+            AND accounts.domain = $3::text
+        )
+        SELECT SUM(size) FROM new_media_attachments
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure/instance_reports_measure.rb b/app/lib/admin/metrics/measure/instance_reports_measure.rb
new file mode 100644
index 000000000..6b3f35067
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_reports_measure.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceReportsMeasure < Admin::Metrics::Measure::BaseMeasure
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_reports'
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    Report.where(target_account: Account.where(domain: params[:domain])).count
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_reports AS (
+          SELECT reports.id
+          FROM reports
+          INNER JOIN accounts ON accounts.id = reports.target_account_id
+          WHERE date_trunc('day', reports.created_at)::date = axis.period
+            AND accounts.domain = $3::text
+        )
+        SELECT count(*) FROM new_reports
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/admin/metrics/measure/instance_statuses_measure.rb b/app/lib/admin/metrics/measure/instance_statuses_measure.rb
new file mode 100644
index 000000000..86b10da6c
--- /dev/null
+++ b/app/lib/admin/metrics/measure/instance_statuses_measure.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+class Admin::Metrics::Measure::InstanceStatusesMeasure < Admin::Metrics::Measure::BaseMeasure
+  def self.with_params?
+    true
+  end
+
+  def key
+    'instance_statuses'
+  end
+
+  def total_in_time_range?
+    false
+  end
+
+  protected
+
+  def perform_total_query
+    Status.joins(:account).merge(Account.where(domain: params[:domain])).count
+  end
+
+  def perform_previous_total_query
+    nil
+  end
+
+  def perform_data_query
+    sql = <<-SQL.squish
+      SELECT axis.*, (
+        WITH new_statuses AS (
+          SELECT statuses.id
+          FROM statuses
+          INNER JOIN accounts ON accounts.id = statuses.account_id
+          WHERE statuses.id BETWEEN $3 AND $4
+            AND accounts.domain = $5::text
+            AND date_trunc('day', statuses.created_at)::date = axis.period
+        )
+        SELECT count(*) FROM new_statuses
+      ) AS value
+      FROM (
+        SELECT generate_series(date_trunc('day', $1::timestamp)::date, date_trunc('day', $2::timestamp)::date, interval '1 day') AS period
+      ) AS axis
+    SQL
+
+    rows = ActiveRecord::Base.connection.select_all(sql, nil, [[nil, @start_at], [nil, @end_at], [nil, Mastodon::Snowflake.id_at(@start_at, with_random: false)], [nil, Mastodon::Snowflake.id_at(@end_at, with_random: false)], [nil, params[:domain]]])
+
+    rows.map { |row| { date: row['period'], value: row['value'].to_s } }
+  end
+
+  def time_period
+    (@start_at.to_date..@end_at.to_date)
+  end
+
+  def previous_time_period
+    ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
+  end
+
+  def params
+    @params.permit(:domain)
+  end
+end
diff --git a/app/lib/delivery_failure_tracker.rb b/app/lib/delivery_failure_tracker.rb
index 8907ade4c..7b800fc0b 100644
--- a/app/lib/delivery_failure_tracker.rb
+++ b/app/lib/delivery_failure_tracker.rb
@@ -30,7 +30,7 @@ class DeliveryFailureTracker
   end
 
   def exhausted_deliveries_days
-    Redis.current.smembers(exhausted_deliveries_key).sort.map { |date| Date.new(date.slice(0, 4).to_i, date.slice(4, 2).to_i, date.slice(6, 2).to_i) }
+    @exhausted_deliveries_days ||= Redis.current.smembers(exhausted_deliveries_key).sort.map { |date| Date.new(date.slice(0, 4).to_i, date.slice(4, 2).to_i, date.slice(6, 2).to_i) }
   end
 
   alias reset! track_success!
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 2c16689bd..efc9da34b 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -506,7 +506,7 @@ class FeedManager
       Formatter.instance.plaintext(status),
       status.spoiler_text,
       status.preloadable_poll ? status.preloadable_poll.options.join("\n\n") : nil,
-      status.media_attachments.map(&:description).join("\n\n"),
+      status.ordered_media_attachments.map(&:description).join("\n\n"),
     ].compact.join("\n\n")
 
     combined_regex.match?(combined_text)
diff --git a/app/lib/rss/serializer.rb b/app/lib/rss/serializer.rb
index fd56c568c..7e3ed1f17 100644
--- a/app/lib/rss/serializer.rb
+++ b/app/lib/rss/serializer.rb
@@ -11,7 +11,7 @@ class RSS::Serializer
             .pub_date(status.created_at)
             .description(status.spoiler_text.presence || Formatter.instance.format(status, inline_poll_options: true).to_str)
 
-        status.media_attachments.each do |media|
+        status.ordered_media_attachments.each do |media|
           item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, media.file.size)
         end
       end
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 791a94911..a90d5d888 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -13,7 +13,7 @@ module Omniauthable
       Devise.omniauth_configs.keys
     end
 
-    def email_verified?
+    def email_present?
       email && email !~ TEMP_EMAIL_REGEX
     end
   end
@@ -40,16 +40,14 @@ module Omniauthable
     end
 
     def create_for_oauth(auth)
-      # Check if the user exists with provided email if the provider gives us a
-      # verified email.  If no verified email was provided or the user already
-      # exists, we assign a temporary email and ask the user to verify it on
+      # Check if the user exists with provided email. If no email was provided,
+      # we assign a temporary email and ask the user to verify it on
       # the next step via Auth::SetupController.show
 
       strategy          = Devise.omniauth_configs[auth.provider.to_sym].strategy
       assume_verified   = strategy&.security&.assume_email_is_verified
-      email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified
+      email_is_verified = auth.info.verified || auth.info.verified_email || auth.info.email_verified || assume_verified
       email             = auth.info.verified_email || auth.info.email
-      email             = nil unless email_is_verified
 
       user = User.find_by(email: email) if email_is_verified
 
@@ -58,7 +56,7 @@ module Omniauthable
       user = User.new(user_params_from_auth(email, auth))
 
       user.account.avatar_remote_url = auth.info.image if /\A#{URI::DEFAULT_PARSER.make_regexp(%w(http https))}\z/.match?(auth.info.image)
-      user.skip_confirmation!
+      user.skip_confirmation! if email_is_verified
       user.save!
       user
     end
@@ -71,8 +69,8 @@ module Omniauthable
         agreement: true,
         external: true,
         account_attributes: {
-          username: ensure_unique_username(auth.uid),
-          display_name: auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' '),
+          username: ensure_unique_username(ensure_valid_username(auth.uid)),
+          display_name: auth.info.full_name || auth.info.name || [auth.info.first_name, auth.info.last_name].join(' '),
         },
       }
     end
@@ -88,5 +86,12 @@ module Omniauthable
 
       username
     end
+
+    def ensure_valid_username(starting_username)
+      starting_username = starting_username.split('@')[0]
+      temp_username = starting_username.gsub(/[^a-z0-9_]+/i, '')
+      validated_username = temp_username.truncate(30, omission: '')
+      validated_username
+    end
   end
 end
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index bba04c603..2b797ef91 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -30,6 +30,14 @@ class DomainBlock < ApplicationRecord
   scope :with_user_facing_limitations, -> { where(severity: [:silence, :suspend]).or(where(reject_media: true)) }
   scope :by_severity, -> { order(Arel.sql('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), reject_media, domain')) }
 
+  def policies
+    if suspend?
+      [:suspend]
+    else
+      [severity.to_sym, reject_media? ? :reject_media : nil, reject_reports? ? :reject_reports : nil].reject { |policy| policy == :noop || policy.nil? }
+    end
+  end
+
   class << self
     def suspend?(domain)
       !!rule_for(domain)&.suspend?
diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb
index e02ae0705..74d62e777 100644
--- a/app/models/featured_tag.rb
+++ b/app/models/featured_tag.rb
@@ -4,8 +4,8 @@
 # Table name: featured_tags
 #
 #  id             :bigint(8)        not null, primary key
-#  account_id     :bigint(8)
-#  tag_id         :bigint(8)
+#  account_id     :bigint(8)        not null
+#  tag_id         :bigint(8)        not null
 #  statuses_count :bigint(8)        default(0), not null
 #  last_status_at :datetime
 #  created_at     :datetime         not null
diff --git a/app/models/instance.rb b/app/models/instance.rb
index 8949be054..7434d3322 100644
--- a/app/models/instance.rb
+++ b/app/models/instance.rb
@@ -32,35 +32,27 @@ class Instance < ApplicationRecord
     @delivery_failure_tracker ||= DeliveryFailureTracker.new(domain)
   end
 
-  def following_count
-    @following_count ||= Follow.where(account: accounts).count
+  def unavailable?
+    unavailable_domain.present?
   end
 
-  def followers_count
-    @followers_count ||= Follow.where(target_account: accounts).count
+  def failing?
+    failure_days.present? || unavailable?
   end
 
-  def reports_count
-    @reports_count ||= Report.where(target_account: accounts).count
-  end
-
-  def blocks_count
-    @blocks_count ||= Block.where(target_account: accounts).count
-  end
-
-  def public_comment
-    domain_block&.public_comment
+  def to_param
+    domain
   end
 
-  def private_comment
-    domain_block&.private_comment
-  end
+  delegate :exhausted_deliveries_days, to: :delivery_failure_tracker
 
-  def media_storage
-    @media_storage ||= MediaAttachment.where(account: accounts).sum(:file_file_size)
-  end
+  def availability_over_days(num_days, end_date = Time.now.utc.to_date)
+    failures_map    = exhausted_deliveries_days.index_with { true }
+    period_end_at   = exhausted_deliveries_days.last || end_date
+    period_start_at = period_end_at - num_days.days
 
-  def to_param
-    domain
+    (period_start_at..period_end_at).map do |date|
+      [date, failures_map[date]]
+    end
   end
 end
diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb
index 9e533c4aa..e7e5166a1 100644
--- a/app/models/instance_filter.rb
+++ b/app/models/instance_filter.rb
@@ -4,8 +4,7 @@ class InstanceFilter
   KEYS = %i(
     limited
     by_domain
-    warning
-    unavailable
+    availability
   ).freeze
 
   attr_reader :params
@@ -34,12 +33,21 @@ class InstanceFilter
       Instance.joins(:domain_allow).reorder(Arel.sql('domain_allows.id desc'))
     when 'by_domain'
       Instance.matches_domain(value)
-    when 'warning'
+    when 'availability'
+      availability_scope(value)
+    else
+      raise "Unknown filter: #{key}"
+    end
+  end
+
+  def availability_scope(value)
+    case value
+    when 'failing'
       Instance.where(domain: DeliveryFailureTracker.warning_domains)
     when 'unavailable'
       Instance.joins(:unavailable_domain)
     else
-      raise "Unknown filter: #{key}"
+      raise "Unknown availability: #{value}"
     end
   end
 end
diff --git a/app/models/report.rb b/app/models/report.rb
index 8ba2dd8fd..6d4166540 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -63,8 +63,20 @@ class Report < ApplicationRecord
     Status.with_discarded.where(id: status_ids)
   end
 
-  def media_attachments
-    MediaAttachment.where(status_id: status_ids)
+  def media_attachments_count
+    statuses_to_query = []
+    count = 0
+
+    statuses.pluck(:id, :ordered_media_attachment_ids).each do |id, ordered_ids|
+      if ordered_ids.nil?
+        statuses_to_query << id
+      else
+        count += ordered_ids.size
+      end
+    end
+
+    count += MediaAttachment.where(status_id: statuses_to_query).count unless statuses_to_query.empty?
+    count
   end
 
   def rules
diff --git a/app/models/status.rb b/app/models/status.rb
index 6a848baee..ba9d7f0aa 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -3,31 +3,31 @@
 #
 # Table name: statuses
 #
-#  id                     :bigint(8)        not null, primary key
-#  uri                    :string
-#  text                   :text             default(""), not null
-#  created_at             :datetime         not null
-#  updated_at             :datetime         not null
-#  in_reply_to_id         :bigint(8)
-#  reblog_of_id           :bigint(8)
-#  url                    :string
-#  sensitive              :boolean          default(FALSE), not null
-#  visibility             :integer          default("public"), not null
-#  spoiler_text           :text             default(""), not null
-#  reply                  :boolean          default(FALSE), not null
-#  language               :string
-#  conversation_id        :bigint(8)
-#  local                  :boolean
-#  account_id             :bigint(8)        not null
-#  application_id         :bigint(8)
-#  in_reply_to_account_id :bigint(8)
-#  local_only             :boolean
-#  full_status_text       :text             default(""), not null
-#  poll_id                :bigint(8)
-#  content_type           :string
-#  deleted_at             :datetime
-#  edited_at              :datetime
-#  trendable              :boolean
+#  id                           :bigint(8)        not null, primary key
+#  uri                          :string
+#  text                         :text             default(""), not null
+#  created_at                   :datetime         not null
+#  updated_at                   :datetime         not null
+#  in_reply_to_id               :bigint(8)
+#  reblog_of_id                 :bigint(8)
+#  url                          :string
+#  sensitive                    :boolean          default(FALSE), not null
+#  visibility                   :integer          default("public"), not null
+#  spoiler_text                 :text             default(""), not null
+#  reply                        :boolean          default(FALSE), not null
+#  language                     :string
+#  conversation_id              :bigint(8)
+#  local                        :boolean
+#  account_id                   :bigint(8)        not null
+#  application_id               :bigint(8)
+#  in_reply_to_account_id       :bigint(8)
+#  local_only                   :boolean
+#  poll_id                      :bigint(8)
+#  content_type                 :string
+#  deleted_at                   :datetime
+#  edited_at                    :datetime
+#  trendable                    :boolean
+#  ordered_media_attachment_ids :bigint(8)        is an Array
 #
 
 class Status < ApplicationRecord
@@ -217,14 +217,18 @@ class Status < ApplicationRecord
     public_visibility? || unlisted_visibility?
   end
 
-  def snapshot!(media_attachments_changed: false, account_id: nil, at_time: nil)
+  def snapshot!(account_id: nil, at_time: nil, rate_limit: true)
     edits.create!(
       text: text,
       spoiler_text: spoiler_text,
-      media_attachments_changed: media_attachments_changed,
+      sensitive: sensitive,
+      ordered_media_attachment_ids: ordered_media_attachment_ids || media_attachments.pluck(:id),
+      media_descriptions: ordered_media_attachments.map(&:description),
+      poll_options: preloadable_poll&.options,
       account_id: account_id || self.account_id,
       content_type: content_type,
-      created_at: at_time || edited_at
+      created_at: at_time || edited_at,
+      rate_limit: rate_limit
     )
   end
 
@@ -235,7 +239,7 @@ class Status < ApplicationRecord
   alias sign? distributable?
 
   def with_media?
-    media_attachments.any?
+    ordered_media_attachments.any?
   end
 
   def with_preview_card?
@@ -259,6 +263,15 @@ class Status < ApplicationRecord
     @emojis = CustomEmoji.from_text(fields.join(' '), account.domain)
   end
 
+  def ordered_media_attachments
+    if ordered_media_attachment_ids.nil?
+      media_attachments
+    else
+      map = media_attachments.index_by(&:id)
+      ordered_media_attachment_ids.map { |media_attachment_id| map[media_attachment_id] }
+    end
+  end
+
   def replies_count
     status_stat&.replies_count || 0
   end
@@ -428,6 +441,63 @@ class Status < ApplicationRecord
     super || build_status_stat
   end
 
+  # Hack to use a "INSERT INTO ... SELECT ..." query instead of "INSERT INTO ... VALUES ..." query
+  def self._insert_record(values)
+    if values.is_a?(Hash) && values['reblog_of_id'].present?
+      primary_key = self.primary_key
+      primary_key_value = nil
+
+      if primary_key
+        primary_key_value = values[primary_key]
+
+        if !primary_key_value && prefetch_primary_key?
+          primary_key_value = next_sequence_value
+          values[primary_key] = primary_key_value
+        end
+      end
+
+      # The following line is where we differ from stock ActiveRecord implementation
+      im = _compile_reblog_insert(values)
+
+      # Since we are using SELECT instead of VALUES, a non-error `nil` return is possible.
+      # For our purposes, it's equivalent to a foreign key constraint violation
+      result = connection.insert(im, "#{self} Create", primary_key || false, primary_key_value)
+      raise ActiveRecord::InvalidForeignKey, "(reblog_of_id)=(#{values['reblog_of_id']}) is not present in table \"statuses\"" if result.nil?
+
+      result
+    else
+      super
+    end
+  end
+
+  def self._compile_reblog_insert(values)
+    # This is somewhat equivalent to the following code of ActiveRecord::Persistence:
+    # `arel_table.compile_insert(_substitute_values(values))`
+    # The main difference is that we use a `SELECT` instead of a `VALUES` clause,
+    # which means we have to build the `SELECT` clause ourselves and do a bit more
+    # manual work.
+
+    # Instead of using Arel::InsertManager#values, we are going to use Arel::InsertManager#select
+    im = Arel::InsertManager.new
+    im.into(arel_table)
+
+    binds = []
+    reblog_bind = nil
+    values.each do |name, value|
+      attr = arel_table[name]
+      bind = predicate_builder.build_bind_attribute(attr.name, value)
+
+      im.columns << attr
+      binds << bind
+
+      reblog_bind = bind if name == 'reblog_of_id'
+    end
+
+    im.select(arel_table.where(arel_table[:id].eq(reblog_bind)).where(arel_table[:deleted_at].eq(nil)).project(*binds))
+
+    im
+  end
+
   private
 
   def update_status_stat!(attrs)
diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb
index 3d8098fe7..33528eb0d 100644
--- a/app/models/status_edit.rb
+++ b/app/models/status_edit.rb
@@ -3,18 +3,39 @@
 #
 # Table name: status_edits
 #
-#  id                        :bigint(8)        not null, primary key
-#  status_id                 :bigint(8)        not null
-#  account_id                :bigint(8)
-#  text                      :text             default(""), not null
-#  spoiler_text              :text             default(""), not null
-#  media_attachments_changed :boolean          default(FALSE), not null
-#  created_at                :datetime         not null
-#  updated_at                :datetime         not null
-#  content_type              :string
+#  id                           :bigint(8)        not null, primary key
+#  status_id                    :bigint(8)        not null
+#  account_id                   :bigint(8)
+#  text                         :text             default(""), not null
+#  spoiler_text                 :text             default(""), not null
+#  created_at                   :datetime         not null
+#  updated_at                   :datetime         not null
+#  content_type                 :string
+#  ordered_media_attachment_ids :bigint(8)        is an Array
+#  media_descriptions           :text             is an Array
+#  poll_options                 :string           is an Array
+#  sensitive                    :boolean
 #
 
 class StatusEdit < ApplicationRecord
+  include RateLimitable
+
+  self.ignored_columns = %w(
+    media_attachments_changed
+  )
+
+  class PreservedMediaAttachment < ActiveModelSerializers::Model
+    attributes :media_attachment, :description
+
+    delegate :id, :type, :url, :preview_url, :remote_url,
+             :preview_remote_url, :text_url, :meta, :blurhash,
+             :not_processed?, :needs_redownload?, :local?,
+             :file, :thumbnail, :thumbnail_remote_url,
+             :shortcode, to: :media_attachment
+  end
+
+  rate_limit by: :account, family: :statuses
+
   belongs_to :status
   belongs_to :account, optional: true
 
@@ -26,4 +47,17 @@ class StatusEdit < ApplicationRecord
     return @emojis if defined?(@emojis)
     @emojis = CustomEmoji.from_text([spoiler_text, text].join(' '), status.account.domain)
   end
+
+  def ordered_media_attachments
+    return @ordered_media_attachments if defined?(@ordered_media_attachments)
+
+    @ordered_media_attachments = begin
+      if ordered_media_attachment_ids.nil?
+        []
+      else
+        map = status.media_attachments.index_by(&:id)
+        ordered_media_attachment_ids.map.with_index { |media_attachment_id, index| PreservedMediaAttachment.new(media_attachment: map[media_attachment_id], description: media_descriptions[index]) }
+      end
+    end
+  end
 end
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index aa552a724..05f2ee14f 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -15,7 +15,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
 
   attribute :direct_message, if: :non_public?
 
-  has_many :media_attachments, key: :attachment
+  has_many :virtual_attachments, key: :attachment
   has_many :virtual_tags, key: :tag
 
   has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local?
@@ -117,6 +117,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
     object.account.sensitized? || object.sensitive || (!instance_options[:allow_local_only] && Setting.outgoing_spoilers.present?)
   end
 
+  def virtual_attachments
+    object.ordered_media_attachments
+  end
+
   def virtual_tags
     object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis
   end
diff --git a/app/serializers/rest/admin/measure_serializer.rb b/app/serializers/rest/admin/measure_serializer.rb
index 81d655c1a..fc16b85f2 100644
--- a/app/serializers/rest/admin/measure_serializer.rb
+++ b/app/serializers/rest/admin/measure_serializer.rb
@@ -1,12 +1,20 @@
 # frozen_string_literal: true
 
 class REST::Admin::MeasureSerializer < ActiveModel::Serializer
-  attributes :key, :total, :previous_total, :data
+  attributes :key, :unit, :total
+
+  attribute :human_value, if: -> { object.respond_to?(:value_to_human_value) }
+  attribute :previous_total, if: -> { object.total_in_time_range? }
+  attribute :data
 
   def total
     object.total.to_s
   end
 
+  def human_value
+    object.value_to_human_value(object.total)
+  end
+
   def previous_total
     object.previous_total.to_s
   end
diff --git a/app/serializers/rest/status_edit_serializer.rb b/app/serializers/rest/status_edit_serializer.rb
index a1f9e824e..05ccd5e94 100644
--- a/app/serializers/rest/status_edit_serializer.rb
+++ b/app/serializers/rest/status_edit_serializer.rb
@@ -3,12 +3,18 @@
 class REST::StatusEditSerializer < ActiveModel::Serializer
   has_one :account, serializer: REST::AccountSerializer
 
-  attributes :content, :spoiler_text,
-             :media_attachments_changed, :created_at
+  attributes :content, :spoiler_text, :sensitive, :created_at
 
+  has_many :ordered_media_attachments, key: :media_attachments, serializer: REST::MediaAttachmentSerializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
+  attribute :poll, if: -> { object.poll_options.present? }
+
   def content
     Formatter.instance.format(object)
   end
+
+  def poll
+    { options: object.poll_options.map { |title| { title: title } } }
+  end
 end
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index 7b5263eee..0a00ed77e 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -21,7 +21,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   belongs_to :application, if: :show_application?
   belongs_to :account, serializer: REST::AccountSerializer
 
-  has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
+  has_many :ordered_media_attachments, key: :media_attachments, serializer: REST::MediaAttachmentSerializer
   has_many :ordered_mentions, key: :mentions
   has_many :tags
   has_many :emojis, serializer: REST::CustomEmojiSerializer
diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb
index 7438a7c53..1260c0482 100644
--- a/app/services/activitypub/process_status_update_service.rb
+++ b/app/services/activitypub/process_status_update_service.rb
@@ -76,13 +76,14 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
       end
     end
 
-    removed_media_attachments = previous_media_attachments - next_media_attachments
-    added_media_attachments   = next_media_attachments - previous_media_attachments
+    added_media_attachments = next_media_attachments - previous_media_attachments
 
-    MediaAttachment.where(id: removed_media_attachments.map(&:id)).update_all(status_id: nil)
     MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id)
 
-    @media_attachments_changed = true if removed_media_attachments.any? || added_media_attachments.any?
+    @status.ordered_media_attachment_ids = next_media_attachments.map(&:id)
+    @status.media_attachments.reload
+
+    @media_attachments_changed = true if @status.ordered_media_attachment_ids_changed?
   end
 
   def update_poll!
@@ -215,19 +216,13 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
 
     return if @status.edits.any?
 
-    @status.snapshot!(
-      media_attachments_changed: false,
-      at_time: @status.created_at
-    )
+    @status.snapshot!(at_time: @status.created_at, rate_limit: false)
   end
 
   def create_edit!
     return unless significant_changes?
 
-    @status.snapshot!(
-      media_attachments_changed: @media_attachments_changed || @poll_changed,
-      account_id: @account.id
-    )
+    @status.snapshot!(account_id: @account.id, rate_limit: false)
   end
 
   def skip_download?
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 08fae7935..f182cb83e 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -118,7 +118,7 @@ class FanOutOnWriteService < BaseService
     Redis.current.publish('timeline:public', anonymous_payload)
     Redis.current.publish(@status.local? ? 'timeline:public:local' : 'timeline:public:remote', anonymous_payload)
 
-    if @status.media_attachments.any?
+    if @status.with_media?
       Redis.current.publish('timeline:public:media', anonymous_payload)
       Redis.current.publish(@status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', anonymous_payload)
     end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index c5061dd63..36592a531 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -109,7 +109,10 @@ class PostStatusService < BaseService
   end
 
   def validate_media!
-    return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
+    if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
+      @media = []
+      return
+    end
 
     raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present?
 
@@ -166,12 +169,13 @@ class PostStatusService < BaseService
     {
       text: @text,
       media_attachments: @media || [],
+      ordered_media_attachment_ids: (@options[:media_ids] || []).map(&:to_i) & @media.map(&:id),
       thread: @in_reply_to,
       poll_attributes: poll_attributes,
       sensitive: @sensitive,
       spoiler_text: @options[:spoiler_text] || '',
       visibility: @visibility,
-      language: valid_locale_or_nil(@options[:language].presence || @account.user&.preferred_posting_language || I18n.default_locale),
+      language: valid_locale_cascade(@options[:language], @account.user&.preferred_posting_language, I18n.default_locale),
       application: @options[:application],
       content_type: @options[:content_type] || @account.user&.setting_default_content_type,
       rate_limit: @options[:with_rate_limit],
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index 361cd4d82..c28e16572 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -40,7 +40,7 @@ class RemoveStatusService < BaseService
           remove_reblogs
           remove_from_hashtags
           remove_from_public
-          remove_from_media if @status.media_attachments.any?
+          remove_from_media if @status.with_media?
           remove_from_direct if status.direct_visibility?
           remove_media
         end
diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb
index 6cbbd2876..f5155a2f5 100644
--- a/app/services/update_status_service.rb
+++ b/app/services/update_status_service.rb
@@ -18,8 +18,6 @@ class UpdateStatusService < BaseService
     @status                    = status
     @options                   = options
     @account_id                = account_id
-    @media_attachments_changed = false
-    @poll_changed              = false
 
     Status.transaction do
       create_previous_edit!
@@ -42,14 +40,12 @@ class UpdateStatusService < BaseService
   def update_media_attachments!
     previous_media_attachments = @status.media_attachments.to_a
     next_media_attachments     = validate_media!
-    removed_media_attachments  = previous_media_attachments - next_media_attachments
     added_media_attachments    = next_media_attachments - previous_media_attachments
 
-    MediaAttachment.where(id: removed_media_attachments.map(&:id)).update_all(status_id: nil)
     MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id)
 
+    @status.ordered_media_attachment_ids = (@options[:media_ids] || []).map(&:to_i) & next_media_attachments.map(&:id)
     @status.media_attachments.reload
-    @media_attachments_changed = true if removed_media_attachments.any? || added_media_attachments.any?
   end
 
   def validate_media!
@@ -74,19 +70,18 @@ class UpdateStatusService < BaseService
 
       # If for some reasons the options were changed, it invalidates all previous
       # votes, so we need to remove them
-      @poll_changed = true if @options[:poll][:options] != poll.options || ActiveModel::Type::Boolean.new.cast(@options[:poll][:multiple]) != poll.multiple
+      poll_changed = true if @options[:poll][:options] != poll.options || ActiveModel::Type::Boolean.new.cast(@options[:poll][:multiple]) != poll.multiple
 
       poll.options     = @options[:poll][:options]
       poll.hide_totals = @options[:poll][:hide_totals] || false
       poll.multiple    = @options[:poll][:multiple] || false
       poll.expires_in  = @options[:poll][:expires_in]
-      poll.reset_votes! if @poll_changed
+      poll.reset_votes! if poll_changed
       poll.save!
 
       @status.poll_id = poll.id
     elsif previous_poll.present?
       previous_poll.destroy
-      @poll_changed = true
       @status.poll_id = nil
     end
   end
@@ -95,7 +90,7 @@ class UpdateStatusService < BaseService
     @status.text         = @options[:text].presence || @options.delete(:spoiler_text) || '' if @options.key?(:text)
     @status.spoiler_text = @options[:spoiler_text] || '' if @options.key?(:spoiler_text)
     @status.sensitive    = @options[:sensitive] || @options[:spoiler_text].present? if @options.key?(:sensitive) || @options.key?(:spoiler_text)
-    @status.language     = valid_locale_or_nil(@options[:language] || @status.language || @status.account.user&.preferred_posting_language || I18n.default_locale)
+    @status.language     = valid_locale_cascade(@options[:language], @status.language, @status.account.user&.preferred_posting_language, I18n.default_locale)
     @status.content_type = @options[:content_type] || @status.content_type
     @status.edited_at    = Time.now.utc
 
@@ -138,16 +133,10 @@ class UpdateStatusService < BaseService
 
     return if @status.edits.any?
 
-    @status.snapshot!(
-      media_attachments_changed: false,
-      at_time: @status.created_at
-    )
+    @status.snapshot!(at_time: @status.created_at, rate_limit: false)
   end
 
   def create_edit!
-    @status.snapshot!(
-      media_attachments_changed: @media_attachments_changed || @poll_changed,
-      account_id: @account_id
-    )
+    @status.snapshot!(account_id: @account_id)
   end
 end
diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml
index c76a7a7f8..15d70a39e 100644
--- a/app/views/admin/domain_blocks/edit.html.haml
+++ b/app/views/admin/domain_blocks/edit.html.haml
@@ -21,10 +21,10 @@
     = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint')
 
   .field-group
-    = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), rows: 6
+    = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), as: :string
 
   .field-group
-    = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), rows: 6
+    = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), as: :string
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml
index b04ce7d9c..0944573bf 100644
--- a/app/views/admin/domain_blocks/new.html.haml
+++ b/app/views/admin/domain_blocks/new.html.haml
@@ -21,10 +21,10 @@
     = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint')
 
   .field-group
-    = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), rows: 6
+    = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), as: :string
 
   .field-group
-    = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), rows: 6
+    = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), as: :string
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/domain_blocks/show.html.haml b/app/views/admin/domain_blocks/show.html.haml
deleted file mode 100644
index e64aaa629..000000000
--- a/app/views/admin/domain_blocks/show.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-- content_for :page_title do
-  = t('admin.domain_blocks.show.title', domain: @domain_block.domain)
-
-- if @domain_block.private_comment.present?
-  .speech-bubble
-    .speech-bubble__bubble
-      = simple_format(h(@domain_block.private_comment))
-    .speech-bubble__owner= t 'admin.instances.private_comment'
-
-- if @domain_block.public_comment.present?
-  .speech-bubble
-    .speech-bubble__bubble
-      = simple_format(h(@domain_block.public_comment))
-    .speech-bubble__owner= t 'admin.instances.public_comment'
-
-= simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :delete do |f|
-
-  - unless (@domain_block.noop?)
-    %p= t(".retroactive.#{@domain_block.severity}")
-    %p.hint= t(:affected_accounts,
-      scope: [:admin, :domain_blocks, :show],
-      count: @domain_block.affected_accounts_count)
-
-  .actions
-    = f.button :button, t('.undo'), type: :submit
diff --git a/app/views/admin/instances/_exhausted_deliveries_days.haml b/app/views/admin/instances/_exhausted_deliveries_days.haml
deleted file mode 100644
index e581f542d..000000000
--- a/app/views/admin/instances/_exhausted_deliveries_days.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-%li.negative-hint
-  = l(exhausted_deliveries_days)
diff --git a/app/views/admin/instances/_instance.html.haml b/app/views/admin/instances/_instance.html.haml
index dc81007ac..8a4396002 100644
--- a/app/views/admin/instances/_instance.html.haml
+++ b/app/views/admin/instances/_instance.html.haml
@@ -1,33 +1,15 @@
 .directory__tag
   = link_to admin_instance_path(instance) do
     %h4
+      = fa_icon 'warning fw' if instance.failing?
       = instance.domain
+
       %small
         - if instance.domain_block
-          - first_item = true
-          - if !instance.domain_block.noop?
-            = t("admin.domain_blocks.severity.#{instance.domain_block.severity}")
-            - first_item = false
-          - unless instance.domain_block.suspend?
-            - if instance.domain_block.reject_media?
-              - unless first_item
-                &bull;
-              = t('admin.domain_blocks.rejecting_media')
-              - first_item = false
-            - if instance.domain_block.reject_reports?
-              - unless first_item
-                &bull;
-              = t('admin.domain_blocks.rejecting_reports')
-        - elsif whitelist_mode?
+          = instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' • ')
+        - elsif instance.domain_allow
           = t('admin.accounts.whitelisted')
         - else
           = t('admin.accounts.no_limits_imposed')
-        - if instance.failure_days
-          = ' / '
-          %span.negative-hint
-            = t('admin.instances.delivery.warning_message', count: instance.failure_days)
-        - if instance.unavailable_domain
-          = ' / '
-          %span.negative-hint
-            = t('admin.instances.delivery.unavailable_message')
+
     .trends__item__current{ title: t('admin.instances.known_accounts', count: instance.accounts_count) }= friendly_number_to_human instance.accounts_count
diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
index 797948d94..f8273718d 100644
--- a/app/views/admin/instances/index.html.haml
+++ b/app/views/admin/instances/index.html.haml
@@ -17,22 +17,11 @@
         %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
 
   .filter-subset
-    %strong= t('admin.instances.delivery.title')
+    %strong= t('admin.instances.availability.title')
     %ul
-      %li= filter_link_to t('admin.instances.delivery.all'), warning: nil, unavailable: nil
-      %li= filter_link_to t('admin.instances.delivery.warning'), warning: '1', unavailable: nil
-      %li= filter_link_to t('admin.instances.delivery.unavailable'), warning: nil, unavailable: '1'
-
-  .back-link
-    = link_to admin_instances_path() do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_all')
-    = link_to admin_instances_path(limited: 1) do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_limited')
-    = link_to admin_instances_path(warning: 1) do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_warning')
+      %li= filter_link_to t('admin.instances.delivery.all'), availability: nil
+      %li= filter_link_to t('admin.instances.delivery.failing'), availability: 'failing'
+      %li= filter_link_to t('admin.instances.delivery.unavailable'), availability: 'unavailable'
 
 - unless whitelist_mode?
   = form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml
index 4db8fd15c..bed94f3fe 100644
--- a/app/views/admin/instances/show.html.haml
+++ b/app/views/admin/instances/show.html.haml
@@ -1,88 +1,95 @@
 - content_for :page_title do
   = @instance.domain
 
-.filters
-  .back-link
-    = link_to admin_instances_path() do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_all')
-    = link_to admin_instances_path(limited: 1) do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_limited')
-    = link_to admin_instances_path(warning: 1) do
-      %i.fa.fa-chevron-left.fa-fw
-      = t('admin.instances.back_to_warning')
-
-.dashboard__counters
-  %div
-    = link_to admin_accounts_path(origin: 'remote', by_domain: @instance.domain) do
-      .dashboard__counters__num= number_with_delimiter @instance.accounts_count
-      .dashboard__counters__label= t 'admin.accounts.title'
-  %div
-    = link_to admin_reports_path(by_target_domain: @instance.domain) do
-      .dashboard__counters__num= number_with_delimiter @instance.reports_count
-      .dashboard__counters__label= t 'admin.instances.total_reported'
-  %div
-    %div
-      .dashboard__counters__num= number_to_human_size @instance.media_storage
-      .dashboard__counters__label= t 'admin.instances.total_storage'
-  %div
-    %div
-      .dashboard__counters__num= number_with_delimiter @instance.following_count
-      .dashboard__counters__label= t 'admin.instances.total_followed_by_them'
-  %div
-    %div
-      .dashboard__counters__num= number_with_delimiter @instance.followers_count
-      .dashboard__counters__label= t 'admin.instances.total_followed_by_us'
-  %div
-    %div
-      .dashboard__counters__num= number_with_delimiter @instance.blocks_count
-      .dashboard__counters__label= t 'admin.instances.total_blocked_by_us'
-
-  %div
-    %div
-      .dashboard__counters__num
-        - if @instance.delivery_failure_tracker.available?
-          = fa_icon 'check'
-        - else
-          = fa_icon 'times'
-      .dashboard__counters__label= t 'admin.instances.delivery_available'
-
-- if @instance.private_comment.present?
-  .speech-bubble
-    .speech-bubble__bubble
-      = simple_format(h(@instance.private_comment))
-    .speech-bubble__owner= t 'admin.instances.private_comment'
-
-- if @instance.public_comment.present?
-  .speech-bubble
-    .speech-bubble__bubble
-      = simple_format(h(@instance.public_comment))
-    .speech-bubble__owner= t 'admin.instances.public_comment'
-
-- unless @exhausted_deliveries_days.empty?
-  %h4= t 'admin.instances.delivery_error_days'
-  %ul
-    = render partial: 'exhausted_deliveries_days', collection: @exhausted_deliveries_days
-  %p.hint
-    = t 'admin.instances.delivery_error_hint', count: DeliveryFailureTracker::FAILURE_DAYS_THRESHOLD
+- content_for :header_tags do
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
+
+- content_for :heading_actions do
+  = l(@time_period.first)
+  = ' - '
+  = l(@time_period.last)
+
+%p
+  = fa_icon 'info fw'
+  = t('admin.instances.totals_time_period_hint_html')
+
+.dashboard
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_accounts_measure'), href: admin_accounts_path(origin: 'remote', by_domain: @instance.domain)
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_statuses', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_statuses_measure')
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_media_attachments', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_media_attachments_measure')
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_follows', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_follows_measure')
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_followers', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_followers_measure')
+  .dashboard__item
+    = react_admin_component :counter, measure: 'instance_reports', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_reports_measure'), href: admin_reports_path(by_target_domain: @instance.domain)
+  .dashboard__item
+    = react_admin_component :dimension, dimension: 'instance_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, limit: 8, label: t('admin.instances.dashboard.instance_accounts_dimension')
+  .dashboard__item
+    = react_admin_component :dimension, dimension: 'instance_languages', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, limit: 8, label: t('admin.instances.dashboard.instance_languages_dimension')
 
 %hr.spacer/
 
-%div.action-buttons
-  %div
-    - if @instance.domain_allow
-      = link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
-    - elsif @instance.domain_block
-      = link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button'
-      = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button'
-    - else
-      = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
-    - if @instance.delivery_failure_tracker.available?
-      - unless @exhausted_deliveries_days.empty?
-        = link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button'
-      = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button'
+%h3= t('admin.instances.content_policies.title')
+
+- if whitelist_mode?
+  %p= t('admin.instances.content_policies.limited_federation_mode_description_html')
+
+  - if @instance.domain_allow
+    = link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
+  - else
+    = link_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: 'button', method: :post
+- else
+  %p= t('admin.instances.content_policies.description_html')
+
+  - if @instance.domain_block
+    .table-wrapper
+      %table.table.horizontal-table
+        %tbody
+          %tr
+            %th= t('admin.instances.content_policies.comment')
+            %td= @instance.domain_block.private_comment
+          %tr
+            %th= t('admin.instances.content_policies.reason')
+            %td= @instance.domain_block.public_comment
+          %tr
+            %th= t('admin.instances.content_policies.policy')
+            %td= @instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' • ')
+
+    = link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button'
+    = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
+  - else
+    = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
+
+%hr.spacer/
+
+%h3= t('admin.instances.availability.title')
+
+%p
+  = t('admin.instances.availability.description_html', count: DeliveryFailureTracker::FAILURE_DAYS_THRESHOLD)
+
+.availability-indicator
+  %ul.availability-indicator__graphic
+    - @instance.availability_over_days(14).each do |(date, failing)|
+      %li.availability-indicator__graphic__item{ class: failing ? 'negative' : 'neutral', title: l(date) }
+  .availability-indicator__hint
+    - if @instance.unavailable?
+      %span.negative-hint
+        = t('admin.instances.availability.failure_threshold_reached', date: l(@instance.unavailable_domain.created_at.to_date))
+        = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
+    - elsif @instance.exhausted_deliveries_days.empty?
+      %span.positive-hint
+        = t('admin.instances.availability.no_failures_recorded')
+        = link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
     - else
-      = link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button'
-    - if !@instance.delivery_failure_tracker.available? || @instance.accounts_count.zero? || @instance.domain_block&.suspend?
-      = link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button'
+      %span.negative-hint
+        = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days)
+        = link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } unless @instance.exhausted_deliveries_days.empty?
+
+- if @instance.unavailable?
+  %p= t('admin.instances.purge_description_html')
+
+  = link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button button--destructive'
diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
index 4e06d4bbf..1c033c4c3 100644
--- a/app/views/admin/reports/_status.html.haml
+++ b/app/views/admin/reports/_status.html.haml
@@ -11,15 +11,15 @@
             %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)}
           = Formatter.instance.format(status.proper, custom_emojify: true)
 
-    - unless status.proper.media_attachments.empty?
-      - if status.proper.media_attachments.first.video?
-        - video = status.proper.media_attachments.first
+    - unless status.proper.ordered_media_attachments.empty?
+      - if status.proper.ordered_media_attachments.first.video?
+        - video = status.proper.ordered_media_attachments.first
         = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: status.proper.sensitive?, visible: false, width: 610, height: 343, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json
-      - elsif status.proper.media_attachments.first.audio?
-        - audio = status.proper.media_attachments.first
+      - elsif status.proper.ordered_media_attachments.first.audio?
+        - audio = status.proper.ordered_media_attachments.first
         = react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, duration: audio.file.meta.dig(:original, :duration)
       - else
-        = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive?, visible: false, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
+        = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive?, visible: false, media: status.proper.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 
     .detailed-status__meta
       - if status.application
diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml
index 619173373..248718a73 100644
--- a/app/views/admin/reports/index.html.haml
+++ b/app/views/admin/reports/index.html.haml
@@ -59,11 +59,11 @@
 
               %span.report-card__summary__item__content__icon{ title: t('admin.accounts.statuses') }
                 = fa_icon('comment')
-                = report.statuses.count
+                = report.status_ids.size
 
               %span.report-card__summary__item__content__icon{ title: t('admin.accounts.media_attachments') }
                 = fa_icon('camera')
-                = report.media_attachments.count
+                = report.media_attachments_count
 
               - if report.forwarded?
                 ·
diff --git a/app/views/admin/trends/statuses/_status.html.haml b/app/views/admin/trends/statuses/_status.html.haml
index edb27b9ff..50a855349 100644
--- a/app/views/admin/trends/statuses/_status.html.haml
+++ b/app/views/admin/trends/statuses/_status.html.haml
@@ -9,7 +9,7 @@
       = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', class: 'emojify', rel: 'noopener noreferrer' do
         = one_line_preview(status)
 
-        - status.media_attachments.each do |media_attachment|
+        - status.ordered_media_attachments.each do |media_attachment|
           %abbr{ title: media_attachment.description }
             = fa_icon 'link'
             = media_attachment.file_file_name
diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml
index 7248b2574..0fc32b918 100644
--- a/app/views/disputes/strikes/show.html.haml
+++ b/app/views/disputes/strikes/show.html.haml
@@ -53,7 +53,7 @@
                   = link_to short_account_status_url(@strike.target_account, status_id), class: 'emojify' do
                     = one_line_preview(status)
 
-                    - status.media_attachments.each do |media_attachment|
+                    - status.ordered_media_attachments.each do |media_attachment|
                       %abbr{ title: media_attachment.description }
                         = fa_icon 'link'
                         = media_attachment.file_file_name
diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml
index 31460a76e..f520208e1 100644
--- a/app/views/notification_mailer/_status.html.haml
+++ b/app/views/notification_mailer/_status.html.haml
@@ -33,9 +33,9 @@
                               %div.auto-dir
                                 = Formatter.instance.format(status)
 
-                                - if status.media_attachments.size > 0
+                                - if status.ordered_media_attachments.size > 0
                                   %p
-                                    - status.media_attachments.each do |a|
+                                    - status.ordered_media_attachments.each do |a|
                                       - if status.local?
                                         = link_to full_asset_url(a.file.url(:original)), full_asset_url(a.file.url(:original))
                                       - else
diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml
index 1922f53ce..6ccf3725a 100644
--- a/app/views/statuses/_detailed_status.html.haml
+++ b/app/views/statuses/_detailed_status.html.haml
@@ -25,10 +25,10 @@
       - if status.preloadable_poll
         = render_poll_component(status)
 
-  - if !status.media_attachments.empty?
-    - if status.media_attachments.first.video?
+  - if !status.ordered_media_attachments.empty?
+    - if status.ordered_media_attachments.first.video?
       = render_video_component(status, width: 670, height: 380, detailed: true)
-    - elsif status.media_attachments.first.audio?
+    - elsif status.ordered_media_attachments.first.audio?
       = render_audio_component(status, width: 670, height: 380)
     - else
       = render_media_gallery_component(status, height: 380, standalone: true)
diff --git a/app/views/statuses/_og_image.html.haml b/app/views/statuses/_og_image.html.haml
index c8b6147ef..5a647531a 100644
--- a/app/views/statuses/_og_image.html.haml
+++ b/app/views/statuses/_og_image.html.haml
@@ -1,6 +1,6 @@
 - if activity.is_a?(Status) && (activity.non_sensitive_with_media? || (activity.with_media? && Setting.preview_sensitive_media))
   - player_card = false
-  - activity.media_attachments.each do |media|
+  - activity.ordered_media_attachments.each do |media|
     - if media.image?
       = opengraph 'og:image', full_asset_url(media.file.url(:original))
       = opengraph 'og:image:type', media.file_content_type
diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml
index b1e79a1cc..67c6dfc7d 100644
--- a/app/views/statuses/_simple_status.html.haml
+++ b/app/views/statuses/_simple_status.html.haml
@@ -37,10 +37,10 @@
       - if status.preloadable_poll
         = render_poll_component(status)
 
-  - if !status.media_attachments.empty?
-    - if status.media_attachments.first.video?
+  - if !status.ordered_media_attachments.empty?
+    - if status.ordered_media_attachments.first.video?
       = render_video_component(status, width: 610, height: 343)
-    - elsif status.media_attachments.first.audio?
+    - elsif status.ordered_media_attachments.first.audio?
       = render_audio_component(status, width: 610, height: 343)
     - else
       = render_media_gallery_component(status, height: 343)
diff --git a/app/views/user_mailer/warning.text.erb b/app/views/user_mailer/warning.text.erb
index 31d7308ae..1f410f441 100644
--- a/app/views/user_mailer/warning.text.erb
+++ b/app/views/user_mailer/warning.text.erb
@@ -32,4 +32,5 @@
 ---
 <% end %>
 
-<%= t 'user_mailer.warning.get_in_touch', instance: @instance %>
+<%= t 'user_mailer.warning.appeal_description', instance: @instance %>
+<%= disputes_strike_url(@warning) %>
diff --git a/app/workers/admin/domain_purge_worker.rb b/app/workers/admin/domain_purge_worker.rb
index 7cba2c89e..095232a6d 100644
--- a/app/workers/admin/domain_purge_worker.rb
+++ b/app/workers/admin/domain_purge_worker.rb
@@ -3,6 +3,8 @@
 class Admin::DomainPurgeWorker
   include Sidekiq::Worker
 
+  sidekiq_options queue: 'pull', lock: :until_executed
+
   def perform(domain)
     PurgeDomainService.new.call(domain)
   end