gab-social/app/javascript/gabsocial/components/header.js

352 lines
14 KiB
JavaScript
Raw Normal View History

2020-02-05 22:45:48 +00:00
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/bind'
import Avatar from './avatar'
import Button from './button'
import Icon from './icon'
import DisplayName from './display_name'
import { closeSidebar } from '../actions/sidebar'
import { shortNumberFormat } from '../utils/numbers'
import { me } from '../initial_state'
import { makeGetAccount } from '../selectors'
// import ProgressPanel from './progress_panel'
import GabLogo from './assets/gab_logo'
2020-02-03 18:24:24 +00:00
import {
GroupIcon,
HomeIcon,
NotificationsIcon,
2020-02-05 22:45:48 +00:00
} from './assets/tabs_bar_icon'
2019-08-15 04:04:03 +01:00
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' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
lists: { id: 'column.lists', defaultMessage: 'Lists', },
apps: { id: 'tabs_bar.apps', defaultMessage: 'Apps' },
more: { id: 'sidebar.more', defaultMessage: 'More' },
pro: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
trends: { id: 'promo.trends', defaultMessage: 'Trends' },
2019-10-22 21:19:12 +01:00
search: { id: 'tabs_bar.search', defaultMessage: 'Search' },
shop: { id: 'tabs_bar.shop', defaultMessage: 'Store - Buy Merch' },
2020-01-21 21:07:58 +00:00
donate: { id: 'tabs_bar.donate', defaultMessage: 'Make a Donation' },
2019-08-15 04:04:03 +01:00
})
const mapStateToProps = state => {
2020-02-05 22:45:48 +00:00
const getAccount = makeGetAccount()
2019-08-15 04:04:03 +01:00
return {
account: getAccount(state, me),
sidebarOpen: state.get('sidebar').sidebarOpen,
2020-02-05 22:45:48 +00:00
}
}
2019-08-15 04:04:03 +01:00
const mapDispatchToProps = (dispatch) => ({
2020-02-03 18:24:24 +00:00
onClose() {
2020-02-05 22:45:48 +00:00
dispatch(closeSidebar())
2019-08-15 04:04:03 +01:00
},
2020-02-05 22:45:48 +00:00
})
2019-08-15 04:04:03 +01:00
export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl
2020-02-03 18:24:24 +00:00
class Header extends ImmutablePureComponent {
2019-08-15 04:04:03 +01:00
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
sidebarOpen: PropTypes.bool,
onClose: PropTypes.func.isRequired,
2020-02-05 22:45:48 +00:00
}
2019-08-15 04:04:03 +01:00
state = {
moreOpen: false,
2020-02-05 22:45:48 +00:00
hoveringItemIndex: null,
}
2020-02-03 18:24:24 +00:00
componentDidUpdate() {
2020-02-05 22:45:48 +00:00
if (!me) return
if (this.props.sidebarOpen) {
2020-02-05 22:45:48 +00:00
document.body.classList.add('with-modals--active')
} else {
2020-02-05 22:45:48 +00:00
document.body.classList.remove('with-modals--active')
}
}
toggleMore = () => {
this.setState({
moreOpen: !this.state.moreOpen
2020-02-05 22:45:48 +00:00
})
}
onMouseEnterLinkFooterItem = (i) => {
this.setState({
hoveringItemIndex: i,
})
}
onMouseLeaveLinkFooterItem = () => {
this.setState({
hoveringItemIndex: null,
})
}
handleSidebarClose = () => {
2020-02-05 22:45:48 +00:00
this.props.onClose()
this.setState({
moreOpen: false,
2020-02-05 22:45:48 +00:00
})
}
2020-02-03 18:24:24 +00:00
render() {
2020-02-05 22:45:48 +00:00
const { sidebarOpen, intl, account } = this.props
const { moreOpen, hoveringItemIndex } = this.state
2020-02-05 22:45:48 +00:00
if (!me || !account) return null
2020-02-05 22:45:48 +00:00
const acct = account.get('acct')
const isPro = account.get('is_pro')
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// const classes = classNames('sidebar-menu__root', {
// 'sidebar-menu__root--visible': sidebarOpen,
// })
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
const cx = classNames.bind(styles)
const moreIcon = moreOpen ? 'minus' : 'plus'
const moreContainerStyle = { display: moreOpen ? 'block' : 'none' }
2020-02-03 18:24:24 +00:00
const sidebarItems = [
{
name: 'Home',
icon: <NotificationsIcon />,
to: '/',
},
{
name: 'Notifications',
icon: <NotificationsIcon />,
2020-02-04 15:50:18 +00:00
to: '/notifications',
2020-02-03 18:24:24 +00:00
},
{
name: 'Groups',
icon: <NotificationsIcon />,
2020-02-04 15:50:18 +00:00
to: '/groups',
2020-02-03 18:24:24 +00:00
},
{
name: 'Lists',
icon: <NotificationsIcon />,
2020-02-04 15:50:18 +00:00
to: '/lists',
2020-02-03 18:24:24 +00:00
},
{
name: 'Chat',
icon: <NotificationsIcon />,
to: '/',
},
{
name: 'Trends',
icon: <NotificationsIcon />,
to: '/',
},
{
name: 'Profile',
icon: <NotificationsIcon />,
to: '/',
},
2020-02-05 22:45:48 +00:00
]
2020-02-03 18:24:24 +00:00
return (
2020-02-04 15:50:18 +00:00
<header role='banner' className={[styles.default, styles.flexGrow1, styles.z3, styles.alignItemsEnd].join(' ')}>
2020-02-05 22:45:48 +00:00
<div className={[styles.default, styles.width250PX].join(' ')}>
2020-02-04 15:50:18 +00:00
<div className={[styles.default, styles.positionFixed, styles.top0, styles.height100PC].join(' ')}>
2020-02-05 22:45:48 +00:00
<div className={[styles.default, styles.height100PC, styles.width250PX, styles.paddingHorizontal20PX].join(' ')}>
2020-02-04 15:50:18 +00:00
<h1 className={[styles.default].join(' ')}>
<NavLink to='/' aria-label='Gab' className={[styles.default, styles.noSelect, styles.noUnderline, styles.height50PX, styles.justifyContentCenter, styles.cursorPointer, styles.paddingHoizontal10PX].join(' ')}>
2020-02-03 18:24:24 +00:00
<GabLogo />
2020-02-04 15:50:18 +00:00
</NavLink>
2020-02-03 18:24:24 +00:00
</h1>
2020-02-04 15:50:18 +00:00
<nav aria-label='Primary' role='navigation' className={[styles.default, styles.width100PC].join(' ')}>
2020-02-03 18:24:24 +00:00
{
sidebarItems.map((sidebarItem, i) => {
2020-02-05 22:45:48 +00:00
const containerClasses = cx({
default: 1,
maxWidth100PC: 1,
flexRow: 1,
paddingVertical10PX: 1,
paddingHoizontal10PX: 1,
circle: 1,
alignItemsCenter: 1,
backgroundColorBrandLightOpaque: hoveringItemIndex === i,
})
const textClasses = cx({
default: 1,
fontWeightBold: 1,
fontSize19PX: 1,
text: 1,
colorBrand: hoveringItemIndex === i,
colorBlack: hoveringItemIndex !== i,
})
const iconClasses = cx({
fillColorBrand: hoveringItemIndex === i,
fillColorBlack: hoveringItemIndex !== i,
})
2020-02-03 18:24:24 +00:00
return (
2020-02-05 22:45:48 +00:00
<NavLink
to={sidebarItem.to}
key={`header-nav-item-${i}`}
onMouseEnter={() => this.onMouseEnterLinkFooterItem(i)}
onMouseLeave={() => this.onMouseLeaveLinkFooterItem(i)}
className={[styles.default, styles.noUnderline, styles.cursorPointer, styles.width100PC, styles.alignItemsStart, styles.flexGrow1].join(' ')}
>
<div className={containerClasses}>
2020-02-04 15:50:18 +00:00
<div className={[styles.default]}>
2020-02-05 22:45:48 +00:00
<NotificationsIcon className={iconClasses}/>
2020-02-04 15:50:18 +00:00
</div>
<div className={[styles.default, styles.paddingHorizontal20PX, styles.textOverflowEllipsis, styles.overflowWrapBreakWord, styles.displayInline].join(' ')}>
2020-02-05 22:45:48 +00:00
<span className={textClasses}>
2020-02-04 15:50:18 +00:00
{sidebarItem.name}
</span>
</div>
2020-02-03 18:24:24 +00:00
</div>
</NavLink>
)
})
}
</nav>
2020-02-05 22:45:48 +00:00
<Button className={[styles.paddingVertical15PX, styles.marginVertical5PX, styles.fontSize15PX, styles.fontWeightBold].join(' ')}>Gab</Button>
2020-02-03 18:24:24 +00:00
</div>
</div>
</div>
</header>
)
2020-02-05 22:45:48 +00:00
// return (
// <div className={classes}>
// <div className='sidebar-menu__wrapper' role='button' onClick={this.handleSidebarClose} />
// <div className='sidebar-menu'>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu-header'>
// <span className='sidebar-menu-header__title'>Account Info</span>
// <IconButton title='close' onClick={this.handleSidebarClose} icon='close' className='sidebar-menu-header__btn' />
// </div>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu__content'>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu-profile'>
// <div className='sidebar-menu-profile__avatar'>
// <Link to={`/${acct}`} title={acct} onClick={this.handleSidebarClose}>
// <Avatar account={account} />
// </Link>
// </div>
// <div className='sidebar-menu-profile__name'>
// <DisplayName account={account} />
// </div>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu-profile__stats'>
// <NavLink className='sidebar-menu-profile-stat' to={`/${acct}/followers`} onClick={this.handleSidebarClose} title={intl.formatNumber(account.get('followers_count'))}>
// <strong className='sidebar-menu-profile-stat__value'>{shortNumberFormat(account.get('followers_count'))}</strong>
// <span className='sidebar-menu-profile-stat__label'>{intl.formatMessage(messages.followers)}</span>
// </NavLink>
// <NavLink className='sidebar-menu-profile-stat' to={`/${acct}/following`} onClick={this.handleSidebarClose} title={intl.formatNumber(account.get('following_count'))}>
// <strong className='sidebar-menu-profile-stat__value'>{shortNumberFormat(account.get('following_count'))}</strong>
// <span className='sidebar-menu-profile-stat__label'>{intl.formatMessage(messages.follows)}</span>
// </NavLink>
// </div>
2020-01-21 21:07:58 +00:00
2020-02-05 22:45:48 +00:00
// </div>
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu__section'>
// { /* <ProgressPanel /> */ }
// </div>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu__section sidebar-menu__section--borderless'>
// <NavLink className='sidebar-menu-item' to={`/${acct}`} onClick={this.handleSidebarClose}>
// <Icon id='user' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.profile)}</span>
// </NavLink>
// {
// !isPro &&
// <a className='sidebar-menu-item' href='https://pro.gab.com'>
// <Icon id='arrow-up' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.pro)}</span>
// </a>
// }
// <a className='sidebar-menu-item' href='https://shop.dissenter.com/category/donations'>
// <Icon id='heart' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.donate)}</span>
// </a>
// <a className='sidebar-menu-item' href='https://shop.dissenter.com'>
// <Icon id='shopping-cart' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.shop)}</span>
// </a>
// <a className='sidebar-menu-item' href='https://trends.gab.com'>
// <Icon id='signal' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.trends)}</span>
// </a>
// <NavLink className='sidebar-menu-item' to='/search' onClick={this.handleSidebarClose}>
// <Icon id='search' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.search)}</span>
// </NavLink>
// <a className='sidebar-menu-item' href='/settings/preferences'>
// <Icon id='cog' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.preferences)}</span>
// </a>
// </div>
2019-08-15 04:04:03 +01:00
2020-02-05 22:45:48 +00:00
// <div className='sidebar-menu__section'>
// <div className='sidebar-menu-item' onClick={this.toggleMore} role='button'>
// <Icon id={moreIcon} fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.more)}</span>
// </div>
// <div style={moreContainerStyle}>
// <NavLink className='sidebar-menu-item' to='/lists' onClick={this.handleSidebarClose}>
// <Icon id='list' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.lists)}</span>
// </NavLink>
// <NavLink className='sidebar-menu-item' to='/follow_requests' onClick={this.handleSidebarClose}>
// <Icon id='user-plus' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.follow_requests)}</span>
// </NavLink>
// <NavLink className='sidebar-menu-item' to='/blocks' onClick={this.handleSidebarClose}>
// <Icon id='ban' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.blocks)}</span>
// </NavLink>
// <NavLink className='sidebar-menu-item' to='/domain_blocks' onClick={this.handleSidebarClose}>
// <Icon id='sitemap' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.domain_blocks)}</span>
// </NavLink>
// <NavLink className='sidebar-menu-item' to='/mutes' onClick={this.handleSidebarClose}>
// <Icon id='times-circle' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.mutes)}</span>
// </NavLink>
// <a className='sidebar-menu-item' href='/filters'>
// <Icon id='filter' fixedWidth />
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.filters)}</span>
// </a>
// </div>
// </div>
// <div className='sidebar-menu__section'>
// <a className='sidebar-menu-item' href='/auth/sign_out' data-method='delete'>
// <span className='sidebar-menu-item__title'>{intl.formatMessage(messages.logout)}</span>
// </a>
// </div>
// </div>
// </div>
// </div>
// )
2019-08-15 04:04:03 +01:00
}
}