diff --git a/app/soapbox/components/account.js b/app/soapbox/components/account.js
index 189e90686..e1f057b59 100644
--- a/app/soapbox/components/account.js
+++ b/app/soapbox/components/account.js
@@ -11,6 +11,7 @@ import IconButton from './icon_button';
import RelativeTimestamp from './relative_timestamp';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
+import classNames from 'classnames';
const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' },
@@ -44,8 +45,14 @@ class Account extends ImmutablePureComponent {
actionTitle: PropTypes.string,
onActionClick: PropTypes.func,
withDate: PropTypes.bool,
+ withRelationship: PropTypes.bool,
};
+ static defaultProps = {
+ withDate: false,
+ withRelationship: true,
+ }
+
handleFollow = () => {
this.props.onFollow(this.props.account);
}
@@ -71,7 +78,7 @@ class Account extends ImmutablePureComponent {
}
render() {
- const { account, intl, hidden, onActionClick, actionIcon, actionTitle, me, withDate } = this.props;
+ const { account, intl, hidden, onActionClick, actionIcon, actionTitle, me, withDate, withRelationship } = this.props;
if (!account) {
return
;
@@ -87,7 +94,7 @@ class Account extends ImmutablePureComponent {
}
let buttons;
- let followed_by;
+ let followedBy;
if (onActionClick && actionIcon) {
buttons = ;
@@ -97,7 +104,7 @@ class Account extends ImmutablePureComponent {
const blocking = account.getIn(['relationship', 'blocking']);
const muting = account.getIn(['relationship', 'muting']);
- followed_by = account.getIn(['relationship', 'followed_by']);
+ followedBy = account.getIn(['relationship', 'followed_by']);
if (requested) {
buttons = ;
@@ -121,29 +128,36 @@ class Account extends ImmutablePureComponent {
}
}
+ const createdAt = account.get('created_at');
+
+ const joinedAt = createdAt ? (
+
+
+
+
+ ) : null;
+
return (
-
+
- { followed_by ?
-
-
-
- : '' }
+ {withRelationship ? (<>
+ {followedBy &&
+
+
+ }
-
- {buttons}
-
+
+ {buttons}
+
+ >) : withDate && joinedAt}
- {withDate && (
-
-
-
)}
+ {(withDate && withRelationship) && joinedAt}
);
}
diff --git a/app/soapbox/features/admin/components/latest_accounts_panel.js b/app/soapbox/features/admin/components/latest_accounts_panel.js
index 37b82b6e7..5d4f9b662 100644
--- a/app/soapbox/features/admin/components/latest_accounts_panel.js
+++ b/app/soapbox/features/admin/components/latest_accounts_panel.js
@@ -9,6 +9,7 @@ import { fetchUsers } from 'soapbox/actions/admin';
const messages = defineMessages({
title: { id: 'admin.latest_accounts_panel.title', defaultMessage: 'Latest Accounts' },
+ expand: { id: 'admin.latest_accounts_panel.expand_message', defaultMessage: 'Click to see {count} more {count, plural, one {account} other {accounts}}' },
});
const mapStateToProps = state => ({
@@ -28,13 +29,23 @@ class LatestAccountsPanel extends ImmutablePureComponent {
limit: 5,
}
+ state = {
+ total: 0,
+ }
+
componentDidMount() {
const { dispatch, limit } = this.props;
- dispatch(fetchUsers(['local', 'active'], 1, null, limit));
+
+ dispatch(fetchUsers(['local', 'active'], 1, null, limit))
+ .then(({ count }) => {
+ this.setState({ total: count });
+ })
+ .catch(() => {});
}
render() {
const { intl, accountIds, limit, ...props } = this.props;
+ const { total } = this.state;
if (!accountIds || accountIds.isEmpty()) {
return null;
@@ -46,6 +57,11 @@ class LatestAccountsPanel extends ImmutablePureComponent {
title={intl.formatMessage(messages.title)}
accountIds={accountIds}
limit={limit}
+ total={total}
+ expandMessage={intl.formatMessage(messages.expand, { count: total })}
+ expandRoute='/admin/users'
+ withDate
+ withRelationship={false}
{...props}
/>
);
diff --git a/app/soapbox/features/ui/components/account_list_panel.js b/app/soapbox/features/ui/components/account_list_panel.js
index 8563a2231..2159b657b 100644
--- a/app/soapbox/features/ui/components/account_list_panel.js
+++ b/app/soapbox/features/ui/components/account_list_panel.js
@@ -4,6 +4,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Icon from 'soapbox/components/icon';
import AccountContainer from '../../../containers/account_container';
+import { Link } from 'react-router-dom';
export default class AccountListPanel extends ImmutablePureComponent {
@@ -12,6 +13,9 @@ export default class AccountListPanel extends ImmutablePureComponent {
accountIds: ImmutablePropTypes.orderedSet.isRequired,
icon: PropTypes.string.isRequired,
limit: PropTypes.number,
+ total: PropTypes.number,
+ expandMessage: PropTypes.string,
+ expandRoute: PropTypes.string,
};
static defaultProps = {
@@ -19,12 +23,14 @@ export default class AccountListPanel extends ImmutablePureComponent {
}
render() {
- const { title, icon, accountIds, limit, ...props } = this.props;
+ const { title, icon, accountIds, limit, total, expandMessage, expandRoute, ...props } = this.props;
if (!accountIds || accountIds.isEmpty()) {
return null;
}
+ const canExpand = expandMessage && expandRoute && (accountIds.size < total);
+
return (
@@ -40,6 +46,9 @@ export default class AccountListPanel extends ImmutablePureComponent {
))}
+ {canExpand &&
+ {expandMessage}
+ }
);
};
diff --git a/app/soapbox/pages/admin_page.js b/app/soapbox/pages/admin_page.js
index 009b599b2..a010581cc 100644
--- a/app/soapbox/pages/admin_page.js
+++ b/app/soapbox/pages/admin_page.js
@@ -29,7 +29,7 @@ class AdminPage extends ImmutablePureComponent {
diff --git a/app/styles/accounts.scss b/app/styles/accounts.scss
index 35bc1aa3d..7e7e2680d 100644
--- a/app/styles/accounts.scss
+++ b/app/styles/accounts.scss
@@ -518,10 +518,18 @@ a .account__avatar {
}
.account__joined-at {
- padding: 3px 2px 0 48px;
+ padding: 3px 2px 0 5px;
font-size: 14px;
+ display: flex;
+ white-space: nowrap;
i.fa-calendar {
padding-right: 5px;
}
}
+
+.account--with-date.account--with-relationship {
+ .account__joined-at {
+ padding-left: 48px;
+ }
+}