Redesign: Update profile buttons & list wording (#40638)

This commit is contained in:
diondiondion
2026-09-22 09:06:41 +00:00
committed by GitHub
parent c30230fe88
commit 2545647820
9 changed files with 166 additions and 72 deletions

View File

@@ -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 && (
<IconButton
icon={relationship.notifying ? 'bell' : 'bell-o'}
iconComponent={
relationship.notifying ? NotificationsActiveIcon : NotificationsIcon
}
active={relationship.notifying}
title={intl.formatMessage(
relationship.notifying
? messages.disableNotifications
: messages.enableNotifications,
{ name: account.username },
)}
onClick={handleNotifyToggle}
/>
)}
{isFollowing &&
(isRedesignEnabled() ? (
<ToggleIconButton
size='sm'
icon={relationship.notifying ? BellSlashIcon : BellIcon}
active={relationship.notifying}
onClick={handleNotifyToggle}
title={intl.formatMessage(
relationship.notifying
? messages.disableNotifications
: messages.enableNotifications,
{ name: account.username },
)}
>
{intl.formatMessage(messages.enableNotifications, {
name: account.username,
})}
</ToggleIconButton>
) : (
<LegacyIconButton
icon={relationship.notifying ? 'bell' : 'bell-o'}
iconComponent={
relationship.notifying
? NotificationsActiveIcon
: NotificationsIcon
}
active={relationship.notifying}
title={intl.formatMessage(
relationship.notifying
? messages.disableNotifications
: messages.enableNotifications,
{ name: account.username },
)}
onClick={handleNotifyToggle}
/>
))}
{!noShare &&
('share' in navigator ? (
<IconButton
<LegacyIconButton
className='optional'
icon=''
iconComponent={ShareIcon}

View File

@@ -1,7 +1,9 @@
import { useMemo } from 'react';
import type { FC } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { DotsThreeIcon } from '@phosphor-icons/react';
import {
followAccount,
@@ -21,6 +23,13 @@ import {
import { openModal } from '@/mastodon/actions/modal';
import { initMuteModal } from '@/mastodon/actions/mutes';
import { initReport } from '@/mastodon/actions/reports';
import { IconButton } from '@/mastodon/components/button/redesign';
import {
Menu,
MenuList,
MenuTrigger,
LegacyDropdownMenuItems,
} from '@/mastodon/components/menu';
import {
canAccountBeAdded,
canAccountBeAddedByFollowers,
@@ -28,7 +37,7 @@ import {
import { useAccount } from '@/mastodon/hooks/useAccount';
import { useIdentity } from '@/mastodon/identity_context';
import type { Account } from '@/mastodon/models/account';
import type { MenuItem } from '@/mastodon/models/dropdown_menu';
import type { MenuItem as DropdownMenuItem } from '@/mastodon/models/dropdown_menu';
import type { Relationship } from '@/mastodon/models/relationship';
import {
PERMISSION_MANAGE_FEDERATION,
@@ -76,15 +85,37 @@ export const AccountMenu: FC<{ accountId: string }> = ({ accountId }) => {
dispatch,
});
}, [account, signedIn, isMe, permissions, intl, relationship, dispatch]);
return (
<Dropdown
disabled={menuItems.length === 0}
items={menuItems}
icon='ellipsis-v'
iconComponent={MoreHorizIcon}
className={classes.buttonMenu}
/>
);
if (isRedesignEnabled()) {
return (
<Menu>
<MenuTrigger
as={IconButton}
size='sm'
icon={DotsThreeIcon}
disabled={menuItems.length === 0}
>
<FormattedMessage
id='account.menu.label'
defaultMessage='More account options'
/>
</MenuTrigger>
<MenuList>
<LegacyDropdownMenuItems items={menuItems} />
</MenuList>
</Menu>
);
} else {
return (
<Dropdown
disabled={menuItems.length === 0}
items={menuItems}
icon='ellipsis-v'
iconComponent={MoreHorizIcon}
className={classes.buttonMenu}
/>
);
}
};
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({

View File

@@ -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);

View File

@@ -25,6 +25,7 @@ export {
MenuItemRadio,
MenuItemCheckbox,
} from './items';
export { LegacyDropdownMenuItems } from './legacy_dropdown_items';
interface PopoverState {
isMenuOpen: boolean;

View File

@@ -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 <MenuItemDivider key={`divider-${index}`} />;
}
const commonProps = {
destructive: item.dangerous,
disabled: item.disabled,
description: item.description,
icon: item.icon,
} as const;
if ('action' in item) {
return (
<MenuItem key={item.text} onClick={item.action} {...commonProps}>
{item.text}
</MenuItem>
);
}
if ('to' in item) {
return (
<MenuItemLink key={item.text} to={item.to} {...commonProps}>
{item.text}
</MenuItemLink>
);
}
if ('href' in item) {
return (
<MenuItemLink as='a' key={item.text} href={item.href} {...commonProps}>
{item.text}
</MenuItemLink>
);
}
return null;
});
};

View File

@@ -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<{
</MenuTrigger>
<MenuList placement='top-end'>
{menu.map((item, index) => (
<StatusActionItem key={index} item={item} />
))}
<LegacyDropdownMenuItems items={menu} />
</MenuList>
</Menu>
);
};
export const StatusActionItem: React.FC<{ item: DropdownItem }> = ({
item,
}) => {
if (!item) {
return <MenuItemDivider />;
}
const commonProps = {
icon: item.icon,
disabled: item.disabled,
destructive: item.dangerous,
children: item.text,
description: item.description,
} as const;
if ('to' in item) {
return <MenuItemLink {...commonProps} to={item.to} as='link' />;
} else if ('href' in item) {
return <MenuItemLink {...commonProps} href={item.href} as='a' />;
}
return <MenuItem {...commonProps} onClick={item.action} />;
};

View File

@@ -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,
)}
/>
</label>
@@ -184,11 +191,19 @@ const ListAdder: React.FC<{
/>
<NavigationFocusTarget as='h1' className='dialog-modal__header__title'>
<FormattedMessage
id='lists.add_to_lists'
defaultMessage='Add {name} to lists'
values={{ name: <strong>@{account?.acct}</strong> }}
/>
{isRedesignEnabled() ? (
<FormattedMessage
id='custom_feeds.add_to_feeds'
defaultMessage='Add {name} to custom feeds'
values={{ name: <strong>@{account?.acct}</strong> }}
/>
) : (
<FormattedMessage
id='lists.add_to_lists'
defaultMessage='Add {name} to lists'
values={{ name: <strong>@{account?.acct}</strong> }}
/>
)}
</NavigationFocusTarget>
</div>

View File

@@ -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) => (
<StatusActionItem key={index} item={item} />
));
return <LegacyDropdownMenuItems items={menu} />;
};
const StatusRelativeList: React.FC<{

View File

@@ -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",