-features/video/index.jsx: style={{ aspectRatio }}
-features/video/index.jsx: style={{ width: '100%' }}
-features/video/index.jsx:
-features/video/index.jsx:
-features/video/index.jsx: style={{ left: `${progress}%` }}
-features/video/index.jsx:
-features/video/index.jsx: style={{ left: `${muted ? 0 : volume * 100}%` }}
diff --git a/app/views/foo b/app/views/foo
deleted file mode 100644
index 9d80c3bd4..000000000
--- a/app/views/foo
+++ /dev/null
@@ -1,8916 +0,0 @@
-diff --git a/app/views/.rubocop.yml b/app/views/.rubocop.yml
-new file mode 100644
-index 000000000..4e268848c
---- /dev/null
-+++ b/app/views/.rubocop.yml
-@@ -0,0 +1,5 @@
-+inherit_from: ../../.rubocop.yml
-+
-+# Disable for the `Rubocop` lints in haml-lint
-+Style/IfUnlessModifier:
-+ Enabled: false
-diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
-index f19a7878b..19d9fe1eb 100644
---- a/app/views/accounts/show.html.haml
-+++ b/app/views/accounts/show.html.haml
-@@ -1,12 +1,12 @@
- - content_for :page_title do
-- = "#{display_name(@account)} (#{acct(@account)})"
-+ #{display_name(@account)} (#{acct(@account)})
-
- - content_for :header_tags do
- - if @account.user_prefers_noindex?
- %meta{ name: 'robots', content: 'noindex, noarchive' }/
-
-- - if !@account.user&.setting_norss
-- %link{ rel: 'alternate', type: 'application/rss+xml', href: @rss_url }/
-+ - unless @account.user&.setting_norss
-+ %link{ rel: 'alternate', type: 'application/rss+xml', href: rss_url }/
- %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@account) }/
-
- - @account.fields.select(&:verifiable?).each do |field|
-diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml
-index 2a0cae15a..c4311eba9 100644
---- a/app/views/admin/account_actions/new.html.haml
-+++ b/app/views/admin/account_actions/new.html.haml
-@@ -1,30 +1,57 @@
- - content_for :page_title do
- = t('admin.account_actions.title', acct: @account.pretty_acct)
-
-+- if @account.suspended_locally?
-+ .flash-message.alert
-+ = t('admin.account_actions.already_suspended')
-+- elsif @account.silenced?
-+ .flash-message.warn
-+ = t('admin.account_actions.already_silenced')
-+
- = simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f|
-- = f.input :report_id, as: :hidden
-+ = f.input :report_id,
-+ as: :hidden
-
- .fields-group
-- = f.input :type, as: :radio_buttons, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { safe_join([I18n.t("simple_form.labels.admin_account_action.types.#{type}"), content_tag(:span, I18n.t("simple_form.hints.admin_account_action.types.#{type}"), class: 'hint')]) }, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct)
-+ = f.input :type,
-+ as: :radio_buttons,
-+ collection: Admin::AccountAction.types_for_account(@account),
-+ disabled: Admin::AccountAction.disabled_types_for_account(@account),
-+ hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct),
-+ include_blank: false,
-+ label_method: ->(type) { account_action_type_label(type) },
-+ wrapper: :with_block_label
-
- - if @account.local?
- %hr.spacer/
-
- .fields-group
-- = f.input :send_email_notification, as: :boolean, wrapper: :with_label
-+ = f.input :send_email_notification,
-+ as: :boolean,
-+ wrapper: :with_label
-
- - if params[:report_id].present?
- .fields-group
-- = f.input :include_statuses, as: :boolean, wrapper: :with_label
-+ = f.input :include_statuses,
-+ as: :boolean,
-+ wrapper: :with_label
-
- %hr.spacer/
-
- - unless @warning_presets.empty?
- .fields-group
-- = f.input :warning_preset_id, collection: @warning_presets, label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') }, wrapper: :with_block_label
-+ = f.input :warning_preset_id,
-+ collection: @warning_presets,
-+ label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') },
-+ wrapper: :with_block_label
-
- .fields-group
-- = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path)
-+ = f.input :text,
-+ as: :text,
-+ hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path),
-+ wrapper: :with_block_label
-
- .actions
-- = f.button :button, t('admin.account_actions.action'), type: :submit
-+ = f.button :button,
-+ t('admin.account_actions.action'),
-+ type: :submit
-diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml
-index 85bac789f..368e69e63 100644
---- a/app/views/admin/account_warnings/_account_warning.html.haml
-+++ b/app/views/admin/account_warnings/_account_warning.html.haml
-@@ -2,10 +2,13 @@
- .log-entry__header
- .log-entry__avatar
- .indicator-icon{ class: account_warning.overruled? ? 'success' : 'failure' }
-- = fa_icon 'warning'
-+ = material_symbol 'warning'
- .log-entry__content
- .log-entry__title
-- = t(account_warning.action, scope: 'admin.strikes.actions', name: content_tag(:span, account_warning.account ? account_warning.account.username : I18n.t('admin.action_logs.deleted_account'), class: 'username'), target: content_tag(:span, account_warning.target_account.pretty_acct, class: 'target')).html_safe
-+ = t(account_warning.action,
-+ scope: 'admin.strikes.actions',
-+ name: content_tag(:span, account_warning.account ? account_warning.account.username : I18n.t('admin.action_logs.deleted_account'), class: 'username'),
-+ target: content_tag(:span, account_warning.target_account.pretty_acct, class: 'target')).html_safe
- .log-entry__timestamp
- %time.formatted{ datetime: account_warning.created_at.iso8601 }
- = l(account_warning.created_at)
-diff --git a/app/views/admin/accounts/_account.html.haml b/app/views/admin/accounts/_account.html.haml
-index 82dd8dfb2..d2f6652a0 100644
---- a/app/views/admin/accounts/_account.html.haml
-+++ b/app/views/admin/accounts/_account.html.haml
-@@ -1,4 +1,4 @@
--.batch-table__row{ class: [!account.suspended? && account.user_pending? && 'batch-table__row--attention', (account.suspended? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
-+.batch-table__row{ class: [!account.unavailable? && account.user_pending? && 'batch-table__row--attention', (account.unavailable? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
- %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
- = f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
- .batch-table__row__content.batch-table__row__content--unpadded
-@@ -8,13 +8,13 @@
- %td
- = account_link_to account, path: admin_account_path(account.id)
- %td.accounts-table__count.optional
-- - if account.suspended? || account.user_pending?
-+ - if account.unavailable? || account.user_pending?
- \-
- - else
- = friendly_number_to_human account.statuses_count
- %small= t('accounts.posts', count: account.statuses_count).downcase
- %td.accounts-table__count.optional
-- - if account.suspended? || account.user_pending?
-+ - if account.unavailable? || account.user_pending?
- \-
- - else
- = friendly_number_to_human account.followers_count
-@@ -30,6 +30,6 @@
- \-
- %br/
- %samp.ellipsized-ip= relevant_account_ip(account, params[:ip])
-- - if !account.suspended? && account.user_pending? && account.user&.invite_request&.text&.present?
-+ - if !account.unavailable? && account.user_pending? && account.user&.invite_request&.text.present?
- .batch-table__row__content__quote
- %p= account.user&.invite_request&.text
-diff --git a/app/views/admin/accounts/_buttons.html.haml b/app/views/admin/accounts/_buttons.html.haml
-new file mode 100644
-index 000000000..2aaca8962
---- /dev/null
-+++ b/app/views/admin/accounts/_buttons.html.haml
-@@ -0,0 +1,41 @@
-+- if account.suspended?
-+ %hr.spacer/
-+ - if account.suspension_origin_remote?
-+ %p.muted-hint= deletion_request.present? ? t('admin.accounts.remote_suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.remote_suspension_irreversible')
-+ - else
-+ %p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible')
-+ = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account)
-+ = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote?
-+ - if deletion_request.present? && can?(:destroy, account)
-+ = link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') }
-+- else
-+ .action-buttons
-+ %div
-+ - if account.local? && account.user_approved?
-+ = link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account)
-+ - if account.user_disabled?
-+ = link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user)
-+ - elsif can?(:disable, account.user)
-+ = link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button'
-+ - if account.sensitized?
-+ = link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account)
-+ - elsif !account.local? || account.user_approved?
-+ = link_to t('admin.accounts.sensitive'), new_admin_account_action_path(account.id, type: 'sensitive'), class: 'button' if can?(:sensitive, account)
-+ - if account.silenced?
-+ = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsilence, account)
-+ - elsif !account.local? || account.user_approved?
-+ = link_to t('admin.accounts.silence'), new_admin_account_action_path(account.id, type: 'silence'), class: 'button' if can?(:silence, account)
-+ - if account.local?
-+ - if account.user_pending?
-+ = link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user)
-+ = link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user)
-+ - if !account.user_confirmed? && can?(:confirm, account.user)
-+ = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button'
-+ - if (!account.local? || account.user_approved?) && can?(:suspend, account)
-+ = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button'
-+ %div
-+ - if account.local?
-+ - if !account.memorial? && account.user_approved? && can?(:memorialize, account)
-+ = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive'
-+ - elsif can?(:redownload, account)
-+ = link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button'
-diff --git a/app/views/admin/accounts/_counters.html.haml b/app/views/admin/accounts/_counters.html.haml
-new file mode 100644
-index 000000000..00ab98d09
---- /dev/null
-+++ b/app/views/admin/accounts/_counters.html.haml
-@@ -0,0 +1,43 @@
-+.dashboard__counters.admin-account-counters
-+ %div
-+ = link_to admin_account_statuses_path(account.id) do
-+ .dashboard__counters__num= number_with_delimiter account.statuses_count
-+ .dashboard__counters__label= t 'admin.accounts.statuses'
-+ %div
-+ = link_to admin_account_statuses_path(account.id, { media: true }) do
-+ .dashboard__counters__num= number_to_human_size account.media_attachments.sum('file_file_size')
-+ .dashboard__counters__label= t 'admin.accounts.media_attachments'
-+ %div
-+ = link_to admin_account_relationships_path(account.id, location: account.local? ? nil : 'local', relationship: 'followed_by') do
-+ .dashboard__counters__num= number_with_delimiter account.local_followers_count
-+ .dashboard__counters__label= t 'admin.accounts.followers'
-+ %div
-+ = link_to admin_reports_path(account_id: account.id) do
-+ .dashboard__counters__num= number_with_delimiter account.reports.count
-+ .dashboard__counters__label= t 'admin.accounts.show.created_reports'
-+ %div
-+ = link_to admin_reports_path(target_account_id: account.id) do
-+ .dashboard__counters__num= number_with_delimiter account.targeted_reports.count
-+ .dashboard__counters__label= t 'admin.accounts.show.targeted_reports'
-+ %div
-+ = link_to admin_action_logs_path(target_account_id: account.id) do
-+ .dashboard__counters__text
-+ - if account.local? && account.user.nil?
-+ = t('admin.accounts.deleted')
-+ - elsif account.memorial?
-+ = t('admin.accounts.memorialized')
-+ - elsif account.suspended?
-+ = t('admin.accounts.suspended')
-+ - elsif account.silenced?
-+ = t('admin.accounts.silenced')
-+ - elsif account.local? && account.user&.disabled?
-+ = t('admin.accounts.disabled')
-+ - elsif account.local? && !account.user&.confirmed?
-+ = t('admin.accounts.confirming')
-+ - elsif account.local? && !account.user_approved?
-+ = t('admin.accounts.pending')
-+ - elsif account.sensitized?
-+ = t('admin.accounts.sensitive')
-+ - else
-+ = t('admin.accounts.no_limits_imposed')
-+ .dashboard__counters__label= t 'admin.accounts.login_status'
-diff --git a/app/views/admin/accounts/_local_account.html.haml b/app/views/admin/accounts/_local_account.html.haml
-new file mode 100644
-index 000000000..5357ebcce
---- /dev/null
-+++ b/app/views/admin/accounts/_local_account.html.haml
-@@ -0,0 +1,76 @@
-+- if account.avatar?
-+ %tr
-+ %th= t('admin.accounts.avatar')
-+ %td= table_link_to 'delete', t('admin.accounts.remove_avatar'), remove_avatar_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_avatar, account)
-+ %td
-+- if account.header?
-+ %tr
-+ %th= t('admin.accounts.header')
-+ %td= table_link_to 'delete', t('admin.accounts.remove_header'), remove_header_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_header, account)
-+ %td
-+%tr
-+ %th= t('admin.accounts.role')
-+ %td
-+ - if account.user_role&.everyone?
-+ = t('admin.accounts.no_role_assigned')
-+ - else
-+ = account.user_role&.name
-+ %td
-+ = table_link_to 'contact_mail', t('admin.accounts.change_role.label'), admin_user_role_path(account.user) if can?(:change_role, account.user)
-+%tr
-+ %th{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= t('admin.accounts.email')
-+ %td{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= account.user_email
-+ %td= table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(account.id) if can?(:change_email, account.user)
-+%tr
-+ %td= table_link_to 'search', t('admin.accounts.search_same_email_domain'), admin_accounts_path(email: "%@#{account.user_email.split('@').last}")
-+- if can?(:create, :email_domain_block)
-+ %tr
-+ %td= table_link_to 'hide_source', t('admin.accounts.add_email_domain_block'), new_admin_email_domain_block_path(_domain: account.user_email.split('@').last)
-+- if account.user_unconfirmed_email.present?
-+ %tr
-+ %th= t('admin.accounts.unconfirmed_email')
-+ %td= account.user_unconfirmed_email
-+ %td
-+%tr
-+ %th= t('admin.accounts.email_status')
-+ %td
-+ - if account.user&.confirmed?
-+ = t('admin.accounts.confirmed')
-+ - else
-+ = t('admin.accounts.confirming')
-+ %td= table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(account.id), method: :post if can?(:confirm, account.user)
-+%tr
-+ %th{ rowspan: can?(:reset_password, account.user) ? 2 : 1 }= t('admin.accounts.security')
-+ %td{ rowspan: can?(:reset_password, account.user) ? 2 : 1 }
-+ - if account.user&.two_factor_enabled?
-+ = t 'admin.accounts.security_measures.password_and_2fa'
-+ - else
-+ = t 'admin.accounts.security_measures.only_password'
-+ %td
-+ - if account.user&.two_factor_enabled? && can?(:disable_2fa, account.user)
-+ = table_link_to 'lock_open', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(account.user.id), method: :delete
-+- if can?(:reset_password, account.user)
-+ %tr
-+ %td
-+ = table_link_to 'key', t('admin.accounts.reset_password'), admin_account_reset_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-+%tr
-+ %th= t('simple_form.labels.defaults.locale')
-+ %td= standard_locale_name(account.user_locale)
-+ %td
-+%tr
-+ %th= t('admin.accounts.joined')
-+ %td
-+ %time.formatted{ datetime: account.created_at.iso8601, title: l(account.created_at) }= l account.created_at
-+ %td
-+ = render partial: 'admin/accounts/user_ip', collection: account.user.ips.by_latest_used
-+%tr
-+ %th= t('admin.accounts.most_recent_activity')
-+ %td
-+ - if account.user_current_sign_in_at
-+ %time.formatted{ datetime: account.user_current_sign_in_at.iso8601, title: l(account.user_current_sign_in_at) }= l account.user_current_sign_in_at
-+ %td
-+- if account.user&.invited?
-+ %tr
-+ %th= t('admin.accounts.invited_by')
-+ %td= admin_account_link_to account.user.invite.user.account
-+ %td
-diff --git a/app/views/admin/accounts/_remote_account.html.haml b/app/views/admin/accounts/_remote_account.html.haml
-new file mode 100644
-index 000000000..a052e877f
---- /dev/null
-+++ b/app/views/admin/accounts/_remote_account.html.haml
-@@ -0,0 +1,15 @@
-+%tr
-+ %th= t('admin.accounts.inbox_url')
-+ %td
-+ = account.inbox_url
-+ = material_symbol DeliveryFailureTracker.available?(account.inbox_url) ? 'check' : 'close'
-+ %td
-+ = table_link_to 'search', domain_block.present? ? t('admin.domain_blocks.view') : t('admin.accounts.view_domain'), admin_instance_path(account.domain)
-+%tr
-+ %th= t('admin.accounts.shared_inbox_url')
-+ %td
-+ = account.shared_inbox_url
-+ = material_symbol DeliveryFailureTracker.available?(account.shared_inbox_url) ? 'check' : 'close'
-+ %td
-+ - if domain_block.nil?
-+ = table_link_to 'hide_source', t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: account.domain)
-diff --git a/app/views/admin/accounts/_user_ip.html.haml b/app/views/admin/accounts/_user_ip.html.haml
-new file mode 100644
-index 000000000..1938cf7ed
---- /dev/null
-+++ b/app/views/admin/accounts/_user_ip.html.haml
-@@ -0,0 +1,5 @@
-+%tr
-+ - if user_ip_iteration.first?
-+ %th{ rowspan: user_ip_iteration.size }= t('admin.accounts.most_recent_ip')
-+ %td= user_ip.ip
-+ %td= table_link_to 'search', t('admin.accounts.search_same_ip'), admin_accounts_path(ip: user_ip.ip)
-diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
-index da11e4361..9dd4f0e4e 100644
---- a/app/views/admin/accounts/index.html.haml
-+++ b/app/views/admin/accounts/index.html.haml
-@@ -1,30 +1,41 @@
- - content_for :page_title do
- = t('admin.accounts.title')
-
--= form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_accounts_url, method: :get, class: :simple_form do |form|
- .filters
- .filter-subset.filter-subset--with-select
- %strong= t('admin.accounts.location.title')
- .input.select.optional
-- = select_tag :origin, options_for_select([[t('admin.accounts.location.local'), 'local'], [t('admin.accounts.location.remote'), 'remote']], params[:origin]), prompt: I18n.t('generic.all')
-+ = form.select :origin,
-+ options_for_select([[t('admin.accounts.location.local'), 'local'], [t('admin.accounts.location.remote'), 'remote']], params[:origin]),
-+ prompt: I18n.t('generic.all')
- .filter-subset.filter-subset--with-select
- %strong= t('admin.accounts.moderation.title')
- .input.select.optional
-- = select_tag :status, options_for_select([[t('admin.accounts.moderation.active'), 'active'], [t('admin.accounts.moderation.silenced'), 'silenced'], [t('admin.accounts.moderation.disabled'), 'disabled'], [t('admin.accounts.moderation.suspended'), 'suspended'], [safe_join([t('admin.accounts.moderation.pending'), "(#{number_with_delimiter(User.pending.count)})"], ' '), 'pending']], params[:status]), prompt: I18n.t('generic.all')
-+ = form.select :status,
-+ options_for_select(admin_accounts_moderation_options, params[:status]),
-+ prompt: I18n.t('generic.all')
- .filter-subset.filter-subset--with-select
- %strong= t('admin.accounts.role')
- .input.select.optional
-- = select_tag :role_ids, options_from_collection_for_select(UserRole.assignable, :id, :name, params[:role_ids]), prompt: I18n.t('admin.accounts.moderation.all')
-+ = form.select :role_ids,
-+ options_from_collection_for_select(UserRole.assignable, :id, :name, params[:role_ids]),
-+ prompt: I18n.t('admin.accounts.moderation.all')
- .filter-subset.filter-subset--with-select
- %strong= t 'generic.order_by'
- .input.select
-- = select_tag :order, options_for_select([[t('relationships.most_recent'), 'recent'], [t('relationships.last_active'), 'active']], params[:order])
-+ = form.select :order,
-+ options_for_select([[t('relationships.most_recent'), 'recent'], [t('relationships.last_active'), 'active']], params[:order])
-
- .fields-group
- - %i(username by_domain display_name email ip).each do |key|
-- - unless key == :by_domain && params[:origin] != 'remote'
-- .input.string.optional
-- = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}")
-+ - next if key == :by_domain && params[:origin] != 'remote'
-+
-+ .input.string.optional
-+ = form.text_field key,
-+ value: params[key],
-+ class: 'string optional',
-+ placeholder: I18n.t("admin.accounts.#{key}")
-
- .actions
- %button.button= t('admin.accounts.search')
-@@ -32,7 +43,7 @@
-
- %hr.spacer/
-
--= form_for(@form, url: batch_admin_accounts_path) do |f|
-+= form_with model: @form, url: batch_admin_accounts_path do |f|
- = hidden_field_tag :page, params[:page] || 1
- = hidden_field_tag :select_all_matching, '0'
-
-@@ -45,11 +56,23 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - if @accounts.any?(&:user_pending?)
-- = f.button safe_join([fa_icon('check'), t('admin.accounts.approve')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('check'), t('admin.accounts.approve')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :approve,
-+ type: :submit
-
-- = f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('close'), t('admin.accounts.reject')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :reject,
-+ type: :submit
-
-- = f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('lock'), t('admin.accounts.perform_full_suspension')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :suspend,
-+ type: :submit
- - if @accounts.total_count > @accounts.size
- .batch-table__select-all
- .not-selected.active
-diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
-index 44867d0a2..f148b9a08 100644
---- a/app/views/admin/accounts/show.html.haml
-+++ b/app/views/admin/accounts/show.html.haml
-@@ -20,229 +20,27 @@
- %dd{ title: field.value, class: custom_field_classes(field) }
- - if field.verified?
- %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) }
-- = fa_icon 'check'
-+ = material_symbol 'check'
- = prerender_custom_emojis(account_field_value_format(field, with_rel_me: false), account.emojis)
-
- - if account.note.present?
- %div
- .account__header__content.emojify= prerender_custom_emojis(account_bio_format(account), account.emojis)
-
--.dashboard__counters.admin-account-counters
-- %div
-- = link_to admin_account_statuses_path(@account.id) do
-- .dashboard__counters__num= number_with_delimiter @account.statuses_count
-- .dashboard__counters__label= t 'admin.accounts.statuses'
-- %div
-- = link_to admin_account_statuses_path(@account.id, { media: true }) do
-- .dashboard__counters__num= number_to_human_size @account.media_attachments.sum('file_file_size')
-- .dashboard__counters__label= t 'admin.accounts.media_attachments'
-- %div
-- = link_to admin_account_relationships_path(@account.id, location: @account.local? ? nil : 'local', relationship: 'followed_by') do
-- .dashboard__counters__num= number_with_delimiter @account.local_followers_count
-- .dashboard__counters__label= t 'admin.accounts.followers'
-- %div
-- = link_to admin_reports_path(account_id: @account.id) do
-- .dashboard__counters__num= number_with_delimiter @account.reports.count
-- .dashboard__counters__label= t '.created_reports'
-- %div
-- = link_to admin_reports_path(target_account_id: @account.id) do
-- .dashboard__counters__num= number_with_delimiter @account.targeted_reports.count
-- .dashboard__counters__label= t '.targeted_reports'
-- %div
-- = link_to admin_action_logs_path(target_account_id: @account.id) do
-- .dashboard__counters__text
-- - if @account.local? && @account.user.nil?
-- = t('admin.accounts.deleted')
-- - elsif @account.memorial?
-- = t('admin.accounts.memorialized')
-- - elsif @account.suspended?
-- = t('admin.accounts.suspended')
-- - elsif @account.silenced?
-- = t('admin.accounts.silenced')
-- - elsif @account.local? && @account.user&.disabled?
-- = t('admin.accounts.disabled')
-- - elsif @account.local? && !@account.user&.confirmed?
-- = t('admin.accounts.confirming')
-- - elsif @account.local? && !@account.user_approved?
-- = t('admin.accounts.pending')
-- - elsif @account.sensitized?
-- = t('admin.accounts.sensitive')
-- - else
-- = t('admin.accounts.no_limits_imposed')
-- .dashboard__counters__label= t 'admin.accounts.login_status'
-+= render 'admin/accounts/counters', account: @account
-
- - if @account.local? && @account.user.nil?
-- = link_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unblock_email, @account) && CanonicalEmailBlock.where(reference_account_id: @account.id).exists?
-+ = link_to t('admin.accounts.unblock_email'), unblock_email_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unblock_email, @account) && CanonicalEmailBlock.exists?(reference_account_id: @account.id)
- - else
- .table-wrapper
- %table.table.inline-table
- %tbody
- - if @account.local?
-- - if @account.avatar?
-- %tr
-- %th= t('admin.accounts.avatar')
-- %td= table_link_to 'trash', t('admin.accounts.remove_avatar'), remove_avatar_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_avatar, @account)
-- %td
--
-- - if @account.header?
-- %tr
-- %th= t('admin.accounts.header')
-- %td= table_link_to 'trash', t('admin.accounts.remove_header'), remove_header_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:remove_header, @account)
-- %td
--
-- %tr
-- %th= t('admin.accounts.role')
-- %td
-- - if @account.user_role&.everyone?
-- = t('admin.accounts.no_role_assigned')
-- - else
-- = @account.user_role&.name
-- %td
-- = table_link_to 'vcard', t('admin.accounts.change_role.label'), admin_user_role_path(@account.user) if can?(:change_role, @account.user)
--
-- %tr
-- %th{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= t('admin.accounts.email')
-- %td{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= @account.user_email
-- %td= table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user)
--
-- %tr
-- %td= table_link_to 'search', t('admin.accounts.search_same_email_domain'), admin_accounts_path(email: "%@#{@account.user_email.split('@').last}")
--
-- - if can?(:create, :email_domain_block)
-- %tr
-- %td= table_link_to 'ban', t('admin.accounts.add_email_domain_block'), new_admin_email_domain_block_path(_domain: @account.user_email.split('@').last)
--
-- - if @account.user_unconfirmed_email.present?
-- %tr
-- %th= t('admin.accounts.unconfirmed_email')
-- %td= @account.user_unconfirmed_email
-- %td
--
-- %tr
-- %th= t('admin.accounts.email_status')
-- %td
-- - if @account.user&.confirmed?
-- = t('admin.accounts.confirmed')
-- - else
-- = t('admin.accounts.confirming')
-- %td= table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(@account.id), method: :post if can?(:confirm, @account.user)
-- %tr
-- %th{ rowspan: can?(:reset_password, @account.user) ? 2 : 1 }= t('admin.accounts.security')
-- %td{ rowspan: can?(:reset_password, @account.user) ? 2 : 1 }
-- - if @account.user&.two_factor_enabled?
-- = t 'admin.accounts.security_measures.password_and_2fa'
-- - else
-- = t 'admin.accounts.security_measures.only_password'
-- %td
-- - if @account.user&.two_factor_enabled?
-- = table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete if can?(:disable_2fa, @account.user)
--
-- - if can?(:reset_password, @account.user)
-- %tr
-- %td
-- = table_link_to 'key', t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, data: { confirm: t('admin.accounts.are_you_sure') }
--
-- %tr
-- %th= t('simple_form.labels.defaults.locale')
-- %td= standard_locale_name(@account.user_locale)
-- %td
--
-- %tr
-- %th= t('admin.accounts.joined')
-- %td
-- %time.formatted{ datetime: @account.created_at.iso8601, title: l(@account.created_at) }= l @account.created_at
-- %td
--
-- - recent_ips = @account.user.ips.order(used_at: :desc).to_a
--
-- - recent_ips.each_with_index do |recent_ip, i|
-- %tr
-- - if i.zero?
-- %th{ rowspan: recent_ips.size }= t('admin.accounts.most_recent_ip')
-- %td= recent_ip.ip
-- %td= table_link_to 'search', t('admin.accounts.search_same_ip'), admin_accounts_path(ip: recent_ip.ip)
--
-- %tr
-- %th= t('admin.accounts.most_recent_activity')
-- %td
-- - if @account.user_current_sign_in_at
-- %time.formatted{ datetime: @account.user_current_sign_in_at.iso8601, title: l(@account.user_current_sign_in_at) }= l @account.user_current_sign_in_at
-- %td
--
-- - if @account.user&.invited?
-- %tr
-- %th= t('admin.accounts.invited_by')
-- %td= admin_account_link_to @account.user.invite.user.account
-- %td
--
-+ = render 'admin/accounts/local_account', account: @account
- - else
-- %tr
-- %th= t('admin.accounts.inbox_url')
-- %td
-- = @account.inbox_url
-- = fa_icon DeliveryFailureTracker.available?(@account.inbox_url) ? 'check' : 'times'
-- %td
-- = table_link_to 'search', @domain_block.present? ? t('admin.domain_blocks.view') : t('admin.accounts.view_domain'), admin_instance_path(@account.domain)
-- %tr
-- %th= t('admin.accounts.shared_inbox_url')
-- %td
-- = @account.shared_inbox_url
-- = fa_icon DeliveryFailureTracker.available?(@account.shared_inbox_url) ? 'check' : 'times'
-- %td
-- - if @domain_block.nil?
-- = table_link_to 'ban', t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain)
-+ = render 'admin/accounts/remote_account', account: @account, domain_block: @domain_block
-
-- - if @account.suspended?
-- %hr.spacer/
--
-- - if @account.suspension_origin_remote?
-- %p.muted-hint= @deletion_request.present? ? t('admin.accounts.remote_suspension_reversible_hint_html', date: content_tag(:strong, l(@deletion_request.due_at.to_date))) : t('admin.accounts.remote_suspension_irreversible')
-- - else
-- %p.muted-hint= @deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(@deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible')
--
-- = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account)
-- = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account) && @account.suspension_origin_remote?
--
-- - if @deletion_request.present?
-- = link_to t('admin.accounts.delete'), admin_account_path(@account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, @account)
-- - else
-- .action-buttons
-- %div
-- - if @account.local? && @account.user_approved?
-- = link_to t('admin.accounts.warn'), new_admin_account_action_path(@account.id, type: 'none'), class: 'button' if can?(:warn, @account)
--
-- - if @account.user_disabled?
-- = link_to t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post, class: 'button' if can?(:enable, @account.user)
-- - else
-- = link_to t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable'), class: 'button' if can?(:disable, @account.user)
--
-- - if @account.sensitized?
-- = link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsensitive, @account)
-- - elsif !@account.local? || @account.user_approved?
-- = link_to t('admin.accounts.sensitive'), new_admin_account_action_path(@account.id, type: 'sensitive'), class: 'button' if can?(:sensitive, @account)
--
-- - if @account.silenced?
-- = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account)
-- - elsif !@account.local? || @account.user_approved?
-- = link_to t('admin.accounts.silence'), new_admin_account_action_path(@account.id, type: 'silence'), class: 'button' if can?(:silence, @account)
--
-- - if @account.local?
-- - if @account.user_pending?
-- = link_to t('admin.accounts.approve'), approve_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, @account.user)
-- = link_to t('admin.accounts.reject'), reject_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, @account.user)
--
-- - unless @account.user_confirmed?
-- = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user)
--
-- - if !@account.local? || @account.user_approved?
-- = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button' if can?(:suspend, @account)
--
-- %div
-- - if @account.local?
-- - if !@account.memorial? && @account.user_approved?
-- = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, @account)
-- - else
-- = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account)
-+ = render 'admin/accounts/buttons', account: @account, deletion_request: @deletion_request
-
- %hr.spacer/
-
-@@ -264,18 +62,20 @@
- .report-notes
- = render partial: 'admin/report_notes/report_note', collection: @moderation_notes
-
-- = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f|
-- = f.hidden_field :target_account_id
-+ = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |form|
-+ = form.hidden_field :target_account_id
-+
-+ = render 'shared/error_messages', object: @account_moderation_note
-
- .field-group
-- = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6
-+ = form.input :content, input_html: { placeholder: t('admin.reports.notes.placeholder'), maxlength: AccountModerationNote::CONTENT_SIZE_LIMIT, rows: 6, autofocus: @account_moderation_note.errors.any? }
-
- .actions
-- = f.button :button, t('admin.account_moderation_notes.create'), type: :submit
-+ = form.button :button, t('admin.account_moderation_notes.create'), type: :submit
-
- %hr.spacer/
-
-- - if @account.user&.invite_request&.text&.present?
-+ - if @account.user&.invite_request&.text.present?
- .speech-bubble
- .speech-bubble__bubble
- = @account.user&.invite_request&.text
-diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml
-index a2fce2d11..dcc333180 100644
---- a/app/views/admin/action_logs/_action_log.html.haml
-+++ b/app/views/admin/action_logs/_action_log.html.haml
-@@ -4,6 +4,8 @@
- = image_tag action_log.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar'
- .log-entry__content
- .log-entry__title
-- = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target'))
-+ = t "admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html",
-+ name: content_tag(:span, action_log.account.username, class: 'username'),
-+ target: content_tag(:span, log_target(action_log), class: 'target')
- .log-entry__timestamp
- %time.formatted{ datetime: action_log.created_at.iso8601 }
-diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml
-index c4929cc42..a5d418829 100644
---- a/app/views/admin/action_logs/index.html.haml
-+++ b/app/views/admin/action_logs/index.html.haml
-@@ -1,19 +1,23 @@
- - content_for :page_title do
- = t('admin.action_logs.title')
-
--= form_tag admin_action_logs_url, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_action_logs_url, method: :get, class: :simple_form do |form|
- = hidden_field_tag :target_account_id, params[:target_account_id] if params[:target_account_id].present?
-
- .filters
- .filter-subset.filter-subset--with-select
- %strong= t('admin.action_logs.filter_by_user')
- .input.select.optional
-- = select_tag :account_id, options_from_collection_for_select(@auditable_accounts, :id, :username, params[:account_id]), prompt: I18n.t('admin.accounts.moderation.all')
-+ = form.select :account_id,
-+ options_from_collection_for_select(@auditable_accounts, :id, :username, params[:account_id]),
-+ prompt: I18n.t('admin.accounts.moderation.all')
-
- .filter-subset.filter-subset--with-select
- %strong= t('admin.action_logs.filter_by_action')
- .input.select.optional
-- = select_tag :action_type, options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] }, params[:action_type]), prompt: I18n.t('admin.accounts.moderation.all')
-+ = form.select :action_type,
-+ options_for_select(sorted_action_log_types, params[:action_type]),
-+ prompt: I18n.t('admin.accounts.moderation.all')
-
- - if @action_logs.empty?
- .muted-hint.center-text
-diff --git a/app/views/admin/announcements/_announcement.html.haml b/app/views/admin/announcements/_announcement.html.haml
-index 1c7f89ef2..8190f87d2 100644
---- a/app/views/admin/announcements/_announcement.html.haml
-+++ b/app/views/admin/announcements/_announcement.html.haml
-@@ -1,4 +1,4 @@
--.announcements-list__item
-+.announcements-list__item{ id: dom_id(announcement) }
- = link_to edit_admin_announcement_path(announcement), class: 'announcements-list__item__title' do
- = truncate(announcement.text)
-
-@@ -12,8 +12,8 @@
- %div
- - if can?(:update, announcement)
- - if announcement.published?
-- = table_link_to 'toggle-off', t('admin.announcements.unpublish'), unpublish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'toggle_off', t('admin.announcements.unpublish'), unpublish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
- - else
-- = table_link_to 'toggle-on', t('admin.announcements.publish'), publish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'toggle_on', t('admin.announcements.publish'), publish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-
-- = table_link_to 'trash', t('generic.delete'), admin_announcement_path(announcement), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, announcement)
-+ = table_link_to 'delete', t('generic.delete'), admin_announcement_path(announcement), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, announcement)
-diff --git a/app/views/admin/announcements/_form.html.haml b/app/views/admin/announcements/_form.html.haml
-new file mode 100644
-index 000000000..3a9b37190
---- /dev/null
-+++ b/app/views/admin/announcements/_form.html.haml
-@@ -0,0 +1,28 @@
-+.fields-group
-+ = form.input :starts_at,
-+ html5: true,
-+ include_blank: true,
-+ input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder },
-+ wrapper: :with_block_label
-+ = form.input :ends_at,
-+ html5: true,
-+ include_blank: true,
-+ input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder },
-+ wrapper: :with_block_label
-+
-+.fields-group
-+ = form.input :all_day,
-+ as: :boolean,
-+ wrapper: :with_label
-+
-+.fields-group
-+ = form.input :text,
-+ wrapper: :with_block_label
-+
-+- unless form.object.published?
-+ .fields-group
-+ = form.input :scheduled_at,
-+ html5: true,
-+ include_blank: true,
-+ input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder },
-+ wrapper: :with_block_label
-diff --git a/app/views/admin/announcements/edit.html.haml b/app/views/admin/announcements/edit.html.haml
-index df1ac455f..8cec7d36c 100644
---- a/app/views/admin/announcements/edit.html.haml
-+++ b/app/views/admin/announcements/edit.html.haml
-@@ -1,22 +1,12 @@
- - content_for :page_title do
- = t('.title')
-
--= simple_form_for @announcement, url: admin_announcement_path(@announcement), html: { novalidate: false } do |f|
-+= simple_form_for @announcement, url: admin_announcement_path(@announcement), html: { novalidate: false } do |form|
- = render 'shared/error_messages', object: @announcement
-
-- .fields-group
-- = f.input :starts_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
-- = f.input :ends_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
--
-- .fields-group
-- = f.input :all_day, as: :boolean, wrapper: :with_label
--
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
--
-- - unless @announcement.published?
-- .fields-group
-- = f.input :scheduled_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
-+ = render form
-
- .actions
-- = f.button :button, t('generic.save_changes'), type: :submit
-+ = form.button :button,
-+ t('generic.save_changes'),
-+ type: :submit
-diff --git a/app/views/admin/announcements/new.html.haml b/app/views/admin/announcements/new.html.haml
-index cb39672e1..266ca65e8 100644
---- a/app/views/admin/announcements/new.html.haml
-+++ b/app/views/admin/announcements/new.html.haml
-@@ -1,21 +1,12 @@
- - content_for :page_title do
- = t('.title')
-
--= simple_form_for @announcement, url: admin_announcements_path, html: { novalidate: false } do |f|
-+= simple_form_for @announcement, url: admin_announcements_path, html: { novalidate: false } do |form|
- = render 'shared/error_messages', object: @announcement
-
-- .fields-group
-- = f.input :starts_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
-- = f.input :ends_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
--
-- .fields-group
-- = f.input :all_day, as: :boolean, wrapper: :with_label
--
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
--
-- .fields-group
-- = f.input :scheduled_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}(:[0-9]{2}){1,2}', placeholder: Time.now.strftime('%FT%R') }
-+ = render form
-
- .actions
-- = f.button :button, t('.create'), type: :submit
-+ = form.button :button,
-+ t('.create'),
-+ type: :submit
-diff --git a/app/views/admin/custom_emojis/_custom_emoji.html.haml b/app/views/admin/custom_emojis/_custom_emoji.html.haml
-index c6789d4f8..f0cb64ec5 100644
---- a/app/views/admin/custom_emojis/_custom_emoji.html.haml
-+++ b/app/views/admin/custom_emojis/_custom_emoji.html.haml
-@@ -6,7 +6,7 @@
- = custom_emoji_tag(custom_emoji)
-
- .batch-table__row__content__text
-- %samp= ":#{custom_emoji.shortcode}:"
-+ %samp :#{custom_emoji.shortcode}:
-
- - if custom_emoji.local?
- %span.information-badge= custom_emoji.category&.name || t('admin.custom_emojis.uncategorized')
-diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/admin/custom_emojis/index.html.haml
-index 8b4e93ac3..6db97e2e8 100644
---- a/app/views/admin/custom_emojis/index.html.haml
-+++ b/app/views/admin/custom_emojis/index.html.haml
-@@ -21,20 +21,23 @@
- - else
- = filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil
-
--= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_custom_emojis_url, method: :get, class: :simple_form do |form|
- .fields-group
- - CustomEmojiFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- - %i(shortcode by_domain).each do |key|
- .input.string.optional
-- = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.custom_emojis.#{key}")
-+ = form.text_field key,
-+ value: params[key],
-+ class: 'string optional',
-+ placeholder: I18n.t("admin.custom_emojis.#{key}")
-
- .actions
- %button.button= t('admin.accounts.search')
- = link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative'
-
--= form_for(@form, url: batch_admin_custom_emojis_path) do |f|
-+= form_with model: @form, url: batch_admin_custom_emojis_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - CustomEmojiFilter::KEYS.each do |key|
-@@ -46,21 +49,21 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - if params[:local] == '1'
-- = f.button safe_join([fa_icon('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
-- = f.button safe_join([fa_icon('eye'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('visibility'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
-- = f.button safe_join([fa_icon('eye-slash'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('visibility_off'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
-- = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.enable')]), name: :enable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('radio_button_checked'), t('admin.custom_emojis.enable')]), name: :enable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
-- = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('radio_button_unchecked'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
- - if can?(:destroy, :custom_emoji)
-- = f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('close'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
- - if can?(:copy, :custom_emoji) && params[:local] != '1'
-- = f.button safe_join([fa_icon('copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('content_copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-
- - if params[:local] == '1'
- .batch-table__form.simple_form
-@@ -68,12 +71,19 @@
- .fields-group.fields-row__column.fields-row__column-6
- .input.select.optional
- .label_input
-- = f.select :category_id, options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'), prompt: t('admin.custom_emojis.assign_category'), class: 'select optional', 'aria-label': t('admin.custom_emojis.assign_category')
-+ = f.select :category_id,
-+ options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'),
-+ 'aria-label': t('admin.custom_emojis.assign_category'),
-+ class: 'select optional',
-+ prompt: t('admin.custom_emojis.assign_category')
-
- .fields-group.fields-row__column.fields-row__column-6
- .input.string.optional
- .label_input
-- = f.text_field :category_name, class: 'string optional', placeholder: t('admin.custom_emojis.create_new_category'), 'aria-label': t('admin.custom_emojis.create_new_category')
-+ = f.text_field :category_name,
-+ 'aria-label': t('admin.custom_emojis.create_new_category'),
-+ class: 'string optional',
-+ placeholder: t('admin.custom_emojis.create_new_category')
-
- .batch-table__body
- - if @custom_emojis.empty?
-diff --git a/app/views/admin/custom_emojis/new.html.haml b/app/views/admin/custom_emojis/new.html.haml
-index a03676b00..e59ae02b3 100644
---- a/app/views/admin/custom_emojis/new.html.haml
-+++ b/app/views/admin/custom_emojis/new.html.haml
-@@ -5,9 +5,17 @@
- = render 'shared/error_messages', object: @custom_emoji
-
- .fields-group
-- = f.input :shortcode, wrapper: :with_label, label: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
-+ = f.input :shortcode,
-+ wrapper: :with_label,
-+ label: t('admin.custom_emojis.shortcode'),
-+ hint: t('admin.custom_emojis.shortcode_hint')
- .fields-group
-- = f.input :image, wrapper: :with_label, input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(',') }, hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT))
-+ = f.input :image,
-+ wrapper: :with_label,
-+ input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(',') },
-+ hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT))
-
- .actions
-- = f.button :button, t('admin.custom_emojis.upload'), type: :submit
-+ = f.button :button,
-+ t('admin.custom_emojis.upload'),
-+ type: :submit
-diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
-index 3597152e0..2b4d02fa6 100644
---- a/app/views/admin/dashboard/index.html.haml
-+++ b/app/views/admin/dashboard/index.html.haml
-@@ -2,9 +2,7 @@
- = t('admin.dashboard.title')
-
- - content_for :heading_actions do
-- = l(@time_period.first)
-- = ' - '
-- = l(@time_period.last)
-+ = date_range(@time_period)
-
- - unless @system_checks.empty?
- .flash-message-stack
-@@ -16,53 +14,106 @@
-
- .dashboard
- .dashboard__item
-- = react_admin_component :counter, measure: 'new_users', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.new_users'), href: admin_accounts_path(origin: 'local')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ href: admin_accounts_path(origin: 'local'),
-+ label: t('admin.dashboard.new_users'),
-+ measure: 'new_users',
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :counter, measure: 'active_users', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.active_users'), href: admin_accounts_path(origin: 'local')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ href: admin_accounts_path(origin: 'local'),
-+ label: t('admin.dashboard.active_users'),
-+ measure: 'active_users',
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :counter, measure: 'interactions', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.interactions')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.interactions'),
-+ measure: 'interactions',
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :counter, measure: 'opened_reports', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.opened_reports'), href: admin_reports_path
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ href: admin_reports_path,
-+ label: t('admin.dashboard.opened_reports'),
-+ measure: 'opened_reports',
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :counter, measure: 'resolved_reports', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.resolved_reports'), href: admin_reports_path(resolved: '1')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ href: admin_reports_path(resolved: '1'),
-+ label: t('admin.dashboard.resolved_reports'),
-+ measure: 'resolved_reports',
-+ start_at: @time_period.first
-
- .dashboard__item
- = link_to admin_reports_path, class: 'dashboard__quick-access' do
-- %span= t('admin.dashboard.pending_reports_html', count: @pending_reports_count)
-- = fa_icon 'chevron-right fw'
-+ %span= t('admin.dashboard.pending_reports_html', count: @pending_reports_count.value)
-+ = material_symbol 'chevron_right'
-
- = link_to admin_accounts_path(status: 'pending'), class: 'dashboard__quick-access' do
-- %span= t('admin.dashboard.pending_users_html', count: @pending_users_count)
-- = fa_icon 'chevron-right fw'
-+ %span= t('admin.dashboard.pending_users_html', count: @pending_users_count.value)
-+ = material_symbol 'chevron_right'
-
- = link_to admin_trends_tags_path(status: 'pending_review'), class: 'dashboard__quick-access' do
-- %span= t('admin.dashboard.pending_tags_html', count: @pending_tags_count)
-- = fa_icon 'chevron-right fw'
-+ %span= t('admin.dashboard.pending_tags_html', count: @pending_tags_count.value)
-+ = material_symbol 'chevron_right'
-
- = link_to admin_disputes_appeals_path(status: 'pending'), class: 'dashboard__quick-access' do
-- %span= t('admin.dashboard.pending_appeals_html', count: @pending_appeals_count)
-- = fa_icon 'chevron-right fw'
-+ %span= t('admin.dashboard.pending_appeals_html', count: @pending_appeals_count.value)
-+ = material_symbol 'chevron_right'
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'sources', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.sources')
-+ = react_admin_component :dimension,
-+ dimension: 'sources',
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.sources'),
-+ limit: 8,
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'languages', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.top_languages')
-+ = react_admin_component :dimension,
-+ dimension: 'languages',
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.top_languages'),
-+ limit: 8,
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'servers', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.top_servers')
-+ = react_admin_component :dimension,
-+ dimension: 'servers',
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.top_servers'),
-+ limit: 8,
-+ start_at: @time_period.first
-
- .dashboard__item.dashboard__item--span-double-column
-- = react_admin_component :retention, start_at: @time_period.last - 6.months, end_at: @time_period.last, frequency: 'month'
-+ = react_admin_component :retention,
-+ end_at: @time_period.last,
-+ frequency: 'month',
-+ start_at: @time_period.last - 6.months
-
- .dashboard__item.dashboard__item--span-double-row
-- = react_admin_component :trends, limit: 7
-+ = react_admin_component :trends,
-+ limit: 7
-
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'software_versions', start_at: @time_period.first, end_at: @time_period.last, limit: 4, label: t('admin.dashboard.software')
-+ = react_admin_component :dimension,
-+ dimension: 'software_versions',
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.software'),
-+ limit: 4,
-+ start_at: @time_period.first
-
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'space_usage', start_at: @time_period.first, end_at: @time_period.last, limit: 3, label: t('admin.dashboard.space')
-+ = react_admin_component :dimension,
-+ dimension: 'space_usage',
-+ end_at: @time_period.last,
-+ label: t('admin.dashboard.space'),
-+ limit: 3,
-+ start_at: @time_period.first
-diff --git a/app/views/admin/disputes/appeals/_appeal.html.haml b/app/views/admin/disputes/appeals/_appeal.html.haml
-index 3f6efb856..d5611211e 100644
---- a/app/views/admin/disputes/appeals/_appeal.html.haml
-+++ b/app/views/admin/disputes/appeals/_appeal.html.haml
-@@ -4,7 +4,7 @@
- = image_tag appeal.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar'
- .log-entry__content
- .log-entry__title
-- = t(appeal.strike.action, scope: 'admin.strikes.actions', name: content_tag(:span, appeal.strike.account.username, class: 'username'), target: content_tag(:span, appeal.account.username, class: 'target')).html_safe
-+ = strike_action_label(appeal)
- .log-entry__timestamp
- %time.formatted{ datetime: appeal.strike.created_at.iso8601 }
- = l(appeal.strike.created_at)
-diff --git a/app/views/admin/domain_blocks/_form.html.haml b/app/views/admin/domain_blocks/_form.html.haml
-new file mode 100644
-index 000000000..f1785a1fd
---- /dev/null
-+++ b/app/views/admin/domain_blocks/_form.html.haml
-@@ -0,0 +1,46 @@
-+.fields-row
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = form.input :domain,
-+ disabled: form.object.persisted?,
-+ hint: t('admin.domain_blocks.new.hint'),
-+ label: t('admin.domain_blocks.domain'),
-+ readonly: form.object.persisted?,
-+ required: true,
-+ wrapper: :with_label
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = form.input :severity,
-+ collection: DomainBlock.severities.keys,
-+ hint: t('admin.domain_blocks.new.severity.desc_html'),
-+ include_blank: false,
-+ label_method: ->(type) { t("admin.domain_blocks.new.severity.#{type}") },
-+ wrapper: :with_label
-+.fields-group
-+ = form.input :reject_media,
-+ as: :boolean,
-+ hint: I18n.t('admin.domain_blocks.reject_media_hint'),
-+ label: I18n.t('admin.domain_blocks.reject_media'),
-+ wrapper: :with_label
-+.fields-group
-+ = form.input :reject_reports,
-+ as: :boolean,
-+ hint: I18n.t('admin.domain_blocks.reject_reports_hint'),
-+ label: I18n.t('admin.domain_blocks.reject_reports'),
-+ wrapper: :with_label
-+.fields-group
-+ = form.input :obfuscate,
-+ as: :boolean,
-+ hint: I18n.t('admin.domain_blocks.obfuscate_hint'),
-+ label: I18n.t('admin.domain_blocks.obfuscate'),
-+ wrapper: :with_label
-+.field-group
-+ = form.input :private_comment,
-+ as: :string,
-+ hint: t('admin.domain_blocks.private_comment_hint'),
-+ label: I18n.t('admin.domain_blocks.private_comment'),
-+ wrapper: :with_label
-+.field-group
-+ = form.input :public_comment,
-+ as: :string,
-+ hint: t('admin.domain_blocks.public_comment_hint'),
-+ label: I18n.t('admin.domain_blocks.public_comment'),
-+ wrapper: :with_label
-diff --git a/app/views/admin/domain_blocks/confirm_suspension.html.haml b/app/views/admin/domain_blocks/confirm_suspension.html.haml
-index e0e55e70f..4c4f92d71 100644
---- a/app/views/admin/domain_blocks/confirm_suspension.html.haml
-+++ b/app/views/admin/domain_blocks/confirm_suspension.html.haml
-@@ -2,7 +2,6 @@
- = t('.title', domain: Addressable::IDNA.to_unicode(@domain_block.domain))
-
- = simple_form_for @domain_block, url: admin_domain_blocks_path, method: :post do |f|
--
- %p.hint= t('.preamble_html', domain: Addressable::IDNA.to_unicode(@domain_block.domain))
- %ul.hint
- %li= t('.stop_communication')
-@@ -15,7 +14,8 @@
-
- %hr.spacer
-
-- = react_admin_component :impact_report, domain: @domain_block.domain
-+ = react_admin_component :impact_report,
-+ domain: @domain_block.domain
-
- .actions
- = link_to t('.cancel'), admin_instances_path, class: 'button button-tertiary'
-diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml
-index ae76b6777..40c46b8b6 100644
---- a/app/views/admin/domain_blocks/edit.html.haml
-+++ b/app/views/admin/domain_blocks/edit.html.haml
-@@ -1,30 +1,12 @@
- - content_for :page_title do
- = t('admin.domain_blocks.edit')
-
--= simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :put do |f|
-+= simple_form_for @domain_block, url: admin_domain_block_path(@domain_block), method: :put do |form|
- = render 'shared/error_messages', object: @domain_block
-
-- .fields-row
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('admin.domain_blocks.new.hint'), required: true, readonly: true, disabled: true
--
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: ->(type) { t("admin.domain_blocks.new.severity.#{type}") }, hint: t('admin.domain_blocks.new.severity.desc_html')
--
-- .fields-group
-- = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
--
-- .fields-group
-- = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint')
--
-- .fields-group
-- = 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'), 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'), as: :string
-+ = render form
-
- .actions
-- = f.button :button, t('generic.save_changes'), type: :submit
-+ = form.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 86e519f45..78bcfcba8 100644
---- a/app/views/admin/domain_blocks/new.html.haml
-+++ b/app/views/admin/domain_blocks/new.html.haml
-@@ -1,30 +1,12 @@
- - content_for :page_title do
- = t('.title')
-
--= simple_form_for @domain_block, url: admin_domain_blocks_path do |f|
-+= simple_form_for @domain_block, url: admin_domain_blocks_path do |form|
- = render 'shared/error_messages', object: @domain_block
-
-- .fields-row
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('.hint'), required: true
--
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: ->(type) { t(".severity.#{type}") }, hint: t('.severity.desc_html')
--
-- .fields-group
-- = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint')
--
-- .fields-group
-- = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint')
--
-- .fields-group
-- = 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'), 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'), as: :string
-+ = render form
-
- .actions
-- = f.button :button, t('.create'), type: :submit
-+ = form.button :button,
-+ t('.create'),
-+ type: :submit
-diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
-index 7cb973c4b..f6a6e8266 100644
---- a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
-+++ b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
-@@ -12,3 +12,7 @@
- ·
-
- = t('admin.email_domain_blocks.attempts_over_week', count: email_domain_block.history.reduce(0) { |sum, day| sum + day.accounts })
-+
-+ - if email_domain_block.allow_with_approval?
-+ ·
-+ = t('admin.email_domain_blocks.allow_registrations_with_approval')
-diff --git a/app/views/admin/email_domain_blocks/index.html.haml b/app/views/admin/email_domain_blocks/index.html.haml
-index 9f16e0d5c..4fae6557a 100644
---- a/app/views/admin/email_domain_blocks/index.html.haml
-+++ b/app/views/admin/email_domain_blocks/index.html.haml
-@@ -4,7 +4,7 @@
- - content_for :heading_actions do
- = link_to t('admin.email_domain_blocks.add_new'), new_admin_email_domain_block_path, class: 'button'
-
--= form_for(@form, url: batch_admin_email_domain_blocks_path) do |f|
-+= form_with model: @form, url: batch_admin_email_domain_blocks_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- .batch-table
-@@ -12,7 +12,11 @@
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('times'), t('admin.email_domain_blocks.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('close'), t('admin.email_domain_blocks.delete')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :delete,
-+ type: :submit
- .batch-table__body
- - if @email_domain_blocks.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
-index fa1d950ad..2dfdca937 100644
---- a/app/views/admin/email_domain_blocks/new.html.haml
-+++ b/app/views/admin/email_domain_blocks/new.html.haml
-@@ -5,9 +5,18 @@
- = render 'shared/error_messages', object: @email_domain_block
-
- .fields-group
-- = f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain'), input_html: { readonly: defined?(@resolved_records) }
-+ = f.input :domain,
-+ input_html: { readonly: defined?(@resolved_records) },
-+ label: t('admin.email_domain_blocks.domain'),
-+ wrapper: :with_block_label
-
-- - if defined?(@resolved_records)
-+ .fields-group
-+ = f.input :allow_with_approval,
-+ hint: false,
-+ label: I18n.t('admin.email_domain_blocks.allow_registrations_with_approval'),
-+ wrapper: :with_label
-+
-+ - if defined?(@resolved_records) && @resolved_records.any?
- %p.hint= t('admin.email_domain_blocks.resolved_dns_records_hint_html')
-
- .batch-table
-@@ -19,7 +28,11 @@
- - @resolved_records.each do |record|
- .batch-table__row
- %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
-- = f.input_field :other_domains, as: :boolean, checked_value: record.exchange.to_s, include_hidden: false, multiple: true
-+ = f.input_field :other_domains,
-+ as: :boolean,
-+ checked_value: record.exchange.to_s,
-+ include_hidden: false,
-+ multiple: true
- .batch-table__row__content.pending-account
- .pending-account__header
- %samp= record.exchange.to_s
-diff --git a/app/views/admin/export_domain_allows/new.html.haml b/app/views/admin/export_domain_allows/new.html.haml
-index dc0cf8c52..66c6aa8d8 100644
---- a/app/views/admin/export_domain_allows/new.html.haml
-+++ b/app/views/admin/export_domain_allows/new.html.haml
-@@ -4,7 +4,10 @@
- = simple_form_for @import, url: import_admin_export_domain_allows_path, html: { multipart: true } do |f|
- .fields-row
- .fields-group.fields-row__column.fields-row__column-6
-- = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data'), as: :file
-+ = f.input :data,
-+ as: :file,
-+ hint: t('simple_form.hints.imports.data'),
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('imports.upload'), type: :submit
-diff --git a/app/views/admin/export_domain_blocks/_domain_block.html.haml b/app/views/admin/export_domain_blocks/_domain_block.html.haml
-index cdce4fd28..79cc5595c 100644
---- a/app/views/admin/export_domain_blocks/_domain_block.html.haml
-+++ b/app/views/admin/export_domain_blocks/_domain_block.html.haml
-@@ -23,5 +23,5 @@
- = f.object.public_comment
- - if existing_relationships
- ·
-- = fa_icon 'warning fw'
-+ = material_symbol 'warning'
- = t('admin.export_domain_blocks.import.existing_relationships_warning')
-diff --git a/app/views/admin/export_domain_blocks/import.html.haml b/app/views/admin/export_domain_blocks/import.html.haml
-index 01add232d..2b0d2c5eb 100644
---- a/app/views/admin/export_domain_blocks/import.html.haml
-+++ b/app/views/admin/export_domain_blocks/import.html.haml
-@@ -6,13 +6,17 @@
- - if defined?(@global_private_comment) && @global_private_comment.present?
- %p= t('admin.export_domain_blocks.import.private_comment_description_html', comment: @global_private_comment)
-
--= form_for(@form, url: batch_admin_domain_blocks_path) do |f|
-+= form_with model: @form, url: batch_admin_domain_blocks_path do |f|
- .batch-table
- .batch-table__toolbar
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('copy'), t('admin.domain_blocks.import')]), name: :save, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('content_copy'), t('admin.domain_blocks.import')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :save,
-+ type: :submit
- .batch-table__body
- - if @domain_blocks.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/export_domain_blocks/new.html.haml b/app/views/admin/export_domain_blocks/new.html.haml
-index 0291aeed7..9c960d47f 100644
---- a/app/views/admin/export_domain_blocks/new.html.haml
-+++ b/app/views/admin/export_domain_blocks/new.html.haml
-@@ -4,7 +4,10 @@
- = simple_form_for @import, url: import_admin_export_domain_blocks_path, html: { multipart: true } do |f|
- .fields-row
- .fields-group.fields-row__column.fields-row__column-6
-- = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data'), as: :file
-+ = f.input :data,
-+ as: :file,
-+ hint: t('simple_form.hints.imports.data'),
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('imports.upload'), type: :submit
-diff --git a/app/views/admin/follow_recommendations/show.html.haml b/app/views/admin/follow_recommendations/show.html.haml
-index dc65a7213..6c2627743 100644
---- a/app/views/admin/follow_recommendations/show.html.haml
-+++ b/app/views/admin/follow_recommendations/show.html.haml
-@@ -5,22 +5,23 @@
-
- %hr.spacer/
-
--= form_tag admin_follow_recommendations_path, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_follow_recommendations_path, method: :get, class: :simple_form do |form|
- - RelationshipFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- .filters
- .filter-subset.filter-subset--with-select
- %strong= t('admin.follow_recommendations.language')
-- .input.select.optional
-- = select_tag :language, options_for_select(Trends.available_locales.map { |key| [standard_locale_name(key), key] }, @language)
-+ .input.select.select--languages.optional
-+ = form.select :language,
-+ options_for_select(Trends.available_locales.map { |key| [standard_locale_name(key), key] }, @language)
- .filter-subset
- %strong= t('admin.follow_recommendations.status')
- %ul
- %li= filter_link_to t('admin.accounts.moderation.active'), status: nil
- %li= filter_link_to t('admin.follow_recommendations.suppressed'), status: 'suppressed'
-
--= form_for(@form, url: admin_follow_recommendations_path, method: :patch) do |f|
-+= form_with model: @form, url: admin_follow_recommendations_path, method: :patch do |f|
- - RelationshipFilter::KEYS.each do |key|
- = hidden_field_tag key, params[key] if params[key].present?
-
-@@ -30,11 +31,20 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - if params[:status].blank? && can?(:suppress, :follow_recommendation)
-- = f.button safe_join([fa_icon('times'), t('admin.follow_recommendations.suppress')]), name: :suppress, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('close'), t('admin.follow_recommendations.suppress')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :suppress,
-+ type: :submit
- - if params[:status] == 'suppressed' && can?(:unsuppress, :follow_recommendation)
-- = f.button safe_join([fa_icon('plus'), t('admin.follow_recommendations.unsuppress')]), name: :unsuppress, class: 'table-action-link', type: :submit
-+ = f.button safe_join([material_symbol('add'), t('admin.follow_recommendations.unsuppress')]),
-+ class: 'table-action-link',
-+ name: :unsuppress,
-+ type: :submit
- .batch-table__body
- - if @accounts.empty?
- = nothing_here 'nothing-here--under-tabs'
- - else
- = render partial: 'account', collection: @accounts, locals: { f: f }
-+
-+= paginate @accounts
-diff --git a/app/views/admin/instances/_dashboard.html.haml b/app/views/admin/instances/_dashboard.html.haml
-new file mode 100644
-index 000000000..ef8500103
---- /dev/null
-+++ b/app/views/admin/instances/_dashboard.html.haml
-@@ -0,0 +1,66 @@
-+-# locals: (instance_domain:, period_end_at:, period_start_at:)
-+%p
-+ = material_symbol 'info'
-+ = t('admin.instances.totals_time_period_hint_html')
-+
-+.dashboard
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ href: admin_accounts_path(origin: 'remote', by_domain: instance_domain),
-+ label: t('admin.instances.dashboard.instance_accounts_measure'),
-+ measure: 'instance_accounts',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_statuses_measure'),
-+ measure: 'instance_statuses',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_media_attachments_measure'),
-+ measure: 'instance_media_attachments',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_follows_measure'),
-+ measure: 'instance_follows',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_followers_measure'),
-+ measure: 'instance_followers',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :counter,
-+ end_at: period_end_at,
-+ href: admin_reports_path(by_target_domain: instance_domain),
-+ label: t('admin.instances.dashboard.instance_reports_measure'),
-+ measure: 'instance_reports',
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :dimension,
-+ dimension: 'instance_accounts',
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_accounts_dimension'),
-+ limit: 8,
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-+ .dashboard__item
-+ = react_admin_component :dimension,
-+ dimension: 'instance_languages',
-+ end_at: period_end_at,
-+ label: t('admin.instances.dashboard.instance_languages_dimension'),
-+ limit: 8,
-+ params: { domain: instance_domain },
-+ start_at: period_start_at
-diff --git a/app/views/admin/instances/_instance.html.haml b/app/views/admin/instances/_instance.html.haml
-index 65cf789ce..4cae3caf5 100644
---- a/app/views/admin/instances/_instance.html.haml
-+++ b/app/views/admin/instances/_instance.html.haml
-@@ -1,12 +1,16 @@
- .directory__tag
- = link_to admin_instance_path(instance) do
- %h4
-- = fa_icon 'warning fw', title: t('admin.instances.availability.warning') if instance.failing?
-+ = material_symbol 'warning', title: t('admin.instances.availability.warning') if instance.failing?
- = instance.domain
-
- %small
- - if instance.domain_block
- = instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ')
-+ - if instance.domain_block.public_comment.present?
-+ %span.comment.public-comment #{t('admin.domain_blocks.public_comment')}: #{instance.domain_block.public_comment}
-+ - if instance.domain_block.private_comment.present?
-+ %span.comment.private-comment #{t('admin.domain_blocks.private_comment')}: #{instance.domain_block.private_comment}
- - elsif instance.domain_allow
- = t('admin.accounts.whitelisted')
- - else
-diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
-index 7e43b4c53..b5f084f88 100644
---- a/app/views/admin/instances/index.html.haml
-+++ b/app/views/admin/instances/index.html.haml
-@@ -28,14 +28,17 @@
- %li= filter_link_to t('admin.instances.delivery.unavailable'), availability: 'unavailable'
-
- - unless limited_federation_mode?
-- = form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
-+ = form_with url: admin_instances_url, method: :get, class: :simple_form do |form|
- .fields-group
- - InstanceFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- - %i(by_domain).each do |key|
- .input.string.optional
-- = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}")
-+ = form.text_field key,
-+ value: params[key],
-+ class: 'string optional',
-+ placeholder: I18n.t("admin.instances.#{key}")
-
- .actions
- %button.button= t('admin.accounts.search')
-diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml
-index 46b5c301b..812a9c887 100644
---- a/app/views/admin/instances/show.html.haml
-+++ b/app/views/admin/instances/show.html.haml
-@@ -3,31 +3,13 @@
-
- - if current_user.can?(:view_dashboard)
- - content_for :heading_actions do
-- = l(@time_period.first)
-- = ' - '
-- = l(@time_period.last)
-+ = date_range(@time_period)
-
-- %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')
-+ - if @instance.persisted?
-+ = render 'dashboard', instance_domain: @instance.domain, period_end_at: @time_period.last, period_start_at: @time_period.first
-+ - else
-+ %p
-+ = t('admin.instances.unknown_instance')
-
- %hr.spacer/
-
-@@ -62,33 +44,44 @@
- - else
- = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
-
--%hr.spacer/
-+- if @instance.persisted?
-+ %hr.spacer/
-+
-+ %h3= t('admin.instances.audit_log.title')
-+ - if @action_logs.empty?
-+ %p= t('accounts.nothing_here')
-+ - else
-+ .report-notes
-+ = render partial: 'admin/action_logs/action_log', collection: @action_logs
-+ = link_to t('admin.instances.audit_log.view_all'), admin_action_logs_path(target_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
-+ %span.negative-hint
-+ = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days)
-+ %span= 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?
-+ %span= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
-+
-+ - if @instance.purgeable?
-+ %p= t('admin.instances.purge_description_html')
-
--%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
-- %span.negative-hint
-- = t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days)
-- %span= 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?
-- %span= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
--
--- if @instance.purgeable?
-- %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'
-+ = 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/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml
-index e6ad9de34..53eac1d0c 100644
---- a/app/views/admin/invites/_invite.html.haml
-+++ b/app/views/admin/invites/_invite.html.haml
-@@ -2,7 +2,7 @@
- %td
- .input-copy
- .input-copy__wrapper
-- %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) }
-+ = copyable_input value: public_invite_url(invite_code: invite.code)
- %button{ type: :button }= t('generic.copy')
-
- %td
-@@ -12,7 +12,7 @@
-
- - if invite.valid_for_use?
- %td
-- = fa_icon 'user fw'
-+ = material_symbol 'person'
- = invite.uses
- = " / #{invite.max_uses}" unless invite.max_uses.nil?
- %td
-@@ -27,4 +27,4 @@
-
- %td
- - if invite.valid_for_use? && policy(invite).destroy?
-- = table_link_to 'times', t('invites.delete'), admin_invite_path(invite), method: :delete
-+ = table_link_to 'close', t('invites.delete'), admin_invite_path(invite), method: :delete
-diff --git a/app/views/admin/invites/index.html.haml b/app/views/admin/invites/index.html.haml
-index ee6ba0f57..964deaba8 100644
---- a/app/views/admin/invites/index.html.haml
-+++ b/app/views/admin/invites/index.html.haml
-@@ -14,7 +14,8 @@
- - if policy(:invite).create?
- %p= t('invites.prompt')
-
-- = render 'invites/form'
-+ = simple_form_for(@invite, url: admin_invites_path) do |form|
-+ = render partial: 'invites/form', object: form
-
- %hr.spacer/
-
-diff --git a/app/views/admin/ip_blocks/index.html.haml b/app/views/admin/ip_blocks/index.html.haml
-index a48e4791a..207d23aee 100644
---- a/app/views/admin/ip_blocks/index.html.haml
-+++ b/app/views/admin/ip_blocks/index.html.haml
-@@ -5,7 +5,7 @@
- - content_for :heading_actions do
- = link_to t('admin.ip_blocks.add_new'), new_admin_ip_block_path, class: 'button'
-
--= form_for(@form, url: batch_admin_ip_blocks_path) do |f|
-+= form_with model: @form, url: batch_admin_ip_blocks_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- .batch-table
-@@ -14,7 +14,11 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - if can?(:destroy, :ip_block)
-- = f.button safe_join([fa_icon('times'), t('admin.ip_blocks.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('close'), t('admin.ip_blocks.delete')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :delete,
-+ type: :submit
- .batch-table__body
- - if @ip_blocks.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/ip_blocks/new.html.haml b/app/views/admin/ip_blocks/new.html.haml
-index 405c73c90..81493012c 100644
---- a/app/views/admin/ip_blocks/new.html.haml
-+++ b/app/views/admin/ip_blocks/new.html.haml
-@@ -5,16 +5,30 @@
- = render 'shared/error_messages', object: @ip_block
-
- .fields-group
-- = f.input :ip, as: :string, wrapper: :with_block_label, input_html: { placeholder: '192.0.2.0/24' }
-+ = f.input :ip,
-+ as: :string,
-+ input_html: { placeholder: '192.0.2.0/24' },
-+ wrapper: :with_block_label
-
- .fields-group
-- = f.input :expires_in, wrapper: :with_block_label, collection: [1.day, 2.weeks, 1.month, 6.months, 1.year, 3.years].map(&:to_i), label_method: ->(i) { I18n.t("admin.ip_blocks.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
-+ = f.input :expires_in,
-+ collection: [1.day, 2.weeks, 1.month, 6.months, 1.year, 3.years].map(&:to_i),
-+ label_method: ->(i) { I18n.t("admin.ip_blocks.expires_in.#{i}") },
-+ prompt: I18n.t('invites.expires_in_prompt'),
-+ wrapper: :with_block_label
-
- .fields-group
-- = f.input :severity, as: :radio_buttons, collection: IpBlock.severities.keys, include_blank: false, wrapper: :with_block_label, label_method: ->(severity) { safe_join([I18n.t("simple_form.labels.ip_block.severities.#{severity}"), content_tag(:span, I18n.t("simple_form.hints.ip_block.severities.#{severity}"), class: 'hint')]) }
-+ = f.input :severity,
-+ as: :radio_buttons,
-+ collection: IpBlock.severities.keys,
-+ include_blank: false,
-+ label_method: ->(severity) { ip_blocks_severity_label(severity) },
-+ wrapper: :with_block_label
-
- .fields-group
-- = f.input :comment, as: :string, wrapper: :with_block_label
-+ = f.input :comment,
-+ as: :string,
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('admin.ip_blocks.add_new'), type: :submit
-diff --git a/app/views/admin/relationships/index.html.haml b/app/views/admin/relationships/index.html.haml
-index f82cf26a3..83ffd139d 100644
---- a/app/views/admin/relationships/index.html.haml
-+++ b/app/views/admin/relationships/index.html.haml
-@@ -19,18 +19,22 @@
-
- .back-link
- = link_to admin_account_path(@account.id) do
-- = fa_icon 'chevron-left fw'
-+ = material_symbol 'chevron_left'
- = t('admin.statuses.back_to_account')
-
- %hr.spacer/
-
--= form_for(@form, url: batch_admin_accounts_path) do |f|
-+= form_with model: @form, url: batch_admin_accounts_path do |f|
- .batch-table
- .batch-table__toolbar
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('lock'), t('admin.accounts.perform_full_suspension')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :suspend,
-+ type: :submit
- .batch-table__body
- - if @accounts.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/relays/_relay.html.haml b/app/views/admin/relays/_relay.html.haml
-index 667821894..9e9f629ee 100644
---- a/app/views/admin/relays/_relay.html.haml
-+++ b/app/views/admin/relays/_relay.html.haml
-@@ -4,22 +4,22 @@
- %td
- - if relay.accepted?
- %span.positive-hint
-- = fa_icon('check')
-- = ' '
-+ = material_symbol('check')
-+
- = t 'admin.relays.enabled'
- - elsif relay.pending?
-- = fa_icon('hourglass')
-- = ' '
-+ = material_symbol('hourglass')
-+
- = t 'admin.relays.pending'
- - else
- %span.negative-hint
-- = fa_icon('times')
-- = ' '
-+ = material_symbol('close')
-+
- = t 'admin.relays.disabled'
- %td
- - if relay.accepted?
-- = table_link_to 'power-off', t('admin.relays.disable'), disable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'power_off', t('admin.relays.disable'), disable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
- - elsif !relay.pending?
-- = table_link_to 'power-off', t('admin.relays.enable'), enable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'power_off', t('admin.relays.enable'), enable_admin_relay_path(relay), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
-
-- = table_link_to 'times', t('admin.relays.delete'), admin_relay_path(relay), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'close', t('admin.relays.delete'), admin_relay_path(relay), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
-diff --git a/app/views/admin/report_notes/_report_note.html.haml b/app/views/admin/report_notes/_report_note.html.haml
-index 64628989a..dd60f7eab 100644
---- a/app/views/admin/report_notes/_report_note.html.haml
-+++ b/app/views/admin/report_notes/_report_note.html.haml
-@@ -13,6 +13,6 @@
- - if can?(:destroy, report_note)
- .report-notes__item__actions
- - if report_note.is_a?(AccountModerationNote)
-- = table_link_to 'trash', t('admin.reports.notes.delete'), admin_account_moderation_note_path(report_note), method: :delete
-+ = table_link_to 'delete', t('admin.reports.notes.delete'), admin_account_moderation_note_path(report_note), method: :delete
- - else
-- = table_link_to 'trash', t('admin.reports.notes.delete'), admin_report_note_path(report_note), method: :delete
-+ = table_link_to 'delete', t('admin.reports.notes.delete'), admin_report_note_path(report_note), method: :delete
-diff --git a/app/views/admin/reports/_actions.html.haml b/app/views/admin/reports/_actions.html.haml
-index aad441625..ef016e949 100644
---- a/app/views/admin/reports/_actions.html.haml
-+++ b/app/views/admin/reports/_actions.html.haml
-@@ -1,33 +1,49 @@
--= form_tag preview_admin_report_actions_path(@report), method: :post do
-+= form_with url: preview_admin_report_actions_path(report) do |form|
- .report-actions
- .report-actions__item
- .report-actions__item__button
-- = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
-+ = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(report), method: :post, class: 'button'
- .report-actions__item__description
- = t('admin.reports.actions.resolve_description_html')
-- - if @statuses.any? { |status| (status.with_media? || status.with_preview_card?) && !status.discarded? }
-+ - if statuses.any? { |status| (status.with_media? || status.with_preview_card?) && !status.discarded? }
- .report-actions__item
- .report-actions__item__button
-- = button_tag t('admin.reports.mark_as_sensitive'), name: :mark_as_sensitive, class: 'button'
-+ = form.button t('admin.reports.mark_as_sensitive'),
-+ name: :mark_as_sensitive,
-+ class: 'button'
- .report-actions__item__description
- = t('admin.reports.actions.mark_as_sensitive_description_html')
- .report-actions__item
- .report-actions__item__button
-- = button_tag t('admin.reports.delete_and_resolve'), name: :delete, class: 'button button--destructive'
-+ = form.button t('admin.reports.delete_and_resolve'),
-+ name: :delete,
-+ class: 'button button--destructive',
-+ disabled: statuses.empty?,
-+ title: statuses.empty? ? t('admin.reports.actions_no_posts') : ''
- .report-actions__item__description
- = t('admin.reports.actions.delete_description_html')
- .report-actions__item
- .report-actions__item__button
-- = button_tag t('admin.accounts.silence'), name: :silence, class: 'button button--destructive'
-+ = form.button t('admin.accounts.silence'),
-+ name: :silence,
-+ class: 'button button--destructive',
-+ disabled: report.target_account.silenced? || report.target_account.suspended_locally?,
-+ title: report.target_account.silenced? ? t('admin.account_actions.already_silenced') : ''
- .report-actions__item__description
- = t('admin.reports.actions.silence_description_html')
- .report-actions__item
- .report-actions__item__button
-- = button_tag t('admin.accounts.suspend'), name: :suspend, class: 'button button--destructive'
-+ = form.button t('admin.accounts.suspend'),
-+ name: :suspend,
-+ class: 'button button--destructive',
-+ disabled: report.target_account.suspended_locally?,
-+ title: report.target_account.suspended_locally? ? t('admin.account_actions.already_suspended') : ''
- .report-actions__item__description
- = t('admin.reports.actions.suspend_description_html')
- .report-actions__item
- .report-actions__item__button
-- = link_to t('admin.accounts.custom'), new_admin_account_action_path(@report.target_account_id, report_id: @report.id), class: 'button'
-+ = link_to t('admin.accounts.custom'),
-+ new_admin_account_action_path(report.target_account_id, report_id: report.id),
-+ class: 'button'
- .report-actions__item__description
- = t('admin.reports.actions.other_description_html')
-diff --git a/app/views/admin/reports/_comment.html.haml b/app/views/admin/reports/_comment.html.haml
-new file mode 100644
-index 000000000..8c07210af
---- /dev/null
-+++ b/app/views/admin/reports/_comment.html.haml
-@@ -0,0 +1,24 @@
-+- if report.account.instance_actor?
-+ %p= t('admin.reports.comment_description_html', name: content_tag(:strong, site_hostname, class: 'username'))
-+- elsif report.account.local?
-+ %p= t('admin.reports.comment_description_html', name: content_tag(:strong, report.account.username, class: 'username'))
-+- else
-+ %p= t('admin.reports.comment_description_html', name: t('admin.reports.remote_user_placeholder', instance: report.account.domain))
-+.report-notes
-+ .report-notes__item
-+ - if report.account.local? && !report.account.instance_actor?
-+ = image_tag report.account.avatar.url, class: 'report-notes__item__avatar'
-+ - else
-+ = image_tag(full_asset_url('avatars/original/missing.png', skip_pipeline: true), class: 'report-notes__item__avatar')
-+ .report-notes__item__header
-+ %span.username
-+ - if report.account.instance_actor?
-+ = site_hostname
-+ - elsif report.account.local?
-+ = link_to report.account.username, admin_account_path(report.account_id)
-+ - else
-+ = link_to report.account.domain, admin_instance_path(report.account.domain)
-+ %time.relative-formatted{ datetime: report.created_at.iso8601 }
-+ = l report.created_at.to_date
-+ .report-notes__item__content
-+ = simple_format(h(report.comment))
-diff --git a/app/views/admin/reports/_header_card.html.haml b/app/views/admin/reports/_header_card.html.haml
-new file mode 100644
-index 000000000..52e62b449
---- /dev/null
-+++ b/app/views/admin/reports/_header_card.html.haml
-@@ -0,0 +1,52 @@
-+.report-header__card
-+ .account-card
-+ - if report.target_account.suspended?
-+ .account-card__warning-badge
-+ - if report.target_account.suspension_origin_local?
-+ = t('admin.reports.already_suspended_badges.local')
-+ - else
-+ = t('admin.reports.already_suspended_badges.remote')
-+ .account-card__header
-+ = image_tag report.target_account.header.url, alt: ''
-+ .account-card__title
-+ .account-card__title__avatar
-+ = image_tag report.target_account.avatar.url, alt: ''
-+ .display-name
-+ %bdi
-+ %strong.emojify.p-name= display_name(report.target_account, custom_emojify: true)
-+ %span
-+ = acct(report.target_account)
-+ = material_symbol('lock') if report.target_account.locked?
-+ - if report.target_account.note.present?
-+ .account-card__bio.emojify
-+ = prerender_custom_emojis(account_bio_format(report.target_account), report.target_account.emojis)
-+ .account-card__actions
-+ .account-card__counters
-+ .account-card__counters__item
-+ = friendly_number_to_human report.target_account.statuses_count
-+ %small= t('accounts.posts', count: report.target_account.statuses_count).downcase
-+ .account-card__counters__item
-+ = friendly_number_to_human report.target_account.followers_count
-+ %small= t('accounts.followers', count: report.target_account.followers_count).downcase
-+ .account-card__counters__item
-+ = friendly_number_to_human report.target_account.following_count
-+ %small= t('accounts.following', count: report.target_account.following_count).downcase
-+ .account-card__actions__button
-+ = link_to t('admin.reports.view_profile'), admin_account_path(report.target_account_id), class: 'button'
-+ .report-header__details.report-header__details--horizontal
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.accounts.joined')
-+ .report-header__details__item__content
-+ %time.time-ago{ datetime: report.target_account.created_at.iso8601, title: l(report.target_account.created_at) }= l report.target_account.created_at
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('accounts.last_active')
-+ .report-header__details__item__content
-+ - if report.target_account.last_status_at.present?
-+ %time.time-ago{ datetime: report.target_account.last_status_at.to_date.iso8601, title: l(report.target_account.last_status_at.to_date) }= l report.target_account.last_status_at
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.accounts.strikes')
-+ .report-header__details__item__content
-+ = report.target_account.previous_strikes_count
-diff --git a/app/views/admin/reports/_header_details.html.haml b/app/views/admin/reports/_header_details.html.haml
-new file mode 100644
-index 000000000..cf8167084
---- /dev/null
-+++ b/app/views/admin/reports/_header_details.html.haml
-@@ -0,0 +1,59 @@
-+.report-header__details
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.created_at')
-+ .report-header__details__item__content
-+ %time.formatted{ datetime: report.created_at.iso8601 }
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.reported_by')
-+ .report-header__details__item__content
-+ - if report.account.instance_actor?
-+ = site_hostname
-+ - elsif report.account.local?
-+ = admin_account_link_to report.account
-+ - else
-+ = report.account.domain
-+ - if report.application.present?
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.reported_with_application')
-+ .report-header__details__item__content
-+ = report.application.name
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.status')
-+ .report-header__details__item__content
-+ - if report.action_taken?
-+ = t('admin.reports.resolved')
-+ - else
-+ = t('admin.reports.unresolved')
-+ - if report.account.local? && !report.target_account.local?
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.forwarded')
-+ .report-header__details__item__content
-+ - if report.forwarded?
-+ = t('simple_form.yes')
-+ - else
-+ = t('simple_form.no')
-+ - if report.action_taken_by_account.present?
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.action_taken_by')
-+ .report-header__details__item__content
-+ = admin_account_link_to report.action_taken_by_account
-+ - else
-+ .report-header__details__item
-+ .report-header__details__item__header
-+ %strong= t('admin.reports.assigned')
-+ .report-header__details__item__content
-+ - if report.assigned_account.nil?
-+ = t 'admin.reports.no_one_assigned'
-+ - else
-+ = admin_account_link_to report.assigned_account
-+ —
-+ - if report.assigned_account != current_user.account
-+ = table_link_to 'person', t('admin.reports.assign_to_self'), assign_to_self_admin_report_path(report), method: :post
-+ - elsif !report.assigned_account.nil?
-+ = table_link_to 'delete', t('admin.reports.unassign'), unassign_admin_report_path(report), method: :post
-diff --git a/app/views/admin/reports/_media_attachments.html.haml b/app/views/admin/reports/_media_attachments.html.haml
-index 8ecd7444d..45cc4c5aa 100644
---- a/app/views/admin/reports/_media_attachments.html.haml
-+++ b/app/views/admin/reports/_media_attachments.html.haml
-@@ -2,6 +2,16 @@
- = render_video_component(status, visible: false)
- - elsif status.ordered_media_attachments.first.audio?
- - audio = status.ordered_media_attachments.first
-- = react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, lang: status.language, duration: audio.file.meta.dig(:original, :duration)
-+ = react_component :audio,
-+ alt: audio.description,
-+ duration: audio.file.meta.dig(:original, :duration),
-+ height: 110,
-+ lang: status.language,
-+ src: audio.file.url(:original)
- - else
-- = react_component :media_gallery, height: 343, sensitive: status.sensitive?, visible: false, lang: status.language, media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
-+ = react_component :media_gallery,
-+ height: 343,
-+ lang: status.language,
-+ media: serialized_media_attachments(status.ordered_media_attachments),
-+ sensitive: status.sensitive?,
-+ visible: false
-diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml
-index 848348c5a..297774c0e 100644
---- a/app/views/admin/reports/_status.html.haml
-+++ b/app/views/admin/reports/_status.html.haml
-@@ -18,24 +18,26 @@
- - if status.application
- = status.application.name
- ·
-- = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
-+ = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
- %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
- - if status.edited?
- ·
-- = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')), admin_account_status_path(status.account_id, status), class: 'detailed-status__datetime'
-+ = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')),
-+ admin_account_status_path(status.account_id, status),
-+ class: 'detailed-status__datetime'
- - if status.discarded?
- ·
- %span.negative-hint= t('admin.statuses.deleted')
- ·
- - if status.reblog?
-- = fa_icon('retweet fw')
-+ = material_symbol('repeat_active')
- = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account))
- - else
-- = fa_visibility_icon(status)
-+ = material_symbol visibility_icon(status)
- = t("statuses.visibilities.#{status.visibility}")
- - if status.proper.sensitive?
- ·
-- = fa_icon('eye-slash fw')
-+ = material_symbol('visibility_off')
- = t('stream_entries.sensitive_content')
- - if status.proper.local_only
- ·
-diff --git a/app/views/admin/reports/actions/preview.html.haml b/app/views/admin/reports/actions/preview.html.haml
-index eb67eebe0..79c444453 100644
---- a/app/views/admin/reports/actions/preview.html.haml
-+++ b/app/views/admin/reports/actions/preview.html.haml
-@@ -4,8 +4,8 @@
- - content_for :page_title do
- = t('admin.reports.confirm_action', acct: target_acct)
-
--= form_tag admin_report_actions_path(@report), class: 'simple_form', method: :post do
-- = hidden_field_tag :moderation_action, @moderation_action
-+= form_with url: admin_report_actions_path(@report), class: :simple_form do |form|
-+ = form.hidden_field :moderation_action, value: @moderation_action
-
- %p.hint= t("admin.reports.summary.action_preambles.#{@moderation_action}_html", acct: target_acct)
- %ul.hint
-@@ -30,7 +30,9 @@
- %p= t "user_mailer.warning.explanation.#{warning_action}", instance: Rails.configuration.x.local_domain
-
- .fields-group
-- = text_area_tag :text, nil, placeholder: t('admin.reports.summary.warning_placeholder')
-+ = form.text_area :text,
-+ value: nil,
-+ placeholder: t('admin.reports.summary.warning_placeholder')
-
- - unless @report.other?
- %p
-@@ -58,10 +60,10 @@
-
- - status.ordered_media_attachments.each do |media_attachment|
- %abbr{ title: media_attachment.description }
-- = fa_icon 'link'
-+ = material_symbol 'link'
- = media_attachment.file_file_name
- .strike-card__statuses-list__item__meta
-- = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank' do
-+ = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener noreferrer' do
- %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
- - unless status.application.nil?
- ·
-@@ -75,4 +77,7 @@
-
- .actions
- = link_to t('admin.reports.cancel'), admin_report_path(@report), class: 'button button-tertiary'
-- = button_tag t('admin.reports.confirm'), name: :confirm, class: 'button', type: :submit
-+ = form.button t('admin.reports.confirm'),
-+ name: :confirm,
-+ class: 'button',
-+ type: :submit
-diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml
-index e94847d67..b476c6ccf 100644
---- a/app/views/admin/reports/index.html.haml
-+++ b/app/views/admin/reports/index.html.haml
-@@ -14,20 +14,23 @@
- %li= filter_link_to t('admin.accounts.location.local'), target_origin: 'local'
- %li= filter_link_to t('admin.accounts.location.remote'), target_origin: 'remote'
-
--= form_tag admin_reports_url, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_reports_url, method: :get, class: :simple_form do |form|
- .fields-group
- - ReportFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- - %i(by_target_domain).each do |key|
- .input.string.optional
-- = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.reports.#{key}")
-+ = form.text_field key,
-+ value: params[key],
-+ class: 'string optional',
-+ placeholder: I18n.t("admin.reports.#{key}")
-
- .actions
- %button.button= t('admin.accounts.search')
- = link_to t('admin.accounts.reset'), admin_reports_path, class: 'button negative'
-
--- @reports.group_by(&:target_account_id).each do |_target_account_id, reports|
-+- @reports.group_by(&:target_account_id).each_value do |reports|
- - target_account = reports.first.target_account
- .report-card
- .report-card__profile
-@@ -58,11 +61,11 @@
- .one-line= report.comment.presence || t('admin.reports.comment.none')
-
- %span.report-card__summary__item__content__icon{ title: t('admin.accounts.statuses') }
-- = fa_icon('comment')
-+ = material_symbol('comment')
- = report.status_ids.size
-
- %span.report-card__summary__item__content__icon{ title: t('admin.accounts.media_attachments') }
-- = fa_icon('camera')
-+ = material_symbol('photo_camera')
- = report.media_attachments_count
-
- - if report.forwarded?
-diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml
-index 2508bc2b5..69e9c0292 100644
---- a/app/views/admin/reports/show.html.haml
-+++ b/app/views/admin/reports/show.html.haml
-@@ -7,107 +7,12 @@
- - else
- = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button'
-
-+- unless @report.account.local? || @report.target_account.local?
-+ .flash-message= t('admin.reports.forwarded_replies_explanation')
-+
- .report-header
-- .report-header__card
-- .account-card
-- .account-card__header
-- = image_tag @report.target_account.header.url, alt: ''
-- .account-card__title
-- .account-card__title__avatar
-- = image_tag @report.target_account.avatar.url, alt: ''
-- .display-name
-- %bdi
-- %strong.emojify.p-name= display_name(@report.target_account, custom_emojify: true)
-- %span
-- = acct(@report.target_account)
-- = fa_icon('lock') if @report.target_account.locked?
-- - if @report.target_account.note.present?
-- .account-card__bio.emojify
-- = prerender_custom_emojis(account_bio_format(@report.target_account), @report.target_account.emojis)
-- .account-card__actions
-- .account-card__counters
-- .account-card__counters__item
-- = friendly_number_to_human @report.target_account.statuses_count
-- %small= t('accounts.posts', count: @report.target_account.statuses_count).downcase
-- .account-card__counters__item
-- = friendly_number_to_human @report.target_account.followers_count
-- %small= t('accounts.followers', count: @report.target_account.followers_count).downcase
-- .account-card__counters__item
-- = friendly_number_to_human @report.target_account.following_count
-- %small= t('accounts.following', count: @report.target_account.following_count).downcase
-- .account-card__actions__button
-- = link_to t('admin.reports.view_profile'), admin_account_path(@report.target_account_id), class: 'button'
-- .report-header__details.report-header__details--horizontal
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.accounts.joined')
-- .report-header__details__item__content
-- %time.time-ago{ datetime: @report.target_account.created_at.iso8601, title: l(@report.target_account.created_at) }= l @report.target_account.created_at
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('accounts.last_active')
-- .report-header__details__item__content
-- - if @report.target_account.last_status_at.present?
-- %time.time-ago{ datetime: @report.target_account.last_status_at.to_date.iso8601, title: l(@report.target_account.last_status_at.to_date) }= l @report.target_account.last_status_at
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.accounts.strikes')
-- .report-header__details__item__content
-- = @report.target_account.previous_strikes_count
--
-- .report-header__details
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.created_at')
-- .report-header__details__item__content
-- %time.formatted{ datetime: @report.created_at.iso8601 }
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.reported_by')
-- .report-header__details__item__content
-- - if @report.account.instance_actor?
-- = site_hostname
-- - elsif @report.account.local?
-- = admin_account_link_to @report.account
-- - else
-- = @report.account.domain
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.status')
-- .report-header__details__item__content
-- - if @report.action_taken?
-- = t('admin.reports.resolved')
-- - else
-- = t('admin.reports.unresolved')
-- - unless @report.target_account.local?
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.forwarded')
-- .report-header__details__item__content
-- - if @report.forwarded?
-- = t('simple_form.yes')
-- - else
-- = t('simple_form.no')
-- - if @report.action_taken_by_account.present?
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.action_taken_by')
-- .report-header__details__item__content
-- = admin_account_link_to @report.action_taken_by_account
-- - else
-- .report-header__details__item
-- .report-header__details__item__header
-- %strong= t('admin.reports.assigned')
-- .report-header__details__item__content
-- - if @report.assigned_account.nil?
-- = t 'admin.reports.no_one_assigned'
-- - else
-- = admin_account_link_to @report.assigned_account
-- —
-- - if @report.assigned_account != current_user.account
-- = table_link_to 'user', t('admin.reports.assign_to_self'), assign_to_self_admin_report_path(@report), method: :post
-- - elsif !@report.assigned_account.nil?
-- = table_link_to 'trash', t('admin.reports.unassign'), unassign_admin_report_path(@report), method: :post
-+ = render 'admin/reports/header_card', report: @report
-+ = render 'admin/reports/header_details', report: @report
-
- %hr.spacer
-
-@@ -115,36 +20,14 @@
-
- %p= t 'admin.reports.category_description_html'
-
--= react_admin_component :report_reason_selector, id: @report.id, category: @report.category, rule_ids: @report.rule_ids&.map(&:to_s), disabled: @report.action_taken?
-+= react_admin_component :report_reason_selector,
-+ category: @report.category,
-+ disabled: @report.action_taken?,
-+ id: @report.id,
-+ rule_ids: @report.rule_ids&.map(&:to_s)
-
- - if @report.comment.present?
-- - if @report.account.instance_actor?
-- %p= t('admin.reports.comment_description_html', name: content_tag(:strong, site_hostname, class: 'username'))
-- - elsif @report.account.local?
-- %p= t('admin.reports.comment_description_html', name: content_tag(:strong, @report.account.username, class: 'username'))
-- - else
-- %p= t('admin.reports.comment_description_html', name: t('admin.reports.remote_user_placeholder', instance: @report.account.domain))
--
-- .report-notes
-- .report-notes__item
-- - if @report.account.local? && !@report.account.instance_actor?
-- = image_tag @report.account.avatar.url, class: 'report-notes__item__avatar'
-- - else
-- = image_tag(full_asset_url('avatars/original/missing.png', skip_pipeline: true), class: 'report-notes__item__avatar')
--
-- .report-notes__item__header
-- %span.username
-- - if @report.account.instance_actor?
-- = site_hostname
-- - elsif @report.account.local?
-- = link_to @report.account.username, admin_account_path(@report.account_id)
-- - else
-- = link_to @report.account.domain, admin_instance_path(@report.account.domain)
-- %time.relative-formatted{ datetime: @report.created_at.iso8601 }
-- = l @report.created_at.to_date
--
-- .report-notes__item__content
-- = simple_format(h(@report.comment))
-+ = render 'admin/reports/comment', report: @report
-
- %hr.spacer/
-
-@@ -152,22 +35,24 @@
- = t 'admin.reports.statuses'
- %small.section-skip-link
- = link_to '#actions' do
-- = fa_icon 'angle-double-down'
-+ = material_symbol 'keyboard_double_arrow_down'
- = t('admin.reports.skip_to_actions')
-
- %p
- = t 'admin.reports.statuses_description_html'
- —
-- = link_to safe_join([fa_icon('plus'), t('admin.reports.add_to_report')]), admin_account_statuses_path(@report.target_account_id, report_id: @report.id), class: 'table-action-link'
-+ = link_to safe_join([material_symbol('add'), t('admin.reports.add_to_report')]),
-+ admin_account_statuses_path(@report.target_account_id, report_id: @report.id),
-+ class: 'table-action-link'
-
--= form_for(@form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id)) do |f|
-+= form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f|
- .batch-table
- .batch-table__toolbar
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - if !@statuses.empty? && @report.unresolved?
-- = f.button safe_join([fa_icon('times'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit
- .batch-table__body
- - if @statuses.empty?
- = nothing_here 'nothing-here--under-tabs'
-@@ -179,7 +64,7 @@
-
- %p#actions= t(@report.target_account.local? ? 'admin.reports.actions_description_html' : 'admin.reports.actions_description_remote_html')
-
-- = render partial: 'admin/reports/actions'
-+ = render partial: 'admin/reports/actions', locals: { report: @report, statuses: @statuses }
-
- - unless @action_logs.empty?
- %hr.spacer/
-@@ -198,15 +83,17 @@
- .report-notes
- = render @report_notes
-
--= simple_form_for @report_note, url: admin_report_notes_path do |f|
-- = f.input :report_id, as: :hidden
-+= simple_form_for @report_note, url: admin_report_notes_path do |form|
-+ = form.input :report_id, as: :hidden
-+
-+ = render 'shared/error_messages', object: @report_note
-
- .field-group
-- = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6
-+ = form.input :content, input_html: { placeholder: t('admin.reports.notes.placeholder'), maxlength: ReportNote::CONTENT_SIZE_LIMIT, rows: 6, autofocus: @report_note.errors.any? }
-
- .actions
- - if @report.unresolved?
-- = f.button :button, t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, type: :submit
-+ = form.button :button, t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, type: :submit
- - else
-- = f.button :button, t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, type: :submit
-- = f.button :button, t('admin.reports.notes.create'), type: :submit
-+ = form.button :button, t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, type: :submit
-+ = form.button :button, t('admin.reports.notes.create'), type: :submit
-diff --git a/app/views/admin/roles/_form.html.haml b/app/views/admin/roles/_form.html.haml
-index 3cbec0d0b..0b1c31016 100644
---- a/app/views/admin/roles/_form.html.haml
-+++ b/app/views/admin/roles/_form.html.haml
-@@ -1,40 +1,53 @@
--= simple_form_for @role, url: @role.new_record? ? admin_roles_path : admin_role_path(@role) do |f|
-- = render 'shared/error_messages', object: @role
-+= render 'shared/error_messages', object: form.object
-
-- - if @role.everyone?
-- .flash-message.info
-- = t('admin.roles.everyone_full_description_html')
-- - else
-- .fields-group
-- = f.input :name, wrapper: :with_label
--
-- - unless current_user.role.id == @role.id
-- .fields-group
-- = f.input :position, wrapper: :with_label, input_html: { max: current_user.role.position - 1 }
--
-- .fields-group
-- = f.input :color, wrapper: :with_label, input_html: { placeholder: '#000000', type: 'color' }
--
-- %hr.spacer/
-+- if form.object.everyone?
-+ .flash-message.info
-+ = t('admin.roles.everyone_full_description_html')
-+- else
-+ .fields-group
-+ = form.input :name,
-+ wrapper: :with_label
-
-+ - unless current_user.role == form.object
- .fields-group
-- = f.input :highlighted, wrapper: :with_label
--
-- %hr.spacer/
--
-- - unless current_user.role.id == @role.id
--
-- .field-group
-- .input.with_block_label
-- %label= t('simple_form.labels.user_role.permissions_as_keys')
-- %span.hint= t('simple_form.hints.user_role.permissions_as_keys')
--
-- - (@role.everyone? ? UserRole::Flags::CATEGORIES.slice(:invites) : UserRole::Flags::CATEGORIES).each do |category, permissions|
-- %h4= t(category, scope: 'admin.roles.categories')
--
-- = f.input :permissions_as_keys, collection: permissions, wrapper: :with_block_label, include_blank: false, label_method: ->(privilege) { safe_join([t("admin.roles.privileges.#{privilege}"), content_tag(:span, t("admin.roles.privileges.#{privilege}_description"), class: 'hint')]) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label: false, hint: false, disabled: permissions.filter { |privilege| UserRole::FLAGS[privilege] & current_user.role.computed_permissions == 0 }
--
-- %hr.spacer/
--
-- .actions
-- = f.button :button, @role.new_record? ? t('admin.roles.add_new') : t('generic.save_changes'), type: :submit
-+ = form.input :position,
-+ input_html: { max: current_user.role.position - 1 },
-+ wrapper: :with_label
-+
-+ .fields-group
-+ = form.input :color,
-+ input_html: { placeholder: '#000000', type: 'color' },
-+ wrapper: :with_label
-+
-+ %hr.spacer/
-+
-+ .fields-group
-+ = form.input :highlighted,
-+ wrapper: :with_label
-+
-+ %hr.spacer/
-+
-+- unless current_user.role == form.object
-+
-+ .field-group
-+ .input.with_block_label
-+ %label= t('simple_form.labels.user_role.permissions_as_keys')
-+ %span.hint= t('simple_form.hints.user_role.permissions_as_keys')
-+
-+ - (form.object.everyone? ? UserRole::Flags::CATEGORIES.slice(:invites) : UserRole::Flags::CATEGORIES).each do |category, permissions|
-+ %h4= t(category, scope: 'admin.roles.categories')
-+
-+ = form.input :permissions_as_keys,
-+ as: :check_boxes,
-+ collection_wrapper_tag: 'ul',
-+ collection: permissions,
-+ disabled: disable_permissions?(permissions),
-+ hint: false,
-+ include_blank: false,
-+ item_wrapper_tag: 'li',
-+ label_method: ->(privilege) { privilege_label(privilege) },
-+ label: false,
-+ required: false,
-+ wrapper: :with_block_label
-+
-+ %hr.spacer/
-diff --git a/app/views/admin/roles/_role.html.haml b/app/views/admin/roles/_role.html.haml
-index d6c6b62c8..636127354 100644
---- a/app/views/admin/roles/_role.html.haml
-+++ b/app/views/admin/roles/_role.html.haml
-@@ -2,7 +2,7 @@
- - if can?(:update, role)
- = link_to edit_admin_role_path(role), class: 'announcements-list__item__title' do
- %span.user-role{ class: "user-role-#{role.id}" }
-- = fa_icon 'users fw'
-+ = material_symbol 'group'
-
- - if role.everyone?
- = t('admin.roles.everyone')
-@@ -11,7 +11,7 @@
- - else
- %span.announcements-list__item__title
- %span.user-role{ class: "user-role-#{role.id}" }
-- = fa_icon 'users fw'
-+ = material_symbol 'group'
-
- - if role.everyone?
- = t('admin.roles.everyone')
-@@ -27,4 +27,4 @@
- ·
- %abbr{ title: role.permissions_as_keys.map { |privilege| I18n.t("admin.roles.privileges.#{privilege}") }.join(', ') }= t('admin.roles.permissions_count', count: role.permissions_as_keys.size)
- %div
-- = table_link_to 'pencil', t('admin.accounts.edit'), edit_admin_role_path(role) if can?(:update, role)
-+ = table_link_to 'edit', t('admin.accounts.edit'), edit_admin_role_path(role) if can?(:update, role)
-diff --git a/app/views/admin/roles/edit.html.haml b/app/views/admin/roles/edit.html.haml
-index 5688b69b1..ec3f5b6fb 100644
---- a/app/views/admin/roles/edit.html.haml
-+++ b/app/views/admin/roles/edit.html.haml
-@@ -4,4 +4,7 @@
- - content_for :heading_actions do
- = link_to t('admin.roles.delete'), admin_role_path(@role), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:destroy, @role)
-
--= render partial: 'form'
-+= simple_form_for @role, url: admin_role_path(@role) do |form|
-+ = render partial: 'form', object: form
-+ .actions
-+ = form.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/roles/index.html.haml b/app/views/admin/roles/index.html.haml
-index 4f6c511b4..90a647cc8 100644
---- a/app/views/admin/roles/index.html.haml
-+++ b/app/views/admin/roles/index.html.haml
-@@ -8,10 +8,10 @@
-
- %hr.spacer/
-
--.applications-list
-+.announcements-list
- = render partial: 'role', collection: @roles.select(&:everyone?)
-
- %hr.spacer/
-
--.applications-list
-+.announcements-list
- = render partial: 'role', collection: @roles.reject(&:everyone?)
-diff --git a/app/views/admin/roles/new.html.haml b/app/views/admin/roles/new.html.haml
-index 821079271..6ca0c2137 100644
---- a/app/views/admin/roles/new.html.haml
-+++ b/app/views/admin/roles/new.html.haml
-@@ -1,4 +1,7 @@
- - content_for :page_title do
- = t('admin.roles.add_new')
-
--= render partial: 'form'
-+= simple_form_for @role, url: admin_roles_path do |form|
-+ = render partial: 'form', object: form
-+ .actions
-+ = form.button :button, t('admin.roles.add_new'), type: :submit
-diff --git a/app/views/admin/rules/_form.html.haml b/app/views/admin/rules/_form.html.haml
-new file mode 100644
-index 000000000..9fc54e288
---- /dev/null
-+++ b/app/views/admin/rules/_form.html.haml
-@@ -0,0 +1,7 @@
-+.fields-group
-+ = form.input :text,
-+ wrapper: :with_block_label
-+
-+.fields-group
-+ = form.input :hint,
-+ wrapper: :with_block_label
-diff --git a/app/views/admin/rules/_rule.html.haml b/app/views/admin/rules/_rule.html.haml
-index f8a9ac786..eb97eefb3 100644
---- a/app/views/admin/rules/_rule.html.haml
-+++ b/app/views/admin/rules/_rule.html.haml
-@@ -1,11 +1,11 @@
- .announcements-list__item
- = link_to edit_admin_rule_path(rule), class: 'announcements-list__item__title' do
-- = "#{rule_counter + 1}."
-+ #{rule_counter + 1}.
- = truncate(rule.text)
-
- .announcements-list__item__action-bar
- .announcements-list__item__meta
-- = rule.text
-+ = rule.hint
-
- %div
-- = table_link_to 'trash', t('admin.rules.delete'), admin_rule_path(rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, rule)
-+ = table_link_to 'delete', t('admin.rules.delete'), admin_rule_path(rule), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, rule)
-diff --git a/app/views/admin/rules/edit.html.haml b/app/views/admin/rules/edit.html.haml
-index ba7e6451a..9e3c91581 100644
---- a/app/views/admin/rules/edit.html.haml
-+++ b/app/views/admin/rules/edit.html.haml
-@@ -1,11 +1,10 @@
- - content_for :page_title do
- = t('admin.rules.edit')
-
--= simple_form_for @rule, url: admin_rule_path(@rule) do |f|
-+= simple_form_for @rule, url: admin_rule_path(@rule) do |form|
- = render 'shared/error_messages', object: @rule
-
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
-+ = render form
-
- .actions
-- = f.button :button, t('generic.save_changes'), type: :submit
-+ = form.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/rules/index.html.haml b/app/views/admin/rules/index.html.haml
-index aa6a4c1b6..5a2789edc 100644
---- a/app/views/admin/rules/index.html.haml
-+++ b/app/views/admin/rules/index.html.haml
-@@ -6,14 +6,13 @@
- %hr.spacer/
-
- - if can? :create, :rule
-- = simple_form_for @rule, url: admin_rules_path do |f|
-+ = simple_form_for @rule, url: admin_rules_path do |form|
- = render 'shared/error_messages', object: @rule
-
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
-+ = render form
-
- .actions
-- = f.button :button, t('admin.rules.add_new'), type: :submit
-+ = form.button :button, t('admin.rules.add_new'), type: :submit
-
- %hr.spacer/
-
-diff --git a/app/views/admin/settings/about/show.html.haml b/app/views/admin/settings/about/show.html.haml
-index 1237c20fa..1eb47a0b5 100644
---- a/app/views/admin/settings/about/show.html.haml
-+++ b/app/views/admin/settings/about/show.html.haml
-@@ -11,7 +11,10 @@
- %p.lead= t('admin.settings.about.preamble')
-
- .fields-group
-- = f.input :site_extended_description, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
-+ = f.input :site_extended_description,
-+ as: :text,
-+ input_html: { rows: 8 },
-+ wrapper: :with_block_label
-
- %p.hint
- = t 'admin.settings.about.rules_hint'
-@@ -19,15 +22,32 @@
-
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :show_domain_blocks, wrapper: :with_label, collection: %i(disabled users all), label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-+ = f.input :show_domain_blocks,
-+ collection_wrapper_tag: 'ul',
-+ collection: %i(disabled users all),
-+ include_blank: false,
-+ item_wrapper_tag: 'li',
-+ label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") },
-+ wrapper: :with_label
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :show_domain_blocks_rationale, wrapper: :with_label, collection: %i(disabled users all), label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
-+ = f.input :show_domain_blocks_rationale,
-+ collection_wrapper_tag: 'ul',
-+ collection: %i(disabled users all),
-+ include_blank: false,
-+ item_wrapper_tag: 'li',
-+ label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") },
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :status_page_url, wrapper: :with_block_label, input_html: { placeholder: "https://status.#{Rails.configuration.x.local_domain}" }
-+ = f.input :status_page_url,
-+ input_html: { placeholder: "https://status.#{Rails.configuration.x.local_domain}" },
-+ wrapper: :with_block_label
-
- .fields-group
-- = f.input :site_terms, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
-+ = f.input :site_terms,
-+ as: :text,
-+ input_html: { rows: 8 },
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/settings/appearance/show.html.haml b/app/views/admin/settings/appearance/show.html.haml
-index ed61774c9..c610f9f94 100644
---- a/app/views/admin/settings/appearance/show.html.haml
-+++ b/app/views/admin/settings/appearance/show.html.haml
-@@ -11,20 +11,29 @@
- %p.lead= t('admin.settings.appearance.preamble')
-
- .fields-group
-- = f.input :theme, collection: Themes.instance.names, label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
-+ = f.input :theme,
-+ collection: Themes.instance.names,
-+ include_blank: false,
-+ label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) },
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
-+ = f.input :custom_css,
-+ as: :text,
-+ input_html: { rows: 8 },
-+ wrapper: :with_block_label
-
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :mascot, as: :file, wrapper: :with_block_label
-+ = f.input :mascot,
-+ as: :file,
-+ wrapper: :with_block_label
-
- .fields-row__column.fields-row__column-6.fields-group
- - if @admin_settings.mascot.persisted?
- = image_tag @admin_settings.mascot.file.url, class: 'fields-group__thumbnail'
- = link_to admin_site_upload_path(@admin_settings.mascot), data: { method: :delete }, class: 'link-button link-button--destructive' do
-- = fa_icon 'trash fw'
-+ = material_symbol 'delete'
- = t('admin.site_uploads.delete')
-
- .actions
-diff --git a/app/views/admin/settings/branding/show.html.haml b/app/views/admin/settings/branding/show.html.haml
-index aee730689..62e9c7245 100644
---- a/app/views/admin/settings/branding/show.html.haml
-+++ b/app/views/admin/settings/branding/show.html.haml
-@@ -11,25 +11,61 @@
- %p.lead= t('admin.settings.branding.preamble')
-
- .fields-group
-- = f.input :site_title, wrapper: :with_label
-+ = f.input :site_title,
-+ wrapper: :with_label
-
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :site_contact_username, wrapper: :with_label
-+ = f.input :site_contact_username,
-+ wrapper: :with_label
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :site_contact_email, wrapper: :with_label
-+ = f.input :site_contact_email,
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :site_short_description, wrapper: :with_block_label, as: :text, input_html: { rows: 2, maxlength: 200 }
-+ = f.input :site_short_description,
-+ as: :text,
-+ input_html: { rows: 2, maxlength: Form::AdminSettings::DESCRIPTION_LIMIT },
-+ wrapper: :with_block_label
-
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :thumbnail, as: :file, wrapper: :with_block_label
-+ = f.input :thumbnail,
-+ as: :file,
-+ wrapper: :with_block_label
- .fields-row__column.fields-row__column-6.fields-group
- - if @admin_settings.thumbnail.persisted?
- = image_tag @admin_settings.thumbnail.file.url(:'@1x'), class: 'fields-group__thumbnail'
- = link_to admin_site_upload_path(@admin_settings.thumbnail), data: { method: :delete }, class: 'link-button link-button--destructive' do
-- = fa_icon 'trash fw'
-+ = material_symbol 'delete'
-+ = t('admin.site_uploads.delete')
-+
-+ .fields-row
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = f.input :favicon,
-+ as: :file,
-+ input_html: { accept: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].join(',') },
-+ wrapper: :with_block_label
-+
-+ .fields-row__column.fields-row__column-6.fields-group
-+ - if @admin_settings.favicon.persisted?
-+ = image_tag @admin_settings.favicon.file.url('48'), class: 'fields-group__thumbnail'
-+ = link_to admin_site_upload_path(@admin_settings.favicon), data: { method: :delete }, class: 'link-button link-button--destructive' do
-+ = material_symbol 'delete'
-+ = t('admin.site_uploads.delete')
-+
-+ .fields-row
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = f.input :app_icon,
-+ as: :file,
-+ input_html: { accept: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].join(',') },
-+ wrapper: :with_block_label
-+
-+ .fields-row__column.fields-row__column-6.fields-group
-+ - if @admin_settings.app_icon.persisted?
-+ = image_tag @admin_settings.app_icon.file.url('48'), class: 'fields-group__thumbnail'
-+ = link_to admin_site_upload_path(@admin_settings.app_icon), data: { method: :delete }, class: 'link-button link-button--destructive' do
-+ = material_symbol 'delete'
- = t('admin.site_uploads.delete')
-
- .actions
-diff --git a/app/views/admin/settings/content_retention/show.html.haml b/app/views/admin/settings/content_retention/show.html.haml
-index 5a6701614..57485c110 100644
---- a/app/views/admin/settings/content_retention/show.html.haml
-+++ b/app/views/admin/settings/content_retention/show.html.haml
-@@ -11,9 +11,21 @@
- %p.lead= t('admin.settings.content_retention.preamble')
-
- .fields-group
-- = f.input :media_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
-- = f.input :content_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }, hint: false, warning_hint: t('simple_form.hints.form_admin_settings.content_cache_retention_period')
-- = f.input :backups_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
-+ = f.input :media_cache_retention_period,
-+ input_html: { pattern: '[0-9]+' },
-+ wrapper: :with_block_label
-+ = f.input :backups_retention_period,
-+ input_html: { pattern: '[0-9]+' },
-+ wrapper: :with_block_label
-+
-+ %h4= t('admin.settings.content_retention.danger_zone')
-+
-+ .fields-group
-+ = f.input :content_cache_retention_period,
-+ hint: false,
-+ input_html: { pattern: '[0-9]+' },
-+ warning_hint: t('simple_form.hints.form_admin_settings.content_cache_retention_period'),
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml
-index 62011d5c5..82ce01aae 100644
---- a/app/views/admin/settings/discovery/show.html.haml
-+++ b/app/views/admin/settings/discovery/show.html.haml
-@@ -13,46 +13,75 @@
- %h4= t('admin.settings.discovery.trends')
-
- .fields-group
-- = f.input :trends, as: :boolean, wrapper: :with_label
-+ = f.input :trends,
-+ as: :boolean,
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :trends_as_landing_page, as: :boolean, wrapper: :with_label
-+ = f.input :trends_as_landing_page,
-+ as: :boolean,
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :trendable_by_default, as: :boolean, wrapper: :with_label, recommended: :not_recommended
-+ = f.input :trendable_by_default,
-+ as: :boolean,
-+ wrapper: :with_label,
-+ recommended: :not_recommended
-
- %h4= t('admin.settings.discovery.public_timelines')
-
- .fields-group
-- = f.input :timeline_preview, as: :boolean, wrapper: :with_label
-+ = f.input :timeline_preview,
-+ as: :boolean,
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :noindex, as: :boolean, wrapper: :with_label, label: t('admin.settings.default_noindex.title'), hint: t('admin.settings.default_noindex.desc_html')
-+ = f.input :noindex,
-+ as: :boolean,
-+ hint: t('admin.settings.default_noindex.desc_html'),
-+ label: t('admin.settings.default_noindex.title'),
-+ wrapper: :with_label
-
- %h4= t('admin.settings.discovery.publish_statistics')
-
- .fields-group
-- = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, recommended: :recommended
-+ = f.input :activity_api_enabled,
-+ as: :boolean,
-+ wrapper: :with_label,
-+ recommended: :recommended
-
- %h4= t('admin.settings.discovery.publish_discovered_servers')
-
- .fields-group
-- = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, recommended: :recommended
-+ = f.input :peers_api_enabled,
-+ as: :boolean,
-+ wrapper: :with_label,
-+ recommended: :recommended
-
- %h4= t('admin.settings.security.federation_authentication')
-
- .fields-group
-- = f.input :authorized_fetch, as: :boolean, wrapper: :with_label, label: t('admin.settings.security.authorized_fetch'), warning_hint: authorized_fetch_overridden? ? t('admin.settings.security.authorized_fetch_overridden_hint') : nil, hint: t('admin.settings.security.authorized_fetch_hint'), disabled: authorized_fetch_overridden?, recommended: authorized_fetch_overridden? ? :overridden : nil
-+ = f.input :authorized_fetch,
-+ as: :boolean,
-+ disabled: authorized_fetch_overridden?,
-+ hint: discovery_hint_text,
-+ label: t('admin.settings.security.authorized_fetch'),
-+ recommended: discovery_recommended_value,
-+ warning_hint: discovery_warning_hint_text,
-+ wrapper: :with_label
-
- %h4= t('admin.settings.discovery.follow_recommendations')
-
- .fields-group
-- = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label
-+ = f.input :bootstrap_timeline_accounts,
-+ wrapper: :with_block_label
-
- %h4= t('admin.settings.discovery.profile_directory')
-
- .fields-group
-- = f.input :profile_directory, as: :boolean, wrapper: :with_label
-+ = f.input :profile_directory,
-+ as: :boolean,
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/settings/registrations/show.html.haml b/app/views/admin/settings/registrations/show.html.haml
-index 4ece27bf4..4dbc5fbec 100644
---- a/app/views/admin/settings/registrations/show.html.haml
-+++ b/app/views/admin/settings/registrations/show.html.haml
-@@ -14,17 +14,32 @@
-
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :registrations_mode, collection: %w(open approved none), wrapper: :with_label, include_blank: false, label_method: ->(mode) { I18n.t("admin.settings.registrations_mode.modes.#{mode}") }, warning_hint: I18n.t('admin.settings.registrations_mode.warning_hint')
-+ = f.input :registrations_mode,
-+ collection: %w(open approved none),
-+ include_blank: false,
-+ label_method: ->(mode) { I18n.t("admin.settings.registrations_mode.modes.#{mode}") },
-+ warning_hint: I18n.t('admin.settings.registrations_mode.warning_hint'),
-+ wrapper: :with_label
-
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :require_invite_text, as: :boolean, wrapper: :with_label, disabled: !approved_registrations?
-+ = f.input :require_invite_text,
-+ as: :boolean,
-+ disabled: !approved_registrations?,
-+ wrapper: :with_label
-
- - if captcha_available?
- .fields-group
-- = f.input :captcha_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.captcha_enabled.title'), hint: t('admin.settings.captcha_enabled.desc_html')
-+ = f.input :captcha_enabled,
-+ as: :boolean,
-+ hint: t('admin.settings.captcha_enabled.desc_html'),
-+ label: t('admin.settings.captcha_enabled.title'),
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, input_html: { rows: 2 }
-+ = f.input :closed_registrations_message,
-+ as: :text,
-+ input_html: { rows: 2 },
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/settings/shared/_links.html.haml b/app/views/admin/settings/shared/_links.html.haml
-index 9a7e05492..58ede8a3d 100644
---- a/app/views/admin/settings/shared/_links.html.haml
-+++ b/app/views/admin/settings/shared/_links.html.haml
-@@ -1,10 +1,10 @@
- .content__heading__tabs
- = render_navigation renderer: :links do |primary|
- :ruby
-- primary.item :branding, safe_join([fa_icon('pencil fw'), t('admin.settings.branding.title')]), admin_settings_branding_path
-- primary.item :about, safe_join([fa_icon('file-text fw'), t('admin.settings.about.title')]), admin_settings_about_path
-- primary.item :registrations, safe_join([fa_icon('users fw'), t('admin.settings.registrations.title')]), admin_settings_registrations_path
-- primary.item :discovery, safe_join([fa_icon('search fw'), t('admin.settings.discovery.title')]), admin_settings_discovery_path
-- primary.item :content_retention, safe_join([fa_icon('history fw'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path
-- primary.item :appearance, safe_join([fa_icon('desktop fw'), t('admin.settings.appearance.title')]), admin_settings_appearance_path
-- primary.item :hometown, safe_join([fa_icon('home fw'), t('admin.settings.hometown.title')]), admin_settings_hometown_path
-+ primary.item :branding, safe_join([material_symbol('edit'), t('admin.settings.branding.title')]), admin_settings_branding_path
-+ primary.item :about, safe_join([material_symbol('description'), t('admin.settings.about.title')]), admin_settings_about_path
-+ primary.item :registrations, safe_join([material_symbol('group'), t('admin.settings.registrations.title')]), admin_settings_registrations_path
-+ primary.item :discovery, safe_join([material_symbol('search'), t('admin.settings.discovery.title')]), admin_settings_discovery_path
-+ primary.item :content_retention, safe_join([material_symbol('history'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path
-+ primary.item :appearance, safe_join([material_symbol('computer'), t('admin.settings.appearance.title')]), admin_settings_appearance_path
-+ primary.item :hometown, safe_join([material_symbol('home'), t('admin.settings.hometown.title')]), admin_settings_hometown_path
-diff --git a/app/views/admin/software_updates/index.html.haml b/app/views/admin/software_updates/index.html.haml
-index 7a223ee07..d2ba11559 100644
---- a/app/views/admin/software_updates/index.html.haml
-+++ b/app/views/admin/software_updates/index.html.haml
-@@ -23,7 +23,7 @@
- %td= update.version
- %td= t("admin.software_updates.types.#{update.type}")
- - if update.urgent?
-- %td.critical= t("admin.software_updates.critical_update")
-+ %td.critical= t('admin.software_updates.critical_update')
- - else
- %td
- %td= table_link_to 'link', t('admin.software_updates.release_notes'), update.release_notes
-diff --git a/app/views/admin/status_edits/_status_edit.html.haml b/app/views/admin/status_edits/_status_edit.html.haml
-index 19a0e063d..0bec0159e 100644
---- a/app/views/admin/status_edits/_status_edit.html.haml
-+++ b/app/views/admin/status_edits/_status_edit.html.haml
-@@ -1,20 +1,30 @@
--.status
-- .status__content><
-- - if status_edit.spoiler_text.blank?
-- = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
-- - else
-- %details<
-- %summary><
-- %strong> Content warning: #{prerender_custom_emojis(h(status_edit.spoiler_text), status_edit.emojis)}
-- = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
-+%li
-+ .history__entry
-+ %h5
-+ - if status_edit_iteration.first?
-+ = t('admin.statuses.original_status')
-+ - else
-+ = t('admin.statuses.status_changed')
-+ ·
-+ %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
-
-- - unless status_edit.ordered_media_attachments.empty?
-- = render partial: 'admin/reports/media_attachments', locals: { status: status_edit }
-+ .status
-+ .status__content><
-+ - if status_edit.spoiler_text.blank?
-+ = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
-+ - else
-+ %details<
-+ %summary><
-+ %strong> Content warning: #{prerender_custom_emojis(h(status_edit.spoiler_text), status_edit.emojis)}
-+ = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
-
-- .detailed-status__meta
-- %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
-+ - unless status_edit.ordered_media_attachments.empty?
-+ = render partial: 'admin/reports/media_attachments', locals: { status: status_edit }
-
-- - if status_edit.sensitive?
-- ·
-- = fa_icon('eye-slash fw')
-- = t('stream_entries.sensitive_content')
-+ .detailed-status__meta
-+ %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
-+
-+ - if status_edit.sensitive?
-+ ·
-+ = material_symbol('visibility_off')
-+ = t('stream_entries.sensitive_content')
-diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml
-index 9163dee79..4d5d03706 100644
---- a/app/views/admin/statuses/index.html.haml
-+++ b/app/views/admin/statuses/index.html.haml
-@@ -1,27 +1,27 @@
- - content_for :page_title do
- = t('admin.statuses.title')
- \-
-- = "@#{@account.pretty_acct}"
-+ @#{@account.pretty_acct}
-
- .filters
- .filter-subset
- %strong= t('admin.statuses.media.title')
- %ul
- %li= filter_link_to t('generic.all'), media: nil, id: nil
-- %li= filter_link_to t('admin.statuses.with_media'), media: '1'
-+ %li= filter_link_to t('admin.statuses.with_media'), media: true
- .back-link
- - if params[:report_id]
- = link_to admin_report_path(params[:report_id].to_i) do
-- = fa_icon 'chevron-left fw'
-+ = material_symbol 'chevron_left'
- = t('admin.statuses.back_to_report')
- - else
- = link_to admin_account_path(@account.id) do
-- = fa_icon 'chevron-left fw'
-+ = material_symbol 'chevron_left'
- = t('admin.statuses.back_to_account')
-
- %hr.spacer/
-
--= form_for(@status_batch_action, url: batch_admin_account_statuses_path(@account.id)) do |f|
-+= form_with model: @status_batch_action, url: batch_admin_account_statuses_path(@account.id) do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Admin::StatusFilter::KEYS.each do |key|
-@@ -33,7 +33,11 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - unless @statuses.empty?
-- = f.button safe_join([fa_icon('flag'), t('admin.statuses.batch.report')]), name: :report, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('flag'), t('admin.statuses.batch.report')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :report,
-+ type: :submit
- .batch-table__body
- - if @statuses.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml
-index e070e5872..9cadde287 100644
---- a/app/views/admin/statuses/show.html.haml
-+++ b/app/views/admin/statuses/show.html.haml
-@@ -2,7 +2,7 @@
- = t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
-
- - content_for :heading_actions do
-- = link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank'
-+ = link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank', rel: 'noopener noreferrer'
-
- %h3= t('admin.statuses.metadata')
-
-@@ -47,15 +47,4 @@
- %h3= t('admin.statuses.history')
-
- %ol.history
-- - @status.edits.includes(:account, status: [:account]).each.with_index do |status_edit, i|
-- %li
-- .history__entry
-- %h5
-- - if i.zero?
-- = t('admin.statuses.original_status')
-- - else
-- = t('admin.statuses.status_changed')
-- ·
-- %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
--
-- = render status_edit
-+ = render partial: 'admin/status_edits/status_edit', collection: batched_ordered_status_edits
-diff --git a/app/views/admin/tags/_tag.html.haml b/app/views/admin/tags/_tag.html.haml
-new file mode 100644
-index 000000000..322eee040
---- /dev/null
-+++ b/app/views/admin/tags/_tag.html.haml
-@@ -0,0 +1,27 @@
-+.batch-table__row{ class: [!tag.requires_review? && !tag.usable? && 'batch-table__row--muted'] }
-+ .batch-table__row__content.batch-table__row__content--padded.pending-account
-+ .pending-account__header
-+ %strong
-+ = link_to tag.formatted_name, admin_tag_path(tag.id)
-+
-+ %br/
-+
-+ - if tag.usable?
-+ = t('admin.tags.moderation.usable')
-+ - else
-+ = t('admin.tags.moderation.not_usable')
-+
-+ ·
-+ - if tag.trendable?
-+ = t('admin.tags.moderation.trendable')
-+ - else
-+ = t('admin.tags.moderation.not_trendable')
-+
-+ - if tag.requested_review? || tag.requires_review?
-+ ·
-+ - if tag.requested_review?
-+ %span.negative-hint
-+ = t('admin.tags.moderation.review_requested')
-+ - else
-+ %span.warning-hint
-+ = t('admin.tags.moderation.pending_review')
-diff --git a/app/views/admin/tags/index.html.haml b/app/views/admin/tags/index.html.haml
-new file mode 100644
-index 000000000..be699e5ab
---- /dev/null
-+++ b/app/views/admin/tags/index.html.haml
-@@ -0,0 +1,39 @@
-+- content_for :page_title do
-+ = t('admin.tags.title')
-+
-+= form_with url: admin_tags_url, method: :get, class: :simple_form do |form|
-+ .filters
-+ .filter-subset.filter-subset--with-select
-+ %strong= t('admin.tags.moderation.title')
-+ .input.select.optional
-+ = form.select :status,
-+ options_for_select(admin_tags_moderation_options, params[:status]),
-+ prompt: t('generic.all')
-+
-+ .filter-subset.filter-subset--with-select
-+ %strong= t 'generic.order_by'
-+ .input.select
-+ = form.select :order,
-+ options_for_select([[t('admin.tags.newest'), 'newest'], [t('admin.tags.oldest'), 'oldest']], params[:order])
-+
-+ .fields-group
-+ .input.string.optional
-+ = form.text_field :name,
-+ value: params[:name],
-+ class: 'string optional',
-+ placeholder: t('admin.tags.name')
-+
-+ .actions
-+ %button.button= t('admin.tags.search')
-+ = link_to t('admin.tags.reset'), admin_tags_path, class: 'button negative'
-+
-+%hr.spacer/
-+
-+.batch-table
-+ .batch-table__body
-+ - if @tags.empty?
-+ = nothing_here 'nothing-here--under-tabs nothing-here--no-toolbar'
-+ - else
-+ = render partial: 'tag', collection: @tags
-+
-+= paginate @tags
-diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml
-index 71bce0c0c..462ca312a 100644
---- a/app/views/admin/tags/show.html.haml
-+++ b/app/views/admin/tags/show.html.haml
-@@ -1,48 +1,79 @@
- - content_for :page_title do
-- = "##{@tag.display_name}"
-+ = @tag.formatted_name
-
--- if current_user.can?(:view_dashboard)
-- - content_for :heading_actions do
-- = l(@time_period.first)
-- = ' - '
-- = l(@time_period.last)
-+- content_for :heading_actions do
-+ - if current_user.can?(:view_dashboard)
-+ .time-period
-+ = date_range(@time_period)
-+
-+ = link_to t('admin.tags.open'), tag_url(@tag), class: 'button', target: '_blank', rel: 'noopener noreferrer'
-
-+- if current_user.can?(:view_dashboard)
- .dashboard
- .dashboard__item
-- = react_admin_component :counter, measure: 'tag_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_accounts_measure'), href: tag_url(@tag), target: '_blank'
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ href: tag_url(@tag),
-+ label: t('admin.trends.tags.dashboard.tag_accounts_measure'),
-+ measure: 'tag_accounts',
-+ params: { id: @tag.id },
-+ rel: 'noopener noreferrer',
-+ start_at: @time_period.first,
-+ target: '_blank'
- .dashboard__item
-- = react_admin_component :counter, measure: 'tag_uses', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_uses_measure')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ label: t('admin.trends.tags.dashboard.tag_uses_measure'),
-+ measure: 'tag_uses',
-+ params: { id: @tag.id },
-+ start_at: @time_period.first
- .dashboard__item
-- = react_admin_component :counter, measure: 'tag_servers', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_servers_measure')
-+ = react_admin_component :counter,
-+ end_at: @time_period.last,
-+ label: t('admin.trends.tags.dashboard.tag_servers_measure'),
-+ measure: 'tag_servers',
-+ params: { id: @tag.id },
-+ start_at: @time_period.first
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'tag_servers', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, limit: 8, label: t('admin.trends.tags.dashboard.tag_servers_dimension')
-+ = react_admin_component :dimension,
-+ dimension: 'tag_servers',
-+ end_at: @time_period.last,
-+ label: t('admin.trends.tags.dashboard.tag_servers_dimension'),
-+ limit: 8,
-+ params: { id: @tag.id },
-+ start_at: @time_period.first
- .dashboard__item
-- = react_admin_component :dimension, dimension: 'tag_languages', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, limit: 8, label: t('admin.trends.tags.dashboard.tag_languages_dimension')
-+ = react_admin_component :dimension,
-+ dimension: 'tag_languages',
-+ end_at: @time_period.last,
-+ label: t('admin.trends.tags.dashboard.tag_languages_dimension'),
-+ limit: 8,
-+ params: { id: @tag.id },
-+ start_at: @time_period.first
- .dashboard__item
- = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.usable? ? 'positive' : 'negative'] do
- - if @tag.usable?
- %span= t('admin.trends.tags.usable')
-- = fa_icon 'check fw'
-+ = material_symbol 'check'
- - else
- %span= t('admin.trends.tags.not_usable')
-- = fa_icon 'lock fw'
-+ = material_symbol 'lock'
-
- = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.trendable? ? 'positive' : 'negative'] do
- - if @tag.trendable?
- %span= t('admin.trends.tags.trendable')
-- = fa_icon 'check fw'
-+ = material_symbol 'check'
- - else
- %span= t('admin.trends.tags.not_trendable')
-- = fa_icon 'lock fw'
--
-+ = material_symbol 'lock'
-
- = link_to admin_tag_path(@tag.id), class: ['dashboard__quick-access', @tag.listable? ? 'positive' : 'negative'] do
- - if @tag.listable?
- %span= t('admin.trends.tags.listable')
-- = fa_icon 'check fw'
-+ = material_symbol 'check'
- - else
- %span= t('admin.trends.tags.not_listable')
-- = fa_icon 'lock fw'
-+ = material_symbol 'lock'
-
- %hr.spacer/
-
-diff --git a/app/views/admin/trends/links/_preview_card.html.haml b/app/views/admin/trends/links/_preview_card.html.haml
-index 1ca348371..49e0dd3fc 100644
---- a/app/views/admin/trends/links/_preview_card.html.haml
-+++ b/app/views/admin/trends/links/_preview_card.html.haml
-@@ -4,12 +4,12 @@
-
- .batch-table__row__content.pending-account
- .pending-account__header
-- = link_to preview_card.title, preview_card.url
-+ = link_to preview_card.title, url_for_preview_card(preview_card), lang: preview_card.language
-
- %br/
-
- - if preview_card.provider_name.present?
-- = preview_card.provider_name
-+ %span{ lang: preview_card.language }= preview_card.provider_name
- ·
-
- - if preview_card.language.present?
-diff --git a/app/views/admin/trends/links/index.html.haml b/app/views/admin/trends/links/index.html.haml
-index e6ed9d95f..e54acd656 100644
---- a/app/views/admin/trends/links/index.html.haml
-+++ b/app/views/admin/trends/links/index.html.haml
-@@ -5,15 +5,17 @@
-
- %hr.spacer/
-
--= form_tag admin_trends_links_path, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_trends_links_path, method: :get, class: :simple_form do |form|
- - Trends::PreviewCardFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- .filters
- .filter-subset.filter-subset--with-select
- %strong= t('admin.follow_recommendations.language')
- .input.select.optional
-- = select_tag :locale, options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), include_blank: true
-+ = form.select :locale,
-+ options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]),
-+ include_blank: true
- .filter-subset
- %strong= t('admin.trends.trending')
- %ul
-@@ -22,9 +24,9 @@
- .back-link
- = link_to admin_trends_links_preview_card_providers_path do
- = t('admin.trends.preview_card_providers.title')
-- = fa_icon 'chevron-right fw'
-+ = material_symbol 'chevron_right'
-
--= form_for(@form, url: batch_admin_trends_links_path) do |f|
-+= form_with model: @form, url: batch_admin_trends_links_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Trends::PreviewCardFilter::KEYS.each do |key|
-@@ -35,10 +37,26 @@
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('check'), t('admin.trends.links.allow')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('check'), t('admin.trends.links.allow_provider')]), name: :approve_providers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow_provider')]), name: :reject_providers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.links.allow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.links.confirm_allow') },
-+ name: :approve,
-+ type: :submit
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.links.allow_provider')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.links.confirm_allow_provider') },
-+ name: :approve_providers,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.links.disallow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.links.confirm_disallow') },
-+ name: :reject,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.links.disallow_provider')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.links.confirm_disallow_provider') },
-+ name: :reject_providers,
-+ type: :submit
- .batch-table__body
- - if @preview_cards.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/trends/links/preview_card_providers/index.html.haml b/app/views/admin/trends/links/preview_card_providers/index.html.haml
-index d9ad12fc9..93daf25f3 100644
---- a/app/views/admin/trends/links/preview_card_providers/index.html.haml
-+++ b/app/views/admin/trends/links/preview_card_providers/index.html.haml
-@@ -12,15 +12,15 @@
- %li= filter_link_to t('generic.all'), status: nil
- %li= filter_link_to t('admin.trends.approved'), status: 'approved'
- %li= filter_link_to t('admin.trends.rejected'), status: 'rejected'
-- %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.pending_review.count})"], ' '), status: 'pending_review'
-+ %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.unreviewed.count})"], ' '), status: 'pending_review'
- .back-link
- = link_to admin_trends_links_path do
-- = fa_icon 'chevron-left fw'
-+ = material_symbol 'chevron_left'
- = t('admin.trends.links.title')
-
- %hr.spacer/
-
--= form_for(@form, url: batch_admin_trends_links_preview_card_providers_path) do |f|
-+= form_with model: @form, url: batch_admin_trends_links_preview_card_providers_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Trends::PreviewCardProviderFilter::KEYS.each do |key|
-@@ -31,8 +31,16 @@
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('check'), t('admin.trends.allow')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.allow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :approve,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.disallow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.reports.are_you_sure') },
-+ name: :reject,
-+ type: :submit
-
- .batch-table__body
- - if @preview_card_providers.empty?
-diff --git a/app/views/admin/trends/statuses/_status.html.haml b/app/views/admin/trends/statuses/_status.html.haml
-index 98f2e7709..09547ff03 100644
---- a/app/views/admin/trends/statuses/_status.html.haml
-+++ b/app/views/admin/trends/statuses/_status.html.haml
-@@ -11,10 +11,12 @@
-
- - status.ordered_media_attachments.each do |media_attachment|
- %abbr{ title: media_attachment.description }
-- = fa_icon 'link'
-+ = material_symbol 'link'
- = media_attachment.file_file_name
-
-- = t('admin.trends.statuses.shared_by', count: status.reblogs_count + status.favourites_count, friendly_count: friendly_number_to_human(status.reblogs_count + status.favourites_count))
-+ = t 'admin.trends.statuses.shared_by',
-+ count: status.reblogs_count + status.favourites_count,
-+ friendly_count: friendly_number_to_human(status.reblogs_count + status.favourites_count)
-
- - if status.account.domain.present?
- ·
-diff --git a/app/views/admin/trends/statuses/index.html.haml b/app/views/admin/trends/statuses/index.html.haml
-index bf04772f2..93d4177a6 100644
---- a/app/views/admin/trends/statuses/index.html.haml
-+++ b/app/views/admin/trends/statuses/index.html.haml
-@@ -5,22 +5,25 @@
-
- %hr.spacer/
-
--= form_tag admin_trends_statuses_path, method: 'GET', class: 'simple_form' do
-+= form_with url: admin_trends_statuses_path, method: :get, class: :simple_form do |form|
- - Trends::StatusFilter::KEYS.each do |key|
-- = hidden_field_tag key, params[key] if params[key].present?
-+ = form.hidden_field key, value: params[key] if params[key].present?
-
- .filters
- .filter-subset.filter-subset--with-select
- %strong= t('admin.follow_recommendations.language')
-- .input.select.optional
-- = select_tag :locale, options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), include_blank: true
-+ .input.select.select--languages.optional
-+ = form.select :locale,
-+ options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]),
-+ { include_blank: true },
-+ { disabled: @locales.empty? }
- .filter-subset
- %strong= t('admin.trends.trending')
- %ul
- %li= filter_link_to t('generic.all'), trending: nil
- %li= filter_link_to t('admin.trends.only_allowed'), trending: 'allowed'
-
--= form_for(@form, url: batch_admin_trends_statuses_path) do |f|
-+= form_with model: @form, url: batch_admin_trends_statuses_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Trends::StatusFilter::KEYS.each do |key|
-@@ -31,10 +34,26 @@
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('check'), t('admin.trends.statuses.allow')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('check'), t('admin.trends.statuses.allow_account')]), name: :approve_accounts, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow_account')]), name: :reject_accounts, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.statuses.allow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.statuses.confirm_allow') },
-+ name: :approve,
-+ type: :submit
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.statuses.allow_account')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.statuses.confirm_allow_account') },
-+ name: :approve_accounts,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.statuses.disallow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.statuses.confirm_disallow') },
-+ name: :reject,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.statuses.disallow_account')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.statuses.confirm_disallow_account') },
-+ name: :reject_accounts,
-+ type: :submit
- .batch-table__body
- - if @statuses.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/admin/trends/tags/_tag.html.haml b/app/views/admin/trends/tags/_tag.html.haml
-index 72f8178ef..b1e714a91 100644
---- a/app/views/admin/trends/tags/_tag.html.haml
-+++ b/app/views/admin/trends/tags/_tag.html.haml
-@@ -4,13 +4,11 @@
-
- .batch-table__row__content.pending-account
- .pending-account__header
-- = link_to admin_tag_path(tag.id) do
-- = fa_icon 'hashtag'
-- = tag.display_name
-+ = link_to tag.formatted_name, admin_tag_path(tag.id)
-
- %br/
-
-- = link_to tag_path(tag), target: '_blank' do
-+ = link_to tag_path(tag), target: '_blank', rel: 'noopener noreferrer' do
- = t('admin.trends.tags.used_by_over_week', count: tag.history.reduce(0) { |sum, day| sum + day.accounts })
-
- - if tag.trendable? && (rank = Trends.tags.rank(tag.id))
-diff --git a/app/views/admin/trends/tags/index.html.haml b/app/views/admin/trends/tags/index.html.haml
-index 4730d20c1..480877456 100644
---- a/app/views/admin/trends/tags/index.html.haml
-+++ b/app/views/admin/trends/tags/index.html.haml
-@@ -14,7 +14,7 @@
- %li= filter_link_to t('admin.trends.rejected'), status: 'rejected'
- %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), status: 'pending_review'
-
--= form_for(@form, url: batch_admin_trends_tags_path) do |f|
-+= form_with model: @form, url: batch_admin_trends_tags_path do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Trends::TagFilter::KEYS.each do |key|
-@@ -25,8 +25,16 @@
- %label.batch-table__toolbar__select.batch-checkbox-all
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
-- = f.button safe_join([fa_icon('check'), t('admin.trends.allow')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-- = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
-+ = f.button safe_join([material_symbol('check'), t('admin.trends.allow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.confirm_allow') },
-+ name: :approve,
-+ type: :submit
-+ = f.button safe_join([material_symbol('close'), t('admin.trends.disallow')]),
-+ class: 'table-action-link',
-+ data: { confirm: t('admin.trends.confirm_disallow') },
-+ name: :reject,
-+ type: :submit
-
- .batch-table__body
- - if @tags.empty?
-diff --git a/app/views/admin/users/roles/show.html.haml b/app/views/admin/users/roles/show.html.haml
-index 821618060..01b3830f4 100644
---- a/app/views/admin/users/roles/show.html.haml
-+++ b/app/views/admin/users/roles/show.html.haml
-@@ -3,7 +3,14 @@
-
- = simple_form_for @user, url: admin_user_role_path(@user) do |f|
- .fields-group
-- = f.association :role, wrapper: :with_block_label, collection: UserRole.assignable, label_method: :name, include_blank: I18n.t('admin.accounts.change_role.no_role')
-+ = f.association :role,
-+ collection: UserRole.assignable,
-+ include_blank: I18n.t('admin.accounts.change_role.no_role'),
-+ label_method: :name,
-+ wrapper: :with_block_label,
-+ hint: safe_join([I18n.t('simple_form.hints.user.role'), ' ', link_to(I18n.t('admin.accounts.change_role.edit_roles'), admin_roles_path)])
-
- .actions
-- = f.button :button, t('generic.save_changes'), type: :submit
-+ = f.button :button,
-+ t('generic.save_changes'),
-+ type: :submit
-diff --git a/app/views/admin/warning_presets/_form.html.haml b/app/views/admin/warning_presets/_form.html.haml
-new file mode 100644
-index 000000000..cba74163c
---- /dev/null
-+++ b/app/views/admin/warning_presets/_form.html.haml
-@@ -0,0 +1,7 @@
-+.fields-group
-+ = form.input :title,
-+ wrapper: :with_block_label
-+
-+.fields-group
-+ = form.input :text,
-+ wrapper: :with_block_label
-diff --git a/app/views/admin/warning_presets/_warning_preset.html.haml b/app/views/admin/warning_presets/_warning_preset.html.haml
-index a58199c80..2cc056420 100644
---- a/app/views/admin/warning_presets/_warning_preset.html.haml
-+++ b/app/views/admin/warning_presets/_warning_preset.html.haml
-@@ -7,4 +7,4 @@
- = truncate(warning_preset.text)
-
- %div
-- = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(warning_preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, warning_preset)
-+ = table_link_to 'delete', t('admin.warning_presets.delete'), admin_warning_preset_path(warning_preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, warning_preset)
-diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml
-index b5c5107ef..f0bd9c12e 100644
---- a/app/views/admin/warning_presets/edit.html.haml
-+++ b/app/views/admin/warning_presets/edit.html.haml
-@@ -1,14 +1,10 @@
- - content_for :page_title do
- = t('admin.warning_presets.edit_preset')
-
--= simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f|
-+= simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |form|
- = render 'shared/error_messages', object: @warning_preset
-
-- .fields-group
-- = f.input :title, wrapper: :with_block_label
--
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
-+ = render form
-
- .actions
-- = f.button :button, t('generic.save_changes'), type: :submit
-+ = form.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml
-index b26a13d96..22fee2105 100644
---- a/app/views/admin/warning_presets/index.html.haml
-+++ b/app/views/admin/warning_presets/index.html.haml
-@@ -2,17 +2,13 @@
- = t('admin.warning_presets.title')
-
- - if can? :create, :account_warning_preset
-- = simple_form_for @warning_preset, url: admin_warning_presets_path do |f|
-+ = simple_form_for @warning_preset, url: admin_warning_presets_path do |form|
- = render 'shared/error_messages', object: @warning_preset
-
-- .fields-group
-- = f.input :title, wrapper: :with_block_label
--
-- .fields-group
-- = f.input :text, wrapper: :with_block_label
-+ = render form
-
- .actions
-- = f.button :button, t('admin.warning_presets.add_new'), type: :submit
-+ = form.button :button, t('admin.warning_presets.add_new'), type: :submit
-
- %hr.spacer/
-
-diff --git a/app/views/admin/webhooks/_form.html.haml b/app/views/admin/webhooks/_form.html.haml
-index c870e943f..bdba08a45 100644
---- a/app/views/admin/webhooks/_form.html.haml
-+++ b/app/views/admin/webhooks/_form.html.haml
-@@ -1,14 +1,22 @@
--= simple_form_for @webhook, url: @webhook.new_record? ? admin_webhooks_path : admin_webhook_path(@webhook) do |f|
-- = render 'shared/error_messages', object: @webhook
-+= render 'shared/error_messages', object: form.object
-
-- .fields-group
-- = f.input :url, wrapper: :with_block_label, input_html: { placeholder: 'https://' }
-+.fields-group
-+ = form.input :url,
-+ wrapper: :with_block_label,
-+ input_html: { placeholder: 'https://' }
-
-- .fields-group
-- = f.input :events, collection: Webhook::EVENTS, wrapper: :with_block_label, include_blank: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', disabled: Webhook::EVENTS.filter { |event| !current_user.role.can?(Webhook.permission_for_event(event)) }
-+.fields-group
-+ = form.input :events,
-+ collection: Webhook::EVENTS,
-+ wrapper: :with_block_label,
-+ include_blank: false,
-+ as: :check_boxes,
-+ collection_wrapper_tag: 'ul',
-+ item_wrapper_tag: 'li',
-+ disabled: Webhook::EVENTS.filter { |event| !current_user.role.can?(Webhook.permission_for_event(event)) },
-+ label_method: ->(event) { tag.samp(event) }
-
-- .fields-group
-- = f.input :template, wrapper: :with_block_label, input_html: { placeholder: '{ "content": "Hello {{object.username}}" }' }
--
-- .actions
-- = f.button :button, @webhook.new_record? ? t('admin.webhooks.add_new') : t('generic.save_changes'), type: :submit
-+.fields-group
-+ = form.input :template,
-+ wrapper: :with_block_label,
-+ input_html: { placeholder: '{ "content": "Hello {{object.username}}" }' }
-diff --git a/app/views/admin/webhooks/_webhook.html.haml b/app/views/admin/webhooks/_webhook.html.haml
-index 6b3e49eba..dca5abeb7 100644
---- a/app/views/admin/webhooks/_webhook.html.haml
-+++ b/app/views/admin/webhooks/_webhook.html.haml
-@@ -1,6 +1,6 @@
- .applications-list__item
- = link_to admin_webhook_path(webhook), class: 'announcements-list__item__title' do
-- = fa_icon 'inbox'
-+ = material_symbol 'inbox'
- = webhook.url
-
- .announcements-list__item__action-bar
-@@ -15,5 +15,5 @@
- %abbr{ title: webhook.events.join(', ') }= t('admin.webhooks.enabled_events', count: webhook.events.size)
-
- %div
-- = table_link_to 'pencil', t('admin.webhooks.edit'), edit_admin_webhook_path(webhook) if can?(:update, webhook)
-- = table_link_to 'trash', t('admin.webhooks.delete'), admin_webhook_path(webhook), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, webhook)
-+ = table_link_to 'edit', t('admin.webhooks.edit'), edit_admin_webhook_path(webhook) if can?(:update, webhook)
-+ = table_link_to 'delete', t('admin.webhooks.delete'), admin_webhook_path(webhook), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, webhook)
-diff --git a/app/views/admin/webhooks/edit.html.haml b/app/views/admin/webhooks/edit.html.haml
-index 3dc0ace9b..abc9bdfab 100644
---- a/app/views/admin/webhooks/edit.html.haml
-+++ b/app/views/admin/webhooks/edit.html.haml
-@@ -1,4 +1,7 @@
- - content_for :page_title do
- = t('admin.webhooks.edit')
-
--= render partial: 'form'
-+= simple_form_for @webhook, url: admin_webhook_path(@webhook) do |form|
-+ = render form
-+ .actions
-+ = form.button :button, t('generic.save_changes'), type: :submit
-diff --git a/app/views/admin/webhooks/new.html.haml b/app/views/admin/webhooks/new.html.haml
-index 1258df74a..50fcdc2be 100644
---- a/app/views/admin/webhooks/new.html.haml
-+++ b/app/views/admin/webhooks/new.html.haml
-@@ -1,4 +1,7 @@
- - content_for :page_title do
- = t('admin.webhooks.new')
-
--= render partial: 'form'
-+= simple_form_for @webhook, url: admin_webhooks_path do |form|
-+ = render form
-+ .actions
-+ = form.button :button, t('admin.webhooks.add_new'), type: :submit
-diff --git a/app/views/admin/webhooks/show.html.haml b/app/views/admin/webhooks/show.html.haml
-index 5ac809efc..a389e6110 100644
---- a/app/views/admin/webhooks/show.html.haml
-+++ b/app/views/admin/webhooks/show.html.haml
-@@ -5,7 +5,7 @@
- .content__heading__row
- %h2
- %small
-- = fa_icon 'inbox'
-+ = material_symbol 'inbox'
- = t('admin.webhooks.webhook')
- = @webhook.url
- .content__heading__actions
-@@ -19,10 +19,10 @@
- %td
- - if @webhook.enabled?
- %span.positive-hint= t('admin.webhooks.enabled')
-- = table_link_to 'power-off', t('admin.webhooks.disable'), disable_admin_webhook_path(@webhook), method: :post if can?(:disable, @webhook)
-+ = table_link_to 'power_off', t('admin.webhooks.disable'), disable_admin_webhook_path(@webhook), method: :post if can?(:disable, @webhook)
- - else
- %span.negative-hint= t('admin.webhooks.disabled')
-- = table_link_to 'power-off', t('admin.webhooks.enable'), enable_admin_webhook_path(@webhook), method: :post if can?(:enable, @webhook)
-+ = table_link_to 'power_off', t('admin.webhooks.enable'), enable_admin_webhook_path(@webhook), method: :post if can?(:enable, @webhook)
- %tr
- %th= t('admin.webhooks.events')
- %td
-diff --git a/app/views/admin_mailer/_new_trending_links.text.erb b/app/views/admin_mailer/_new_trending_links.text.erb
-index 85f3f8039..0e2a6a20a 100644
---- a/app/views/admin_mailer/_new_trending_links.text.erb
-+++ b/app/views/admin_mailer/_new_trending_links.text.erb
-@@ -1,6 +1,6 @@
- <%= raw t('admin_mailer.new_trends.new_trending_links.title') %>
-
--<% @links.each do |link| %>
-+<% new_trending_links.each do |link| %>
- - <%= link.title %> · <%= link.url %>
- <%= standard_locale_name(link.language) %> · <%= raw t('admin.trends.links.usage_comparison', today: link.history.get(Time.now.utc).accounts, yesterday: link.history.get(Time.now.utc - 1.day).accounts) %> · <%= t('admin.trends.tags.current_score', score: link.trend.score.round(2)) %>
- <% end %>
-diff --git a/app/views/admin_mailer/_new_trending_statuses.text.erb b/app/views/admin_mailer/_new_trending_statuses.text.erb
-index eedbfff9d..05bb9733f 100644
---- a/app/views/admin_mailer/_new_trending_statuses.text.erb
-+++ b/app/views/admin_mailer/_new_trending_statuses.text.erb
-@@ -1,6 +1,6 @@
- <%= raw t('admin_mailer.new_trends.new_trending_statuses.title') %>
-
--<% @statuses.each do |status| %>
-+<% new_trending_statuses.each do |status| %>
- - <%= ActivityPub::TagManager.instance.url_for(status) %>
- <%= standard_locale_name(status.language) %> · <%= raw t('admin.trends.tags.current_score', score: status.trend.score.round(2)) %>
- <% end %>
-diff --git a/app/views/admin_mailer/_new_trending_tags.text.erb b/app/views/admin_mailer/_new_trending_tags.text.erb
-index d528ab8eb..f738caaf3 100644
---- a/app/views/admin_mailer/_new_trending_tags.text.erb
-+++ b/app/views/admin_mailer/_new_trending_tags.text.erb
-@@ -1,14 +1,8 @@
- <%= raw t('admin_mailer.new_trends.new_trending_tags.title') %>
-
--<% @tags.each do |tag| %>
-+<% new_trending_tags.each do |tag| %>
- - #<%= tag.display_name %>
- <%= raw t('admin.trends.tags.usage_comparison', today: tag.history.get(Time.now.utc).accounts, yesterday: tag.history.get(Time.now.utc - 1.day).accounts) %> · <%= t('admin.trends.tags.current_score', score: Trends.tags.score(tag.id).round(2)) %>
- <% end %>
-
--<% if @lowest_trending_tag %>
--<%= raw t('admin_mailer.new_trends.new_trending_tags.requirements', lowest_tag_name: @lowest_trending_tag.display_name, lowest_tag_score: Trends.tags.score(@lowest_trending_tag.id).round(2), rank: Trends.tags.options[:review_threshold]) %>
--<% else %>
--<%= raw t('admin_mailer.new_trends.new_trending_tags.no_approved_tags') %>
--<% end %>
--
- <%= raw t('application_mailer.view')%> <%= admin_trends_tags_url(status: 'pending_review') %>
-diff --git a/app/views/admin_mailer/new_appeal.text.erb b/app/views/admin_mailer/new_appeal.text.erb
-index 8b8582360..0494f8898 100644
---- a/app/views/admin_mailer/new_appeal.text.erb
-+++ b/app/views/admin_mailer/new_appeal.text.erb
-@@ -1,5 +1,3 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw t('admin_mailer.new_appeal.body', target: @appeal.account.username, action_taken_by: @appeal.strike.account.username, date: l(@appeal.strike.created_at, format: :with_time_zone), type: t(@appeal.strike.action, scope: 'admin_mailer.new_appeal.actions')) %>
-
- > <%= raw word_wrap(@appeal.text, break_sequence: "\n> ") %>
-diff --git a/app/views/admin_mailer/new_critical_software_updates.text.erb b/app/views/admin_mailer/new_critical_software_updates.text.erb
-index c901bc50f..a3f031bda 100644
---- a/app/views/admin_mailer/new_critical_software_updates.text.erb
-+++ b/app/views/admin_mailer/new_critical_software_updates.text.erb
-@@ -1,5 +1,7 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw t('admin_mailer.new_critical_software_updates.body') %>
-
-+<% @software_updates.each do |update| %>
-+- Mastodon <%= update.version %>: <%= update.release_notes %>
-+<% end %>
-+
- <%= raw t('application_mailer.view')%> <%= admin_software_updates_url %>
-diff --git a/app/views/admin_mailer/new_pending_account.text.erb b/app/views/admin_mailer/new_pending_account.text.erb
-index a8a2a35fa..9eabb8f15 100644
---- a/app/views/admin_mailer/new_pending_account.text.erb
-+++ b/app/views/admin_mailer/new_pending_account.text.erb
-@@ -1,5 +1,3 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw t('admin_mailer.new_pending_account.body') %>
-
- <%= @account.user_email %> (@<%= @account.username %>)
-diff --git a/app/views/admin_mailer/new_report.text.erb b/app/views/admin_mailer/new_report.text.erb
-index f8a5224a1..8482225ab 100644
---- a/app/views/admin_mailer/new_report.text.erb
-+++ b/app/views/admin_mailer/new_report.text.erb
-@@ -1,5 +1,3 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw(@report.account.local? ? t('admin_mailer.new_report.body', target: @report.target_account.pretty_acct, reporter: @report.account.pretty_acct) : t('admin_mailer.new_report.body_remote', target: @report.target_account.acct, domain: @report.account.domain)) %>
-
- <%= raw t('application_mailer.view')%> <%= admin_report_url(@report) %>
-diff --git a/app/views/admin_mailer/new_software_updates.text.erb b/app/views/admin_mailer/new_software_updates.text.erb
-index 2fc4d1a5f..0eccbbf9e 100644
---- a/app/views/admin_mailer/new_software_updates.text.erb
-+++ b/app/views/admin_mailer/new_software_updates.text.erb
-@@ -1,5 +1,7 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw t('admin_mailer.new_software_updates.body') %>
-
-+<% @software_updates.each do |update| %>
-+- Mastodon <%= update.version %>: <%= update.release_notes %>
-+<% end %>
-+
- <%= raw t('application_mailer.view')%> <%= admin_software_updates_url %>
-diff --git a/app/views/admin_mailer/new_trends.text.erb b/app/views/admin_mailer/new_trends.text.erb
-index 13b296846..4bcfa1401 100644
---- a/app/views/admin_mailer/new_trends.text.erb
-+++ b/app/views/admin_mailer/new_trends.text.erb
-@@ -1,13 +1,5 @@
--<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
--
- <%= raw t('admin_mailer.new_trends.body') %>
-
--<% unless @links.empty? %>
--<%= render 'new_trending_links' %>
--<% end %>
--<% unless @tags.empty? %>
--<%= render 'new_trending_tags' unless @tags.empty? %>
--<% end %>
--<% unless @statuses.empty? %>
--<%= render 'new_trending_statuses' unless @statuses.empty? %>
--<% end %>
-+<%= render partial: 'new_trending_links', object: @links unless @links.empty? %>
-+<%= render partial: 'new_trending_tags', object: @tags unless @tags.empty? %>
-+<%= render partial: 'new_trending_statuses', object: @statuses unless @statuses.empty? %>
-diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml
-index 1b3dd889c..ae74f1dc6 100644
---- a/app/views/application/_card.html.haml
-+++ b/app/views/application/_card.html.haml
-@@ -15,4 +15,4 @@
- %strong.emojify.p-name= display_name(account, custom_emojify: true)
- %span
- = acct(account)
-- = fa_icon('lock', { data: ({ hidden: true } unless account.locked?) })
-+ = material_symbol('lock', { data: ({ hidden: true } unless account.locked?) })
-diff --git a/app/views/application/mailer/_account.html.haml b/app/views/application/mailer/_account.html.haml
-new file mode 100644
-index 000000000..27493f770
---- /dev/null
-+++ b/app/views/application/mailer/_account.html.haml
-@@ -0,0 +1,30 @@
-+%table.email-w-full.email-account-banner-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-account-banner-td{ height: 140, background: full_asset_url(account.header.url) }
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-account-banner-inner-td
-+ .email-account-banner-overlap-div
-+ %table.email-account-banner-icon-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td
-+ %img{ src: full_asset_url(account.avatar.url), width: 80, height: 80, alt: '' }
-+%table.email-w-full.email-account-body-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-account-body-td
-+ %p.email-account-name= display_name(account)
-+ %p.email-account-handle= acct(account)
-+ %table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-padding-top-16
-+ %table.email-w-full.email-account-stats-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td
-+ %b= account_formatted_stat(account.statuses_count)
-+ %span= t('accounts.posts', count: account.statuses_count)
-+ %td
-+ %b= account_formatted_stat(account.following_count)
-+ %span= t('accounts.following')
-+ %td
-+ %b= account_formatted_stat(account.followers_count)
-+ %span= t('accounts.followers', count: account.followers_count)
-diff --git a/app/views/application/mailer/_button.html.haml b/app/views/application/mailer/_button.html.haml
-new file mode 100644
-index 000000000..0bf80b505
---- /dev/null
-+++ b/app/views/application/mailer/_button.html.haml
-@@ -0,0 +1,7 @@
-+%table.email-btn-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-btn-td
-+ - if defined?(has_arrow) && !has_arrow
-+ = link_to text, url, class: 'email-btn-a email-btn-hover'
-+ - else
-+ = link_to "#{text} ➜", url, class: 'email-btn-a email-btn-hover'
-diff --git a/app/views/application/mailer/_checklist.html.haml b/app/views/application/mailer/_checklist.html.haml
-new file mode 100644
-index 000000000..91c7c98f2
---- /dev/null
-+++ b/app/views/application/mailer/_checklist.html.haml
-@@ -0,0 +1,37 @@
-+%table.email-w-full.email-checklist-wrapper-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-checklist-wrapper-td
-+ %table.email-w-full.email-checklist-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation', class: ('email-checklist-checked' if defined?(checked) && checked) }
-+ %tr
-+ %td.email-checklist-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-checklist-icons-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-checklist-icons-checkbox-td
-+ - if defined?(checked) && checked
-+ = image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-on.png'), alt: '', width: 20, height: 20
-+ - else
-+ = image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20
-+ %td.email-checklist-icons-step-td
-+ - if defined?(key)
-+ = image_tag frontend_asset_url("images/mailer-new/welcome-icons/#{key}_step-#{checked ? 'on' : 'off'}.png"), alt: '', width: 40, height: 40
-+ %td.email-checklist-text-td
-+ .email-desktop-flex
-+ /[if mso]
-+
|
-+ %div
-+ %h3= t("user_mailer.welcome.#{key}_title")
-+ %p= t("user_mailer.welcome.#{key}_step")
-+ /[if mso]
-+ |
-+ %div
-+ - if defined?(show_apps_buttons) && show_apps_buttons
-+ .email-welcome-apps-btns
-+ = link_to image_tag(frontend_asset_url('images/mailer-new/store-icons/btn-app-store.png'), alt: t('user_mailer.welcome.apps_ios_action'), width: 120, height: 40), 'https://apps.apple.com/app/mastodon-for-iphone-and-ipad/id1571998974'
-+ = link_to image_tag(frontend_asset_url('images/mailer-new/store-icons/btn-google-play.png'), alt: t('user_mailer.welcome.apps_android_action'), width: 120, height: 40), 'https://play.google.com/store/apps/details?id=org.joinmastodon.android'
-+ - elsif defined?(button_text) && defined?(button_url) && defined?(checked) && !checked
-+ = render 'application/mailer/button', text: button_text, url: button_url, has_arrow: false
-+ /[if mso]
-+ |
-diff --git a/app/views/application/mailer/_feature.html.haml b/app/views/application/mailer/_feature.html.haml
-new file mode 100644
-index 000000000..94dd4b9cf
---- /dev/null
-+++ b/app/views/application/mailer/_feature.html.haml
-@@ -0,0 +1,30 @@
-+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-feature-wrapper-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-feature-td
-+ .email-desktop-flex{ class: ('email-dir-rtl' if feature_iteration.index.odd?) }
-+ /[if mso]
-+
|
-+ .email-desktop-column
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-column-td
-+ %h2.email-h2= t("user_mailer.welcome.feature_#{feature}_title")
-+ %p.email-p= t("user_mailer.welcome.feature_#{feature}")
-+ - if defined?(feature_btn_url)
-+ = link_to '', href: feature_btn_url, class: 'email-link-with-arrow' do
-+ #{t('user_mailer.welcome.feature_action')}
-+ %span= '❯'
-+ /[if mso]
-+ |
-+ .email-desktop-column
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-column-td
-+ - if defined?(feature)
-+ %p{ class: ('email-desktop-text-right' if feature_iteration.index.even?) }
-+ = image_tag frontend_asset_url("images/mailer-new/welcome/feature_#{feature}.png"), alt: '', width: 240, height: 230
-+ /[if mso]
-+ |
-diff --git a/app/views/application/mailer/_follow.html.haml b/app/views/application/mailer/_follow.html.haml
-new file mode 100644
-index 000000000..382151a23
---- /dev/null
-+++ b/app/views/application/mailer/_follow.html.haml
-@@ -0,0 +1,15 @@
-+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-wrapper-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-follow-img-td
-+ = image_tag full_asset_url(follow.account.avatar.url), alt: '', width: 40, height: 40
-+ %td.email-mini-follow-text-td
-+ %h3= follow.account.display_name.presence || follow.account.username
-+ %p @#{follow.account.pretty_acct}
-+ %td.email-mini-follow-btn-td
-+ = render 'application/mailer/button', text: t('user_mailer.welcome.follow_action'), url: web_url("@#{follow.account.acct}"), has_arrow: false
-diff --git a/app/views/application/mailer/_frame.html.haml b/app/views/application/mailer/_frame.html.haml
-new file mode 100644
-index 000000000..74403e767
---- /dev/null
-+++ b/app/views/application/mailer/_frame.html.haml
-@@ -0,0 +1,4 @@
-+%table.email-w-full.email-frame-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-frame-td
-+ %p= text
-diff --git a/app/views/application/mailer/_hashtag.html.haml b/app/views/application/mailer/_hashtag.html.haml
-new file mode 100644
-index 000000000..b740ba31b
---- /dev/null
-+++ b/app/views/application/mailer/_hashtag.html.haml
-@@ -0,0 +1,21 @@
-+- accounts = hashtag.statuses.public_visibility.joins(:account).merge(Account.without_suspended.without_silenced).includes(:account).limit(3).map(&:account)
-+
-+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-wrapper-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-hashtag-td{ height: 40 }
-+ %h3 ##{hashtag.display_name}
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-mini-hashtag-img-td
-+ - accounts.each do |account|
-+ %span.email-mini-hashtag-img-span
-+ = image_tag full_asset_url(account.avatar.url), alt: '', width: 16, height: 16
-+ %td
-+ - people = hashtag.history.aggregate(2.days.ago.to_date..Time.zone.today).accounts
-+ %p= t('user_mailer.welcome.hashtags_recent_count', people: number_with_delimiter(people), count: people)
-diff --git a/app/views/application/mailer/_heading.html.haml b/app/views/application/mailer/_heading.html.haml
-new file mode 100644
-index 000000000..9fc5dc747
---- /dev/null
-+++ b/app/views/application/mailer/_heading.html.haml
-@@ -0,0 +1,13 @@
-+%table.email-w-full.email-header-heading-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ %td.email-header-heading-td
-+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
-+ %tr
-+ - if defined?(heading_image_url)
-+ %td.email-header-heading-img-td
-+ = image_tag heading_image_url, alt: '', width: 56, height: 56
-+ %td.email-header-heading-txt-td
-+ - if defined?(heading_title)
-+ %h1= heading_title
-+ - if defined?(heading_subtitle)
-+ %p= heading_subtitle
-diff --git a/app/views/auth/challenges/new.html.haml b/app/views/auth/challenges/new.html.haml
-index 4f21e4af6..50dcebb00 100644
---- a/app/views/auth/challenges/new.html.haml
-+++ b/app/views/auth/challenges/new.html.haml
-@@ -5,7 +5,11 @@
- = f.input :return_to, as: :hidden
-
- .field-group
-- = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password', autofocus: true }, label: t('challenge.prompt'), required: true
-+ = f.input :current_password,
-+ input_html: { autocomplete: 'current-password', autofocus: true },
-+ label: t('challenge.prompt'),
-+ required: true,
-+ wrapper: :with_block_label
-
- .actions
- = f.button :button, t('challenge.confirm'), type: :submit
-diff --git a/app/views/auth/confirmations/captcha.html.haml b/app/views/auth/confirmations/captcha.html.haml
-index 964d0e63e..035ac3a86 100644
---- a/app/views/auth/confirmations/captcha.html.haml
-+++ b/app/views/auth/confirmations/captcha.html.haml
-@@ -1,11 +1,13 @@
- - content_for :page_title do
- = t('auth.captcha_confirmation.title')
-
--= form_tag auth_captcha_confirmation_url, method: 'POST', class: 'simple_form' do
-+= form_with url: auth_captcha_confirmation_url, class: :simple_form do |form|
- = render 'auth/shared/progress', stage: 'confirm'
-
-- = hidden_field_tag :confirmation_token, params[:confirmation_token]
-- = hidden_field_tag :redirect_to_app, params[:redirect_to_app]
-+ = form.hidden_field :confirmation_token,
-+ value: params[:confirmation_token]
-+ = form.hidden_field :redirect_to_app,
-+ value: params[:redirect_to_app]
-
- %h1.title= t('auth.captcha_confirmation.title')
- %p.lead= t('auth.captcha_confirmation.hint_html')
-@@ -15,4 +17,6 @@
- %p.lead= t('auth.captcha_confirmation.help_html', email: mail_to(Setting.site_contact_email, nil))
-
- .actions
-- = button_tag t('challenge.confirm'), class: 'button', type: :submit
-+ = form.button t('challenge.confirm'),
-+ class: 'button',
-+ type: :submit
-diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml
-index a98257873..eaa9d9add 100644
---- a/app/views/auth/confirmations/new.html.haml
-+++ b/app/views/auth/confirmations/new.html.haml
-@@ -1,13 +1,35 @@
- - content_for :page_title do
- = t('auth.resend_confirmation')
-
--= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
-- = render 'shared/error_messages', object: resource
-+- if resource.errors.of_kind?(:email, :already_confirmed)
-+ .simple_form
-+ = render 'auth/shared/progress', stage: resource.approved? ? 'completed' : 'confirmed'
-
-- .fields-group
-- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint')
-+ - if resource.approved?
-+ %h1.title= t('auth.confirmations.welcome_title', name: resource.account.username)
-+ %p.lead= t('auth.confirmations.registration_complete', domain: site_hostname)
-+ - if resource.created_by_application && redirect_to_app?
-+ - app = resource.created_by_application
-+ %p.lead= t('auth.confirmations.redirect_to_app_html', app_name: app.name, clicking_this_link: link_to(t('auth.confirmations.clicking_this_link'), app.confirmation_redirect_uri))
-+ - else
-+ %p.lead= t('auth.confirmations.proceed_to_login_html', login_link: link_to_login(t('auth.confirmations.login_link')))
-+ - else
-+ %h1.title= t('auth.confirmations.awaiting_review_title')
-+ %p.lead= t('auth.confirmations.awaiting_review', domain: site_hostname)
-+- else
-+ = simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
-+ = render 'shared/error_messages', object: resource
-
-- .actions
-- = f.button :button, t('auth.resend_confirmation'), type: :submit
-+ .fields-group
-+ = f.input :email,
-+ autofocus: true,
-+ hint: current_user.present? && t('auth.confirmations.wrong_email_hint'),
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email') },
-+ label: t('simple_form.labels.defaults.email'),
-+ readonly: current_user.present?,
-+ wrapper: :with_label
-+
-+ .actions
-+ = f.button :button, t('auth.resend_confirmation'), type: :submit
-
- .form-footer= render 'auth/shared/links'
-diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml
-index b95a9b676..a75dc2d9f 100644
---- a/app/views/auth/passwords/edit.html.haml
-+++ b/app/views/auth/passwords/edit.html.haml
-@@ -8,9 +8,18 @@
- = f.input :reset_password_token, as: :hidden
-
- .fields-group
-- = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, required: true
-+ = f.input :password,
-+ autofocus: true,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last },
-+ label: t('simple_form.labels.defaults.new_password'),
-+ required: true,
-+ wrapper: :with_label
- .fields-group
-- = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, required: true
-+ = f.input :password_confirmation,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' },
-+ label: t('simple_form.labels.defaults.confirm_new_password'),
-+ required: true,
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('auth.set_new_password'), type: :submit
-diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml
-index 10ad108ea..8d5adaf3b 100644
---- a/app/views/auth/passwords/new.html.haml
-+++ b/app/views/auth/passwords/new.html.haml
-@@ -5,7 +5,12 @@
- = render 'shared/error_messages', object: resource
-
- .fields-group
-- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false
-+ = f.input :email,
-+ autofocus: true,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email') },
-+ label: t('simple_form.labels.defaults.email'),
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('auth.reset_password'), type: :submit
-diff --git a/app/views/auth/registrations/_account_warning.html.haml b/app/views/auth/registrations/_account_warning.html.haml
-index 40e7e1296..d558e1d9c 100644
---- a/app/views/auth/registrations/_account_warning.html.haml
-+++ b/app/views/auth/registrations/_account_warning.html.haml
-@@ -1,12 +1,14 @@
--= link_to disputes_strike_path(account_warning), class: 'log-entry' do
-- .log-entry__header
-- .log-entry__avatar
-+= link_to disputes_strike_path(account_warning), class: 'strike-entry' do
-+ .strike-entry__header
-+ .strike-entry__avatar
- .indicator-icon{ class: account_warning.overruled? ? 'success' : 'failure' }
-- = fa_icon 'warning'
-- .log-entry__content
-- .log-entry__title
-- = t('disputes.strikes.title', action: t(account_warning.action, scope: 'disputes.strikes.title_actions'), date: l(account_warning.created_at.to_date))
-- .log-entry__timestamp
-+ = material_symbol 'warning'
-+ .strike-entry__content
-+ .strike-entry__title
-+ = t 'disputes.strikes.title',
-+ action: t(account_warning.action, scope: 'disputes.strikes.title_actions'),
-+ date: l(account_warning.created_at.to_date)
-+ .strike-entry__timestamp
- %time.formatted{ datetime: account_warning.created_at.iso8601 }= l(account_warning.created_at)
-
- - if account_warning.overruled?
-diff --git a/app/views/auth/registrations/_session.html.haml b/app/views/auth/registrations/_session.html.haml
-index 11eae566f..92e514759 100644
---- a/app/views/auth/registrations/_session.html.haml
-+++ b/app/views/auth/registrations/_session.html.haml
-@@ -1,9 +1,11 @@
- %tr
- %td
- %span{ title: session.user_agent }<
-- = fa_icon "#{session_device_icon(session)} fw", 'aria-label': session_device_icon(session)
-- = ' '
-- = t 'sessions.description', browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s), platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s)
-+ = material_symbol session_device_icon(session), 'aria-label': session_device_icon(session)
-+
-+ = t 'sessions.description',
-+ browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s),
-+ platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s)
- %td
- %samp= session.ip
- %td
-@@ -13,4 +15,4 @@
- %time.time-ago{ datetime: session.updated_at.iso8601, title: l(session.updated_at) }= l(session.updated_at)
- %td
- - if current_session.session_id != session.session_id && !current_account.suspended?
-- = table_link_to 'times', t('sessions.revoke'), settings_session_path(session), method: :delete
-+ = table_link_to 'close', t('sessions.revoke'), settings_session_path(session), method: :delete
-diff --git a/app/views/auth/registrations/_status.html.haml b/app/views/auth/registrations/_status.html.haml
-index 759bbc41c..8f44eee01 100644
---- a/app/views/auth/registrations/_status.html.haml
-+++ b/app/views/auth/registrations/_status.html.haml
-@@ -1,30 +1,30 @@
--- if !@user.confirmed?
-+- if !user.confirmed?
- .flash-message.warning
- = t('auth.status.confirming')
- = link_to t('auth.didnt_get_confirmation'), new_user_confirmation_path
--- elsif !@user.approved?
-+- elsif !user.approved?
- .flash-message.warning
- = t('auth.status.pending')
--- elsif @user.account.moved_to_account_id.present?
-+- elsif user.account.moved_to_account_id.present?
- .flash-message.warning
-- = t('auth.status.redirecting_to', acct: @user.account.moved_to_account.pretty_acct)
-+ = t('auth.status.redirecting_to', acct: user.account.moved_to_account.pretty_acct)
- = link_to t('migrations.cancel'), settings_migration_path
-
- %h3= t('auth.status.account_status')
-
- %p.hint
-- - if @user.account.suspended?
-+ - if user.account.suspended?
- %span.negative-hint= t('user_mailer.warning.explanation.suspend')
-- - elsif @user.disabled?
-+ - elsif user.disabled?
- %span.negative-hint= t('user_mailer.warning.explanation.disable')
-- - elsif @user.account.silenced?
-+ - elsif user.account.silenced?
- %span.warning-hint= t('user_mailer.warning.explanation.silence')
- - else
- %span.positive-hint= t('auth.status.functional')
-
--= render partial: 'account_warning', collection: @strikes
-+= render partial: 'account_warning', collection: strikes
-
--- if @user.account.strikes.exists?
-+- if user.account.strikes.exists?
- %hr.spacer/
-
- %p.muted-hint
-diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml
-index 3e9b0cb6b..07d6c1af5 100644
---- a/app/views/auth/registrations/edit.html.haml
-+++ b/app/views/auth/registrations/edit.html.haml
-@@ -1,7 +1,11 @@
- - content_for :page_title do
- = t('settings.account_settings')
-
--= render 'status'
-+- if self_destruct?
-+ .flash-message.warning
-+ = t('auth.status.self_destruct', domain: Rails.configuration.x.local_domain)
-+- else
-+ = render partial: 'status', locals: { user: @user, strikes: @strikes }
-
- %h3= t('auth.security')
-
-@@ -11,15 +15,33 @@
- - if (!use_seamless_external_login? || resource.encrypted_password.present?) && !omniauth_only?
- .fields-row
- .fields-row__column.fields-group.fields-row__column-6
-- = f.input :email, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended?
-+ = f.input :email,
-+ disabled: current_account.suspended?,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email') },
-+ required: true,
-+ wrapper: :with_label
- .fields-row__column.fields-group.fields-row__column-6
-- = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, required: true, disabled: current_account.suspended?, hint: false
-+ = f.input :current_password,
-+ disabled: current_account.suspended?,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' },
-+ required: true,
-+ wrapper: :with_label
-
- .fields-row
- .fields-row__column.fields-group.fields-row__column-6
-- = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended?
-+ = f.input :password,
-+ disabled: current_account.suspended?,
-+ hint: t('simple_form.hints.defaults.password'),
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last },
-+ label: t('simple_form.labels.defaults.new_password'),
-+ wrapper: :with_label
- .fields-row__column.fields-group.fields-row__column-6
-- = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, disabled: current_account.suspended?
-+ = f.input :password_confirmation,
-+ disabled: current_account.suspended?,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' },
-+ label: t('simple_form.labels.defaults.confirm_new_password'),
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('generic.save_changes'), type: :submit, class: 'button', disabled: current_account.suspended?
-@@ -32,7 +54,7 @@
-
- = render partial: 'sessions', object: @sessions
-
--- unless current_account.suspended?
-+- unless current_account.suspended? || self_destruct?
- %hr.spacer/
-
- %h3= t('auth.migrate_account')
-diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml
-index f473a993b..d58f1ccf4 100644
---- a/app/views/auth/registrations/new.html.haml
-+++ b/app/views/auth/registrations/new.html.haml
-@@ -19,26 +19,61 @@
-
- .fields-group
- = f.simple_fields_for :account do |ff|
-- = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}"
-- = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false
-- = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false
-- = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false
-- = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, hint: false
-- = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' }
--
-- - if approved_registrations? && !@invite.present?
-+ = ff.input :username,
-+ append: "@#{site_hostname}",
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: Account::USERNAME_LENGTH_LIMIT },
-+ label: false,
-+ required: true,
-+ wrapper: :with_label
-+ = f.input :email,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' },
-+ placeholder: t('simple_form.labels.defaults.email'),
-+ required: true
-+ = f.input :password,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last },
-+ placeholder: t('simple_form.labels.defaults.password'),
-+ required: true
-+ = f.input :password_confirmation,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' },
-+ placeholder: t('simple_form.labels.defaults.confirm_password'),
-+ required: true
-+ = f.input :confirm_password,
-+ as: :string,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' },
-+ placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')),
-+ required: false
-+ = f.input :website,
-+ as: :url,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' },
-+ label: t('simple_form.labels.defaults.honeypot', label: 'Website'),
-+ required: false,
-+ wrapper: :with_label
-+
-+ - if approved_registrations? && @invite.blank?
- %p.lead= t('auth.sign_up.manual_review', domain: site_hostname)
-
- .fields-group
- = f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields|
-- = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text, label: false, hint: false
--
-+ = invite_request_fields.input :text,
-+ as: :text,
-+ hint: false,
-+ label: false,
-+ required: Setting.require_invite_text,
-+ wrapper: :with_block_label
-
- = hidden_field_tag :accept, params[:accept]
- = f.input :invite_code, as: :hidden
-
- .fields-group
-- = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), required: true
-+ = f.input :agreement,
-+ as: :boolean,
-+ label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path),
-+ required: true,
-+ wrapper: :with_label
-
- .actions
- = f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit
-diff --git a/app/views/auth/registrations/rules.html.haml b/app/views/auth/registrations/rules.html.haml
-index 234f4a601..3a05ed54f 100644
---- a/app/views/auth/registrations/rules.html.haml
-+++ b/app/views/auth/registrations/rules.html.haml
-@@ -20,6 +20,7 @@
- - @rules.each do |rule|
- %li
- .rules-list__text= rule.text
-+ .rules-list__hint= rule.hint
-
- .stacked-actions
- - accept_path = @invite_code.present? ? public_invite_url(invite_code: @invite_code, accept: @accept_token) : new_user_registration_path(accept: @accept_token)
-diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml
-index 7914e0157..89903581a 100644
---- a/app/views/auth/sessions/new.html.haml
-+++ b/app/views/auth/sessions/new.html.haml
-@@ -10,11 +10,25 @@
- %p.lead= t('auth.sign_in.preamble_html', domain: site_hostname)
- .fields-group
- - if use_seamless_external_login?
-- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, hint: false
-+ = f.input :email,
-+ autofocus: true,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') },
-+ label: t('simple_form.labels.defaults.username_or_email'),
-+ wrapper: :with_label
- - else
-- = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false
-+ = f.input :email,
-+ autofocus: true,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email') },
-+ label: t('simple_form.labels.defaults.email'),
-+ wrapper: :with_label
- .fields-group
-- = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, hint: false
-+ = f.input :password,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' },
-+ label: t('simple_form.labels.defaults.password'),
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('auth.login'), type: :submit
-diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml
-index 20232d8dc..653f15580 100644
---- a/app/views/auth/sessions/two_factor.html.haml
-+++ b/app/views/auth/sessions/two_factor.html.haml
-@@ -3,7 +3,7 @@
-
- = javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous'
-
--- if @webauthn_enabled
-+- if webauthn_enabled?
- = render partial: 'auth/sessions/two_factor/webauthn_form', locals: { hidden: @scheme_type != 'webauthn' }
-
- = render partial: 'auth/sessions/two_factor/otp_authentication_form', locals: { hidden: @scheme_type != 'totp' }
-diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
-index 094b502b1..30e97a68c 100644
---- a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
-+++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml
-@@ -5,7 +5,12 @@
- %p.hint.authentication-hint= t('simple_form.hints.sessions.otp')
-
- .fields-group
-- = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, autofocus: true
-+ = f.input :otp_attempt,
-+ autofocus: true,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' },
-+ label: t('simple_form.labels.defaults.otp_attempt'),
-+ type: :number,
-+ wrapper: :with_label
-
- .actions
- = f.button :button, t('auth.login'), type: :submit
-@@ -13,6 +18,6 @@
- - if Setting.site_contact_email.present?
- %p.hint.subtle-hint= t('users.otp_lost_help_html', email: mail_to(Setting.site_contact_email, nil))
-
-- - if @webauthn_enabled
-+ - if webauthn_enabled?
- .form-footer
- = link_to(t('auth.link_to_webauth'), '#', id: 'link-to-webauthn')
-diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml
-index 97c826d70..713f77470 100644
---- a/app/views/auth/setup/show.html.haml
-+++ b/app/views/auth/setup/show.html.haml
-@@ -16,7 +16,10 @@
- %p.lead= t('auth.setup.email_below_hint_html')
-
- .fields-group
-- = f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }
-+ = f.input :email,
-+ hint: false,
-+ input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' },
-+ required: true
-
- .actions
- = f.button :button, t('auth.resend_confirmation'), type: :submit, class: 'button timer-button', disabled: true
-diff --git a/app/views/auth/shared/_progress.html.haml b/app/views/auth/shared/_progress.html.haml
-index 578f62fa9..8fb338541 100644
---- a/app/views/auth/shared/_progress.html.haml
-+++ b/app/views/auth/shared/_progress.html.haml
-@@ -1,4 +1,4 @@
--- progress_index = { rules: 0, details: 1, confirm: 2 }[stage.to_sym]
-+- progress_index = { rules: 0, details: 1, confirm: 2, confirmed: 3, completed: 4 }[stage.to_sym]
-
- %ol.progress-tracker
- %li{ class: progress_index.positive? ? 'completed' : 'active' }
-@@ -20,6 +20,8 @@
- .label= t('auth.progress.confirm')
- - if approved_registrations?
- %li.separator{ class: progress_index > 2 ? 'completed' : nil }
-- %li
-+ %li{ class: [progress_index > 3 && 'completed', progress_index == 3 && 'active'] }
- .circle
-+ - if progress_index > 3
-+ = check_icon
- .label= t('auth.progress.review')
-diff --git a/app/views/custom_css/show.css.erb b/app/views/custom_css/show.css.erb
-index 9cd38fb37..78da809ed 100644
---- a/app/views/custom_css/show.css.erb
-+++ b/app/views/custom_css/show.css.erb
-@@ -1,8 +1,8 @@
--<%- if Setting.custom_css.present? %>
--<%= raw Setting.custom_css %>
-+<%- if custom_css_styles.present? %>
-+<%= raw custom_css_styles %>
-
- <%- end %>
--<%- UserRole.where(highlighted: true).select { |role| role.color.present? }.each do |role| %>
-+<%- @user_roles.each do |role| %>
- .user-role-<%= role.id %> {
- --user-role-accent: <%= role.color %>;
- }
-diff --git a/app/views/disputes/strikes/_card.html.haml b/app/views/disputes/strikes/_card.html.haml
-new file mode 100644
-index 000000000..58965ad60
---- /dev/null
-+++ b/app/views/disputes/strikes/_card.html.haml
-@@ -0,0 +1,38 @@
-+.strike-card
-+ - unless strike.none_action?
-+ %p= t "user_mailer.warning.explanation.#{strike.action}", instance: Rails.configuration.x.local_domain
-+ - if strike.text.present?
-+ = linkify(strike.text)
-+ - if strike.report && !strike.report.other?
-+ %p
-+ %strong= t('user_mailer.warning.reason')
-+ = t("user_mailer.warning.categories.#{strike.report.category}")
-+ - if strike.report.violation? && strike.report.rule_ids.present?
-+ %ul.strike-card__rules
-+ - strike.report.rules.each do |rule|
-+ %li
-+ %span.strike-card__rules__text= rule.text
-+ - if strike.status_ids.present? && !strike.status_ids.empty?
-+ %p
-+ %strong= t('user_mailer.warning.statuses')
-+ .strike-card__statuses-list
-+ - status_map = strike.statuses.includes(:application, :media_attachments).index_by(&:id)
-+ - strike.status_ids.each do |status_id|
-+ .strike-card__statuses-list__item
-+ - if (status = status_map[status_id.to_i])
-+ .one-liner
-+ .emojify= one_line_preview(status)
-+ - status.ordered_media_attachments.each do |media_attachment|
-+ %abbr{ title: media_attachment.description }
-+ = material_symbol 'link'
-+ = media_attachment.file_file_name
-+ .strike-card__statuses-list__item__meta
-+ = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank', rel: 'noopener noreferrer' do
-+ %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
-+ - unless status.application.nil?
-+ ·
-+ = status.application.name
-+ - else
-+ .one-liner= t('disputes.strikes.status', id: status_id)
-+ .strike-card__statuses-list__item__meta
-+ = t('disputes.strikes.status_removed')
-diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml
-index ce52e470d..150dc0675 100644
---- a/app/views/disputes/strikes/show.html.haml
-+++ b/app/views/disputes/strikes/show.html.haml
-@@ -9,63 +9,19 @@
- - if @strike.overruled?
- %p.hint
- %span.positive-hint
-- = fa_icon 'check'
-- = ' '
-+ = material_symbol 'check'
-+
- = t 'disputes.strikes.appeal_approved'
- - elsif @appeal.persisted? && @appeal.rejected?
- %p.hint
- %span.negative-hint
-- = fa_icon 'times'
-- = ' '
-+ = material_symbol 'close'
-+
- = t 'disputes.strikes.appeal_rejected'
-
- .report-header
- .report-header__card
-- .strike-card
-- - unless @strike.none_action?
-- %p= t "user_mailer.warning.explanation.#{@strike.action}", instance: Rails.configuration.x.local_domain
--
-- - unless @strike.text.blank?
-- = linkify(@strike.text)
--
-- - if @strike.report && !@strike.report.other?
-- %p
-- %strong= t('user_mailer.warning.reason')
-- = t("user_mailer.warning.categories.#{@strike.report.category}")
--
-- - if @strike.report.violation? && @strike.report.rule_ids.present?
-- %ul.strike-card__rules
-- - @strike.report.rules.each do |rule|
-- %li
-- %span.strike-card__rules__text= rule.text
--
-- - if @strike.status_ids.present? && !@strike.status_ids.empty?
-- %p
-- %strong= t('user_mailer.warning.statuses')
--
-- .strike-card__statuses-list
-- - status_map = @strike.statuses.includes(:application, :media_attachments).index_by(&:id)
--
-- - @strike.status_ids.each do |status_id|
-- .strike-card__statuses-list__item
-- - if (status = status_map[status_id.to_i])
-- .one-liner
-- .emojify= one_line_preview(status)
--
-- - status.ordered_media_attachments.each do |media_attachment|
-- %abbr{ title: media_attachment.description }
-- = fa_icon 'link'
-- = media_attachment.file_file_name
-- .strike-card__statuses-list__item__meta
-- = link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank' do
-- %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
-- - unless status.application.nil?
-- ·
-- = status.application.name
-- - else
-- .one-liner= t('disputes.strikes.status', id: status_id)
-- .strike-card__statuses-list__item__meta
-- = t('disputes.strikes.status_removed')
-+ = render 'disputes/strikes/card', strike: @strike
-
- .report-header__details
- .report-header__details__item
-@@ -120,7 +76,7 @@
-
- = simple_form_for(@appeal, url: disputes_strike_appeal_path(@strike)) do |f|
- .fields-group
-- = f.input :text, wrapper: :with_label, input_html: { maxlength: 500 }
-+ = f.input :text, wrapper: :with_label, input_html: { maxlength: Appeal::TEXT_LENGTH_LIMIT }
-
- .actions
- = f.button :button, t('disputes.strikes.appeals.submit'), type: :submit
-diff --git a/app/views/errors/self_destruct.html.haml b/app/views/errors/self_destruct.html.haml
-new file mode 100644
-index 000000000..b9ff48f68
---- /dev/null
-+++ b/app/views/errors/self_destruct.html.haml
-@@ -0,0 +1,20 @@
-+- content_for :page_title do
-+ = t('self_destruct.title')
-+
-+.simple_form
-+ %h1.title= t('self_destruct.title')
-+ %p.lead= t('self_destruct.lead_html', domain: Rails.configuration.x.local_domain)
-+
-+.form-footer
-+ %ul.no-list
-+ - if user_signed_in?
-+ %li= link_to t('settings.account_settings'), edit_user_registration_path
-+ - else
-+ - if controller_name != 'sessions'
-+ %li= link_to_login t('auth.login')
-+
-+ - if controller_name != 'passwords' && controller_name != 'registrations'
-+ %li= link_to t('auth.forgot_password'), new_user_password_path
-+
-+ - if user_signed_in?
-+ %li= link_to t('auth.logout'), destroy_user_session_path, data: { method: :delete }
-diff --git a/app/views/filters/_filter.html.haml b/app/views/filters/_filter.html.haml
-index 9993ad2ee..a544ac3a7 100644
---- a/app/views/filters/_filter.html.haml
-+++ b/app/views/filters/_filter.html.haml
-@@ -14,7 +14,7 @@
- - unless filter.keywords.empty?
- %li.permissions-list__item
- .permissions-list__item__icon
-- = fa_icon('paragraph')
-+ = material_symbol('format_paragraph')
- .permissions-list__item__text
- .permissions-list__item__text__title
- = t('filters.index.keywords', count: filter.keywords.size)
-@@ -25,7 +25,7 @@
- - unless filter.statuses.empty?
- %li.permissions-list__item
- .permissions-list__item__icon
-- = fa_icon('comment')
-+ = material_symbol('chat')
- .permissions-list__item__text
- .permissions-list__item__text__title
- = t('filters.index.statuses', count: filter.statuses.size)
-@@ -37,5 +37,5 @@
- = t('filters.index.contexts', contexts: filter.context.map { |context| I18n.t("filters.contexts.#{context}") }.join(', '))
-
- %div
-- = table_link_to 'pencil', t('filters.edit.title'), edit_filter_path(filter)
-- = table_link_to 'times', t('filters.index.delete'), filter_path(filter), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
-+ = table_link_to 'edit', t('filters.edit.title'), edit_filter_path(filter)
-+ = table_link_to 'close', t('filters.index.delete'), filter_path(filter), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
-diff --git a/app/views/filters/_filter_fields.html.haml b/app/views/filters/_filter_fields.html.haml
-index 0690e8dd5..797c969b2 100644
---- a/app/views/filters/_filter_fields.html.haml
-+++ b/app/views/filters/_filter_fields.html.haml
-@@ -1,16 +1,37 @@
- .fields-row
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :title, as: :string, wrapper: :with_label, hint: false
-+ = f.input :title,
-+ as: :string,
-+ hint: false,
-+ wrapper: :with_label
- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: ->(i) { I18n.t("invites.expires_in.#{i}") }, include_blank: I18n.t('invites.expires_in_prompt')
-+ = f.input :expires_in,
-+ collection: CustomFilter::EXPIRATION_DURATIONS.map(&:to_i),
-+ include_blank: I18n.t('invites.expires_in_prompt'),
-+ label_method: ->(i) { I18n.t("invites.expires_in.#{i}") },
-+ wrapper: :with_label
-
- .fields-group
-- = f.input :context, wrapper: :with_block_label, collection: CustomFilter::VALID_CONTEXTS, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label_method: ->(context) { I18n.t("filters.contexts.#{context}") }, include_blank: false
-+ = f.input :context,
-+ as: :check_boxes,
-+ collection_wrapper_tag: 'ul',
-+ collection: CustomFilter::VALID_CONTEXTS,
-+ include_blank: false,
-+ item_wrapper_tag: 'li',
-+ label_method: ->(context) { I18n.t("filters.contexts.#{context}") },
-+ wrapper: :with_block_label
-
- %hr.spacer/
-
- .fields-group
-- = f.input :filter_action, as: :radio_buttons, collection: %i(warn hide), include_blank: false, wrapper: :with_block_label, label_method: ->(action) { safe_join([t("simple_form.labels.filters.actions.#{action}"), content_tag(:span, t("simple_form.hints.filters.actions.#{action}"), class: 'hint')]) }, hint: t('simple_form.hints.filters.action'), required: true
-+ = f.input :filter_action,
-+ as: :radio_buttons,
-+ collection: %i(warn hide),
-+ hint: t('simple_form.hints.filters.action'),
-+ include_blank: false,
-+ label_method: ->(action) { filter_action_label(action) },
-+ required: true,
-+ wrapper: :with_block_label
-
- %hr.spacer/
-
-@@ -37,4 +58,4 @@
- %tr
- %td{ colspan: 3 }
- = link_to_add_association f, :keywords, class: 'table-action-link', partial: 'keyword_fields', 'data-association-insertion-node': '.keywords-table tbody', 'data-association-insertion-method': 'append' do
-- = safe_join([fa_icon('plus'), t('filters.edit.add_keyword')])
-+ = safe_join([material_symbol('add'), t('filters.edit.add_keyword')])
-diff --git a/app/views/filters/_keyword_fields.html.haml b/app/views/filters/_keyword_fields.html.haml
-index eedd514ef..136ab1653 100644
---- a/app/views/filters/_keyword_fields.html.haml
-+++ b/app/views/filters/_keyword_fields.html.haml
-@@ -5,4 +5,4 @@
- %td
- = f.hidden_field :id if f.object&.persisted? # Required so Rails doesn't put the field outside of the
|
- = link_to_remove_association(f, class: 'table-action-link') do
-- = safe_join([fa_icon('times'), t('filters.index.delete')])
-+ = safe_join([material_symbol('close'), t('filters.index.delete')])
-diff --git a/app/views/filters/statuses/_status_filter.html.haml b/app/views/filters/statuses/_status_filter.html.haml
-index ba1170cf9..d0d04638d 100644
---- a/app/views/filters/statuses/_status_filter.html.haml
-+++ b/app/views/filters/statuses/_status_filter.html.haml
-@@ -15,12 +15,12 @@
-
- - status.ordered_media_attachments.each do |media_attachment|
- %abbr{ title: media_attachment.description }
-- = fa_icon 'link'
-+ = material_symbol 'link'
- = media_attachment.file_file_name
-
- .detailed-status__meta
- = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'name-tag', target: '_blank', rel: 'noopener noreferrer' do
-- = image_tag(status.account.avatar.url, width: 15, height: 15, alt: display_name(status.account), class: 'avatar')
-+ = image_tag(status.account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar')
- .username= status.account.acct
- ·
- = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
-@@ -29,9 +29,9 @@
- ·
- = t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted'))
- ·
-- = fa_visibility_icon(status)
-+ = material_symbol visibility_icon(status)
- = t("statuses.visibilities.#{status.visibility}")
- - if status.sensitive?
- ·
-- = fa_icon('eye-slash fw')
-+ = material_symbol 'visibility_off'
- = t('stream_entries.sensitive_content')
-diff --git a/app/views/filters/statuses/index.html.haml b/app/views/filters/statuses/index.html.haml
-index eaa39e170..f9f94eee9 100644
---- a/app/views/filters/statuses/index.html.haml
-+++ b/app/views/filters/statuses/index.html.haml
-@@ -6,14 +6,14 @@
- .filters
- .back-link
- = link_to edit_filter_path(@filter) do
-- = fa_icon 'chevron-left fw'
-+ = material_symbol 'chevron_left'
- = t('filters.statuses.back_to_filter')
-
- %p.hint= t('filters.statuses.index.hint')
-
- %hr.spacer/
-
--= form_for(@status_filter_batch_action, url: batch_filter_statuses_path(@filter.id)) do |f|
-+= form_with model: @status_filter_batch_action, url: batch_filter_statuses_path(@filter.id) do |f|
- = hidden_field_tag :page, params[:page] || 1
-
- - Admin::StatusFilter::KEYS.each do |key|
-@@ -25,7 +25,7 @@
- = check_box_tag :batch_checkbox_all, nil, false
- .batch-table__toolbar__actions
- - unless @status_filters.empty?
-- = f.button safe_join([fa_icon('times'), t('filters.statuses.batch.remove')]), name: :remove, class: 'table-action-link', type: :submit
-+ = f.button safe_join([material_symbol('close'), t('filters.statuses.batch.remove')]), name: :remove, class: 'table-action-link', type: :submit
- .batch-table__body
- - if @status_filters.empty?
- = nothing_here 'nothing-here--under-tabs'
-diff --git a/app/views/invites/_form.html.haml b/app/views/invites/_form.html.haml
-index 7ea521ebc..dbbb785e8 100644
---- a/app/views/invites/_form.html.haml
-+++ b/app/views/invites/_form.html.haml
-@@ -1,14 +1,13 @@
--= simple_form_for(@invite, url: controller.is_a?(Admin::InvitesController) ? admin_invites_path : invites_path) do |f|
-- = render 'shared/error_messages', object: @invite
-+= render 'shared/error_messages', object: form.object
-
-- .fields-row
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :max_uses, wrapper: :with_label, collection: [1, 5, 10, 25, 50, 100], label_method: ->(num) { I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
-- .fields-row__column.fields-row__column-6.fields-group
-- = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: ->(i) { I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
-+.fields-row
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = form.input :max_uses, wrapper: :with_label, collection: invites_max_uses_options, label_method: ->(num) { I18n.t('invites.max_uses', count: num) }, prompt: I18n.t('invites.max_uses_prompt')
-+ .fields-row__column.fields-row__column-6.fields-group
-+ = form.input :expires_in, wrapper: :with_label, collection: invites_expires_options.map(&:to_i), label_method: ->(i) { I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')
-
-- .fields-group
-- = f.input :autofollow, wrapper: :with_label
-+.fields-group
-+ = form.input :autofollow, wrapper: :with_label
-
-- .actions
-- = f.button :button, t('invites.generate'), type: :submit
-+.actions
-+ = form.button :button, t('invites.generate'), type: :submit
-diff --git a/app/views/invites/_invite.html.haml b/app/views/invites/_invite.html.haml
-index 62799ca5b..7c94062de 100644
---- a/app/views/invites/_invite.html.haml
-+++ b/app/views/invites/_invite.html.haml
-@@ -1,13 +1,13 @@
--%tr
-+%tr{ id: dom_id(invite) }
- %td
- .input-copy
- .input-copy__wrapper
-- %input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: public_invite_url(invite_code: invite.code) }
-+ = copyable_input value: public_invite_url(invite_code: invite.code)
- %button{ type: :button }= t('generic.copy')
-
- - if invite.valid_for_use?
- %td
-- = fa_icon 'user fw'
-+ = material_symbol 'person'
- = invite.uses
- = " / #{invite.max_uses}" unless invite.max_uses.nil?
- %td
-@@ -22,4 +22,4 @@
-
- %td
- - if invite.valid_for_use? && policy(invite).destroy?
-- = table_link_to 'times', t('invites.delete'), invite_path(invite), method: :delete
-+ = table_link_to 'close', t('invites.delete'), invite_path(invite), method: :delete
-diff --git a/app/views/invites/index.html.haml b/app/views/invites/index.html.haml
-index 61420ab1e..88ed662af 100644
---- a/app/views/invites/index.html.haml
-+++ b/app/views/invites/index.html.haml
-@@ -4,7 +4,8 @@
- - if policy(:invite).create?
- %p= t('invites.prompt')
-
-- = render 'form'
-+ = simple_form_for(@invite, url: invites_path) do |form|
-+ = render partial: 'form', object: form
-
- %hr.spacer/
-
-diff --git a/app/views/kaminari/_next_page.html.haml b/app/views/kaminari/_next_page.html.haml
-index c44aea1f1..5f27f4c8e 100644
---- a/app/views/kaminari/_next_page.html.haml
-+++ b/app/views/kaminari/_next_page.html.haml
-@@ -8,4 +8,4 @@
- remote: data-remote
-
- %span.next
-- = link_to_unless current_page.last?, safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), url, rel: 'next', remote: remote
-+ = link_to_unless current_page.last?, safe_join([t('pagination.next'), material_symbol('chevron_right')], ' '), url, rel: 'next', remote: remote
-diff --git a/app/views/kaminari/_prev_page.html.haml b/app/views/kaminari/_prev_page.html.haml
-index 284d6223b..c5584f6a8 100644
---- a/app/views/kaminari/_prev_page.html.haml
-+++ b/app/views/kaminari/_prev_page.html.haml
-@@ -7,4 +7,4 @@
- per_page: number of items to fetch per page
- remote: data-remote
- %span.prev
-- = link_to_unless current_page.first?, safe_join([fa_icon('chevron-left'), t('pagination.prev')], ' '), url, rel: 'prev', remote: remote
-+ = link_to_unless current_page.first?, safe_join([material_symbol('chevron_left'), t('pagination.prev')], ' '), url, rel: 'prev', remote: remote
-diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
-index bc18e2599..9a1bf3f5d 100644
---- a/app/views/layouts/admin.html.haml
-+++ b/app/views/layouts/admin.html.haml
-@@ -3,6 +3,8 @@
- = javascript_pack_tag 'public', crossorigin: 'anonymous'
- = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
-
-+- content_for :body_classes, 'admin'
-+
- - content_for :content do
- .admin-wrapper
- .sidebar-wrapper
-@@ -19,8 +21,8 @@
- = site_title
-
- = link_to '#', class: 'sidebar__toggle__icon', 'aria-label': t('navigation.toggle_menu'), 'aria-expanded': 'false' do
-- = fa_icon 'bars'
-- = fa_icon 'times'
-+ = material_symbol 'menu'
-+ = material_symbol 'close'
-
- = render_navigation
-
-diff --git a/app/views/layouts/admin_mailer.text.erb b/app/views/layouts/admin_mailer.text.erb
-new file mode 100644
-index 000000000..298007ac8
---- /dev/null
-+++ b/app/views/layouts/admin_mailer.text.erb
-@@ -0,0 +1,3 @@
-+<%= raw t('application_mailer.salutation', name: display_name(@me)) %>
-+
-+<%= yield %>
-diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
-index 5c99b6302..0b48974ec 100755
---- a/app/views/layouts/application.html.haml
-+++ b/app/views/layouts/application.html.haml
-@@ -11,29 +11,29 @@
- - if storage_host?
- %link{ rel: 'dns-prefetch', href: storage_host }/
-
-- %link{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' }/
-+ - SiteUpload::FAVICON_SIZES.each do |size|
-+ %link{ rel: 'icon', sizes: "#{size}x#{size}", href: favicon_path(size.to_i) || frontend_asset_path("icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/
-
-- - %w(16 32 48).each do |size|
-- %link{ rel: 'icon', sizes: "#{size}x#{size}", href: asset_pack_path("media/icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/
-+ - SiteUpload::APPLE_ICON_SIZES.each do |size|
-+ %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: app_icon_path(size.to_i) || frontend_asset_path("icons/apple-touch-icon-#{size}x#{size}.png") }/
-
-- - %w(57 60 72 76 114 120 144 152 167 180 1024).each do |size|
-- %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: asset_pack_path("media/icons/apple-touch-icon-#{size}x#{size}.png") }/
--
-- %link{ rel: 'mask-icon', href: asset_pack_path('media/images/logo-symbol-icon.svg'), color: '#6364FF' }/
-+ - if use_mask_icon?
-+ %link{ rel: 'mask-icon', href: frontend_asset_path('images/logo-symbol-icon.svg'), color: '#6364FF' }/
- %link{ rel: 'manifest', href: manifest_path(format: :json) }/
-- %meta{ name: 'theme-color', content: '#191b22' }/
-- %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/
-+ = theme_color_tags current_theme
-+ %meta{ name: 'mobile-web-app-capable', content: 'yes' }/
-+
-+ %title= html_title
-
-- %title= content_for?(:page_title) ? safe_join([yield(:page_title).chomp.html_safe, title], ' - ') : title
-+ = theme_style_tags current_theme
-+ -# Needed for the wicg-inert polyfill. It needs to be on it's own