Configure react-intl

This commit is contained in:
dominik-zeglen 2019-08-14 18:21:41 +02:00
parent 11ae9fc3c3
commit c5248a2ffb
8 changed files with 86 additions and 7 deletions

View file

@ -5,6 +5,7 @@
"@babel/preset-typescript" "@babel/preset-typescript"
], ],
"plugins": [ "plugins": [
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-class-properties",
[ [
"@babel/plugin-proposal-decorators", "@babel/plugin-proposal-decorators",
@ -16,8 +17,10 @@
[ [
"react-intl", "react-intl",
{ {
"extractFromFormatMessageCall": true,
"messagesDir": "build/locale/" "messagesDir": "build/locale/"
} }
] ]
] ],
"ignore": ["**/*.test.ts", "**/*.test.tsx", "src/storybook"]
} }

19
package-lock.json generated
View file

@ -453,6 +453,16 @@
"@babel/plugin-syntax-json-strings": "^7.2.0" "@babel/plugin-syntax-json-strings": "^7.2.0"
} }
}, },
"@babel/plugin-proposal-numeric-separator": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.2.0.tgz",
"integrity": "sha512-DohMOGDrZiMKS7LthjUZNNcWl8TAf5BZDwZAH4wpm55FuJTHgfqPGdibg7rZDmont/8Yg0zA03IgT6XLeP+4sg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-numeric-separator": "^7.2.0"
}
},
"@babel/plugin-proposal-object-rest-spread": { "@babel/plugin-proposal-object-rest-spread": {
"version": "7.5.5", "version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz",
@ -538,6 +548,15 @@
"@babel/helper-plugin-utils": "^7.0.0" "@babel/helper-plugin-utils": "^7.0.0"
} }
}, },
"@babel/plugin-syntax-numeric-separator": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.2.0.tgz",
"integrity": "sha512-DroeVNkO/BnGpL2R7+ZNZqW+E24aR/4YWxP3Qb15d6lPU8KDzF8HlIUIRCOJRn4X77/oyW4mJY+7FHfY82NLtQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-object-rest-spread": { "@babel/plugin-syntax-object-rest-spread": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz",

View file

@ -75,6 +75,7 @@
"@babel/core": "^7.5.4", "@babel/core": "^7.5.4",
"@babel/plugin-proposal-class-properties": "^7.5.0", "@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/plugin-proposal-decorators": "^7.4.4", "@babel/plugin-proposal-decorators": "^7.4.4",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-object-rest-spread": "^7.5.4", "@babel/plugin-proposal-object-rest-spread": "^7.5.4",
"@babel/preset-env": "^7.5.4", "@babel/preset-env": "^7.5.4",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
@ -163,7 +164,10 @@
}, },
"scripts": { "scripts": {
"build": "webpack -p", "build": "webpack -p",
"build-messages": "babel src/**/*.{ts,tsx} -o build/dashboard.bundle.js && rip json2pot \"build/locale/**/*.json\" -c id -o locale/messages.pot", "extract-json-messages": "babel src 'src/**/*.{ts,tsx}' -o build/dashboard.bundle.js",
"extract-pot-messages": "rip json2pot \"build/locale/**/*.json\" -c description -o locale/messages.pot",
"extract-messages": "npm run extract-json-messages && npm run extract-pot-messages",
"build-messages": "rip po2json 'locale/**/*.po' -m 'build/locale/**/*.json' -o 'locale' -c 'description'",
"build-types": "apollo client:codegen --target=typescript types --globalTypesFile=src/types/globalTypes.ts", "build-types": "apollo client:codegen --target=typescript types --globalTypesFile=src/types/globalTypes.ts",
"generate-component": "plop --plopfile .plop/plopfile.js", "generate-component": "plop --plopfile .plop/plopfile.js",
"lint": "tslint 'src/**/*.{ts,tsx}'", "lint": "tslint 'src/**/*.{ts,tsx}'",

View file

@ -18,7 +18,7 @@ export class DateProvider extends React.Component<{}, DateProviderState> {
componentDidMount() { componentDidMount() {
this.intervalId = window.setInterval( this.intervalId = window.setInterval(
() => this.setState({ date: Date.now() }), () => this.setState({ date: Date.now() }),
10_000 10000
); );
} }

View file

@ -1,5 +1,7 @@
import { LOCALE_URI } from "@saleor/config";
import React from "react"; import React from "react";
import { IntlProvider } from "react-intl"; import { IntlProvider } from "react-intl";
import urlJoin from "url-join";
export type LocaleContextType = string; export type LocaleContextType = string;
export const LocaleContext = React.createContext<LocaleContextType>("en"); export const LocaleContext = React.createContext<LocaleContextType>("en");
@ -7,11 +9,32 @@ export const LocaleContext = React.createContext<LocaleContextType>("en");
const { Consumer: LocaleConsumer, Provider } = LocaleContext; const { Consumer: LocaleConsumer, Provider } = LocaleContext;
const LocaleProvider = ({ children }) => { const LocaleProvider = ({ children }) => {
const [locale] = React.useState(navigator.language); const [localeIndex, setLocaleIndex] = React.useState(0);
const [messages, setMessages] = React.useState({});
const locale = navigator.languages[localeIndex];
React.useEffect(() => {
async function fetchLocale() {
if (locale) {
const res = await fetch(urlJoin(LOCALE_URI, `${locale}.json`), {
credentials: "same-origin",
mode: "cors"
});
if (res.ok) {
const localeData = await res.json();
setMessages(localeData);
} else {
setLocaleIndex(localeIndex + 1);
}
}
}
fetchLocale();
}, [localeIndex]);
return ( return (
<IntlProvider locale={locale}> <IntlProvider locale={locale} messages={messages} key={locale}>
<Provider value={navigator.language}>{children}</Provider> <Provider value={locale}>{children}</Provider>
</IntlProvider> </IntlProvider>
); );
}; };

View file

@ -3,6 +3,7 @@ import { ListSettings, ListViews } from "./types";
export const APP_MOUNT_URI = process.env.APP_MOUNT_URI || "/"; export const APP_MOUNT_URI = process.env.APP_MOUNT_URI || "/";
export const API_URI = process.env.API_URI || "/graphql/"; export const API_URI = process.env.API_URI || "/graphql/";
export const LOCALE_URI = process.env.LOCALE_URI || "/";
export const DEFAULT_INITIAL_SEARCH_DATA: SearchQueryVariables = { export const DEFAULT_INITIAL_SEARCH_DATA: SearchQueryVariables = {
after: null, after: null,

28
src/intl.ts Normal file
View file

@ -0,0 +1,28 @@
import { defineMessages } from "react-intl";
export const commonMessages = defineMessages({
cancel: {
defaultMessage: "Cancel",
id: "cancel"
},
confirm: {
defaultMessage: "Confirm",
id: "confirm"
},
save: {
defaultMessage: "save",
id: "save"
},
savedChanges: {
defaultMessage: "Saved changes",
id: "savedChanges"
}
});
export const sectionNames = defineMessages({
attributes: {
defaultMessage: "attributes",
description: "attributes section name",
id: "attributes"
}
});

View file

@ -21,7 +21,8 @@ const htmlWebpackPlugin = new HtmlWebpackPlugin({
}); });
const environmentPlugin = new webpack.EnvironmentPlugin([ const environmentPlugin = new webpack.EnvironmentPlugin([
"APP_MOUNT_URI", "APP_MOUNT_URI",
"API_URI" "API_URI",
"LOCALE_URI"
]); ]);
const dashboardBuildPath = "build/dashboard/"; const dashboardBuildPath = "build/dashboard/";