Commit 56682556 authored by Eugen Rochko's avatar Eugen Rochko

Add instance picker

parent b43b909d
......@@ -3,12 +3,18 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.16.2",
"gh-pages": "^0.12.0",
"react": "^15.5.3",
"react-custom-scrollbars": "^4.1.2",
"react-dom": "^15.5.3",
"react-motion": "^0.4.7",
"react-redux": "^5.0.5",
"react-router-dom": "^4.0.0",
"react-snapshot": "^1.1.0"
"react-snapshot": "^1.1.0",
"redux": "^3.7.1",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1"
},
"devDependencies": {
"node-sass": "^4.5.2",
......
......@@ -6,7 +6,7 @@ import {
} from 'react-router-dom';
import Features from './Features';
import Wizard from './Wizard';
import Wizard from './WizardContainer';
import githubLogo from './assets/github-logo.svg';
import mastodonLogo from './assets/mastodon-logo.svg';
......
import React from 'react';
import { fetchInstances } from './actions';
import WizardRow from './WizardRow';
import { Scrollbars } from 'react-custom-scrollbars';
const Wizard = () => (
<div>
Wizard
</div>
);
export default class Wizard extends React.Component {
export default Wizard;
componentDidMount () {
this.props.dispatch(fetchInstances());
}
render () {
const { instances } = this.props;
return (
<div className='wizard-page'>
<h2>Instance picker</h2>
<p>Each instance is a separate, independently owned gateway into the fediverse. You can talk to your friends regardless of which one you choose, but they have different moderation policies and interest groups.</p>
<div className='wizard'>
<div className='wizard-header'>
<div className='wizard-column'>Server</div>
<div className='wizard-column'>Stability</div>
<div className='wizard-column'>Population</div>
<div className='wizard-column'>Theme</div>
</div>
<Scrollbars className='wizard-content' style={{ height: 500 }}>
{instances.map(item =>
<WizardRow key={item._id} instance={item} />
)}
</Scrollbars>
</div>
<p>If you are interested in running your own instance &mdash; for your friends, family or organization &mdash; you can get started by reading the installation documentation. You only host your own users and the content that they subscribe to.</p>
<p><a href='https://github.com/tootsuite/documentation#running-mastodon' className='cta button alt'>Read the docs</a></p>
</div>
);
}
}
import Wizard from './Wizard';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
const getInstances = createSelector(
[state => state.instances],
instances => instances.filter(item => !item.dead && item.uptime > 0.70)
);
const mapStateToProps = state => ({
instances: getInstances(state),
});
export default connect(mapStateToProps)(Wizard);
import React from 'react';
const WizardRow = ({ instance }) => {
const theme = (instance.info && instance.info.theme) || 'General';
let stabilityColor, stabilityLabel,
populationColor, populationLabel;
if (instance.uptime > 0.98) {
stabilityLabel = 'Stable';
stabilityColor = 'green';
} else if (instance.uptime > 0.50) {
stabilityLabel = 'Intermittent'
stabilityColor = 'yellow';
} else {
stabilityLabel = 'Awful'
stabilityColor = 'red';
}
if (!instance.openRegistrations) {
populationLabel = 'Full';
populationColor = 'red';
} else if (instance.users > 20000) {
populationLabel = 'Medium';
populationColor = 'yellow';
} else {
populationLabel = 'New';
populationColor = 'green';
}
return (
<div className='wizard-row'>
<div className='wizard-column'>{instance.name}</div>
<div className='wizard-column'><span className={`indicator-text ${stabilityColor}`}><i className={`indicator ${stabilityColor}`} /> {stabilityLabel}</span></div>
<div className='wizard-column'><span className={`indicator-text ${populationColor}`}><i className={`indicator ${populationColor}`} /> {populationLabel}</span></div>
<div className='wizard-column'>{theme}</div>
</div>
);
};
export default WizardRow;
import axios from 'axios';
export const INSTANCES_FETCH_SUCCESS = 'INSTANCES_FETCH_SUCCESS';
export function fetchInstances() {
return (dispatch, getState) => {
if (getState().instances.length > 0) {
return;
}
axios.get('https://instances.mastodon.xyz/instances.json')
.then(response => dispatch(fetchInstancesSuccess(response.data)));
};
};
export function fetchInstancesSuccess(data) {
return {
type: INSTANCES_FETCH_SUCCESS,
data,
};
};
import React from 'react';
import { render } from 'react-snapshot';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
import App from './App';
import './index.css';
const store = createStore(reducer, applyMiddleware(thunk));
render(
<App />,
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
......@@ -5,3 +5,4 @@
@import 'scss/reset.scss';
@import 'scss/global.scss';
@import 'scss/App.scss';
@import 'scss/Wizard.scss';
import { INSTANCES_FETCH_SUCCESS } from './actions';
const initialState = {
instances: [],
};
export default function reducer(state = initialState, action) {
switch(action.type) {
case INSTANCES_FETCH_SUCCESS:
return { ...state, instances: action.data };
default:
return state;
}
};
@import './variables.scss';
.wizard-page {
max-width: 800px;
margin: 100px auto;
h2 {
font-family: 'Montserrat', sans-serif;
font-size: 21px;
margin-bottom: 20px;
color: $lighter;
}
p {
font-size: 16px;
line-height: 24px;
margin-bottom: 20px;
}
}
.wizard {
margin: 50px auto;
border: 1px solid darken($darkest, 4%);
background: lighten($darkest, 8%);
border-radius: 10px;
max-width: 800px;
.wizard-header {
display: flex;
border-bottom: 1px solid $darkest;
.wizard-column {
font-family: 'Montserrat', sans-serif;
font-weight: 500;
font-size: 14px;
color: $lighter;
border-right: 1px solid $darkest;
&:last-child {
border-right: 0;
}
}
}
.wizard-row {
display: flex;
font-size: 14px;
&:nth-child(even) {
background: lighten($darkest, 2%);
}
&:hover {
color: $lightest;
}
}
.wizard-column {
padding: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:nth-child(1n) {
width: 20%;
}
&:nth-child(2n), &:nth-child(3n) {
width: 17%;
}
&:nth-child(4n) {
width: 100% - 2*17% - 20%;
}
}
.wizard-content {
height: 500px;
overflow-y: hidden;
background: lighten($darkest, 4%);
color: $lighter;
.wizard-column {
cursor: pointer;
}
}
}
.indicator-text {
font-weight: 500;
.indicator {
margin-right: 5px;
}
&.green {
color: $success;
}
&.yellow {
color: #ca8f04;
}
&.red {
color: $error;
}
}
.indicator {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 14px;
&.green {
background: $success;
}
&.yellow {
background: #ca8f04;
}
&.red {
background: $error;
}
}
......@@ -41,6 +41,10 @@ acorn@^5.0.1:
version "5.0.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
add-px-to-style@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/add-px-to-style/-/add-px-to-style-1.0.0.tgz#d0c135441fa8014a8137904531096f67f28f263a"
ajv-keywords@^1.0.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
......@@ -257,6 +261,13 @@ aws4@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
axios@^0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
dependencies:
follow-redirects "^1.2.3"
is-buffer "^1.1.5"
babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
......@@ -1360,6 +1371,14 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1:
parse-json "^2.2.0"
require-from-string "^1.1.0"
create-react-class@^15.5.3:
version "15.6.0"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
object-assign "^4.1.1"
cross-spawn@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
......@@ -1543,7 +1562,7 @@ debug@2.6.1:
dependencies:
ms "0.7.2"
debug@2.6.3, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0, debug@^2.6.0:
debug@2.6.3, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0, debug@^2.4.5, debug@^2.6.0:
version "2.6.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
dependencies:
......@@ -1635,6 +1654,14 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"
dom-css@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/dom-css/-/dom-css-2.1.0.tgz#fdbc2d5a015d0a3e1872e11472bbd0e7b9e6a202"
dependencies:
add-px-to-style "1.0.0"
prefix-style "2.0.1"
to-camel-case "1.0.0"
dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
......@@ -2224,6 +2251,12 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
follow-redirects@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.4.tgz#355e8f4d16876b43f577b0d5ce2668b9723214ea"
dependencies:
debug "^2.4.5"
for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
......@@ -2506,6 +2539,10 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoist-non-react-statics@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
......@@ -2581,7 +2618,7 @@ http-errors@~1.6.1:
setprototypeof "1.0.3"
statuses ">= 1.3.1 < 2"
http-proxy-middleware@0.17.3, http-proxy-middleware@~0.17.1:
http-proxy-middleware@0.17.3:
version "0.17.3"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.3.tgz#940382147149b856084f5534752d5b5a8168cd1d"
dependencies:
......@@ -2590,7 +2627,7 @@ http-proxy-middleware@0.17.3, http-proxy-middleware@~0.17.1:
lodash "^4.17.2"
micromatch "^2.3.11"
http-proxy-middleware@^0.17.4:
http-proxy-middleware@^0.17.4, http-proxy-middleware@~0.17.1:
version "0.17.4"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833"
dependencies:
......@@ -2701,7 +2738,7 @@ interpret@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d"
invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
......@@ -2729,7 +2766,7 @@ is-binary-path@^1.0.0:
dependencies:
binary-extensions "^1.0.0"
is-buffer@^1.0.2:
is-buffer@^1.0.2, is-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
......@@ -3333,6 +3370,10 @@ loader-utils@0.2.x, loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.
json5 "^0.5.0"
object-assign "^4.0.1"
lodash-es@^4.2.0, lodash-es@^4.2.1:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
lodash._arraycopy@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1"
......@@ -3430,7 +3471,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.2.0, lodash@^4.3.0:
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
......@@ -3843,7 +3884,7 @@ oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0:
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
......@@ -4331,6 +4372,10 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
source-map "^0.5.6"
supports-color "^3.2.3"
prefix-style@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/prefix-style/-/prefix-style-2.0.1.tgz#66bba9a870cfda308a5dc20e85e9120932c95a06"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
......@@ -4378,6 +4423,13 @@ promise@7.1.1, promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.10:
version "15.5.10"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
prop-types@^15.5.2, prop-types@~15.5.0:
version "15.5.4"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.4.tgz#2ed3692716a5060f8cc020946d8238e7419d92c0"
......@@ -4481,6 +4533,14 @@ rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-custom-scrollbars@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/react-custom-scrollbars/-/react-custom-scrollbars-4.1.2.tgz#0e60c4a46c4a61f9e4994a7663e2b9cbbc5187a3"
dependencies:
dom-css "^2.0.0"
prop-types "^15.5.10"
raf "^3.1.0"
react-dev-utils@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-0.5.2.tgz#50d0b962d3a94b6c2e8f2011ed6468e4124bc410"
......@@ -4512,6 +4572,18 @@ react-motion@^0.4.7:
performance-now "^0.2.0"
raf "^3.1.0"
react-redux@^5.0.5:
version "5.0.5"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.5.tgz#f8e8c7b239422576e52d6b7db06439469be9846a"
dependencies:
create-react-class "^15.5.3"
hoist-non-react-statics "^1.0.3"
invariant "^2.0.0"
lodash "^4.2.0"
lodash-es "^4.2.0"
loose-envify "^1.1.0"
prop-types "^15.5.10"
react-router-dom@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.0.0.tgz#4fa4418e14b8cfc5bcc0bdea0c4083fb8c2aef10"
......@@ -4696,6 +4768,19 @@ reduce-function-call@^1.0.1:
dependencies:
balanced-match "^0.4.2"
redux-thunk@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"
redux@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.1.tgz#bfc535c757d3849562ead0af18ac52122cd7268e"
dependencies:
lodash "^4.2.1"
lodash-es "^4.2.1"
loose-envify "^1.1.0"
symbol-observable "^1.0.3"
regenerate@^1.2.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
......@@ -4827,6 +4912,10 @@ requires-port@1.0.x, requires-port@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
reselect@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
......@@ -5257,6 +5346,10 @@ svgo@^0.7.0:
sax "~1.2.1"
whet.extend "~0.9.9"
symbol-observable@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
symbol-tree@^3.2.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
......@@ -5333,10 +5426,26 @@ to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
to-camel-case@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46"
dependencies:
to-space-case "^1.0.0"
to-fast-properties@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
to-no-case@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a"
to-space-case@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17"
dependencies:
to-no-case "^1.0.0"
toposort@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.3.tgz#f02cd8a74bd8be2fc0e98611c3bacb95a171869c"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment