From dfef7d94074e102a29cf2db00e458ad223900438 Mon Sep 17 00:00:00 2001 From: Echo Date: Wed, 17 Sep 2025 11:00:57 +0200 Subject: [PATCH] Refactor: Replace all display name usage for new component (#36137) --- .../__snapshots__/display_name-test.jsx.snap | 27 ---- .../__tests__/display_name-test.jsx | 19 --- .../mastodon/components/display_name.tsx | 122 ------------------ .../components/display_name/default.tsx | 36 ++++++ .../display_name/display_name.stories.tsx | 8 +- .../components/display_name/index.tsx | 111 +++------------- .../components/display_name/no-domain.tsx | 39 ++++++ .../components/display_name/simple.tsx | 23 ++++ app/javascript/mastodon/components/status.jsx | 20 ++- .../components/status_thread_label.tsx | 11 +- .../components/follow_request_note.jsx | 3 +- .../components/account_header.tsx | 4 +- .../components/familiar_followers.tsx | 29 ++--- .../components/moved_note.tsx | 12 +- .../annual_report/highlighted_post.tsx | 7 +- .../components/conversation.jsx | 12 +- .../explore/components/author_link.jsx | 8 +- .../features/interaction_modal/index.tsx | 7 +- .../notifications/components/notification.jsx | 10 +- .../components/notification_request.jsx | 3 +- .../components/displayed_name.tsx | 22 ---- .../components/notification_admin_report.tsx | 7 +- .../notification_group_with_status.tsx | 9 +- .../components/notification_with_status.tsx | 13 +- 24 files changed, 198 insertions(+), 364 deletions(-) delete mode 100644 app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap delete mode 100644 app/javascript/mastodon/components/__tests__/display_name-test.jsx delete mode 100644 app/javascript/mastodon/components/display_name.tsx create mode 100644 app/javascript/mastodon/components/display_name/default.tsx create mode 100644 app/javascript/mastodon/components/display_name/no-domain.tsx create mode 100644 app/javascript/mastodon/components/display_name/simple.tsx delete mode 100644 app/javascript/mastodon/features/notifications_v2/components/displayed_name.tsx diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap deleted file mode 100644 index 9d1b236fad..0000000000 --- a/app/javascript/mastodon/components/__tests__/__snapshots__/display_name-test.jsx.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[` > renders display name + account name 1`] = ` - - - Foo

", - } - } - /> -
- - - @ - bar@baz - -
-`; diff --git a/app/javascript/mastodon/components/__tests__/display_name-test.jsx b/app/javascript/mastodon/components/__tests__/display_name-test.jsx deleted file mode 100644 index 05a0f47170..0000000000 --- a/app/javascript/mastodon/components/__tests__/display_name-test.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import { fromJS } from 'immutable'; - -import renderer from 'react-test-renderer'; - -import { DisplayName } from '../display_name'; - -describe('', () => { - it('renders display name + account name', () => { - const account = fromJS({ - username: 'bar', - acct: 'bar@baz', - display_name_html: '

Foo

', - }); - const component = renderer.create(); - const tree = component.toJSON(); - - expect(tree).toMatchSnapshot(); - }); -}); diff --git a/app/javascript/mastodon/components/display_name.tsx b/app/javascript/mastodon/components/display_name.tsx deleted file mode 100644 index 8409244827..0000000000 --- a/app/javascript/mastodon/components/display_name.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react'; - -import type { List } from 'immutable'; - -import type { Account } from 'mastodon/models/account'; - -import { autoPlayGif } from '../initial_state'; - -import { Skeleton } from './skeleton'; - -interface Props { - account?: Account; - others?: List; - localDomain?: string; -} - -export class DisplayName extends React.PureComponent { - handleMouseEnter: React.ReactEventHandler = ({ - currentTarget, - }) => { - if (autoPlayGif) { - return; - } - - const emojis = - currentTarget.querySelectorAll('img.custom-emoji'); - - emojis.forEach((emoji) => { - const originalSrc = emoji.getAttribute('data-original'); - if (originalSrc != null) emoji.src = originalSrc; - }); - }; - - handleMouseLeave: React.ReactEventHandler = ({ - currentTarget, - }) => { - if (autoPlayGif) { - return; - } - - const emojis = - currentTarget.querySelectorAll('img.custom-emoji'); - - emojis.forEach((emoji) => { - const staticSrc = emoji.getAttribute('data-static'); - if (staticSrc != null) emoji.src = staticSrc; - }); - }; - - render() { - const { others, localDomain } = this.props; - - let displayName: React.ReactNode, - suffix: React.ReactNode, - account: Account | undefined; - - if (others && others.size > 0) { - account = others.first(); - } else if (this.props.account) { - account = this.props.account; - } - - if (others && others.size > 1) { - displayName = others - .take(2) - .map((a) => ( - - - - )) - .reduce((prev, cur) => [prev, ', ', cur]); - - if (others.size - 2 > 0) { - suffix = `+${others.size - 2}`; - } - } else if (account) { - let acct = account.get('acct'); - - if (!acct.includes('@') && localDomain) { - acct = `${acct}@${localDomain}`; - } - - displayName = ( - - - - ); - suffix = @{acct}; - } else { - displayName = ( - - - - - - ); - suffix = ( - - - - ); - } - - return ( - - {displayName} {suffix} - - ); - } -} diff --git a/app/javascript/mastodon/components/display_name/default.tsx b/app/javascript/mastodon/components/display_name/default.tsx new file mode 100644 index 0000000000..57ae24ab26 --- /dev/null +++ b/app/javascript/mastodon/components/display_name/default.tsx @@ -0,0 +1,36 @@ +import { useMemo } from 'react'; +import type { ComponentPropsWithoutRef, FC } from 'react'; + +import { Skeleton } from '../skeleton'; + +import type { DisplayNameProps } from './index'; +import { DisplayNameWithoutDomain } from './no-domain'; + +export const DisplayNameDefault: FC< + Omit & ComponentPropsWithoutRef<'span'> +> = ({ account, localDomain, className, ...props }) => { + const username = useMemo(() => { + if (!account) { + return null; + } + let acct = account.get('acct'); + + if (!acct.includes('@') && localDomain) { + acct = `${acct}@${localDomain}`; + } + return `@${acct}`; + }, [account, localDomain]); + + return ( + + {' '} + + {username ?? } + + + ); +}; diff --git a/app/javascript/mastodon/components/display_name/display_name.stories.tsx b/app/javascript/mastodon/components/display_name/display_name.stories.tsx index ccd7dcbb91..d546fdd135 100644 --- a/app/javascript/mastodon/components/display_name/display_name.stories.tsx +++ b/app/javascript/mastodon/components/display_name/display_name.stories.tsx @@ -18,8 +18,6 @@ const meta = { username: 'mastodon@mastodon.social', name: 'Test User 🧪', loading: false, - simple: false, - noDomain: false, localDomain: 'mastodon.social', }, tags: [], @@ -50,13 +48,13 @@ export const Loading: Story = { export const NoDomain: Story = { args: { - noDomain: true, + variant: 'noDomain', }, }; export const Simple: Story = { args: { - simple: true, + variant: 'simple', }, }; @@ -76,6 +74,6 @@ export const Linked: Story = { acct: username, }) : undefined; - return ; + return ; }, }; diff --git a/app/javascript/mastodon/components/display_name/index.tsx b/app/javascript/mastodon/components/display_name/index.tsx index 6bd4addded..06bc380a10 100644 --- a/app/javascript/mastodon/components/display_name/index.tsx +++ b/app/javascript/mastodon/components/display_name/index.tsx @@ -1,110 +1,37 @@ import type { ComponentPropsWithoutRef, FC } from 'react'; -import { useMemo } from 'react'; -import classNames from 'classnames'; import type { LinkProps } from 'react-router-dom'; import { Link } from 'react-router-dom'; -import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html'; import type { Account } from '@/mastodon/models/account'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; -import { Skeleton } from '../skeleton'; +import { DisplayNameDefault } from './default'; +import { DisplayNameWithoutDomain } from './no-domain'; +import { DisplayNameSimple } from './simple'; -interface Props { +export interface DisplayNameProps { account?: Account; localDomain?: string; - simple?: boolean; - noDomain?: boolean; + variant?: 'default' | 'simple' | 'noDomain'; } -export const DisplayName: FC> = ({ - account, - localDomain, - simple = false, - noDomain = false, - className, - ...props -}) => { - const username = useMemo(() => { - if (!account || noDomain) { - return null; - } - let acct = account.get('acct'); - - if (!acct.includes('@') && localDomain) { - acct = `${acct}@${localDomain}`; - } - return `@${acct}`; - }, [account, localDomain, noDomain]); - - if (!account) { - if (simple) { - return null; - } - return ( - - - - - - - {!noDomain && ( - -   - - - )} - - ); +export const DisplayName: FC< + DisplayNameProps & ComponentPropsWithoutRef<'span'> +> = ({ variant = 'default', ...props }) => { + if (variant === 'simple') { + return ; + } else if (variant === 'noDomain') { + return ; } - const accountName = isModernEmojiEnabled() - ? account.get('display_name') - : account.get('display_name_html'); - if (simple) { - return ( - - - - ); - } - - return ( - - - - - {username && ( -  {username} - )} - - ); + return ; }; export const LinkedDisplayName: FC< - Props & { asProps?: ComponentPropsWithoutRef<'span'> } & Partial -> = ({ - account, - asProps = {}, - className, - localDomain, - simple, - noDomain, - ...linkProps -}) => { - const displayProps = { - account, - className, - localDomain, - simple, - noDomain, - ...asProps, - }; + Omit & { + displayProps: DisplayNameProps & ComponentPropsWithoutRef<'span'>; + } +> = ({ displayProps, children, ...linkProps }) => { + const { account } = displayProps; if (!account) { return ; } @@ -113,9 +40,11 @@ export const LinkedDisplayName: FC< + {children} ); diff --git a/app/javascript/mastodon/components/display_name/no-domain.tsx b/app/javascript/mastodon/components/display_name/no-domain.tsx new file mode 100644 index 0000000000..ccb9a62ab7 --- /dev/null +++ b/app/javascript/mastodon/components/display_name/no-domain.tsx @@ -0,0 +1,39 @@ +import type { ComponentPropsWithoutRef, FC } from 'react'; + +import classNames from 'classnames'; + +import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; + +import { Skeleton } from '../skeleton'; + +import type { DisplayNameProps } from './index'; + +export const DisplayNameWithoutDomain: FC< + Omit & + ComponentPropsWithoutRef<'span'> +> = ({ account, className, children, ...props }) => { + return ( + + + {account ? ( + + ) : ( + + + + )} + + {children} + + ); +}; diff --git a/app/javascript/mastodon/components/display_name/simple.tsx b/app/javascript/mastodon/components/display_name/simple.tsx new file mode 100644 index 0000000000..3190c4384b --- /dev/null +++ b/app/javascript/mastodon/components/display_name/simple.tsx @@ -0,0 +1,23 @@ +import type { ComponentPropsWithoutRef, FC } from 'react'; + +import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html'; +import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; + +import type { DisplayNameProps } from './index'; + +export const DisplayNameSimple: FC< + Omit & + ComponentPropsWithoutRef<'span'> +> = ({ account, ...props }) => { + if (!account) { + return null; + } + const accountName = isModernEmojiEnabled() + ? account.get('display_name') + : account.get('display_name_html'); + return ( + + + + ); +}; diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index bd1d431622..34a9dda497 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -28,7 +28,7 @@ import { displayMedia } from '../initial_state'; import { Avatar } from './avatar'; import { AvatarOverlay } from './avatar_overlay'; -import { DisplayName } from './display_name'; +import { LinkedDisplayName } from './display_name'; import { getHashtagBarForStatus } from './hashtag_bar'; import { RelativeTimestamp } from './relative_timestamp'; import StatusActionBar from './status_action_bar'; @@ -409,12 +409,20 @@ 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 = ( + + ) prepend = (
- }} /> +
); @@ -570,13 +578,11 @@ class Status extends ImmutablePureComponent { {status.get('edited_at') && *} - +
{statusAvatar}
- - - +
{isQuotedPost && !!this.props.onQuoteCancel && ( }} + values={{ + name: ( + + ), + }} /> ); } else { diff --git a/app/javascript/mastodon/features/account/components/follow_request_note.jsx b/app/javascript/mastodon/features/account/components/follow_request_note.jsx index d57fd030b2..9c20f1e062 100644 --- a/app/javascript/mastodon/features/account/components/follow_request_note.jsx +++ b/app/javascript/mastodon/features/account/components/follow_request_note.jsx @@ -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 (
- }} /> + }} />
diff --git a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx index 0bae039503..ed6d9cb83e 100644 --- a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx @@ -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<{

- + @{username} diff --git a/app/javascript/mastodon/features/account_timeline/components/familiar_followers.tsx b/app/javascript/mastodon/features/account_timeline/components/familiar_followers.tsx index 41bd8ab4ba..cc6434c6ee 100644 --- a/app/javascript/mastodon/features/account_timeline/components/familiar_followers.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/familiar_followers.tsx @@ -1,33 +1,26 @@ 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 ( - - ); -}; - const FamiliarFollowersReadout: React.FC<{ familiarFollowers: Account[] }> = ({ familiarFollowers, }) => { const messageData = { - name1: , - name2: , + name1: ( + + ), + name2: ( + + ), othersCount: familiarFollowers.length - 2, }; diff --git a/app/javascript/mastodon/features/account_timeline/components/moved_note.tsx b/app/javascript/mastodon/features/account_timeline/components/moved_note.tsx index 51dbb93c8b..f2457dedd7 100644 --- a/app/javascript/mastodon/features/account_timeline/components/moved_note.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/moved_note.tsx @@ -2,8 +2,8 @@ import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; +import { DisplayName } from '@/mastodon/components/display_name'; import { AvatarOverlay } from 'mastodon/components/avatar_overlay'; -import { DisplayName } from 'mastodon/components/display_name'; import { useAppSelector } from 'mastodon/store'; export const MovedNote: React.FC<{ @@ -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: ( - - - - ), + name: , }} />

diff --git a/app/javascript/mastodon/features/annual_report/highlighted_post.tsx b/app/javascript/mastodon/features/annual_report/highlighted_post.tsx index 3a2a70713d..7edbb2e614 100644 --- a/app/javascript/mastodon/features/annual_report/highlighted_post.tsx +++ b/app/javascript/mastodon/features/annual_report/highlighted_post.tsx @@ -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 && ( - - ), + name: , }} /> diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx index f701ab0f04..9aae588bcc 100644 --- a/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx +++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.jsx @@ -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' }, @@ -139,15 +140,8 @@ export const Conversation = ({ conversation, scrollKey }) => { menu.push({ text: intl.formatMessage(messages.delete), action: handleDelete }); - const names = accounts.map(a => ( - - - - - + const names = accounts.map((account) => ( + )).reduce((prev, cur) => [prev, ', ', cur]); const handlers = { diff --git a/app/javascript/mastodon/features/explore/components/author_link.jsx b/app/javascript/mastodon/features/explore/components/author_link.jsx index 764ae75341..cf92ebc78b 100644 --- a/app/javascript/mastodon/features/explore/components/author_link.jsx +++ b/app/javascript/mastodon/features/explore/components/author_link.jsx @@ -1,9 +1,8 @@ import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; - import { Avatar } from 'mastodon/components/avatar'; import { useAppSelector } from 'mastodon/store'; +import { LinkedDisplayName } from '@/mastodon/components/display_name'; export const AuthorLink = ({ accountId }) => { const account = useAppSelector(state => state.getIn(['accounts', accountId])); @@ -13,10 +12,9 @@ export const AuthorLink = ({ accountId }) => { } return ( - + - - + ); }; diff --git a/app/javascript/mastodon/features/interaction_modal/index.tsx b/app/javascript/mastodon/features/interaction_modal/index.tsx index 2abfceaa0b..d17521d1e3 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.tsx +++ b/app/javascript/mastodon/features/interaction_modal/index.tsx @@ -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 { openModal, closeModal } from 'mastodon/actions/modal'; import { apiRequest } from 'mastodon/api'; import { Button } from 'mastodon/components/button'; @@ -404,15 +405,13 @@ const InteractionModal: React.FC<{ url: string; }> = ({ accountId, url }) => { 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 = ; + const account = useAppSelector((state) => state.accounts.get(accountId)); + const name = ; const handleSignupClick = useCallback(() => { dispatch( diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index 7151f17100..4fbae1e047 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -18,6 +18,7 @@ import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import { Account } from 'mastodon/components/account'; +import { LinkedDisplayName } from '@/mastodon/components/display_name'; import { Icon } from 'mastodon/components/icon'; import { Hotkeys } from 'mastodon/components/hotkeys'; import { StatusQuoteManager } from 'mastodon/components/status_quoted'; @@ -485,8 +486,10 @@ class Notification extends ImmutablePureComponent { } const targetAccount = report.get('target_account'); - const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') }; - const targetLink = ; + const targetLink = ; return ( @@ -508,8 +511,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 = ; + const link = ; switch(notification.get('type')) { case 'follow': diff --git a/app/javascript/mastodon/features/notifications/components/notification_request.jsx b/app/javascript/mastodon/features/notifications/components/notification_request.jsx index 381bb1153f..76ac99894e 100644 --- a/app/javascript/mastodon/features/notifications/components/notification_request.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification_request.jsx @@ -16,6 +16,7 @@ import { acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/ import { initReport } from 'mastodon/actions/reports'; import { Avatar } from 'mastodon/components/avatar'; import { CheckBox } from 'mastodon/components/check_box'; +import { DisplayName } from '@/mastodon/components/display_name'; import { IconButton } from 'mastodon/components/icon_button'; import { Dropdown } from 'mastodon/components/dropdown_menu'; import { makeGetAccount } from 'mastodon/selectors'; @@ -96,7 +97,7 @@ export const NotificationRequest = ({ id, accountId, notificationsCount, checked
- +
@{account?.get('acct')} diff --git a/app/javascript/mastodon/features/notifications_v2/components/displayed_name.tsx b/app/javascript/mastodon/features/notifications_v2/components/displayed_name.tsx deleted file mode 100644 index 82ecb93ee5..0000000000 --- a/app/javascript/mastodon/features/notifications_v2/components/displayed_name.tsx +++ /dev/null @@ -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 ( - - - - ); -}; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx index e41a6b2736..03f047fb7f 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_admin_report.tsx @@ -2,6 +2,7 @@ import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; import classNames from 'classnames'; +import { DisplayName } from '@/mastodon/components/display_name'; import FlagIcon from '@/material-icons/400-24px/flag-fill.svg?react'; import { Icon } from 'mastodon/components/icon'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; @@ -42,11 +43,9 @@ export const NotificationAdminReport: React.FC<{ if (!account || !targetAccount) return null; - const domain = account.acct.split('@')[1]; - const values = { - name: {domain ?? `@${account.acct}`}, - target: @{targetAccount.acct}, + name: , + target: , category: intl.formatMessage(messages[report.category]), count: report.status_ids.length, }; diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx index 4be1eefcdd..00746560da 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_group_with_status.tsx @@ -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; @@ -61,15 +61,18 @@ export const NotificationGroupWithStatus: React.FC<{ additionalContent, }) => { const dispatch = useAppDispatch(); + const account = useAppSelector((state) => + state.accounts.get(accountIds.at(0) ?? ''), + ); const label = useMemo( () => labelRenderer( - , + , count, labelSeeMoreHref, ), - [labelRenderer, accountIds, count, labelSeeMoreHref], + [labelRenderer, account, count, labelSeeMoreHref], ); const isPrivateMention = useAppSelector( diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx index 96a4a4d65d..bc219cba12 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_with_status.tsx @@ -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,16 @@ export const NotificationWithStatus: React.FC<{ }) => { const dispatch = useAppDispatch(); + const account = useAppSelector((state) => + state.accounts.get(accountIds.at(0) ?? ''), + ); const label = useMemo( - () => labelRenderer(, count), - [labelRenderer, accountIds, count], + () => + labelRenderer( + , + count, + ), + [labelRenderer, account, count], ); const isPrivateMention = useAppSelector(