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'; import { injectIntl, defineMessages } from 'react-intl'; import classNames from 'classnames'; import Avatar from './avatar'; import IconButton from './icon_button'; import Icon from './icon'; import DisplayName from './display_name'; import { closeSidebar } from '../actions/sidebar'; import { isStaff } from '../utils/accounts'; import { makeGetAccount } from '../selectors'; 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, is as ImmutableIs } from 'immutable'; const messages = defineMessages({ followers: { id: 'account.followers', defaultMessage: 'Followers' }, follows: { id: 'account.follows', defaultMessage: 'Follows' }, profile: { id: 'account.profile', defaultMessage: 'Profile' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' }, admin_settings: { id: 'navigation_bar.admin_settings', defaultMessage: 'Admin settings' }, soapbox_config: { id: 'navigation_bar.soapbox_config', defaultMessage: 'Soapbox config' }, import_data: { id: 'navigation_bar.import_data', defaultMessage: 'Import data' }, security: { id: 'navigation_bar.security', defaultMessage: 'Security' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, lists: { id: 'column.lists', defaultMessage: 'Lists' }, bookmarks: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' }, apps: { id: 'tabs_bar.apps', defaultMessage: 'Apps' }, 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, }; }; const mapDispatchToProps = (dispatch) => ({ onClose() { dispatch(closeSidebar()); }, onClickLogOut(e) { dispatch(logOut()); e.preventDefault(); }, fetchOwnAccounts() { dispatch(fetchOwnAccounts()); }, switchAccount(account) { dispatch(switchAccount(account.get('id'))); }, }); export default @connect(mapStateToProps, mapDispatchToProps) @injectIntl class SidebarMenu extends ImmutablePureComponent { static propTypes = { intl: PropTypes.object.isRequired, account: ImmutablePropTypes.map, otherAccounts: ImmutablePropTypes.list, sidebarOpen: PropTypes.bool, onClose: PropTypes.func.isRequired, isStaff: PropTypes.bool.isRequired, }; static defaultProps = { isStaff: false, } state = { switcher: false, } handleClose = () => { this.setState({ switcher: false }); this.props.onClose(); } 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(prevProps) { const accountChanged = !ImmutableIs(prevProps.account, this.props.account); const otherAccountsChanged = !ImmutableIs(prevProps.otherAccounts, this.props.otherAccounts); if (accountChanged || otherAccountsChanged) { this.fetchOwnAccounts(); } } renderAccount = account => { return (
); } render() { const { sidebarOpen, intl, account, onClickLogOut, donateUrl, isStaff, otherAccounts } = this.props; const { switcher } = this.state; if (!account) return null; const acct = account.get('acct'); const classes = classNames('sidebar-menu__root', { 'sidebar-menu__root--visible': sidebarOpen, }); return (
Account Info
{switcher &&
{otherAccounts.map(account => this.renderAccount(account))} {intl.formatMessage(messages.add_account)}
}
{intl.formatMessage(messages.profile)} {donateUrl ? {intl.formatMessage(messages.donate)} : ''} {intl.formatMessage(messages.lists)} {intl.formatMessage(messages.bookmarks)}
{intl.formatMessage(messages.follow_requests)} {intl.formatMessage(messages.blocks)} {intl.formatMessage(messages.domain_blocks)} {intl.formatMessage(messages.mutes)} {intl.formatMessage(messages.filters)} { isStaff && {intl.formatMessage(messages.admin_settings)} } { isStaff && {intl.formatMessage(messages.soapbox_config)} } {intl.formatMessage(messages.preferences)} {intl.formatMessage(messages.import_data)} {intl.formatMessage(messages.security)}
{intl.formatMessage(messages.info)}
{intl.formatMessage(messages.logout)}
); } }