From d6c0b93c859febbb88332276d8fa40b9297efbea Mon Sep 17 00:00:00 2001 From: diondiondion Date: Thu, 9 Apr 2026 17:31:49 +0200 Subject: [PATCH] Change "My collections" path to `/@username/collections` (#38630) --- .../mastodon/components/column_header.tsx | 2 +- .../mastodon/features/collections/index.tsx | 63 +++++++++++++------ .../features/navigation_panel/index.tsx | 4 +- .../confirmation_modals/delete_collection.tsx | 7 ++- app/javascript/mastodon/features/ui/index.jsx | 14 ++--- app/javascript/mastodon/locales/en.json | 3 +- .../mastodon/reducers/slices/collections.ts | 2 +- config/routes.rb | 1 + 8 files changed, 63 insertions(+), 33 deletions(-) diff --git a/app/javascript/mastodon/components/column_header.tsx b/app/javascript/mastodon/components/column_header.tsx index 49c2bb1d4a..b8ab2bbe54 100644 --- a/app/javascript/mastodon/components/column_header.tsx +++ b/app/javascript/mastodon/components/column_header.tsx @@ -73,7 +73,7 @@ const BackButton: React.FC<{ }; export interface Props { - title?: string; + title?: React.ReactNode; icon?: string; iconComponent?: IconProp; active?: boolean; diff --git a/app/javascript/mastodon/features/collections/index.tsx b/app/javascript/mastodon/features/collections/index.tsx index 57258d6ff4..200a58620a 100644 --- a/app/javascript/mastodon/features/collections/index.tsx +++ b/app/javascript/mastodon/features/collections/index.tsx @@ -10,11 +10,14 @@ import CollectionsFilledIcon from '@/material-icons/400-24px/category-fill.svg?r import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react'; import { Column } from 'mastodon/components/column'; import { ColumnHeader } from 'mastodon/components/column_header'; +import { DisplayNameSimple } from 'mastodon/components/display_name/simple'; import { Icon } from 'mastodon/components/icon'; import { ItemList, Scrollable, } from 'mastodon/components/scrollable_list/components'; +import { useAccount } from 'mastodon/hooks/useAccount'; +import { useAccountId, useCurrentAccountId } from 'mastodon/hooks/useAccountId'; import { fetchAccountCollections, selectAccountCollections, @@ -25,7 +28,11 @@ import { CollectionListItem } from './components/collection_list_item'; import { messages as editorMessages } from './editor'; const messages = defineMessages({ - heading: { id: 'column.collections', defaultMessage: 'My collections' }, + headingMe: { id: 'column.my_collections', defaultMessage: 'My collections' }, + headingOther: { + id: 'column.other_collections', + defaultMessage: 'Collections by {name}', + }, }); export const Collections: React.FC<{ @@ -33,17 +40,22 @@ export const Collections: React.FC<{ }> = ({ multiColumn }) => { const dispatch = useAppDispatch(); const intl = useIntl(); - const me = useAppSelector((state) => state.meta.get('me') as string); + const me = useCurrentAccountId(); + const accountId = useAccountId(); + const account = useAccount(accountId); + const { collections, status } = useAppSelector((state) => - selectAccountCollections(state, me), + selectAccountCollections(state, accountId), ); useEffect(() => { - void dispatch(fetchAccountCollections({ accountId: me })); - }, [dispatch, me]); + if (accountId) { + void dispatch(fetchAccountCollections({ accountId })); + } + }, [dispatch, accountId]); const emptyMessage = - status === 'error' ? ( + status === 'error' || !accountId ? ( ); + const isOwnCollection = accountId === me; + const titleMessage = isOwnCollection + ? messages.headingMe + : messages.headingOther; + + const pageTitle = intl.formatMessage(titleMessage, { + name: account?.get('display_name'), + }); + const pageTitleHtml = intl.formatMessage(titleMessage, { + name: , + }); + return ( - + - - + isOwnCollection && ( + + + + ) } /> @@ -105,7 +128,7 @@ export const Collections: React.FC<{ - {intl.formatMessage(messages.heading)} + {pageTitle} diff --git a/app/javascript/mastodon/features/navigation_panel/index.tsx b/app/javascript/mastodon/features/navigation_panel/index.tsx index 1c1e911a7b..33a2a43a70 100644 --- a/app/javascript/mastodon/features/navigation_panel/index.tsx +++ b/app/javascript/mastodon/features/navigation_panel/index.tsx @@ -10,6 +10,7 @@ import type { Map as ImmutableMap } from 'immutable'; import { animated, useSpring } from '@react-spring/web'; import { useDrag } from '@use-gesture/react'; +import { useAccount } from '@/mastodon/hooks/useAccount'; import AddIcon from '@/material-icons/400-24px/add.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import BookmarksActiveIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; @@ -212,6 +213,7 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ const { signedIn, permissions, disabledAccountId } = useIdentity(); const location = useLocation(); const showSearch = useBreakpoint('full') && !multiColumn; + const account = useAccount(me); let banner: React.ReactNode; @@ -335,7 +337,7 @@ export const NavigationPanel: React.FC<{ multiColumn?: boolean }> = ({ {areCollectionsEnabled() && ( { void dispatch(deleteCollection({ collectionId: id })); - history.push('/collections'); - }, [dispatch, history, id]); + history.push(`/@${currentUserName}/collections`); + }, [dispatch, history, id, currentUserName]); return ( + {areCollectionsEnabled() && + [ + , + , + , + ] + } @@ -255,13 +262,6 @@ class SwitchingColumnsArea extends PureComponent { - {areCollectionsEnabled() && - [ - , - , - - ] - } diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 7f715e9ee6..16a11e35ec 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -417,7 +417,6 @@ "column.about": "About", "column.blocks": "Blocked users", "column.bookmarks": "Bookmarks", - "column.collections": "My collections", "column.community": "Local timeline", "column.create_list": "Create list", "column.direct": "Private mentions", @@ -433,7 +432,9 @@ "column.list_members": "Manage list members", "column.lists": "Lists", "column.mutes": "Muted users", + "column.my_collections": "My collections", "column.notifications": "Notifications", + "column.other_collections": "Collections by {name}", "column.pins": "Pinned posts", "column.public": "Federated timeline", "column_back_button.label": "Back", diff --git a/app/javascript/mastodon/reducers/slices/collections.ts b/app/javascript/mastodon/reducers/slices/collections.ts index 47bbd5e6ba..1a8133be58 100644 --- a/app/javascript/mastodon/reducers/slices/collections.ts +++ b/app/javascript/mastodon/reducers/slices/collections.ts @@ -311,7 +311,7 @@ interface AccountCollectionQuery { export const selectAccountCollections = createAppSelector( [ - (_, accountId: string | null) => accountId, + (_, accountId?: string | null) => accountId, (state) => state.collections.accountCollections, (state) => state.collections.collections, ], diff --git a/config/routes.rb b/config/routes.rb index e2b18cc48c..ba0c308d29 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -158,6 +158,7 @@ Rails.application.routes.draw do with_options to: 'accounts#show' do get '/@:username', as: :short_account get '/@:username/featured' + get '/@:username/collections' get '/@:username/with_replies', as: :short_account_with_replies get '/@:username/media', as: :short_account_media get '/@:username/tagged/:tag', as: :short_account_tag