Merge pull request #2566 from ClearlyClaire/glitch-soc/ports/badge-design

Port upstream's role badge design
pull/2569/head
Claire 2024-01-13 14:25:55 +01:00 committed by GitHub
commit 5f8618443c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 40 deletions

View File

@ -0,0 +1,34 @@
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { ReactComponent as GroupsIcon } from '@material-symbols/svg-600/outlined/group.svg';
import { ReactComponent as PersonIcon } from '@material-symbols/svg-600/outlined/person.svg';
import { ReactComponent as SmartToyIcon } from '@material-symbols/svg-600/outlined/smart_toy.svg';
export const Badge = ({ icon, label, domain }) => (
<div className='account-role'>
{icon}
{label}
{domain && <span className='account-role__domain'>{domain}</span>}
</div>
);
Badge.propTypes = {
icon: PropTypes.node,
label: PropTypes.node,
domain: PropTypes.node,
};
Badge.defaultProps = {
icon: <PersonIcon />,
};
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' />} />
);

View File

@ -10,6 +10,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { Avatar } from 'flavours/glitch/components/avatar'; import { Avatar } from 'flavours/glitch/components/avatar';
import { Badge, AutomatedBadge, GroupBadge } from 'flavours/glitch/components/badge';
import { Button } from 'flavours/glitch/components/button'; import { Button } from 'flavours/glitch/components/button';
import { Icon } from 'flavours/glitch/components/icon'; import { Icon } from 'flavours/glitch/components/icon';
import { IconButton } from 'flavours/glitch/components/icon_button'; import { IconButton } from 'flavours/glitch/components/icon_button';
@ -308,20 +309,17 @@ class Header extends ImmutablePureComponent {
const acct = isLocal && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); const acct = isLocal && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
const isIndexable = !account.get('noindex'); const isIndexable = !account.get('noindex');
let badge; const badges = [];
if (account.get('bot')) { if (account.get('bot')) {
badge = (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Automated' /></div>); badges.push(<AutomatedBadge key='bot-badge' />);
} else if (account.get('group')) { } else if (account.get('group')) {
badge = (<div className='account-role group'><FormattedMessage id='account.badges.group' defaultMessage='Group' /></div>); badges.push(<GroupBadge key='group-badge' />);
} else {
badge = null;
} }
let role = null; account.get('roles', []).forEach((role) => {
if (account.getIn(['roles', 0])) { badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} />);
role = (<div key='role' className={`account-role user-role-${account.getIn(['roles', 0, 'id'])}`}>{account.getIn(['roles', 0, 'name'])}</div>); });
}
return ( return (
<div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> <div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
@ -339,7 +337,6 @@ class Header extends ImmutablePureComponent {
<div className='account__header__tabs'> <div className='account__header__tabs'>
<a className='avatar' href={account.get('avatar')} rel='noopener noreferrer' target='_blank' onClick={this.handleAvatarClick}> <a className='avatar' href={account.get('avatar')} rel='noopener noreferrer' target='_blank' onClick={this.handleAvatarClick}>
<Avatar account={suspended || hidden ? undefined : account} size={90} /> <Avatar account={suspended || hidden ? undefined : account} size={90} />
{role}
</a> </a>
<div className='account__header__tabs__buttons'> <div className='account__header__tabs__buttons'>
@ -356,13 +353,19 @@ class Header extends ImmutablePureComponent {
<div className='account__header__tabs__name'> <div className='account__header__tabs__name'>
<h1> <h1>
<span dangerouslySetInnerHTML={displayNameHtml} /> {badge} <span dangerouslySetInnerHTML={displayNameHtml} />
<small> <small>
<span>@{acct}</span> {lockedIcon} <span>@{acct}</span> {lockedIcon}
</small> </small>
</h1> </h1>
</div> </div>
{badges.length > 0 && (
<div className='account__header__badges'>
{badges}
</div>
)}
{signedIn && <AccountNoteContainer account={account} />} {signedIn && <AccountNoteContainer account={account} />}
{!(suspended || hidden) && ( {!(suspended || hidden) && (

View File

@ -191,7 +191,6 @@
} }
} }
.account-role,
.information-badge, .information-badge,
.simple_form .overridden, .simple_form .overridden,
.simple_form .recommended, .simple_form .recommended,
@ -200,24 +199,55 @@
display: inline-block; display: inline-block;
padding: 4px 6px; padding: 4px 6px;
cursor: default; cursor: default;
border-radius: 3px; border-radius: 4px;
font-size: 12px; font-size: 12px;
line-height: 12px; line-height: 12px;
font-weight: 500; font-weight: 500;
color: $ui-secondary-color; color: $ui-secondary-color;
background-color: var(--user-role-background, rgba($ui-secondary-color, 0.1)); text-overflow: ellipsis;
border: 1px solid var(--user-role-border, rgba($ui-secondary-color, 0.5)); white-space: nowrap;
overflow: hidden;
}
&.moderator { .information-badge,
color: $success-green; .simple_form .recommended,
background-color: rgba($success-green, 0.1); .simple_form .not_recommended {
border-color: rgba($success-green, 0.5); background-color: rgba($ui-secondary-color, 0.1);
border: 1px solid rgba($ui-secondary-color, 0.5);
}
.account-role {
display: inline-flex;
padding: 4px;
padding-inline-end: 8px;
border: 1px solid $highlight-text-color;
color: $highlight-text-color;
font-weight: 500;
font-size: 12px;
letter-spacing: 0.5px;
line-height: 16px;
gap: 4px;
border-radius: 6px;
align-items: center;
svg {
width: auto;
height: 15px;
opacity: 0.85;
fill: currentColor;
} }
&.admin { &__domain {
color: lighten($error-red, 12%); font-weight: 400;
background-color: rgba(lighten($error-red, 12%), 0.1); opacity: 0.75;
border-color: rgba(lighten($error-red, 12%), 0.5); letter-spacing: 0;
}
}
.information-badge {
&.superapp {
background-color: rgba($success-green, 0.1);
border-color: rgba($success-green, 0.5);
} }
} }

View File

@ -534,23 +534,25 @@
} }
} }
&__tabs { &__badges {
display: flex; display: flex;
align-items: flex-end; flex-wrap: wrap;
justify-content: space-between; gap: 8px;
padding: 7px 10px;
margin-top: -81px;
height: 130px;
overflow: hidden;
margin-inline-start: -2px; // aligns the pfp with content below
.account-role { .account-role {
margin: 0 2px; line-height: unset;
padding: 4px 0;
box-sizing: border-box;
min-width: 90px;
text-align: center;
} }
}
&__tabs {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 7px 10px;
margin-top: -55px;
gap: 8px;
overflow: hidden;
margin-inline-start: -2px; // aligns the pfp with content below
&__buttons { &__buttons {
display: flex; display: flex;
@ -579,10 +581,6 @@
&__name { &__name {
padding: 5px 10px; padding: 5px 10px;
.account-role {
vertical-align: top;
}
.emojione { .emojione {
width: 22px; width: 22px;
height: 22px; height: 22px;