From 000199f003eecafbf2e6a6166d5e179fea4e5948 Mon Sep 17 00:00:00 2001 From: Echo Date: Tue, 24 Mar 2026 14:03:44 +0100 Subject: [PATCH] Profile redesign: Simplify header for follower/following lists (#38366) --- .../features/followers/components/header.tsx | 36 +++++++++++++++++++ .../features/followers/components/list.tsx | 6 ++-- .../mastodon/features/followers/index.tsx | 17 ++++++++- .../features/followers/styles.module.scss | 11 ++++++ .../mastodon/features/following/index.tsx | 17 ++++++++- app/javascript/mastodon/locales/en.json | 3 ++ 6 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 app/javascript/mastodon/features/followers/components/header.tsx create mode 100644 app/javascript/mastodon/features/followers/styles.module.scss diff --git a/app/javascript/mastodon/features/followers/components/header.tsx b/app/javascript/mastodon/features/followers/components/header.tsx new file mode 100644 index 0000000000..2733e1d0f4 --- /dev/null +++ b/app/javascript/mastodon/features/followers/components/header.tsx @@ -0,0 +1,36 @@ +import type { FC } from 'react'; + +import { FormattedMessage, useIntl } from 'react-intl'; +import type { MessageDescriptor } from 'react-intl'; + +import { DisplayNameSimple } from '@/mastodon/components/display_name/simple'; +import { useAccount } from '@/mastodon/hooks/useAccount'; + +import classes from '../styles.module.scss'; + +export const AccountListHeader: FC<{ + accountId: string; + total?: number; + titleText: MessageDescriptor; +}> = ({ accountId, total, titleText }) => { + const intl = useIntl(); + const account = useAccount(accountId); + return ( + <> +

+ {intl.formatMessage(titleText, { + name: , + })} +

+ {!!total && ( +

+ +

+ )} + + ); +}; diff --git a/app/javascript/mastodon/features/followers/components/list.tsx b/app/javascript/mastodon/features/followers/components/list.tsx index 24d442d229..8134a96ece 100644 --- a/app/javascript/mastodon/features/followers/components/list.tsx +++ b/app/javascript/mastodon/features/followers/components/list.tsx @@ -11,8 +11,6 @@ import { useAccount } from '@/mastodon/hooks/useAccount'; import { useAccountVisibility } from '@/mastodon/hooks/useAccountVisibility'; import { useLayout } from '@/mastodon/hooks/useLayout'; -import { AccountHeader } from '../../account_timeline/components/account_header'; - import { RemoteHint } from './remote'; export interface AccountList { @@ -25,6 +23,7 @@ interface AccountListProps { accountId?: string | null; append?: ReactNode; emptyMessage: ReactNode; + header?: ReactNode; footer?: ReactNode; list?: AccountList | null; loadMore: () => void; @@ -36,6 +35,7 @@ export const AccountList: FC = ({ accountId, append, emptyMessage, + header, footer, list, loadMore, @@ -90,7 +90,7 @@ export const AccountList: FC = ({ hasMore={!forceEmptyState && list?.hasMore} isLoading={list?.isLoading ?? true} onLoadMore={loadMore} - prepend={} + prepend={header} alwaysPrepend append={append ?? } emptyMessage={emptyMessage} diff --git a/app/javascript/mastodon/features/followers/index.tsx b/app/javascript/mastodon/features/followers/index.tsx index 15dcbb5a69..bba2f4cb08 100644 --- a/app/javascript/mastodon/features/followers/index.tsx +++ b/app/javascript/mastodon/features/followers/index.tsx @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import type { FC } from 'react'; -import { FormattedMessage } from 'react-intl'; +import { defineMessage, FormattedMessage } from 'react-intl'; import { useDebouncedCallback } from 'use-debounce'; @@ -14,8 +14,14 @@ import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import type { EmptyMessageProps } from './components/empty'; import { BaseEmptyMessage } from './components/empty'; +import { AccountListHeader } from './components/header'; import { AccountList } from './components/list'; +const titleText = defineMessage({ + id: 'followers.title', + defaultMessage: 'Following {name}', +}); + const Followers: FC = () => { const accountId = useAccountId(); const account = useAccount(accountId); @@ -64,6 +70,15 @@ const Followers: FC = () => { return ( + ) + } footer={footer} emptyMessage={} list={followerList} diff --git a/app/javascript/mastodon/features/followers/styles.module.scss b/app/javascript/mastodon/features/followers/styles.module.scss new file mode 100644 index 0000000000..f58b345bec --- /dev/null +++ b/app/javascript/mastodon/features/followers/styles.module.scss @@ -0,0 +1,11 @@ +.title { + font-size: 20px; + font-weight: 600; + margin: 20px 16px 10px; +} + +.subtitle { + font-size: 14px; + color: var(--color-text-secondary); + margin: 10px 16px; +} diff --git a/app/javascript/mastodon/features/following/index.tsx b/app/javascript/mastodon/features/following/index.tsx index 85894c18af..6bc7abda69 100644 --- a/app/javascript/mastodon/features/following/index.tsx +++ b/app/javascript/mastodon/features/following/index.tsx @@ -1,7 +1,7 @@ import { useEffect } from 'react'; import type { FC } from 'react'; -import { FormattedMessage } from 'react-intl'; +import { defineMessage, FormattedMessage } from 'react-intl'; import { useDebouncedCallback } from 'use-debounce'; @@ -14,10 +14,16 @@ import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import type { EmptyMessageProps } from '../followers/components/empty'; import { BaseEmptyMessage } from '../followers/components/empty'; +import { AccountListHeader } from '../followers/components/header'; import { AccountList } from '../followers/components/list'; import { RemoteHint } from './components/remote'; +const titleText = defineMessage({ + id: 'following.title', + defaultMessage: 'Followed by {name}', +}); + const Followers: FC = () => { const accountId = useAccountId(); const account = useAccount(accountId); @@ -69,6 +75,15 @@ const Followers: FC = () => { accountId={accountId} append={domain && } emptyMessage={} + header={ + accountId && ( + + ) + } footer={footer} list={followingList} loadMore={loadMore} diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index c33e48dcdd..948b0f5110 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -234,6 +234,7 @@ "account_edit_tags.search_placeholder": "Enter a hashtag…", "account_edit_tags.suggestions": "Suggestions:", "account_edit_tags.tag_status_count": "{count, plural, one {# post} other {# posts}}", + "account_list.total": "{total, plural, one {# account} other {# accounts}}", "account_note.placeholder": "Click to add note", "admin.dashboard.daily_retention": "User retention rate by day after sign-up", "admin.dashboard.monthly_retention": "User retention rate by month after sign-up", @@ -674,7 +675,9 @@ "follow_suggestions.who_to_follow": "Who to follow", "followed_tags": "Followed hashtags", "followers.hide_other_followers": "This user has chosen to not make their other followers visible", + "followers.title": "Following {name}", "following.hide_other_following": "This user has chosen to not make the rest of who they follow visible", + "following.title": "Followed by {name}", "footer.about": "About", "footer.about_mastodon": "About Mastodon", "footer.about_server": "About {domain}",