HelloWorld.jsx 4.21 KB
Newer Older
1 2
import PropTypes from 'prop-types';
import React from 'react';
3 4
import { Motion, StaggeredMotion, spring, presets } from 'react-motion';
import { FormattedMessage, FormattedNumber } from 'react-intl';
5

6
export default class HelloWorld extends React.PureComponent {
7
  static propTypes = {
Eugen Rochko's avatar
Eugen Rochko committed
8 9 10
    status: PropTypes.string,
    total: PropTypes.number,
    at: PropTypes.number,
11 12 13 14 15 16
    results: PropTypes.array.isRequired,
    domains: PropTypes.array.isRequired,
    inProgress: PropTypes.bool.isRequired,
    fetchProgress: PropTypes.func.isRequired,
    fetchResults: PropTypes.func.isRequired,
    mastodonIsConnected: PropTypes.bool.isRequired,
17 18
  };

19 20 21
  componentDidMount () {
    const { fetchProgress } = this.props;
    fetchProgress();
22 23
  }

24 25 26 27 28
  render () {
    const { status, inProgress, at, total, results, domains, mastodonIsConnected } = this.props;

    if (inProgress) {
      const pct   = total > 0 ? (at / total).toFixed(2) * 100 : 10;
Eugen Rochko's avatar
Eugen Rochko committed
29
      const label = total > 0 ? <span>{at || 0} / {total || 0}</span> : 'Preparing';
30 31 32 33 34 35 36 37 38 39 40

      return (
        <div>
          <div className='page-heading'>
            <h3>
              Searching for your friends...
              <small>Please wait while your Twitter friends are being fetched</small>
            </h3>
          </div>

          <div className='progress-bar'>
Eugen Rochko's avatar
Eugen Rochko committed
41
            <Motion defaultStyle={{ x: 0 }} style={{ x: spring(pct, presets.wobbly) }}>
42 43 44 45 46 47 48 49
              {value => <div style={{ width: `${value.x}%` }} />}
            </Motion>

            <div>{label}</div>
          </div>
        </div>
      );
    }
50 51 52

    return (
      <div>
53 54 55 56 57 58 59 60 61 62 63
        <div className={`page-heading ${!mastodonIsConnected ? 'bottomless' : ''}`}>
          <h3>
            Your friends
            <small>Here are your Twitter friends who are on Mastodon:</small>
          </h3>
        </div>

        {!mastodonIsConnected && <div className='connect-prompt'>
          For your friends to find you as well, you still need to <a target='_blank' href='/users/auth/mastodon'>login via Mastodon</a>
        </div>}

Eugen Rochko's avatar
Eugen Rochko committed
64
        <StaggeredMotion defaultStyles={results.map(_ => ({ scale: 0 }))} styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {
65
          return i == 0
Eugen Rochko's avatar
Eugen Rochko committed
66 67
            ? { scale: spring(1, presets.wobbly) }
            : { scale: spring(prevInterpolatedStyles[i - 1].scale, presets.wobbly) };
68 69 70 71
        })}>
          {interpolatingStyles => (
            <div className='grid'>
              {interpolatingStyles.map((style, i) => (
Eugen Rochko's avatar
Eugen Rochko committed
72
                <a target='_blank' href={results[i].mastodon_url} style={{ transformOrigin: 'center center', transform: `scale(${style.scale})` }} key={results[i].mastodon_username} className='user-card' title={`@${results[i].twitter_username} on Twitter`}>
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
                  <div className='avatar'><img src={results[i].avatar_url} /></div>

                  {results[i].following && <div className='following-indicator'>
                    <i className='fa fa-check' />
                  </div>}

                  <div className='name'>
                    <span className='display-name'>{results[i].display_name}</span>
                    <span className='username'>@{results[i].mastodon_username}</span>
                  </div>
                </a>
              ))}
            </div>
          )}
        </StaggeredMotion>

        <div className='page-heading'>
          <h3>
            Your friends' instances
            <small>Here are the servers your friends are using:</small>
          </h3>
        </div>

        <div className='grid'>
          {domains.map(domain => (
            <a target='_blank' className='instance-card' href={`https://${domain.uri}/about`} key={domain.uri} style={{ backgroundImage: `url(${domain.thumbnail})` }}>
              <div className='info'>
                <span className='title'>{domain.title}</span>
                <span className='uri'>{domain.uri}</span>

                {domain.stats && <span className='users'> (<FormattedMessage id='num_users' defaultMessage='{formatted_count} {count, plural, one {person} other {people}}' values={{ count: domain.stats.user_count, formatted_count: <FormattedNumber value={domain.stats.user_count} /> }} />)</span>}
              </div>
            </a>
          ))}
        </div>
108 109 110 111
      </div>
    );
  }
}