import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { Link } from 'react-router-dom'; import BundleContainer from '../containers/bundle_container'; import ColumnLoading from './column_loading'; import DrawerLoading from './drawer_loading'; import BundleColumnError from './bundle_column_error'; import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, BookmarkedStatuses, ListTimeline, Directory, } from '../../ui/util/async-components'; import Icon from 'mastodon/components/icon'; import ComposePanel from './compose_panel'; import NavigationPanel from './navigation_panel'; import { supportsPassiveEvents } from 'detect-passive-events'; import { scrollRight } from '../../../scroll'; const componentMap = { 'COMPOSE': Compose, 'HOME': HomeTimeline, 'NOTIFICATIONS': Notifications, 'PUBLIC': PublicTimeline, 'REMOTE': PublicTimeline, 'COMMUNITY': CommunityTimeline, 'HASHTAG': HashtagTimeline, 'DIRECT': DirectTimeline, 'FAVOURITES': FavouritedStatuses, 'BOOKMARKS': BookmarkedStatuses, 'LIST': ListTimeline, 'DIRECTORY': Directory, }; const messages = defineMessages({ publish: { id: 'compose_form.publish', defaultMessage: 'Publish' }, }); const shouldHideFAB = path => path.match(/^\/statuses\/|^\/@[^/]+\/\d+|^\/publish|^\/explore|^\/getting-started|^\/start/); export default @(component => injectIntl(component, { withRef: true })) class ColumnsArea extends ImmutablePureComponent { static contextTypes = { router: PropTypes.object.isRequired, identity: PropTypes.object.isRequired, }; static propTypes = { intl: PropTypes.object.isRequired, columns: ImmutablePropTypes.list.isRequired, isModalOpen: PropTypes.bool.isRequired, singleColumn: PropTypes.bool, children: PropTypes.node, }; // Corresponds to (max-width: $no-gap-breakpoint + 285px - 1px) in SCSS mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 1174px)'); state = { renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches), } componentDidMount() { if (!this.props.singleColumn) { this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false); } if (this.mediaQuery) { if (this.mediaQuery.addEventListener) { this.mediaQuery.addEventListener('change', this.handleLayoutChange); } else { this.mediaQuery.addListener(this.handleLayoutChange); } this.setState({ renderComposePanel: !this.mediaQuery.matches }); } this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl'); } componentWillUpdate(nextProps) { if (this.props.singleColumn !== nextProps.singleColumn && nextProps.singleColumn) { this.node.removeEventListener('wheel', this.handleWheel); } } componentDidUpdate(prevProps) { if (this.props.singleColumn !== prevProps.singleColumn && !this.props.singleColumn) { this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false); } } componentWillUnmount () { if (!this.props.singleColumn) { this.node.removeEventListener('wheel', this.handleWheel); } if (this.mediaQuery) { if (this.mediaQuery.removeEventListener) { this.mediaQuery.removeEventListener('change', this.handleLayoutChange); } else { this.mediaQuery.removeListener(this.handleLayouteChange); } } } handleChildrenContentChange() { if (!this.props.singleColumn) { const modifier = this.isRtlLayout ? -1 : 1; this._interruptScrollAnimation = scrollRight(this.node, (this.node.scrollWidth - window.innerWidth) * modifier); } } handleLayoutChange = (e) => { this.setState({ renderComposePanel: !e.matches }); } handleWheel = () => { if (typeof this._interruptScrollAnimation !== 'function') { return; } this._interruptScrollAnimation(); } setRef = (node) => { this.node = node; } renderLoading = columnId => () => { return columnId === 'COMPOSE' ? : ; } renderError = (props) => { return ; } render () { const { columns, children, singleColumn, isModalOpen, intl } = this.props; const { renderComposePanel } = this.state; const { signedIn } = this.context.identity; if (singleColumn) { const floatingActionButton = (!signedIn || shouldHideFAB(this.context.router.history.location.pathname)) ? null : ; return (
{renderComposePanel && }
{children}
{floatingActionButton}
); } return (
{columns.map(column => { const params = column.get('params', null) === null ? null : column.get('params').toJS(); const other = params && params.other ? params.other : {}; return ( {SpecificComponent => } ); })} {React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))}
); } }