Enable custom emojis in profiles (notes, field values, display names) (#7374)
Follow-up to #6124main
parent
bd10a7e480
commit
61a9018607
|
@ -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)
|
||||
|
|
|
@ -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(/<br\s*\/?>/g, '\n').replace(/<\/p><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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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)) }
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue