mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 20:21:35 +00:00
Implement react i18n-next
This commit is contained in:
parent
2c8dfdbff5
commit
1061403487
@ -27,7 +27,7 @@ services:
|
||||
build: ./frontend
|
||||
container_name: npm-dev
|
||||
restart: always
|
||||
command: npm run build
|
||||
command: npm run dev
|
||||
volumes:
|
||||
- ./frontend:/usr/src/frontend
|
||||
|
||||
|
62
frontend/package-lock.json
generated
62
frontend/package-lock.json
generated
@ -4273,6 +4273,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"html-escaper": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
|
||||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
|
||||
},
|
||||
"html-parse-stringify": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
|
||||
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
|
||||
"requires": {
|
||||
"void-elements": "3.1.0"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
||||
@ -4296,6 +4309,40 @@
|
||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||
},
|
||||
"i18next": {
|
||||
"version": "21.6.14",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.14.tgz",
|
||||
"integrity": "sha512-XL6WyD+xlwQwbieXRlXhKWoLb/rkch50/rA+vl6untHnJ+aYnkQ0YDZciTWE78PPhOpbi2gR0LTJCJpiAhA+uQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.17.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.17.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
|
||||
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"i18next-browser-languagedetector": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.4.tgz",
|
||||
"integrity": "sha512-wukWnFeU7rKIWT66VU5i8I+3Zc4wReGcuDK2+kuFhtoxBRGWGdvYI9UQmqNL/yQH1KogWwh+xGEaIPH8V/i2Zg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.14.6"
|
||||
}
|
||||
},
|
||||
"i18next-xhr-backend": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-3.2.2.tgz",
|
||||
"integrity": "sha512-OtRf2Vo3IqAxsttQbpjYnmMML12IMB5e0fc5B7qKJFLScitYaXa1OhMX0n0X/3vrfFlpHL9Ro/H+ps4Ej2j7QQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.5.5"
|
||||
}
|
||||
},
|
||||
"image-size": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
|
||||
@ -6355,6 +6402,16 @@
|
||||
"scheduler": "^0.20.2"
|
||||
}
|
||||
},
|
||||
"react-i18next": {
|
||||
"version": "11.16.2",
|
||||
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.2.tgz",
|
||||
"integrity": "sha512-1iuZduvARUelL5ux663FvIoDZExwFO+9QtRAAt4uvs1/aun4cUZt8XBrVg7iiDgNls9cOSORAhE7Ri5KA9RMvg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.14.5",
|
||||
"html-escaper": "^2.0.2",
|
||||
"html-parse-stringify": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
@ -7993,6 +8050,11 @@
|
||||
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
|
||||
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
|
||||
},
|
||||
"void-elements": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
"integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
|
||||
},
|
||||
"walker": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
|
||||
|
@ -33,8 +33,12 @@
|
||||
"@mui/x-data-grid": "^5.2.2",
|
||||
"country-flag-icons": "^1.4.25",
|
||||
"date-fns": "^2.28.0",
|
||||
"i18next": "^21.6.14",
|
||||
"i18next-browser-languagedetector": "^6.1.4",
|
||||
"i18next-xhr-backend": "^3.2.2",
|
||||
"material-ui-image": "^3.3.2",
|
||||
"react-countdown": "^2.3.2",
|
||||
"react-i18next": "^11.16.2",
|
||||
"react-native": "^0.66.4",
|
||||
"react-native-svg": "^12.1.1",
|
||||
"react-qr-code": "^2.0.3",
|
||||
|
@ -5,6 +5,9 @@ import { CssBaseline, IconButton} from "@mui/material";
|
||||
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||
import UnsafeAlert from "./UnsafeAlert";
|
||||
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import i18n from "./i18n";
|
||||
|
||||
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||
import LightModeIcon from '@mui/icons-material/LightMode';
|
||||
|
||||
@ -12,18 +15,16 @@ export default class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
nickname: null,
|
||||
token: null,
|
||||
dark: false,
|
||||
lang: 'en',
|
||||
}
|
||||
}
|
||||
|
||||
setAppState=(newState)=>{
|
||||
this.setState(newState)
|
||||
setLang=(newLang)=>{
|
||||
this.setState({lang:newLang})
|
||||
}
|
||||
|
||||
lightTheme = createTheme({
|
||||
});
|
||||
lightTheme = createTheme({});
|
||||
|
||||
darkTheme = createTheme({
|
||||
palette: {
|
||||
@ -36,14 +37,16 @@ export default class App extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<ThemeProvider theme={this.state.dark ? this.darkTheme : this.lightTheme}>
|
||||
<CssBaseline/>
|
||||
<IconButton sx={{position:'fixed',right:'0px'}} onClick={()=>this.setState({dark:!this.state.dark})}>
|
||||
{this.state.dark ? <LightModeIcon/>:<DarkModeIcon/>}
|
||||
</IconButton>
|
||||
<UnsafeAlert className="unsafeAlert"/>
|
||||
<HomePage setAppState={this.setAppState}/>
|
||||
<HomePage changeLang={i18n.changeLanguage}/>
|
||||
</ThemeProvider>
|
||||
</I18nextProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -553,14 +553,7 @@ bottomBarDesktop =()=>{
|
||||
|
||||
<Grid container item xs={1}>
|
||||
<Grid item xs={6}>
|
||||
<Select
|
||||
size = 'small'
|
||||
defaultValue={1}
|
||||
inputProps={{
|
||||
style: {textAlign:"center"}
|
||||
}}>
|
||||
<MenuItem value={1}>EN</MenuItem>
|
||||
</Select>
|
||||
<this.LangSelect/>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<Tooltip enterTouchDelay="250" title="Show community and support links">
|
||||
@ -587,6 +580,26 @@ bottomBarDesktop =()=>{
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
handleChangeLang=(e)=>{
|
||||
this.props.changeLang(e.target.value)
|
||||
}
|
||||
LangSelect = () => {
|
||||
return(
|
||||
<Select
|
||||
size = 'small'
|
||||
defaultValue={'en'}
|
||||
inputProps={{
|
||||
style: {textAlign:"center"}
|
||||
}}
|
||||
onChange={this.handleChangeLang}>
|
||||
<MenuItem value={'en'}>EN</MenuItem>
|
||||
<MenuItem value={'es'}>ES</MenuItem>
|
||||
<MenuItem value={'de'}>DE</MenuItem>
|
||||
<MenuItem value={'ru'}>RU</MenuItem>
|
||||
<MenuItem value={'cn'}>CN</MenuItem>
|
||||
</Select>
|
||||
)
|
||||
}
|
||||
|
||||
handleClickOpenExchangeSummary = () => {
|
||||
this.getInfo();
|
||||
@ -770,14 +783,7 @@ bottomBarPhone =()=>{
|
||||
|
||||
<Grid container item xs={3.8}>
|
||||
<Grid item xs={6}>
|
||||
<Select
|
||||
size = 'small'
|
||||
defaultValue={1}
|
||||
inputProps={{
|
||||
style: {textAlign:"center"}
|
||||
}}>
|
||||
<MenuItem value={1}>EN</MenuItem>
|
||||
</Select>
|
||||
<this.LangSelect/>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<Tooltip enterTouchDelay="250" title="Show community and support links">
|
||||
|
@ -41,7 +41,7 @@ export default class HomePage extends Component {
|
||||
</Switch>
|
||||
</div>
|
||||
<div className='bottomBar'>
|
||||
<BottomBar redirectTo={this.redirectTo} {...this.state} setAppState={this.setAppState} />
|
||||
<BottomBar changeLang={this.props.changeLang} redirectTo={this.redirectTo} {...this.state} setAppState={this.setAppState} />
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
|
@ -10,6 +10,8 @@ import RoboSatsNoTextIcon from "./icons/RoboSatsNoTextIcon"
|
||||
|
||||
import BoltIcon from '@mui/icons-material/Bolt';
|
||||
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== '') {
|
||||
@ -27,7 +29,7 @@ function getCookie(name) {
|
||||
}
|
||||
const csrftoken = getCookie('csrftoken');
|
||||
|
||||
export default class UserGenPage extends Component {
|
||||
class UserGenPage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -101,8 +103,7 @@ export default class UserGenPage extends Component {
|
||||
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
|
||||
};
|
||||
fetch("/api/user", requestOptions)
|
||||
.then((response) => response.json())
|
||||
.then((data) => console.log(data));
|
||||
.then((response) => response.json());
|
||||
}
|
||||
|
||||
handleClickNewRandomToken=()=>{
|
||||
@ -150,6 +151,7 @@ export default class UserGenPage extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
return (
|
||||
<Grid container spacing={1}>
|
||||
<Grid item>
|
||||
@ -168,7 +170,7 @@ export default class UserGenPage extends Component {
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12} align="center">
|
||||
<Tooltip enterTouchDelay="0" title="This is your trading avatar">
|
||||
<Tooltip enterTouchDelay="0" title={t("This is your trading avatar")}>
|
||||
<div style={{ maxWidth: 200, maxHeight: 200 }}>
|
||||
<Image className='newAvatar'
|
||||
disableError='true'
|
||||
@ -276,3 +278,5 @@ export default class UserGenPage extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withTranslation()(UserGenPage);
|
104
frontend/src/components/i18n.js
Normal file
104
frontend/src/components/i18n.js
Normal file
@ -0,0 +1,104 @@
|
||||
import i18n from "i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
// we init with resources
|
||||
resources: {
|
||||
en: {
|
||||
translations: {
|
||||
Your_avatar: "Avatar",
|
||||
"This is your trading avatar":
|
||||
"This is your trading avatar",
|
||||
"Plugins to detect the user language":
|
||||
"Plugins to detect the user language",
|
||||
"Plugins to load translations": "Plugins to load translations",
|
||||
"Optionally cache the translations":
|
||||
"Optionally cache the translations",
|
||||
Advantages: "Advantages",
|
||||
"Flexibility to use other packages": "Flexibility to use other packages"
|
||||
}
|
||||
},
|
||||
es: {
|
||||
translations: {
|
||||
Your_avatar: "Avatar",
|
||||
"This is your trading avatar":
|
||||
"Este es tu avatar para comprar y vender",
|
||||
"Plugins to detect the user language":
|
||||
"ユーザー言語を検出するためのプラグイン",
|
||||
"Plugins to load translations": "翻訳をロードするためのプラグイン",
|
||||
"Optionally cache the translations": "必要に応じて翻訳をキャッシュする",
|
||||
Advantages: "利点",
|
||||
"Flexibility to use other packages": "他のパッケージを使用する柔軟性"
|
||||
}
|
||||
},
|
||||
|
||||
ru: {
|
||||
translations: {
|
||||
Introduction: "प्रस्तावना",
|
||||
"is an internationalization-framework which offers a complete solution to localize your product from web to mobile and desktop":
|
||||
"एक अंतर्राष्ट्रीयकरण - ढांचा है जो आपके उत्पाद को वेब से मोबाइल और डेस्कटॉप पर स्थानांतरित करने का एक संपूर्ण समाधान प्रदान करता है",
|
||||
"Plugins to detect the user language":
|
||||
"उपयोगकर्ता भाषा का पता लगाने के लिए प्लगइन्स",
|
||||
"Plugins to load translations": "अनुवाद लोड करने के लिए प्लगइन्स",
|
||||
"Optionally cache the translations": "वैकल्पिक रूप से अनुवाद कैश करें",
|
||||
Advantages: "लाभ",
|
||||
"Flexibility to use other packages":
|
||||
"अन्य पैकेजों का उपयोग करने के लिए लचीलापन"
|
||||
}
|
||||
},
|
||||
|
||||
de: {
|
||||
translations: {
|
||||
Introduction: "Einführung",
|
||||
"is an internationalization-framework which offers a complete solution to localize your product from web to mobile and desktop":
|
||||
"ist ein Internationalisierungs-Framework, das eine Komplettlösung für die Lokalisierung Ihres Produkts vom Web auf das Handy und den Desktop bietet",
|
||||
"Plugins to detect the user language":
|
||||
"Plugins zur Erkennung der Benutzersprache",
|
||||
"Plugins to load translations": "Plugins zum Laden von Übersetzungen",
|
||||
"Optionally cache the translations":
|
||||
"Optional die Übersetzungen zwischenspeichern",
|
||||
Advantages: "Vorteile",
|
||||
"Flexibility to use other packages":
|
||||
"Flexibilität zur Verwendung anderer Pakete"
|
||||
}
|
||||
},
|
||||
cn: {
|
||||
translations: {
|
||||
Introduction: "Introduction",
|
||||
"is an internationalization-framework which offers a complete solution to localize your product from web to mobile and desktop":
|
||||
"est un cadre d'internationalisation qui offre une solution complète pour localiser votre produit du Web au mobile et au bureau",
|
||||
"Plugins to detect the user language":
|
||||
"Plugins pour détecter la langue de l'utilisateur",
|
||||
"Plugins to load translations": "Plugins pour charger les traductions",
|
||||
"Optionally cache the translations":
|
||||
"Cachez éventuellement les traductions",
|
||||
Advantages: "Les avantages",
|
||||
"Flexibility to use other packages":
|
||||
"Flexibilité d'utiliser d'autres packages"
|
||||
}
|
||||
}
|
||||
},
|
||||
fallbackLng: "en",
|
||||
debug: true,
|
||||
|
||||
// have a common namespace used around the full app
|
||||
ns: ["translations"],
|
||||
defaultNS: "translations",
|
||||
|
||||
keySeparator: false, // we use content as keys
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
formatSeparator: ","
|
||||
},
|
||||
|
||||
react: {
|
||||
wait: true
|
||||
}
|
||||
});
|
||||
|
||||
export default i18n;
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user