Replace display_name_html across the platform.

This commit is contained in:
ChaosExAnima 2025-07-30 16:18:32 +02:00
parent 2633692a3d
commit dd61fed777
No known key found for this signature in database
GPG Key ID: 8F2B333100FB6117
16 changed files with 69 additions and 99 deletions

View File

@ -405,12 +405,24 @@ class Status extends ImmutablePureComponent {
const matchedFilters = status.get('matched_filters');
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
const name = (
<Link
to={`/@${status.getIn(['account', 'acct'])}`}
data-id={status.getIn(['account', 'id'])}
data-hover-card-account={status.getIn(['account', 'id'])}
>
<DisplayName
account={status.get('account')}
className="muted"
noDomain
/>
</Link>
);
prepend = (
<div className='status__prepend'>
<div className='status__prepend__icon'><Icon id='retweet' icon={RepeatIcon} /></div>
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <Link data-id={status.getIn(['account', 'id'])} data-hover-card-account={status.getIn(['account', 'id'])} to={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></Link> }} />
<div className="status__prepend">
<Icon id='retweet' icon={RepeatIcon} className="status__prepend__icon" />
<FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name }} />
</div>
);

View File

@ -2,9 +2,10 @@ import { FormattedMessage } from 'react-intl';
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
import { Icon } from 'mastodon/components/icon';
import { DisplayedName } from 'mastodon/features/notifications_v2/components/displayed_name';
import { useAppSelector } from 'mastodon/store';
import { LinkedDisplayName } from './display_name';
export const StatusThreadLabel: React.FC<{
accountId: string;
inReplyToAccountId: string;
@ -27,7 +28,9 @@ export const StatusThreadLabel: React.FC<{
<FormattedMessage
id='status.replied_to'
defaultMessage='Replied to {name}'
values={{ name: <DisplayedName accountIds={[inReplyToAccountId]} /> }}
values={{
name: <LinkedDisplayName account={inReplyToAccount} simple />,
}}
/>
);
} else {

View File

@ -6,6 +6,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { Icon } from 'mastodon/components/icon';
import { DisplayName } from '@/mastodon/components/display_name';
export default class FollowRequestNote extends ImmutablePureComponent {
@ -19,7 +20,7 @@ export default class FollowRequestNote extends ImmutablePureComponent {
return (
<div className='follow-request-banner'>
<div className='follow-request-banner__message'>
<FormattedMessage id='account.requested_follow' defaultMessage='{name} has requested to follow you' values={{ name: <bdi><strong dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi> }} />
<FormattedMessage id='account.requested_follow' defaultMessage='{name} has requested to follow you' values={{ name: <DisplayName account={account} simple /> }} />
</div>
<div className='follow-request-banner__action'>

View File

@ -7,6 +7,7 @@ import { Helmet } from 'react-helmet';
import { NavLink } from 'react-router-dom';
import { AccountBio } from '@/mastodon/components/account_bio';
import { DisplayName } from '@/mastodon/components/display_name';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
@ -774,7 +775,6 @@ export const AccountHeader: React.FC<{
);
}
const displayNameHtml = { __html: account.display_name_html };
const fields = account.fields;
const isLocal = !account.acct.includes('@');
const username = account.acct.split('@')[0];
@ -863,7 +863,7 @@ export const AccountHeader: React.FC<{
<div className='account__header__tabs__name'>
<h1>
<span dangerouslySetInnerHTML={displayNameHtml} />
<DisplayName account={account} simple />
<small>
<span>
@{username}

View File

@ -1,33 +1,18 @@
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import { Avatar } from '@/mastodon/components/avatar';
import { AvatarGroup } from '@/mastodon/components/avatar_group';
import { LinkedDisplayName } from '@/mastodon/components/display_name';
import type { Account } from '@/mastodon/models/account';
import { useFetchFamiliarFollowers } from '../hooks/familiar_followers';
const AccountLink: React.FC<{ account?: Account }> = ({ account }) => {
if (!account) {
return null;
}
return (
<Link
to={`/@${account.acct}`}
data-hover-card-account={account.id}
dangerouslySetInnerHTML={{ __html: account.display_name_html }}
/>
);
};
const FamiliarFollowersReadout: React.FC<{ familiarFollowers: Account[] }> = ({
familiarFollowers,
}) => {
const messageData = {
name1: <AccountLink account={familiarFollowers.at(0)} />,
name2: <AccountLink account={familiarFollowers.at(1)} />,
name1: <LinkedDisplayName account={familiarFollowers.at(0)} simple />,
name2: <LinkedDisplayName account={familiarFollowers.at(1)} simple />,
othersCount: familiarFollowers.length - 2,
};

View File

@ -20,15 +20,7 @@ export const MovedNote: React.FC<{
id='account.moved_to'
defaultMessage='{name} has indicated that their new account is now:'
values={{
name: (
<bdi>
<strong
dangerouslySetInnerHTML={{
__html: from?.display_name_html ?? '',
}}
/>
</bdi>
),
name: <DisplayName account={from} simple />,
}}
/>
</div>

View File

@ -6,6 +6,7 @@ import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { DisplayName } from '@/mastodon/components/display_name';
import { toggleStatusSpoilers } from 'mastodon/actions/statuses';
import { DetailedStatus } from 'mastodon/features/status/components/detailed_status';
import { me } from 'mastodon/initial_state';
@ -79,11 +80,7 @@ export const HighlightedPost: React.FC<{
id='annual_report.summary.highlighted_post.possessive'
defaultMessage="{name}'s"
values={{
name: account && (
<bdi
dangerouslySetInnerHTML={{ __html: account.display_name_html }}
/>
),
name: <DisplayName account={account} simple />,
}}
/>
</strong>

View File

@ -4,7 +4,7 @@ import { useCallback } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { Link, useHistory } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import { createSelector } from '@reduxjs/toolkit';
import ImmutablePropTypes from 'react-immutable-proptypes';
@ -25,6 +25,7 @@ import StatusContent from 'mastodon/components/status_content';
import { Dropdown } from 'mastodon/components/dropdown_menu';
import { autoPlayGif } from 'mastodon/initial_state';
import { makeGetStatus } from 'mastodon/selectors';
import { LinkedDisplayName } from '@/mastodon/components/display_name';
const messages = defineMessages({
more: { id: 'status.more', defaultMessage: 'More' },
@ -147,15 +148,8 @@ export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown })
menu.push({ text: intl.formatMessage(messages.delete), action: handleDelete });
const names = accounts.map(a => (
<Link to={`/@${a.get('acct')}`} key={a.get('id')} data-hover-card-account={a.get('id')}>
<bdi>
<strong
className='display-name__html'
dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }}
/>
</bdi>
</Link>
const names = accounts.map(account => (
<LinkedDisplayName account={account} simple />
)).reduce((prev, cur) => [prev, ', ', cur]);
const handlers = {

View File

@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
import { Avatar } from 'mastodon/components/avatar';
import { useAppSelector } from 'mastodon/store';
import { DisplayName } from '@/mastodon/components/display_name';
export const AuthorLink = ({ accountId }) => {
const account = useAppSelector(state => state.getIn(['accounts', accountId]));
@ -15,7 +16,7 @@ export const AuthorLink = ({ accountId }) => {
return (
<Link to={`/@${account.get('acct')}`} className='story__details__shared__author-link' data-hover-card-account={accountId}>
<Avatar account={account} size={16} />
<bdi dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} />
<DisplayName account={account} simple />
</Link>
);
};

View File

@ -7,6 +7,7 @@ import classNames from 'classnames';
import { escapeRegExp } from 'lodash';
import { useDebouncedCallback } from 'use-debounce';
import { DisplayName } from '@/mastodon/components/display_name';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react';
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
@ -411,15 +412,14 @@ const InteractionModal: React.FC<{
type: 'reply' | 'reblog' | 'favourite' | 'follow' | 'vote';
}> = ({ accountId, url, type }) => {
const dispatch = useAppDispatch();
const displayNameHtml = useAppSelector(
(state) => state.accounts.get(accountId)?.display_name_html ?? '',
);
const signupUrl = useAppSelector(
(state) =>
(state.server.getIn(['server', 'registrations', 'url'], null) ||
'/auth/sign_up') as string,
);
const name = <bdi dangerouslySetInnerHTML={{ __html: displayNameHtml }} />;
const account = useAppSelector((state) => state.accounts.get(accountId));
const name = <DisplayName account={account} simple />;
const handleSignupClick = useCallback(() => {
dispatch(

View File

@ -29,6 +29,7 @@ import FollowRequestContainer from '../containers/follow_request_container';
import { ModerationWarning } from './moderation_warning';
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
import Report from './report';
import { LinkedDisplayName } from '@/mastodon/components/display_name';
const messages = defineMessages({
favourite: { id: 'notification.favourite', defaultMessage: '{name} favorited your post' },
@ -434,8 +435,7 @@ class Notification extends ImmutablePureComponent {
}
const targetAccount = report.get('target_account');
const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') };
const targetLink = <bdi><Link className='notification__display-name' title={targetAccount.get('acct')} data-hover-card-account={targetAccount.get('id')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>;
const targetLink = <LinkedDisplayName account={targetAccount} className='notification__display-name' simple />
return (
<Hotkeys handlers={this.getHandlers()}>
@ -457,8 +457,7 @@ class Notification extends ImmutablePureComponent {
render () {
const { notification } = this.props;
const account = notification.get('account');
const displayNameHtml = { __html: account.get('display_name_html') };
const link = <bdi><Link className='notification__display-name' href={`/@${account.get('acct')}`} title={account.get('acct')} data-hover-card-account={account.get('id')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>;
const link = <LinkedDisplayName account={account} className='notification__display-name' simple />;
switch(notification.get('type')) {
case 'follow':

View File

@ -20,6 +20,7 @@ import { IconButton } from 'mastodon/components/icon_button';
import { Dropdown } from 'mastodon/components/dropdown_menu';
import { makeGetAccount } from 'mastodon/selectors';
import { toCappedNumber } from 'mastodon/utils/numbers';
import { DisplayName } from '@/mastodon/components/display_name';
const getAccount = makeGetAccount();
@ -96,7 +97,7 @@ export const NotificationRequest = ({ id, accountId, notificationsCount, checked
<div className='notification-request__name'>
<div className='notification-request__name__display-name'>
<bdi><strong dangerouslySetInnerHTML={{ __html: account?.get('display_name_html') }} /></bdi>
<DisplayName account={account} simple />
</div>
<span>@{account?.get('acct')}</span>

View File

@ -1,22 +0,0 @@
import { Link } from 'react-router-dom';
import { useAppSelector } from 'mastodon/store';
export const DisplayedName: React.FC<{
accountIds: string[];
}> = ({ accountIds }) => {
const lastAccountId = accountIds[0] ?? '0';
const account = useAppSelector((state) => state.accounts.get(lastAccountId));
if (!account) return null;
return (
<Link
to={`/@${account.acct}`}
title={`@${account.acct}`}
data-hover-card-account={account.id}
>
<bdi dangerouslySetInnerHTML={{ __html: account.display_name_html }} />
</Link>
);
};

View File

@ -3,6 +3,7 @@ import type { JSX } from 'react';
import classNames from 'classnames';
import { LinkedDisplayName } from '@/mastodon/components/display_name';
import { replyComposeById } from 'mastodon/actions/compose';
import { navigateToStatus } from 'mastodon/actions/statuses';
import { Avatar } from 'mastodon/components/avatar';
@ -14,7 +15,6 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import { NOTIFICATIONS_GROUP_MAX_AVATARS } from 'mastodon/models/notification_group';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { DisplayedName } from './displayed_name';
import { EmbeddedStatus } from './embedded_status';
const AVATAR_SIZE = 28;
@ -62,14 +62,17 @@ export const NotificationGroupWithStatus: React.FC<{
}) => {
const dispatch = useAppDispatch();
const account = useAppSelector((state) =>
state.accounts.get(accountIds.at(0) ?? ''),
);
const label = useMemo(
() =>
labelRenderer(
<DisplayedName accountIds={accountIds} />,
<LinkedDisplayName account={account} simple />,
count,
labelSeeMoreHref,
),
[labelRenderer, accountIds, count, labelSeeMoreHref],
[labelRenderer, count, labelSeeMoreHref, account],
);
const isPrivateMention = useAppSelector(

View File

@ -2,6 +2,7 @@ import { useMemo } from 'react';
import classNames from 'classnames';
import { LinkedDisplayName } from '@/mastodon/components/display_name';
import { replyComposeById } from 'mastodon/actions/compose';
import { toggleReblog, toggleFavourite } from 'mastodon/actions/interactions';
import {
@ -15,7 +16,6 @@ import { StatusQuoteManager } from 'mastodon/components/status_quoted';
import { getStatusHidden } from 'mastodon/selectors/filters';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { DisplayedName } from './displayed_name';
import type { LabelRenderer } from './notification_group_with_status';
export const NotificationWithStatus: React.FC<{
@ -39,9 +39,12 @@ export const NotificationWithStatus: React.FC<{
}) => {
const dispatch = useAppDispatch();
const account = useAppSelector((state) =>
state.accounts.get(accountIds.at(0) ?? ''),
);
const label = useMemo(
() => labelRenderer(<DisplayedName accountIds={accountIds} />, count),
[labelRenderer, accountIds, count],
() => labelRenderer(<LinkedDisplayName account={account} simple />, count),
[labelRenderer, count, account],
);
const isPrivateMention = useAppSelector(

View File

@ -1655,21 +1655,22 @@ body > [data-popper-placement] {
font-weight: 500;
color: $dark-text-color;
a {
text-decoration: none;
color: inherit;
&:hover {
text-decoration: underline;
}
}
&__icon {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
.icon {
width: 16px;
height: 16px;
}
}
a {
color: inherit;
text-decoration: none;
width: 16px;
height: 16px;
}
> span {