diff --git a/app/soapbox/components/sidebar_menu.js b/app/soapbox/components/sidebar_menu.js index 306303417..b4bda0099 100644 --- a/app/soapbox/components/sidebar_menu.js +++ b/app/soapbox/components/sidebar_menu.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { throttle } from 'lodash'; import { Link, NavLink } from 'react-router-dom'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -14,8 +15,10 @@ import { closeSidebar } from '../actions/sidebar'; import { shortNumberFormat } from '../utils/numbers'; import { isStaff } from '../utils/accounts'; import { makeGetAccount } from '../selectors'; -import { logOut } from 'soapbox/actions/auth'; +import { logOut, switchAccount } from 'soapbox/actions/auth'; import ThemeToggle from '../features/ui/components/theme_toggle_container'; +import { fetchOwnAccounts } from 'soapbox/actions/auth'; +import { List as ImmutableList } from 'immutable'; const messages = defineMessages({ followers: { id: 'account.followers', defaultMessage: 'Followers' }, @@ -38,17 +41,30 @@ const messages = defineMessages({ news: { id: 'tabs_bar.news', defaultMessage: 'News' }, donate: { id: 'donate', defaultMessage: 'Donate' }, info: { id: 'column.info', defaultMessage: 'Server information' }, + add_account: { id: 'profile_dropdown.add_account', defaultMessage: 'Add an existing account' }, }); const mapStateToProps = state => { const me = state.get('me'); const getAccount = makeGetAccount(); + const otherAccounts = + state + .getIn(['auth', 'users']) + .keySeq() + .reduce((list, id) => { + if (id === me) return list; + const account = state.getIn(['accounts', id]); + return account ? list.push(account) : list; + }, ImmutableList()); + return { account: getAccount(state, me), sidebarOpen: state.get('sidebar').sidebarOpen, donateUrl: state.getIn(['patron', 'instance', 'url']), isStaff: isStaff(state.getIn(['accounts', me])), + otherAccounts, + }; }; @@ -60,6 +76,12 @@ const mapDispatchToProps = (dispatch) => ({ dispatch(logOut()); e.preventDefault(); }, + fetchOwnAccounts() { + dispatch(fetchOwnAccounts()); + }, + switchAccount(account) { + dispatch(switchAccount(account.get('id'))); + }, }); export default @connect(mapStateToProps, mapDispatchToProps) @@ -78,8 +100,52 @@ class SidebarMenu extends ImmutablePureComponent { isStaff: false, } + state = { + switcher: false, + } + + handleSwitchAccount = account => { + return e => { + this.props.switchAccount(account); + e.preventDefault(); + }; + } + + handleSwitcherClick = e => { + this.setState({ switcher: !this.state.switcher }); + e.preventDefault(); + } + + fetchOwnAccounts = throttle(() => { + this.props.fetchOwnAccounts(); + }, 2000); + + componentDidMount() { + this.fetchOwnAccounts(); + } + + componentDidUpdate() { + this.fetchOwnAccounts(); + } + + renderAccount = account => { + return ( + +
+
+
+
+ +
+
+
+
+ ); + } + render() { - const { sidebarOpen, onClose, intl, account, onClickLogOut, donateUrl, isStaff } = this.props; + const { sidebarOpen, onClose, intl, account, onClickLogOut, donateUrl, isStaff, otherAccounts } = this.props; + const { switcher } = this.state; if (!account) return null; const acct = account.get('acct'); @@ -105,24 +171,22 @@ class SidebarMenu extends ImmutablePureComponent { -
+ -
- -
- - {shortNumberFormat(account.get('followers_count'))} - {intl.formatMessage(messages.followers)} - - - {shortNumberFormat(account.get('following_count'))} - {intl.formatMessage(messages.follows)} - -
- + +
-
+ {switcher &&
+ {otherAccounts.map(account => this.renderAccount(account))} + + + + {intl.formatMessage(messages.add_account)} + +
} + +
diff --git a/app/styles/components/sidebar-menu.scss b/app/styles/components/sidebar-menu.scss index 2207a2aed..dc4c897a7 100644 --- a/app/styles/components/sidebar-menu.scss +++ b/app/styles/components/sidebar-menu.scss @@ -98,14 +98,23 @@ } &__name { - display: block; + display: flex; margin-top: 10px; + color: var(--primary-text-color); + text-decoration: none; + align-items: center; .display-name__account { display: block; margin-top: 2px; color: var(--primary-text-color--faint); } + + i.fa-caret-up, + i.fa-caret-down { + margin-left: auto; + padding-left: 10px; + } } &__stats { @@ -140,6 +149,10 @@ } } +.sidebar-account { + text-decoration: none; +} + .sidebar-menu-item { display: flex; padding: 16px 18px;