content: import React from 'react';
  import { connect } from 'react-redux';
  import ImmutablePropTypes from 'react-immutable-proptypes';
  import PropTypes from 'prop-types';
  import { lookupAccount, fetchAccount } from '../../actions/accounts';
  import { expandAccountFeaturedTimeline, expandAccountTimeline } from '../../actions/timelines';
  import StatusList from '../../components/status_list';
  import LoadingIndicator from '../../components/loading_indicator';
  import Column from '../ui/components/column';
  import HeaderContainer from './containers/header_container';
  import ColumnBackButton from '../../components/column_back_button';
  import { List as ImmutableList } from 'immutable';
  import ImmutablePureComponent from 'react-immutable-pure-component';
  import { FormattedMessage } from 'react-intl';
  import MissingIndicator from 'mastodon/components/missing_indicator';
  import TimelineHint from 'mastodon/components/timeline_hint';
  import { me } from 'mastodon/initial_state';
  import { connectTimeline, disconnectTimeline } from 'mastodon/actions/timelines';
  
  const emptyList = ImmutableList();
  
  const mapStateToProps = (state, { params: { acct, id }, withReplies = false }) => {
    const accountId = id || state.getIn(['accounts_map', acct]);
  
    if (!accountId) {
      return {
        isLoading: true,
      };
    }
  
    const path = withReplies ? `${accountId}:with_replies` : accountId;
  
    return {
      accountId,
      remote: !!(state.getIn(['accounts', accountId, 'acct']) !== state.getIn(['accounts', accountId, 'username'])),
      remoteUrl: state.getIn(['accounts', accountId, 'url']),
      isAccount: !!state.getIn(['accounts', accountId]),
      statusIds: state.getIn(['timelines', `account:${path}`, 'items'], emptyList),
      featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList),
      isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']),
      hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']),
      suspended: state.getIn(['accounts', accountId, 'suspended'], false),
      blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false),
    };
  };
  
  const RemoteHint = ({ url }) => (
    <TimelineHint url={url} resource={<FormattedMessage id='timeline_hint.resources.statuses' defaultMessage='Older posts' />} />
  );
  
  RemoteHint.propTypes = {
    url: PropTypes.string.isRequired,
  };
  
  export default @connect(mapStateToProps)
  class AccountTimeline extends ImmutablePureComponent {
  
    static propTypes = {
      params: PropTypes.shape({
        acct: PropTypes.string,
        id: PropTypes.string,
      }).isRequired,
      accountId: PropTypes.string,
      dispatch: PropTypes.func.isRequired,
      statusIds: ImmutablePropTypes.list,
      featuredStatusIds: ImmutablePropTypes.list,
      isLoading: PropTypes.bool,
      hasMore: PropTypes.bool,
      withReplies: PropTypes.bool,
      blockedBy: PropTypes.bool,
      isAccount: PropTypes.bool,
      suspended: PropTypes.bool,
      remote: PropTypes.bool,
      remoteUrl: PropTypes.string,
      multiColumn: PropTypes.bool,
    };
  
    _load () {
      const { accountId, withReplies, dispatch } = this.props;
  
      dispatch(fetchAccount(accountId));
  
      if (!withReplies) {
        dispatch(expandAccountFeaturedTimeline(accountId));
      }
  
      dispatch(expandAccountTimeline(accountId, { withReplies }));
  
      if (accountId === me) {
        dispatch(connectTimeline(`account:${me}`));
      }
    }
  
    componentDidMount () {
      const { params: { acct }, accountId, dispatch } = this.props;
  
      if (accountId) {
        this._load();
      } else {
        dispatch(lookupAccount(acct));
      }
    }
  
    componentDidUpdate (prevProps) {
      const { params: { acct }, accountId, dispatch } = this.props;
  
      if (prevProps.accountId !== accountId && accountId) {
        this._load();
      } else if (prevProps.params.acct !== acct) {
        dispatch(lookupAccount(acct));
      }
  
      if (prevProps.accountId === me && accountId !== me) {
        dispatch(disconnectTimeline(`account:${me}`));
      }
    }
  
    componentWillUnmount () {
      const { dispatch, accountId } = this.props;
  
      if (accountId === me) {
        dispatch(disconnectTimeline(`account:${me}`));
      }
    }
  
    handleLoadMore = maxId => {
      this.props.dispatch(expandAccountTimeline(this.props.accountId, { maxId, withReplies: this.props.withReplies }));
    }
  
    render () {
      const { statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, suspended, isAccount, multiColumn, remote, remoteUrl } = this.props;
  
      if (!isAccount) {
        return (
          <Column>
            <ColumnBackButton multiColumn={multiColumn} />
            <MissingIndicator />
          </Column>
        );
      }
  
      if (!statusIds && isLoading) {
        return (
          <Column>
            <LoadingIndicator />
          </Column>
        );
      }
  
      let emptyMessage;
  
      if (suspended) {
        emptyMessage = <FormattedMessage id='empty_column.account_suspended' defaultMessage='Account suspended' />;
      } else if (blockedBy) {
        emptyMessage = <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' />;
      } else if (remote && statusIds.isEmpty()) {
        emptyMessage = <RemoteHint url={remoteUrl} />;
      } else {
        emptyMessage = <FormattedMessage id='empty_column.account_timeline' defaultMessage='No posts found' />;
      }
  
      const remoteMessage = remote ? <RemoteHint url={remoteUrl} /> : null;
  
      return (
        <Column>
          <ColumnBackButton multiColumn={multiColumn} />
  
          <StatusList
            prepend={<HeaderContainer accountId={this.props.accountId} />}
            alwaysPrepend
            append={remoteMessage}
            scrollKey='account_timeline'
            statusIds={(suspended || blockedBy) ? emptyList : statusIds}
            featuredStatusIds={featuredStatusIds}
            isLoading={isLoading}
            hasMore={hasMore}
            onLoadMore={this.handleLoadMore}
            emptyMessage={emptyMessage}
            bindToDocument={!multiColumn}
            timelineId='account'
          />
        </Column>
      );
    }
  
  }
  