diff --git a/app/javascript/flavours/glitch/components/account.jsx b/app/javascript/flavours/glitch/components/account.jsx
index 78cf59e345..6342ef6f48 100644
--- a/app/javascript/flavours/glitch/components/account.jsx
+++ b/app/javascript/flavours/glitch/components/account.jsx
@@ -1,15 +1,21 @@
import PropTypes from 'prop-types';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+
+import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
-import { Skeleton } from 'flavours/glitch/components/skeleton';
+import { EmptyAccount } from 'flavours/glitch/components/empty_account';
+import { ShortNumber } from 'flavours/glitch/components/short_number';
+import { VerifiedBadge } from 'flavours/glitch/components/verified_badge';
import { me } from '../initial_state';
import { Avatar } from './avatar';
+import { Button } from './button';
+import { FollowersCounter } from './counters';
import { DisplayName } from './display_name';
import { IconButton } from './icon_button';
import Permalink from './permalink';
@@ -18,13 +24,13 @@ import { RelativeTimestamp } from './relative_timestamp';
const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' },
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
- requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' },
- unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
- unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
- mute_notifications: { id: 'account.mute_notifications', defaultMessage: 'Mute notifications from @{name}' },
- unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' },
- mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
- block: { id: 'account.block', defaultMessage: 'Block @{name}' },
+ cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Withdraw follow request' },
+ unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' },
+ unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' },
+ mute_notifications: { id: 'account.mute_notifications_short', defaultMessage: 'Mute notifications' },
+ unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
+ mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
+ block: { id: 'account.block_short', defaultMessage: 'Block' },
});
class Account extends ImmutablePureComponent {
@@ -38,14 +44,16 @@ class Account extends ImmutablePureComponent {
onMuteNotifications: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
hidden: PropTypes.bool,
+ minimal: PropTypes.bool,
actionIcon: PropTypes.string,
actionTitle: PropTypes.string,
defaultAction: PropTypes.string,
onActionClick: PropTypes.func,
+ withBio: PropTypes.bool,
};
static defaultProps = {
- size: 36,
+ size: 46,
};
handleFollow = () => {
@@ -73,19 +81,10 @@ class Account extends ImmutablePureComponent {
};
render () {
- const { account, intl, hidden, onActionClick, actionIcon, actionTitle, defaultAction, size } = this.props;
+ const { account, intl, hidden, withBio, onActionClick, actionIcon, actionTitle, defaultAction, size, minimal } = this.props;
if (!account) {
- return (
-
- );
+ return ;
}
if (hidden) {
@@ -99,61 +98,91 @@ class Account extends ImmutablePureComponent {
let buttons;
- if (onActionClick) {
- if (actionIcon) {
- buttons = ;
- }
- } else if (account.get('id') !== me && account.get('relationship', null) !== null) {
+ if (actionIcon && onActionClick) {
+ buttons = ;
+ } else if (!actionIcon && account.get('id') !== me && account.get('relationship', null) !== null) {
const following = account.getIn(['relationship', 'following']);
const requested = account.getIn(['relationship', 'requested']);
const blocking = account.getIn(['relationship', 'blocking']);
const muting = account.getIn(['relationship', 'muting']);
if (requested) {
- buttons = ;
+ buttons = ;
} else if (blocking) {
- buttons = ;
+ buttons = ;
} else if (muting) {
let hidingNotificationsButton;
+
if (account.getIn(['relationship', 'muting_notifications'])) {
- hidingNotificationsButton = ;
+ hidingNotificationsButton = ;
} else {
- hidingNotificationsButton = ;
+ hidingNotificationsButton = ;
}
+
buttons = (
<>
-
+
{hidingNotificationsButton}
>
);
} else if (defaultAction === 'mute') {
- buttons = ;
+ buttons = ;
} else if (defaultAction === 'block') {
- buttons = ;
+ buttons = ;
} else if (!account.get('moved') || following) {
- buttons = ;
+ buttons = ;
}
}
- let mute_expires_at;
+ let muteTimeRemaining;
+
if (account.get('mute_expires_at')) {
- mute_expires_at =
;
+ muteTimeRemaining = <>ยท >;
+ }
+
+ let verification;
+
+ const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
+
+ if (firstVerifiedField) {
+ verification = ;
}
return (
-
+
-
- {mute_expires_at}
-
+
+
+
+
+ {!minimal && (
+
+ {account.get('followers_count') !== -1 && (
+
+ )} {verification} {muteTimeRemaining}
+
+ )}
+
- {buttons ?
+
+ {!minimal && (
{buttons}
- : null}
+ )}
+
+ {withBio && (account.get('note').length > 0 ? (
+
+ ) : (
+
+ ))}
);
}
diff --git a/app/javascript/flavours/glitch/components/empty_account.tsx b/app/javascript/flavours/glitch/components/empty_account.tsx
new file mode 100644
index 0000000000..55322fb575
--- /dev/null
+++ b/app/javascript/flavours/glitch/components/empty_account.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+
+import classNames from 'classnames';
+
+import { DisplayName } from 'flavours/glitch/components/display_name';
+import { Skeleton } from 'flavours/glitch/components/skeleton';
+
+interface Props {
+ size?: number;
+ minimal?: boolean;
+}
+
+export const EmptyAccount: React.FC
= ({
+ size = 46,
+ minimal = false,
+}) => {
+ return (
+
+ );
+};
diff --git a/app/javascript/flavours/glitch/components/server_banner.jsx b/app/javascript/flavours/glitch/components/server_banner.jsx
index 677e13706b..1b449ff1a8 100644
--- a/app/javascript/flavours/glitch/components/server_banner.jsx
+++ b/app/javascript/flavours/glitch/components/server_banner.jsx
@@ -63,7 +63,7 @@ class ServerBanner extends PureComponent {
diff --git a/app/javascript/flavours/glitch/components/verified_badge.tsx b/app/javascript/flavours/glitch/components/verified_badge.tsx
new file mode 100644
index 0000000000..9a6adcfa86
--- /dev/null
+++ b/app/javascript/flavours/glitch/components/verified_badge.tsx
@@ -0,0 +1,27 @@
+import { Icon } from './icon';
+
+const domParser = new DOMParser();
+
+const stripRelMe = (html: string) => {
+ const document = domParser.parseFromString(html, 'text/html').documentElement;
+
+ document.querySelectorAll
('a[rel]').forEach((link) => {
+ link.rel = link.rel
+ .split(' ')
+ .filter((x: string) => x !== 'me')
+ .join(' ');
+ });
+
+ const body = document.querySelector('body');
+ return body ? { __html: body.innerHTML } : undefined;
+};
+
+interface Props {
+ link: string;
+}
+export const VerifiedBadge: React.FC = ({ link }) => (
+
+
+
+
+);
diff --git a/app/javascript/flavours/glitch/features/about/index.jsx b/app/javascript/flavours/glitch/features/about/index.jsx
index 79b5f8114e..0b78385562 100644
--- a/app/javascript/flavours/glitch/features/about/index.jsx
+++ b/app/javascript/flavours/glitch/features/about/index.jsx
@@ -128,7 +128,7 @@ class About extends PureComponent {
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index 5d4426fbc6..e5ac494425 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -6,15 +6,31 @@
.account__display-name {
flex: 1 1 auto;
- display: block;
+ display: flex;
+ align-items: center;
+ gap: 10px;
color: $darker-text-color;
overflow: hidden;
text-decoration: none;
font-size: 14px;
- &--with-note {
- strong {
- display: inline;
+ .display-name {
+ margin-bottom: 4px;
+ }
+
+ .display-name strong {
+ display: inline;
+ }
+ }
+
+ &--minimal {
+ .account__display-name {
+ .display-name {
+ margin-bottom: 0;
+ }
+
+ .display-name strong {
+ display: block;
}
}
}
@@ -41,12 +57,12 @@
.account__wrapper {
display: flex;
+ gap: 10px;
+ align-items: center;
}
.account__avatar-wrapper {
float: left;
- margin-inline-start: 12px;
- margin-inline-end: 12px;
}
.account__avatar {
@@ -129,9 +145,10 @@
}
.account__relationship {
- height: 18px;
- padding: 10px;
white-space: nowrap;
+ display: flex;
+ align-items: center;
+ gap: 4px;
}
.account__header__wrapper {
@@ -749,6 +766,36 @@
}
}
+.account__contents {
+ overflow: hidden;
+}
+
+.account__details {
+ display: flex;
+ flex-wrap: wrap;
+ column-gap: 1em;
+}
+
+.verified-badge {
+ display: inline-flex;
+ align-items: center;
+ color: $valid-value-color;
+ gap: 4px;
+ overflow: hidden;
+ white-space: nowrap;
+
+ > span {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ a {
+ color: inherit;
+ font-weight: 500;
+ text-decoration: none;
+ }
+}
+
.moved-account-banner,
.follow-request-banner,
.account-memorial-banner {
diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss
index 0b720637de..85e3165a88 100644
--- a/app/javascript/flavours/glitch/styles/components/status.scss
+++ b/app/javascript/flavours/glitch/styles/components/status.scss
@@ -626,7 +626,7 @@
.status__display-name,
.account__display-name {
- strong {
+ .display-name strong {
color: $primary-text-color;
}
}
@@ -641,12 +641,12 @@ a.status__display-name,
.reply-indicator__display-name,
.detailed-status__display-name,
.account__display-name {
- &:hover strong {
+ &:hover .display-name strong {
text-decoration: underline;
}
}
-.account__display-name strong {
+.account__display-name .display-name strong {
display: block;
overflow: hidden;
text-overflow: ellipsis;