From c7d1a2e400cd6677057a8af90fff866207576098 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 23:06:29 +0200 Subject: Improve admin UI for accounts (#7360) * Improve design of account statuses admin UI (consistent with reports) * Make account moderation notes look consistent with report notes * i18n-tasks remove-unused * Fix code style issues * Fix tests --- app/views/admin/reports/_status.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/views/admin/reports') diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 137609539..9057e6048 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -7,7 +7,7 @@ %p>< %strong= Formatter.instance.format_spoiler(status) - = Formatter.instance.format(status) + = Formatter.instance.format(status, custom_emojify: true) - unless status.media_attachments.empty? - if status.media_attachments.first.video? -- cgit From 61a90186070395e133ad2f8e959bdf003a8615ca Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 May 2018 11:48:51 +0200 Subject: Enable custom emojis in profiles (notes, field values, display names) (#7374) Follow-up to #6124 --- app/helpers/stream_entries_helper.rb | 4 ++-- .../mastodon/actions/importer/normalizer.js | 19 +++++++++++-------- app/lib/formatter.rb | 12 ++++++++++-- app/models/account.rb | 6 +++++- app/serializers/rest/account_serializer.rb | 1 + app/views/about/_administration.html.haml | 2 +- app/views/about/_contact.html.haml | 2 +- app/views/accounts/_grid_card.html.haml | 2 +- app/views/accounts/_header.html.haml | 4 ++-- app/views/accounts/_moved_strip.html.haml | 4 ++-- app/views/admin/reports/_account.html.haml | 2 +- app/views/authorize_follows/_card.html.haml | 2 +- app/views/remote_unfollows/_card.html.haml | 2 +- app/views/shared/_landing_strip.html.haml | 2 +- app/views/stream_entries/_detailed_status.html.haml | 2 +- app/views/stream_entries/_simple_status.html.haml | 2 +- app/views/stream_entries/_status.html.haml | 2 +- 17 files changed, 43 insertions(+), 27 deletions(-) (limited to 'app/views/admin/reports') diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index c6f12ecd4..707c8e26c 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -4,8 +4,8 @@ module StreamEntriesHelper EMBEDDED_CONTROLLER = 'statuses' EMBEDDED_ACTION = 'embed' - def display_name(account) - account.display_name.presence || account.username + def display_name(account, **options) + Formatter.instance.format_display_name(account, options) end def account_description(account) diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 5f1274fab..057bff58b 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -3,18 +3,25 @@ import emojify from '../../features/emoji/emoji'; const domParser = new DOMParser(); +const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => { + obj[`:${emoji.shortcode}:`] = emoji; + return obj; +}, {}); + export function normalizeAccount(account) { account = { ...account }; + const emojiMap = makeEmojiMap(account); const displayName = account.display_name.length === 0 ? account.username : account.display_name; - account.display_name_html = emojify(escapeTextContentForBrowser(displayName)); - account.note_emojified = emojify(account.note); + + account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap); + account.note_emojified = emojify(account.note, emojiMap); if (account.fields) { account.fields = account.fields.map(pair => ({ ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), - value_emojified: emojify(pair.value), + value_emojified: emojify(pair.value, emojiMap), })); } @@ -42,11 +49,7 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.hidden = normalOldStatus.get('hidden'); } else { const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); - - const emojiMap = normalStatus.emojis.reduce((obj, emoji) => { - obj[`:${emoji.shortcode}:`] = emoji; - return obj; - }, {}); + const emojiMap = makeEmojiMap(normalStatus); normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 050c651ee..e1ab05cc0 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -67,9 +67,17 @@ class Formatter html.html_safe # rubocop:disable Rails/OutputSafety end - def format_field(account, str) + def format_display_name(account, **options) + html = encode(account.display_name.presence || account.username) + html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify] + html.html_safe # rubocop:disable Rails/OutputSafety + end + + def format_field(account, str, **options) return reformat(str).html_safe unless account.local? # rubocop:disable Rails/OutputSafety - encode_and_link_urls(str, me: true).html_safe # rubocop:disable Rails/OutputSafety + html = encode_and_link_urls(str, me: true) + html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify] + html.html_safe # rubocop:disable Rails/OutputSafety end def linkify(text) diff --git a/app/models/account.rb b/app/models/account.rb index 72ba0398e..4467d1512 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -398,7 +398,7 @@ class Account < ApplicationRecord end def emojis - @emojis ||= CustomEmoji.from_text(note, domain) + @emojis ||= CustomEmoji.from_text(emojifiable_text, domain) end before_create :generate_keys @@ -425,4 +425,8 @@ class Account < ApplicationRecord self.domain = TagManager.instance.normalize_domain(domain) end + + def emojifiable_text + [note, display_name, fields.map(&:value)].join(' ') + end end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 863238eb7..8761bbb5e 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -8,6 +8,7 @@ class REST::AccountSerializer < ActiveModel::Serializer :followers_count, :following_count, :statuses_count has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested? + has_many :emojis, serializer: REST::CustomEmojiSerializer class FieldSerializer < ActiveModel::Serializer attributes :name, :value diff --git a/app/views/about/_administration.html.haml b/app/views/about/_administration.html.haml index ec5834f9c..02286d68b 100644 --- a/app/views/about/_administration.html.haml +++ b/app/views/about/_administration.html.haml @@ -6,7 +6,7 @@ .account__avatar{ style: "background-image: url(#{@instance_presenter.contact_account.avatar.url})" } %span.display-name %bdi - %strong.display-name__html.emojify= display_name(@instance_presenter.contact_account) + %strong.display-name__html.emojify= display_name(@instance_presenter.contact_account, custom_emojify: true) %span.display-name__account @#{@instance_presenter.contact_account.acct} - else .account__display-name diff --git a/app/views/about/_contact.html.haml b/app/views/about/_contact.html.haml index cf21ad5a3..3215d50b5 100644 --- a/app/views/about/_contact.html.haml +++ b/app/views/about/_contact.html.haml @@ -12,7 +12,7 @@ .avatar= image_tag contact.contact_account.avatar.url .name = link_to TagManager.instance.url_for(contact.contact_account) do - %span.display_name.emojify= display_name(contact.contact_account) + %span.display_name.emojify= display_name(contact.contact_account, custom_emojify: true) %span.username @#{contact.contact_account.acct} - else .owner diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml index 95acbd581..a59ed128e 100644 --- a/app/views/accounts/_grid_card.html.haml +++ b/app/views/accounts/_grid_card.html.haml @@ -5,7 +5,7 @@ .avatar= image_tag account.avatar.url(:original) .name = link_to TagManager.instance.url_for(account) do - %span.display_name.emojify= display_name(account) + %span.display_name.emojify= display_name(account, custom_emojify: true) %span.username @#{account.local? ? account.local_username_and_domain : account.acct} = fa_icon('lock') if account.locked? diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 41315f039..13dcaf616 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -5,7 +5,7 @@ .card__bio %h1.name - %span.p-name.emojify= display_name(account) + %span.p-name.emojify= display_name(account, custom_emojify: true) %small< %span>< @#{account.local_username_and_domain} = fa_icon('lock') if account.locked? @@ -28,7 +28,7 @@ - account.fields.each do |field| %dl %dt.emojify{ title: field.name }= field.name - %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value) + %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true) .details-counters .counter{ class: active_nav_class(short_account_url(account)) } diff --git a/app/views/accounts/_moved_strip.html.haml b/app/views/accounts/_moved_strip.html.haml index 6a14a5dd3..ae18c6dc7 100644 --- a/app/views/accounts/_moved_strip.html.haml +++ b/app/views/accounts/_moved_strip.html.haml @@ -3,7 +3,7 @@ .moved-strip .moved-strip__message = fa_icon 'suitcase' - = t('accounts.moved_html', name: content_tag(:strong, display_name(account), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention')) + = t('accounts.moved_html', name: content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention')) .moved-strip__card = link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do @@ -13,5 +13,5 @@ .account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" } %span.display-name - %strong.emojify= display_name(moved_to_account) + %strong.emojify= display_name(moved_to_account, custom_emojify: true) %span @#{moved_to_account.acct} diff --git a/app/views/admin/reports/_account.html.haml b/app/views/admin/reports/_account.html.haml index 22b7a0861..9ac161c9c 100644 --- a/app/views/admin/reports/_account.html.haml +++ b/app/views/admin/reports/_account.html.haml @@ -15,5 +15,5 @@ .account__avatar{ style: "background-image: url(#{account.avatar.url}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" } %span.display-name %bdi - %strong.display-name__html.emojify= display_name(account) + %strong.display-name__html.emojify= display_name(account, custom_emojify: true) %span.display-name__account @#{account.acct} diff --git a/app/views/authorize_follows/_card.html.haml b/app/views/authorize_follows/_card.html.haml index e81e292ba..9abcfd37e 100644 --- a/app/views/authorize_follows/_card.html.haml +++ b/app/views/authorize_follows/_card.html.haml @@ -6,7 +6,7 @@ %span.display-name - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account) = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do - %strong.emojify= display_name(account) + %strong.emojify= display_name(account, custom_emojify: true) %span @#{account.acct} - if account.note? diff --git a/app/views/remote_unfollows/_card.html.haml b/app/views/remote_unfollows/_card.html.haml index e81e292ba..9abcfd37e 100644 --- a/app/views/remote_unfollows/_card.html.haml +++ b/app/views/remote_unfollows/_card.html.haml @@ -6,7 +6,7 @@ %span.display-name - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account) = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do - %strong.emojify= display_name(account) + %strong.emojify= display_name(account, custom_emojify: true) %span @#{account.acct} - if account.note? diff --git a/app/views/shared/_landing_strip.html.haml b/app/views/shared/_landing_strip.html.haml index ae26fc1ff..78f5ed4bc 100644 --- a/app/views/shared/_landing_strip.html.haml +++ b/app/views/shared/_landing_strip.html.haml @@ -2,7 +2,7 @@ = image_tag asset_pack_path('logo.svg'), class: 'logo' %div - = t('landing_strip_html', name: content_tag(:span, display_name(account), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path)) + = t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path)) - if open_registrations? = t('landing_strip_signup_html', sign_up_path: new_user_registration_path) diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml index afc66d148..c0f1e4f0f 100644 --- a/app/views/stream_entries/_detailed_status.html.haml +++ b/app/views/stream_entries/_detailed_status.html.haml @@ -4,7 +4,7 @@ .avatar = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'u-photo' %span.display-name - %strong.p-name.emojify= display_name(status.account) + %strong.p-name.emojify= display_name(status.account, custom_emojify: true) %span= acct(status.account) - if embedded_view? diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml index a6f5120fb..b89860ad9 100644 --- a/app/views/stream_entries/_simple_status.html.haml +++ b/app/views/stream_entries/_simple_status.html.haml @@ -10,7 +10,7 @@ %div = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo' %span.display-name - %strong.p-name.emojify= display_name(status.account) + %strong.p-name.emojify= display_name(status.account, custom_emojify: true) %span= acct(status.account) .status__content.p-name.emojify< diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml index 9764bc74d..b87ca2177 100644 --- a/app/views/stream_entries/_status.html.haml +++ b/app/views/stream_entries/_status.html.haml @@ -28,7 +28,7 @@ = fa_icon('retweet fw') %span = link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do - %strong.emojify= display_name(status.account) + %strong.emojify= display_name(status.account, custom_emojify: true) = t('stream_entries.reblogged') - elsif pinned .pre-header -- cgit From 0f2fbf7d05825447a0f2a1e82b6137c069cb1658 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 12 May 2018 17:44:15 +0200 Subject: Improvements to toots display in admin view (#7452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Distinguish boosts from original statuses in the admin panel (fixes #7449) * Show the “show more” button in admin view to make CWs clearer (fixes #7451) * Make content warnings swag --- .../admin/account_moderation_notes_helper.rb | 10 +++++-- app/javascript/styles/mastodon/admin.scss | 33 +++++++++++++++------- app/javascript/styles/mastodon/tables.scss | 11 ++++++++ app/views/admin/reports/_status.html.haml | 26 +++++++++-------- config/locales/en.yml | 1 + 5 files changed, 58 insertions(+), 23 deletions(-) (limited to 'app/views/admin/reports') diff --git a/app/helpers/admin/account_moderation_notes_helper.rb b/app/helpers/admin/account_moderation_notes_helper.rb index fdfadef08..49e764cef 100644 --- a/app/helpers/admin/account_moderation_notes_helper.rb +++ b/app/helpers/admin/account_moderation_notes_helper.rb @@ -10,10 +10,16 @@ module Admin::AccountModerationNotesHelper end end + def admin_account_inline_link_to(account) + link_to admin_account_path(account.id), class: name_tag_classes(account, true) do + content_tag(:span, account.acct, class: 'username') + end + end + private - def name_tag_classes(account) - classes = ['name-tag'] + def name_tag_classes(account, inline = false) + classes = [inline ? 'inline-name-tag' : 'name-tag'] classes << 'suspended' if account.suspended? classes.join(' ') end diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 1948a2a23..560b11ddf 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -484,19 +484,12 @@ } a.name-tag, -.name-tag { - display: flex; - align-items: center; +.name-tag, +a.inline-name-tag, +.inline-name-tag { text-decoration: none; color: $secondary-text-color; - .avatar { - display: block; - margin: 0; - margin-right: 5px; - border-radius: 50%; - } - .username { font-weight: 500; } @@ -514,6 +507,26 @@ a.name-tag, } } +a.name-tag, +.name-tag { + display: flex; + align-items: center; + + .avatar { + display: block; + margin: 0; + margin-right: 5px; + border-radius: 50%; + } + + &.suspended { + .avatar { + filter: grayscale(100%); + opacity: 0.8; + } + } +} + .speech-bubble { margin-bottom: 20px; border-left: 4px solid $ui-highlight-color; diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index fa876e603..982bfd990 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -1,3 +1,9 @@ +@keyframes Swag { + 0% { background-position: 0% 0%; } + 50% { background-position: 100% 0%; } + 100% { background-position: 200% 0%; } +} + .table { width: 100%; max-width: 100%; @@ -187,6 +193,11 @@ a.table-action-link { strong { font-weight: 700; + background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet,orange , yellow, green, cyan, blue, violet); + background-size: 200% 100%; + background-clip: text; + color: transparent; + animation: Swag 2s linear 0s infinite; } } } diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 9057e6048..5e174f312 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -3,26 +3,30 @@ = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id .batch-table__row__content .status__content>< - - unless status.spoiler_text.blank? + - unless status.proper.spoiler_text.blank? %p>< - %strong= Formatter.instance.format_spoiler(status) + %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)} - = Formatter.instance.format(status, custom_emojify: true) + = Formatter.instance.format(status.proper, custom_emojify: true) - - unless status.media_attachments.empty? - - if status.media_attachments.first.video? - - video = status.media_attachments.first - = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true + - unless status.proper.media_attachments.empty? + - if status.proper.media_attachments.first.video? + - video = status.proper.media_attachments.first + = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true - else - = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } + = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } .detailed-status__meta = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) · - = fa_visibility_icon(status) - = t("statuses.visibilities.#{status.visibility}") - - if status.sensitive? + - if status.reblog? + = fa_icon('retweet fw') + = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account)) + - else + = fa_visibility_icon(status) + = t("statuses.visibilities.#{status.visibility}") + - if status.proper.sensitive? · = fa_icon('eye-slash fw') = t('stream_entries.sensitive_content') diff --git a/config/locales/en.yml b/config/locales/en.yml index 5369311ac..c074fa5b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -682,6 +682,7 @@ en: video: one: "%{count} video" other: "%{count} videos" + boosted_from_html: Boosted from %{acct_link} content_warning: 'Content warning: %{warning}' disallowed_hashtags: one: 'contained a disallowed hashtag: %{tags}' -- cgit From 40ef46dbeff676827d1ba3483f9f6f72b17bca89 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 May 2018 17:33:20 +0200 Subject: Display only domain of report account if remote under comment (#7574) --- app/views/admin/reports/show.html.haml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'app/views/admin/reports') diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index c9ebc0415..b13bb5303 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -75,7 +75,11 @@ .speech-bubble .speech-bubble__bubble= simple_format(@report.comment.presence || t('admin.reports.comment.none')) .speech-bubble__owner - = admin_account_link_to @report.account + - if @report.account.local? + = admin_account_link_to @report.account + - else + = @report.account.domain + %br/ %time.formatted{ datetime: @report.created_at.iso8601 } - unless @report.statuses.empty? -- cgit