You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.1 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ImmutablePropTypes from 'react-immutable-proptypes';
  4. import ImmutablePureComponent from 'react-immutable-pure-component';
  5. import ReactSwipeableViews from 'react-swipeable-views';
  6. import { links, getIndex, getLink } from './tabs_bar';
  7. import BundleContainer from '../containers/bundle_container';
  8. import ColumnLoading from './column_loading';
  9. import BundleColumnError from './bundle_column_error';
  10. import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline } from '../../ui/util/async-components';
  11. const componentMap = {
  12. 'COMPOSE': Compose,
  13. 'HOME': HomeTimeline,
  14. 'NOTIFICATIONS': Notifications,
  15. 'PUBLIC': PublicTimeline,
  16. 'COMMUNITY': CommunityTimeline,
  17. 'HASHTAG': HashtagTimeline,
  18. };
  19. export default class ColumnsArea extends ImmutablePureComponent {
  20. static contextTypes = {
  21. router: PropTypes.object.isRequired,
  22. };
  23. static propTypes = {
  24. columns: ImmutablePropTypes.list.isRequired,
  25. singleColumn: PropTypes.bool,
  26. children: PropTypes.node,
  27. };
  28. handleSwipe = (index) => {
  29. window.requestAnimationFrame(() => {
  30. window.requestAnimationFrame(() => {
  31. this.context.router.history.push(getLink(index));
  32. });
  33. });
  34. }
  35. renderView = (link, index) => {
  36. const columnIndex = getIndex(this.context.router.history.location.pathname);
  37. const title = link.props.children[1] && React.cloneElement(link.props.children[1]);
  38. const icon = (link.props.children[0] || link.props.children).props.className.split(' ')[2].split('-')[1];
  39. const view = (index === columnIndex) ?
  40. React.cloneElement(this.props.children) :
  41. <ColumnLoading title={title} icon={icon} />;
  42. return (
  43. <div className='columns-area' key={index}>
  44. {view}
  45. </div>
  46. );
  47. }
  48. renderLoading = () => {
  49. return <ColumnLoading />;
  50. }
  51. renderError = (props) => {
  52. return <BundleColumnError {...props} />;
  53. }
  54. render () {
  55. const { columns, children, singleColumn } = this.props;
  56. const columnIndex = getIndex(this.context.router.history.location.pathname);
  57. if (singleColumn) {
  58. return columnIndex !== -1 ? (
  59. <ReactSwipeableViews index={columnIndex} onChangeIndex={this.handleSwipe} animateTransitions={false} style={{ height: '100%' }}>
  60. {links.map(this.renderView)}
  61. </ReactSwipeableViews>
  62. ) : <div className='columns-area'>{children}></div>;
  63. }
  64. return (
  65. <div className='columns-area'>
  66. {columns.map(column => {
  67. const params = column.get('params', null) === null ? null : column.get('params').toJS();
  68. return (
  69. <BundleContainer key={column.get('uuid')} fetchComponent={componentMap[column.get('id')]} loading={this.renderLoading} error={this.renderError}>
  70. {SpecificComponent => <SpecificComponent columnId={column.get('uuid')} params={params} multiColumn />}
  71. </BundleContainer>
  72. );
  73. })}
  74. {React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))}
  75. </div>
  76. );
  77. }
  78. }