Profile redesign: Badges (#37550)
This commit is contained in:
parent
400c1f3e8e
commit
22ec368574
10
app/javascript/images/icons/icon_admin.svg
Normal file
10
app/javascript/images/icons/icon_admin.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path fill="url(#badgeGradient)" d="M8 .666c.301 0 .595.094.839.268l.101.079.006.005c1.092.956 2.603 1.649 3.721 1.649A1.333 1.333 0 0 1 14 4v4.667c0 1.842-.652 3.259-1.702 4.336-1.032 1.058-2.417 1.76-3.852 2.26l-.005.002a1.334 1.334 0 0 1-.879-.01c-1.437-.496-2.825-1.195-3.858-2.253C2.654 11.926 2 10.509 2 8.667V4a1.334 1.334 0 0 1 1.334-1.333c1.118 0 2.634-.7 3.72-1.65l.007-.004C7.322.789 7.656.666 8 .666Z"/>
|
||||
<path stroke="#fff" fill="none" stroke-linecap="round" stroke-linejoin="round" d="M5 10.998A3.053 3.053 0 0 1 6.173 9.57a3.333 3.333 0 0 1 1.828-.54m0 0c.653 0 1.29.189 1.826.54.537.353.946.852 1.173 1.43M8 9.03c1.179 0 2.133-.903 2.133-2.015C10.133 5.902 9.178 5 8 5c-1.179 0-2.134.902-2.134 2.015 0 1.112.956 2.015 2.135 2.015Z"/>
|
||||
<defs>
|
||||
<linearGradient id="badgeGradient" x1=".5" x2="14" y1="2.5" y2="15" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E17100"/>
|
||||
<stop offset="1" stop-color="#F0B100"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@ -1,31 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import GroupsIcon from '@/material-icons/400-24px/group.svg?react';
|
||||
import PersonIcon from '@/material-icons/400-24px/person.svg?react';
|
||||
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
||||
|
||||
|
||||
export const Badge = ({ icon = <PersonIcon />, label, domain, roleId }) => (
|
||||
<div className='account-role' data-account-role-id={roleId}>
|
||||
{icon}
|
||||
{label}
|
||||
{domain && <span className='account-role__domain'>{domain}</span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
Badge.propTypes = {
|
||||
icon: PropTypes.node,
|
||||
label: PropTypes.node,
|
||||
domain: PropTypes.node,
|
||||
roleId: PropTypes.string
|
||||
};
|
||||
|
||||
export const GroupBadge = () => (
|
||||
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
|
||||
);
|
||||
|
||||
export const AutomatedBadge = () => (
|
||||
<Badge icon={<SmartToyIcon />} label={<FormattedMessage id='account.badges.bot' defaultMessage='Automated' />} />
|
||||
);
|
||||
46
app/javascript/mastodon/components/badge.tsx
Normal file
46
app/javascript/mastodon/components/badge.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import type { FC, ReactNode } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import GroupsIcon from '@/material-icons/400-24px/group.svg?react';
|
||||
import PersonIcon from '@/material-icons/400-24px/person.svg?react';
|
||||
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
||||
|
||||
export const Badge: FC<{
|
||||
label: ReactNode;
|
||||
icon?: ReactNode;
|
||||
className?: string;
|
||||
domain?: ReactNode;
|
||||
roleId?: string;
|
||||
}> = ({ icon = <PersonIcon />, label, className, domain, roleId }) => (
|
||||
<div
|
||||
className={classNames('account-role', className)}
|
||||
data-account-role-id={roleId}
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
{domain && <span className='account-role__domain'>{domain}</span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
export const GroupBadge: FC<{ className?: string }> = ({ className }) => (
|
||||
<Badge
|
||||
icon={<GroupsIcon />}
|
||||
label={
|
||||
<FormattedMessage id='account.badges.group' defaultMessage='Group' />
|
||||
}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
|
||||
export const AutomatedBadge: FC<{ className?: string }> = ({ className }) => (
|
||||
<Badge
|
||||
icon={<SmartToyIcon />}
|
||||
label={
|
||||
<FormattedMessage id='account.badges.bot' defaultMessage='Automated' />
|
||||
}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
@ -1,9 +1,16 @@
|
||||
import type { FC } from 'react';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
|
||||
import IconAdmin from '@/images/icons/icon_admin.svg?react';
|
||||
import { AutomatedBadge, Badge, GroupBadge } from '@/mastodon/components/badge';
|
||||
import { Icon } from '@/mastodon/components/icon';
|
||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||
import type { AccountRole } from '@/mastodon/models/account';
|
||||
import { useAppSelector } from '@/mastodon/store';
|
||||
|
||||
import { isRedesignEnabled } from '../common';
|
||||
|
||||
import classes from './redesign.module.scss';
|
||||
|
||||
export const AccountBadges: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
const account = useAccount(accountId);
|
||||
const localDomain = useAppSelector(
|
||||
@ -15,22 +22,32 @@ export const AccountBadges: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const className = isRedesignEnabled() ? classes.badge : '';
|
||||
|
||||
if (account.bot) {
|
||||
badges.push(<AutomatedBadge key='bot-badge' />);
|
||||
badges.push(<AutomatedBadge key='bot-badge' className={className} />);
|
||||
} else if (account.group) {
|
||||
badges.push(<GroupBadge key='group-badge' />);
|
||||
badges.push(<GroupBadge key='group-badge' className={className} />);
|
||||
}
|
||||
|
||||
const domain = account.acct.includes('@')
|
||||
? account.acct.split('@')[1]
|
||||
: localDomain;
|
||||
account.roles.forEach((role) => {
|
||||
let icon: ReactNode = undefined;
|
||||
if (isAdminBadge(role)) {
|
||||
icon = (
|
||||
<Icon icon={IconAdmin} id='badge-admin' className={classes.badgeIcon} />
|
||||
);
|
||||
}
|
||||
badges.push(
|
||||
<Badge
|
||||
key={`role-badge-${role.get('id')}`}
|
||||
label={<span>{role.get('name')}</span>}
|
||||
domain={domain}
|
||||
roleId={role.get('id')}
|
||||
key={role.id}
|
||||
label={role.name}
|
||||
className={className}
|
||||
domain={isRedesignEnabled() ? `(${domain})` : domain}
|
||||
roleId={role.id}
|
||||
icon={icon}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
@ -39,5 +56,10 @@ export const AccountBadges: FC<{ accountId: string }> = ({ accountId }) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <div className='account__header__badges'>{badges}</div>;
|
||||
return <div className={'account__header__badges'}>{badges}</div>;
|
||||
};
|
||||
|
||||
function isAdminBadge(role: AccountRole) {
|
||||
const name = role.name.toLowerCase();
|
||||
return isRedesignEnabled() && (name === 'admin' || name === 'owner');
|
||||
}
|
||||
|
||||
@ -39,6 +39,27 @@ h1.name > small {
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: none;
|
||||
color: var(--color-text-secondary);
|
||||
font-weight: 600;
|
||||
|
||||
> span {
|
||||
font-weight: unset;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
svg.badgeIcon {
|
||||
opacity: 1;
|
||||
fill: revert-layer;
|
||||
|
||||
path {
|
||||
fill: revert-layer;
|
||||
}
|
||||
}
|
||||
|
||||
.fieldList {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user