Profile redesign: Handle + tab changes (#38579)

This commit is contained in:
Echo 2026-04-07 13:21:39 +02:00 committed by GitHub
parent 9fdc8246f2
commit ed6ceda71d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 91 additions and 38 deletions

View File

@ -8,13 +8,16 @@ import classNames from 'classnames';
import Overlay from 'react-overlays/esm/Overlay';
import FollowerIcon from '@/images/icons/icon_follower.svg?react';
import { showAlert } from '@/mastodon/actions/alerts';
import { Badge } from '@/mastodon/components/badge';
import { Button } from '@/mastodon/components/button';
import { DisplayName } from '@/mastodon/components/display_name';
import { Icon } from '@/mastodon/components/icon';
import { useAccount } from '@/mastodon/hooks/useAccount';
import { useRelationship } from '@/mastodon/hooks/useRelationship';
import { useAppSelector } from '@/mastodon/store';
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
import AtIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import ContentCopyIcon from '@/material-icons/400-24px/content_copy.svg?react';
import HelpIcon from '@/material-icons/400-24px/help.svg?react';
import DomainIcon from '@/material-icons/400-24px/language.svg?react';
@ -30,6 +33,10 @@ const messages = defineMessages({
id: 'account.name_info',
defaultMessage: 'What does this mean?',
},
copied: {
id: 'copy_icon_button.copied',
defaultMessage: 'Copied to clipboard',
},
});
export const AccountName: FC<{ accountId: string }> = ({ accountId }) => {
@ -64,14 +71,12 @@ export const AccountName: FC<{ accountId: string }> = ({ accountId }) => {
/>
)}
</div>
<p className={classes.username}>
@{username}@{domain}
<AccountNameHelp
username={username}
domain={domain}
isSelf={account.id === me}
/>
</p>
<AccountNameHelp
username={username}
domain={domain}
isSelf={account.id === me}
/>
</div>
);
};
@ -90,6 +95,19 @@ const AccountNameHelp: FC<{
setOpen((prev) => !prev);
}, []);
const handle = `@${username}@${domain}`;
const dispatch = useAppDispatch();
const [copied, setCopied] = useState(false);
const handleCopy = useCallback(() => {
void navigator.clipboard.writeText(handle);
setCopied(true);
dispatch(showAlert({ message: messages.copied }));
setTimeout(() => {
setCopied(false);
}, 700);
}, [handle, dispatch]);
return (
<>
<button
@ -100,6 +118,8 @@ const AccountNameHelp: FC<{
aria-expanded={open}
aria-controls={accessibilityId}
>
{handle}
<Icon
id='help'
icon={HelpIcon}
@ -169,6 +189,22 @@ const AccountNameHelp: FC<{
defaultMessage='Just like you can send emails to people using different email clients, you can interact with people on other Mastodon servers and with anyone on other social apps powered by the same set of rules as Mastodon uses (the ActivityPub protocol).'
tagName='p'
/>
<Button onClick={handleCopy} className={classes.handleCopy}>
<Icon id='copy' icon={ContentCopyIcon} />
{!copied && (
<FormattedMessage
id='account.name.copy'
defaultMessage='Copy handle'
/>
)}
{copied && (
<FormattedMessage
id='copypaste.copied'
defaultMessage='Copied'
/>
)}
</Button>
</div>
)}
</Overlay>

View File

@ -43,30 +43,22 @@
color: var(--color-text-secondary);
}
.username {
display: flex;
font-size: 13px;
color: var(--color-text-secondary);
align-items: center;
user-select: all;
margin-top: 4px;
}
.handleHelpButton {
appearance: none;
border: none;
background: none;
display: flex;
gap: 2px;
padding: 0;
color: inherit;
font-size: 1em;
margin-left: 2px;
width: 16px;
height: 16px;
margin-top: 4px;
align-items: center;
appearance: none;
background: none;
border: none;
color: var(--color-text-secondary);
font-size: 13px;
transition: color 0.2s ease-in-out;
> svg {
width: 100%;
height: 100%;
width: 16px;
height: 16px;
}
&:hover,
@ -84,6 +76,10 @@
max-width: 400px;
box-sizing: border-box;
[data-color-scheme='dark'] & {
border: 1px solid var(--color-border-primary);
}
> h3 {
font-size: 17px;
font-weight: 600;
@ -101,15 +97,15 @@
&:first-child {
margin-bottom: 12px;
}
}
svg {
background: var(--color-bg-brand-softest);
width: 28px;
height: 28px;
padding: 5px;
border-radius: 9999px;
box-sizing: border-box;
> svg {
background: var(--color-bg-brand-softest);
width: 28px;
height: 28px;
padding: 5px;
border-radius: 9999px;
box-sizing: border-box;
}
}
strong {
@ -132,6 +128,26 @@ $button-fallback-breakpoint: $button-breakpoint + 55px;
}
}
.handleCopy {
border: 1px solid var(--color-border-primary);
border-radius: 8px;
box-sizing: border-box;
padding: 4px 8px;
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
font-size: 13px;
transition:
color 0.2s ease-in-out,
background-color 0.2s ease-in-out;
margin-top: 12px;
&:active,
&:focus,
&:hover {
background-color: var(--color-bg-brand-softest);
}
}
.buttonsMobile {
position: sticky;
bottom: var(--mobile-bottom-nav-height);
@ -336,7 +352,7 @@ $button-fallback-breakpoint: $button-breakpoint + 55px;
.tabs {
display: flex;
gap: 12px;
gap: 16px;
padding: 0 16px;
@container (width < 500px) {
@ -350,7 +366,7 @@ $button-fallback-breakpoint: $button-breakpoint + 55px;
display: block;
font-size: 15px;
font-weight: 500;
padding: 18px 4px;
padding: 18px 0;
text-decoration: none;
color: var(--color-text-primary);
border-radius: 0;

View File

@ -102,6 +102,7 @@
"account.muted": "Muted",
"account.muting": "Muting",
"account.mutual": "You follow each other",
"account.name.copy": "Copy handle",
"account.name.help.domain": "{domain} is the server that hosts the users profile and posts.",
"account.name.help.domain_self": "{domain} is your server that hosts your profile and posts.",
"account.name.help.footer": "Just like you can send emails to people using different email clients, you can interact with people on other Mastodon servers and with anyone on other social apps powered by the same set of rules as Mastodon uses (the ActivityPub protocol).",