diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 33d4bf6d022..65f803b1012 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -102,6 +102,16 @@ module ApplicationHelper policy(record).public_send(:"#{action}?") end + def conditional_link_to(condition, name, options = {}, html_options = {}, &block) + if condition && !current_page?(block_given? ? name : options) + link_to(name, options, html_options, &block) + elsif block_given? + content_tag(:span, options, html_options, &block) + else + content_tag(:span, name, html_options) + end + end + def material_symbol(icon, attributes = {}) safe_join( [ diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 5696faf81b7..fe1689b3258 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2384,6 +2384,7 @@ a .account__avatar { .detailed-status__display-name, .detailed-status__datetime, .detailed-status__application, +.detailed-status__link, .account__display-name { text-decoration: none; } @@ -2416,7 +2417,8 @@ a.account__display-name { } .detailed-status__application, -.detailed-status__datetime { +.detailed-status__datetime, +.detailed-status__link { color: inherit; } @@ -2602,8 +2604,9 @@ a.account__display-name { } .status__relative-time, -.detailed-status__datetime { - &:hover { +.detailed-status__datetime, +.detailed-status__link { + &:is(a):hover { text-decoration: underline; } } diff --git a/app/models/status_edit.rb b/app/models/status_edit.rb index 25e22288730..2c2306bb750 100644 --- a/app/models/status_edit.rb +++ b/app/models/status_edit.rb @@ -45,6 +45,10 @@ class StatusEdit < ApplicationRecord delegate :local?, :application, :edited?, :edited_at, :discarded?, :visibility, :language, to: :status + def with_media? + ordered_media_attachments.any? + end + def emojis return @emojis if defined?(@emojis) diff --git a/app/views/admin/reports/_media_attachments.html.haml b/app/views/admin/reports/_media_attachments.html.haml deleted file mode 100644 index aa82ec09a89..00000000000 --- a/app/views/admin/reports/_media_attachments.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -- if status.ordered_media_attachments.first.video? - = render_video_component(status, visible: false) -- elsif status.ordered_media_attachments.first.audio? - = render_audio_component(status) -- else - = render_media_gallery_component(status, visible: false) diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml deleted file mode 100644 index c1e47d5b32e..00000000000 --- a/app/views/admin/reports/_status.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -.batch-table__row - %label.batch-table__row__select.batch-checkbox - = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id - .batch-table__row__content - .status__card - - if status.reblog? - .status__prepend - = material_symbol('repeat') - = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account, path: admin_account_status_path(status.proper.account.id, status.proper.id))) - - elsif status.reply? && status.in_reply_to_id.present? - .status__prepend - = material_symbol('reply') - = t('admin.statuses.replied_to_html', acct_link: admin_account_inline_link_to(status.in_reply_to_account, path: status.thread.present? ? admin_account_status_path(status.thread.account_id, status.in_reply_to_id) : nil)) - .status__content>< - - if status.proper.spoiler_text.blank? - = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis) - - else - %details< - %summary>< - %strong> Content warning: #{prerender_custom_emojis(h(status.proper.spoiler_text), status.proper.emojis)} - = prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis) - - - unless status.proper.ordered_media_attachments.empty? - = render partial: 'admin/reports/media_attachments', locals: { status: status.proper } - - .detailed-status__meta - - if status.application - = status.application.name - · - - = link_to admin_account_status_path(status.account.id, status), class: 'detailed-status__datetime' 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' - - if status.discarded? - · - %span.negative-hint= t('admin.statuses.deleted') - · - - = material_symbol visibility_icon(status) - = t("statuses.visibilities.#{status.visibility}") - · - - = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', rel: 'noopener' do - = t('admin.statuses.view_publicly') - - - if status.proper.sensitive? - · - = material_symbol('visibility_off') - = t('stream_entries.sensitive_content') diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 69e9c02921e..516d2f5d2c7 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -57,7 +57,7 @@ - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' - else - = render partial: 'admin/reports/status', collection: @statuses, locals: { f: f } + = render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f } - if @report.unresolved? %hr.spacer/ diff --git a/app/views/admin/shared/_status.html.haml b/app/views/admin/shared/_status.html.haml new file mode 100644 index 00000000000..c042fd7a2cd --- /dev/null +++ b/app/views/admin/shared/_status.html.haml @@ -0,0 +1,40 @@ +-# locals: (status:) + +.status__card>< + - if status.reblog? + .status__prepend + = material_symbol('repeat') + = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account, path: admin_account_status_path(status.proper.account.id, status.proper.id))) + - elsif status.reply? && status.in_reply_to_id.present? + .status__prepend + = material_symbol('reply') + = t('admin.statuses.replied_to_html', acct_link: admin_account_inline_link_to(status.in_reply_to_account, path: status.thread.present? ? admin_account_status_path(status.thread.account_id, status.in_reply_to_id) : nil)) + + = render partial: 'admin/shared/status_content', locals: { status: status.proper } + + .detailed-status__meta + - if status.application + = status.application.name + · + = conditional_link_to can?(:show, status), admin_account_status_path(status.account.id, status), class: 'detailed-status__datetime' do + %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }><= l(status.created_at) + - if status.edited? +  · + = conditional_link_to can?(:show, status), admin_account_status_path(status.account.id, status, { anchor: 'history' }), class: 'detailed-status__datetime' do + %span><= t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'relative-formatted')) + - if status.discarded? +  · + %span.negative-hint= t('admin.statuses.deleted') + - unless status.reblog? +  · + %span< + = material_symbol(visibility_icon(status)) + = t("statuses.visibilities.#{status.visibility}") + - if status.proper.sensitive? +  · + = material_symbol('visibility_off') + = t('stream_entries.sensitive_content') + - unless status.direct_visibility? +  · + = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__link', target: 'blank', rel: 'noopener' do + = t('admin.statuses.view_publicly') diff --git a/app/views/admin/shared/_status_attachments.html.haml b/app/views/admin/shared/_status_attachments.html.haml new file mode 100644 index 00000000000..92cc6964536 --- /dev/null +++ b/app/views/admin/shared/_status_attachments.html.haml @@ -0,0 +1,7 @@ +- if status.with_media? + - if status.ordered_media_attachments.first.video? + = render_video_component(status, visible: false) + - elsif status.ordered_media_attachments.first.audio? + = render_audio_component(status) + - else + = render_media_gallery_component(status, visible: false) diff --git a/app/views/admin/shared/_status_batch_row.html.haml b/app/views/admin/shared/_status_batch_row.html.haml new file mode 100644 index 00000000000..53d8a56e607 --- /dev/null +++ b/app/views/admin/shared/_status_batch_row.html.haml @@ -0,0 +1,5 @@ +.batch-table__row + %label.batch-table__row__select.batch-checkbox + = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id + .batch-table__row__content + = render partial: 'admin/shared/status', object: status diff --git a/app/views/admin/shared/_status_content.html.haml b/app/views/admin/shared/_status_content.html.haml new file mode 100644 index 00000000000..aedd84bdd67 --- /dev/null +++ b/app/views/admin/shared/_status_content.html.haml @@ -0,0 +1,10 @@ +.status__content>< + - if status.spoiler_text.present? + %details< + %summary>< + %strong> Content warning: #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)} + = prerender_custom_emojis(status_content_format(status), status.emojis) + = render partial: 'admin/shared/status_attachments', locals: { status: status.proper } + - else + = prerender_custom_emojis(status_content_format(status), status.emojis) + = render partial: 'admin/shared/status_attachments', locals: { status: status.proper } diff --git a/app/views/admin/status_edits/_status_edit.html.haml b/app/views/admin/status_edits/_status_edit.html.haml index 0bec0159ee4..d4cc4f5ea25 100644 --- a/app/views/admin/status_edits/_status_edit.html.haml +++ b/app/views/admin/status_edits/_status_edit.html.haml @@ -9,17 +9,7 @@ %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) .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) - - - unless status_edit.ordered_media_attachments.empty? - = render partial: 'admin/reports/media_attachments', locals: { status: status_edit } + = render partial: 'admin/shared/status_content', locals: { status: status_edit } .detailed-status__meta %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml index 57b9fe0e15c..e914585db61 100644 --- a/app/views/admin/statuses/index.html.haml +++ b/app/views/admin/statuses/index.html.haml @@ -47,6 +47,6 @@ - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' - else - = render partial: 'admin/reports/status', collection: @statuses, locals: { f: f } + = render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f } = paginate @statuses diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml index 7328eeb0a74..ba5ba819874 100644 --- a/app/views/admin/statuses/show.html.haml +++ b/app/views/admin/statuses/show.html.haml @@ -53,52 +53,11 @@ %h3= t('admin.statuses.contents') -.status__card - - if @status.reblog? - .status__prepend - = material_symbol('repeat') - = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(@status.proper.account, path: admin_account_status_path(@status.proper.account.id, @status.proper.id))) - - elsif @status.reply? && @status.in_reply_to_id.present? - .status__prepend - = material_symbol('reply') - = t('admin.statuses.replied_to_html', acct_link: admin_account_inline_link_to(@status.in_reply_to_account, path: @status.thread.present? ? admin_account_status_path(@status.thread.account_id, @status.in_reply_to_id) : nil)) - .status__content>< - - if @status.proper.spoiler_text.blank? - = prerender_custom_emojis(status_content_format(@status.proper), @status.proper.emojis) - - else - %details< - %summary>< - %strong> Content warning: #{prerender_custom_emojis(h(@status.proper.spoiler_text), @status.proper.emojis)} - = prerender_custom_emojis(status_content_format(@status.proper), @status.proper.emojis) - - - unless @status.proper.ordered_media_attachments.empty? - = render partial: 'admin/reports/media_attachments', locals: { status: @status.proper } - - .detailed-status__meta - - if @status.application - = @status.application.name - · - %span.detailed-status__datetime - %time.formatted{ datetime: @status.created_at.iso8601, title: l(@status.created_at) }= l(@status.created_at) - - if @status.edited? - · - %span.detailed-status__datetime - = 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')) - - if @status.discarded? - · - %span.negative-hint= t('admin.statuses.deleted') - - unless @status.reblog? - · - = material_symbol(visibility_icon(@status)) - = t("statuses.visibilities.#{@status.visibility}") - - if @status.proper.sensitive? - · - = material_symbol('visibility_off') - = t('stream_entries.sensitive_content') += render partial: 'admin/shared/status', object: @status %hr.spacer/ -%h3= t('admin.statuses.history') +%h3#history= t('admin.statuses.history') - if @status.edits.empty? %p= t('admin.statuses.no_history') - else diff --git a/config/locales/en.yml b/config/locales/en.yml index 06db5e3cfce..1c56fcfd82a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1915,7 +1915,7 @@ en: public: Everyone title: '%{name}: "%{quote}"' visibilities: - direct: Direct + direct: Private mention private: Followers-only private_long: Only show to followers public: Public