From 2545647820bbe7319e3e647a4e4a254499117009 Mon Sep 17 00:00:00 2001 From: diondiondion Date: Tue, 22 Sep 2026 09:06:41 +0000 Subject: [PATCH] Redesign: Update profile buttons & list wording (#40638) --- .../components/account_header/buttons.tsx | 59 ++++++++++++----- .../components/account_header/menu.tsx | 65 +++++++++++++++---- .../bottom_sheet/styles.module.scss | 1 + .../mastodon/components/menu/index.tsx | 1 + .../components/menu/legacy_dropdown_items.tsx | 43 ++++++++++++ .../mastodon/components/status/action_bar.tsx | 32 +-------- .../mastodon/features/list_adder/index.tsx | 27 ++++++-- .../mastodon/features/status/redesign.tsx | 6 +- app/javascript/mastodon/locales/en.json | 4 ++ 9 files changed, 166 insertions(+), 72 deletions(-) create mode 100644 app/javascript/mastodon/components/menu/legacy_dropdown_items.tsx diff --git a/app/javascript/mastodon/components/account_header/buttons.tsx b/app/javascript/mastodon/components/account_header/buttons.tsx index ab924cf6d59..6fbcff59c10 100644 --- a/app/javascript/mastodon/components/account_header/buttons.tsx +++ b/app/javascript/mastodon/components/account_header/buttons.tsx @@ -3,6 +3,8 @@ import type { FC } from 'react'; import { defineMessages, useIntl } from 'react-intl'; +import { BellIcon, BellSlashIcon } from '@phosphor-icons/react'; + import { followAccount } from '@/mastodon/actions/accounts'; import { useAccount } from '@/mastodon/hooks/useAccount'; import { useFollowReference } from '@/mastodon/hooks/useFollowReference'; @@ -13,9 +15,10 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react'; import ShareIcon from '@/material-icons/400-24px/share.svg?react'; +import { ToggleIconButton } from '../button/redesign'; import { CopyIconButton } from '../copy_button'; import { FollowButton } from '../follow_button'; -import { IconButton } from '../icon_button'; +import { IconButton as LegacyIconButton } from '../icon_button'; import { AccountMenu } from './menu'; import classes from './styles.module.scss'; @@ -104,25 +107,45 @@ const AccountButtonsOther: FC< reference={reference} /> )} - {isFollowing && ( - - )} + {isFollowing && + (isRedesignEnabled() ? ( + + {intl.formatMessage(messages.enableNotifications, { + name: account.username, + })} + + ) : ( + + ))} {!noShare && ('share' in navigator ? ( - = ({ accountId }) => { dispatch, }); }, [account, signedIn, isMe, permissions, intl, relationship, dispatch]); - return ( - - ); + + if (isRedesignEnabled()) { + return ( + + + + + + + + + ); + } else { + return ( + + ); + } }; interface MenuItemsParams { @@ -149,6 +180,10 @@ const messages = defineMessages({ id: 'account.menu.add_to_list', defaultMessage: 'Add to list…', }, + addToCustomFeed: { + id: 'account.menu.add_to_feed', + defaultMessage: 'Add to custom feed…', + }, addToCollection: { id: 'account.menu.add_to_collection', defaultMessage: 'Add to collection…', @@ -212,8 +247,8 @@ function getMenuItems({ intl, relationship, dispatch, -}: MenuItemsParams): MenuItem[] { - const items: MenuItem[] = []; +}: MenuItemsParams): DropdownMenuItem[] { + const items: DropdownMenuItem[] = []; const isRemote = account.acct !== account.username; const remoteDomain = isRemote ? account.acct.split('@')[1] : null; @@ -291,7 +326,9 @@ function getMenuItems({ // Add to list if (relationship?.following) { items.push({ - text: intl.formatMessage(messages.addToList), + text: intl.formatMessage( + isRedesignEnabled() ? messages.addToCustomFeed : messages.addToList, + ), action: () => { dispatch( openModal({ diff --git a/app/javascript/mastodon/components/bottom_sheet/styles.module.scss b/app/javascript/mastodon/components/bottom_sheet/styles.module.scss index e02423f10d3..78f46883122 100644 --- a/app/javascript/mastodon/components/bottom_sheet/styles.module.scss +++ b/app/javascript/mastodon/components/bottom_sheet/styles.module.scss @@ -42,6 +42,7 @@ } .sheet { + margin-top: var(--space-10); padding: var(--space-4); border-radius: var(--radius-5) var(--radius-5) 0 0; background: var(--color-bg-primary); diff --git a/app/javascript/mastodon/components/menu/index.tsx b/app/javascript/mastodon/components/menu/index.tsx index d32870ea521..15e1d45aeef 100644 --- a/app/javascript/mastodon/components/menu/index.tsx +++ b/app/javascript/mastodon/components/menu/index.tsx @@ -25,6 +25,7 @@ export { MenuItemRadio, MenuItemCheckbox, } from './items'; +export { LegacyDropdownMenuItems } from './legacy_dropdown_items'; interface PopoverState { isMenuOpen: boolean; diff --git a/app/javascript/mastodon/components/menu/legacy_dropdown_items.tsx b/app/javascript/mastodon/components/menu/legacy_dropdown_items.tsx new file mode 100644 index 00000000000..5ecc1207687 --- /dev/null +++ b/app/javascript/mastodon/components/menu/legacy_dropdown_items.tsx @@ -0,0 +1,43 @@ +import type { MenuItem as LegacyDropdownMenuItem } from '@/mastodon/models/dropdown_menu'; + +import { MenuItem, MenuItemLink, MenuItemDivider } from './items'; + +export const LegacyDropdownMenuItems: React.FC<{ + items: LegacyDropdownMenuItem[]; +}> = ({ items }) => { + return items.map((item, index) => { + if (item === null) { + return ; + } + + const commonProps = { + destructive: item.dangerous, + disabled: item.disabled, + description: item.description, + icon: item.icon, + } as const; + + if ('action' in item) { + return ( + + {item.text} + + ); + } + if ('to' in item) { + return ( + + {item.text} + + ); + } + if ('href' in item) { + return ( + + {item.text} + + ); + } + return null; + }); +}; diff --git a/app/javascript/mastodon/components/status/action_bar.tsx b/app/javascript/mastodon/components/status/action_bar.tsx index 55df6f674c2..d3ca0e95e61 100644 --- a/app/javascript/mastodon/components/status/action_bar.tsx +++ b/app/javascript/mastodon/components/status/action_bar.tsx @@ -19,7 +19,6 @@ import { fetchStatus } from '@/mastodon/actions/statuses'; import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId'; import { useAccountStatus } from '@/mastodon/hooks/useStatus'; import { quickBoosting } from '@/mastodon/initial_state'; -import type { MenuItem as DropdownItem } from '@/mastodon/models/dropdown_menu'; import type { AccountStatusShape } from '@/mastodon/models/status'; import { selectStatusConditions } from '@/mastodon/selectors/statuses'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; @@ -34,10 +33,9 @@ import { iconWeight, useIconWeight } from '../icon'; import { Menu, MenuItem, - MenuItemDivider, - MenuItemLink, MenuList, MenuTrigger, + LegacyDropdownMenuItems, } from '../menu'; import { boostItemState, quoteItemState } from './boost_button_utils'; @@ -316,34 +314,8 @@ const StatusActionMenu: React.FC<{ - {menu.map((item, index) => ( - - ))} + ); }; - -export const StatusActionItem: React.FC<{ item: DropdownItem }> = ({ - item, -}) => { - if (!item) { - return ; - } - - const commonProps = { - icon: item.icon, - disabled: item.disabled, - destructive: item.dangerous, - children: item.text, - description: item.description, - } as const; - - if ('to' in item) { - return ; - } else if ('href' in item) { - return ; - } - - return ; -}; diff --git a/app/javascript/mastodon/features/list_adder/index.tsx b/app/javascript/mastodon/features/list_adder/index.tsx index fa549ddbe97..301ebb761c7 100644 --- a/app/javascript/mastodon/features/list_adder/index.tsx +++ b/app/javascript/mastodon/features/list_adder/index.tsx @@ -5,6 +5,7 @@ import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; import { isFulfilled } from '@reduxjs/toolkit'; import { Toggle } from '@/mastodon/components/form_fields'; +import { isRedesignEnabled } from '@/mastodon/utils/environment'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import { fetchLists } from 'mastodon/actions/lists'; @@ -27,6 +28,10 @@ const messages = defineMessages({ id: 'lists.new_list_name', defaultMessage: 'New list name', }, + newFeed: { + id: 'custom_feeds.new_feed_name', + defaultMessage: 'New feed name', + }, createList: { id: 'lists.create', defaultMessage: 'Create', @@ -104,7 +109,9 @@ const NewListItem: React.FC<{ onChange={handleChange} maxLength={30} required - placeholder={intl.formatMessage(messages.newList)} + placeholder={intl.formatMessage( + isRedesignEnabled() ? messages.newFeed : messages.newList, + )} /> @@ -184,11 +191,19 @@ const ListAdder: React.FC<{ /> - @{account?.acct} }} - /> + {isRedesignEnabled() ? ( + @{account?.acct} }} + /> + ) : ( + @{account?.acct} }} + /> + )} diff --git a/app/javascript/mastodon/features/status/redesign.tsx b/app/javascript/mastodon/features/status/redesign.tsx index c07ddba14a1..e5b1adf3691 100644 --- a/app/javascript/mastodon/features/status/redesign.tsx +++ b/app/javascript/mastodon/features/status/redesign.tsx @@ -19,11 +19,11 @@ import { import { DisplayNameSimple } from '@/mastodon/components/display_name/simple'; import { useIconWeight } from '@/mastodon/components/icon'; import { LoadingIndicator } from '@/mastodon/components/loading_indicator'; +import { LegacyDropdownMenuItems } from '@/mastodon/components/menu'; import { FOCUS_TARGET, NavigationFocusTarget, } from '@/mastodon/components/navigation_focus_target'; -import { StatusActionItem } from '@/mastodon/components/status/action_bar'; import { useStatusMenuActions, useTextForScreenReader, @@ -301,9 +301,7 @@ const StatusMenuItems: React.FC<{ status: ExpandedStatusShape }> = ({ }) => { const menu = useStatusMenuActions({ status, contextType: 'detailed' }); - return menu.map((item, index) => ( - - )); + return ; }; const StatusRelativeList: React.FC<{ diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 22a9bb277c8..b120c64dc3f 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -85,6 +85,7 @@ "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", "account.menu.add_to_collection": "Add to collection…", + "account.menu.add_to_feed": "Add to custom feed…", "account.menu.add_to_list": "Add to list…", "account.menu.block": "Block account", "account.menu.block_domain": "Block {domain}", @@ -92,6 +93,7 @@ "account.menu.copy": "Copy link", "account.menu.direct": "Privately mention", "account.menu.hide_reblogs": "Hide boosts in timeline", + "account.menu.label": "More account options", "account.menu.mention": "Mention", "account.menu.message": "Message", "account.menu.mute": "Mute account", @@ -695,12 +697,14 @@ "custom_feed.manage_accounts": "Manage members", "custom_feed.options": "Feed Options", "custom_feeds.add_to_feed": "Add to feed", + "custom_feeds.add_to_feeds": "Add {name} to custom feeds", "custom_feeds.create": "Create", "custom_feeds.create_a_list_to_organize": "Create a new custom feed to organize your Following feed.", "custom_feeds.exclusive_hint": "If someone is in this custom feed, hide them in your Home feed to avoid seeing their posts twice.", "custom_feeds.feed_name": "Feed name", "custom_feeds.manage_accounts": "Manage feed members", "custom_feeds.manage_accounts_title": "Manage Feed Members", + "custom_feeds.new_feed_name": "New feed name", "custom_feeds.no_custom_feeds_yet": "No custom feeds yet.", "custom_feeds.replies_policy.members": "Members of the feed", "custom_feeds.show_replies_to": "Include replies from feed members to",