Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-intl #609

Merged
merged 5 commits into from
Apr 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
"express": "4.13.4",
"express-graphql": "0.5.1",
"express-jwt": "3.3.0",
"express-request-language": "^1.1.4",
"fastclick": "1.0.6",
"fbjs": "0.8.1",
"fbjs": "0.8.0",
"front-matter": "2.0.7",
"graphiql": "0.7.0",
"graphql": "0.5.0",
"history": "2.1.0",
"history": "2.0.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this branch is a little behind the master.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, my bad.. I'm fixing this now..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, I will merge the master into it in a moment.

Copy link
Collaborator Author

@langpavel langpavel Apr 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging master will not help..
I done some weird rebasing against redux and master branch and this is badly copied file. Grrr 🎱

"intl": "^1.1.0",
"intl-locales-supported": "^1.0.0",
"isomorphic-style-loader": "1.0.0",
"jade": "1.11.0",
"jsonwebtoken": "5.7.0",
Expand All @@ -33,6 +36,10 @@
"pretty-error": "2.0.0",
"react": "15.0.1",
"react-dom": "15.0.1",
"react-intl": "^2.1.0",
"react-redux": "^4.4.5",
"redux": "^3.4.0",
"redux-thunk": "^2.0.1",
"sequelize": "^3.21.0",
"source-map-support": "0.4.0",
"sqlite3": "^3.1.3",
Expand All @@ -42,10 +49,11 @@
"devDependencies": {
"assets-webpack-plugin": "^3.4.0",
"autoprefixer": "^6.3.6",
"babel-cli": "^6.7.7",
"babel-core": "^6.7.7",
"babel-eslint": "^6.0.3",
"babel-cli": "^6.7.5",
"babel-core": "^6.7.6",
"babel-eslint": "^6.0.2",
"babel-loader": "^6.2.4",
"babel-plugin-react-intl": "^2.1.2",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-rewire": "^1.0.0-rc-2",
"babel-plugin-transform-react-constant-elements": "^6.5.0",
Expand All @@ -58,7 +66,7 @@
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.7.2",
"babel-template": "^6.7.0",
"babel-types": "^6.7.7",
"babel-types": "^6.7.2",
"browser-sync": "^2.12.3",
"chai": "^3.5.0",
"css-loader": "^0.23.1",
Expand Down Expand Up @@ -90,9 +98,10 @@
"react-transform-catch-errors": "^1.0.2",
"react-transform-hmr": "^1.0.4",
"redbox-react": "^1.2.3",
"redux-logger": "^2.6.1",
"sinon": "^2.0.0-pre",
"stylelint": "^6.0.3",
"stylelint-config-standard": "^6.0.0",
"stylelint": "^5.4.0",
"stylelint-config-standard": "^5.0.0",
"url-loader": "^0.5.7",
"webpack": "^1.13.0",
"webpack-hot-middleware": "^2.10.0",
Expand Down Expand Up @@ -153,6 +162,7 @@
"test:watch": "mocha src/**/*.test.js --require test/setup.js --compilers js:babel-register --reporter min --watch",
"clean": "babel-node tools/run clean",
"copy": "babel-node tools/run copy",
"extractMessages": "babel-node tools/run extractMessages",
"bundle": "babel-node tools/run bundle",
"build": "babel-node tools/run build",
"deploy": "babel-node tools/run deploy",
Expand Down
3 changes: 3 additions & 0 deletions src/actions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Action creators

Action Creators should go there
55 changes: 55 additions & 0 deletions src/actions/intl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import fetch from '../core/fetch';
import {
SET_LOCALE_START,
SET_LOCALE_SUCCESS,
SET_LOCALE_ERROR,
} from '../constants';

export function setLocale({ locale }) {
return async (dispatch) => {
dispatch({
type: SET_LOCALE_START,
payload: {
locale,
},
});

try {
const resp = await fetch('/graphql', {
method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `query{intl(locale:${JSON.stringify(locale)}){id,message}}`,
}),
credentials: 'include',
});
if (resp.status !== 200) throw new Error(resp.statusText);
const { data } = await resp.json();
const messages = data.intl.reduce((msgs, msg) => {
msgs[msg.id] = msg.message; // eslint-disable-line no-param-reassign
return msgs;
}, {});
dispatch({
type: SET_LOCALE_SUCCESS,
payload: {
locale,
messages,
},
});
} catch (error) {
dispatch({
type: SET_LOCALE_ERROR,
payload: {
locale,
error,
},
});
return false;
}

return true;
};
}
11 changes: 11 additions & 0 deletions src/actions/runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { SET_RUNTIME_VARIABLE } from '../constants';

export function setRuntimeVariable({ name, value }) {
return {
type: SET_RUNTIME_VARIABLE,
payload: {
name,
value,
},
};
}
34 changes: 31 additions & 3 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@
*/

import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import FastClick from 'fastclick';
import { match } from 'universal-router';
import routes from './routes';
import history from './core/history';
import configureStore from './store/configureStore';
import { addEventListener, removeEventListener } from './core/DOMUtils';
import Provide from './components/Provide';

import { addLocaleData } from 'react-intl';

import en from 'react-intl/locale-data/en';
import cs from 'react-intl/locale-data/cs';

[en, cs].forEach(addLocaleData);

const context = {
store: null,
insertCss: styles => styles._insertCss(),
setTitle: value => (document.title = value),
setMeta: (name, content) => {
Expand Down Expand Up @@ -60,11 +71,20 @@ let renderComplete = (state, callback) => {
};
};

function render(container, state, component) {
function render(container, state, config, component) {
return new Promise((resolve, reject) => {
if (process.env.NODE_ENV === 'development') {
console.log(// eslint-disable-line no-console
'React rendering. State:',
config.store.getState()
);
}

try {
ReactDOM.render(
component,
<Provide {...config}>
{component}
</Provide>,
container,
renderComplete.bind(undefined, state, resolve)
);
Expand All @@ -77,10 +97,18 @@ function render(container, state, component) {
function run() {
let currentLocation = null;
const container = document.getElementById('app');
const initialState = JSON.parse(
document.
getElementById('source').
getAttribute('data-initial-state')
);

// Make taps on links and buttons work fast on mobiles
FastClick.attach(document.body);

const store = configureStore(initialState);
context.store = store;

// Re-render the app when window.location changes
const removeHistoryListener = history.listen(location => {
currentLocation = location;
Expand All @@ -89,7 +117,7 @@ function run() {
query: location.query,
state: location.state,
context,
render: render.bind(undefined, container, location.state),
render: render.bind(undefined, container, location.state, { store }),
}).catch(err => console.error(err)); // eslint-disable-line no-console
});

Expand Down
10 changes: 7 additions & 3 deletions src/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class App extends Component {
insertCss: PropTypes.func,
setTitle: PropTypes.func,
setMeta: PropTypes.func,
}),
}).isRequired,
children: PropTypes.element.isRequired,
error: PropTypes.object,
};
Expand Down Expand Up @@ -51,14 +51,18 @@ class App extends Component {
}

render() {
return !this.props.error ? (
if (this.props.error) {
return this.props.children;
}

return (
<div>
<Header />
{this.props.children}
<Feedback />
<Footer />
</div>
) : this.props.children;
);
}

}
Expand Down
33 changes: 29 additions & 4 deletions src/components/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,30 @@
*/

import React from 'react';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Header.scss';
import Link from '../Link';
import Navigation from '../Navigation';
import LanguageSwitcher from '../LanguageSwitcher';

const messages = defineMessages({
brand: {
id: 'header.brand',
defaultMessage: 'Your Company Brand',
description: 'Brand name displayed in header',
},
bannerTitle: {
id: 'header.banner.title',
defaultMessage: 'React',
description: 'Title in page header',
},
bannerDesc: {
id: 'header.banner.desc',
defaultMessage: 'Complex web apps made easy',
description: 'Description in header',
},
});

function Header() {
return (
Expand All @@ -20,15 +40,20 @@ function Header() {
<Navigation className={s.nav} />
<Link className={s.brand} to="/">
<img src={require('./logo-small.png')} width="38" height="38" alt="React" />
<span className={s.brandTxt}>Your Company</span>
<span className={s.brandTxt}>
<FormattedMessage {...messages.brand} />
</span>
</Link>
<LanguageSwitcher />
<div className={s.banner}>
<h1 className={s.bannerTitle}>React</h1>
<p className={s.bannerDesc}>Complex web apps made easy</p>
<h1 className={s.bannerTitle}>
<FormattedMessage {...messages.bannerTitle} />
</h1>
<FormattedMessage tagName="p" {...messages.bannerDesc} />
</div>
</div>
</div>
);
}

export default withStyles(s)(Header);
export default injectIntl(withStyles(s)(Header));
42 changes: 42 additions & 0 deletions src/components/LanguageSwitcher/LanguageSwitcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable no-shadow */

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { setLocale } from '../../actions/intl';

function LanguageSwitcher({ currentLocale, availableLocales, setLocale }) {
const isSelected = locale => locale === currentLocale;
return (
<div>
{availableLocales.map(locale => (
<span key={locale}>
{isSelected(locale) ? (
<span>{locale}</span>
) : (
<a
href={`?locale=${locale}`}
onClick={(e) => {
setLocale({ locale });
e.preventDefault();
}}
>{locale}</a>
)}
{' '}
</span>
))}
</div>
);
}

LanguageSwitcher.propTypes = {
currentLocale: PropTypes.string.isRequired,
availableLocales: PropTypes.arrayOf(PropTypes.string).isRequired,
setLocale: PropTypes.func.isRequired,
};

export default connect(state => ({
availableLocales: state.runtime.availableLocales,
currentLocale: state.intl.locale,
}), {
setLocale,
})(LanguageSwitcher);
6 changes: 6 additions & 0 deletions src/components/LanguageSwitcher/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "LanguageSwitcher",
"version": "0.0.0",
"private": true,
"main": "./LanguageSwitcher.js"
}
Loading