Add translation example

Only implemented to a few pages as an example, looking to get feedback.

I do not know japanese, I just used google translate to translate a few words as an example - is most likely incorrect
This commit is contained in:
Dylan Van Nielen 2022-06-14 18:15:48 +09:30
parent eef2d451b7
commit 9f921bd8a6
9 changed files with 315 additions and 37 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ node_modules
devAssets
.DS_Store
.vscode

229
package-lock.json generated
View file

@ -21,6 +21,9 @@
"flux": "^4.0.3",
"formik": "^2.2.9",
"html-react-parser": "^1.4.14",
"i18next": "^21.8.9",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.1",
"katex": "^0.15.6",
"linkifyjs": "^2.1.9",
"matrix-js-sdk": "^18.0.0",
@ -37,6 +40,7 @@
"react-dnd-html5-backend": "^15.1.3",
"react-dom": "^17.0.2",
"react-google-recaptcha": "^2.1.0",
"react-i18next": "^11.17.1",
"react-modal": "^3.15.1",
"sanitize-html": "^2.7.0",
"tippy.js": "^6.3.7",
@ -1694,9 +1698,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
"integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz",
"integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
@ -4573,11 +4577,11 @@
}
},
"node_modules/cross-fetch": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"dependencies": {
"node-fetch": "2.6.1"
"node-fetch": "2.6.7"
}
},
"node_modules/cross-spawn": {
@ -7290,6 +7294,11 @@
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
},
"node_modules/html-loader": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/html-loader/-/html-loader-3.1.0.tgz",
@ -7331,6 +7340,14 @@
"node": ">=12"
}
},
"node_modules/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==",
"dependencies": {
"void-elements": "3.1.0"
}
},
"node_modules/html-react-parser": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-1.4.14.tgz",
@ -7475,6 +7492,44 @@
"node": ">=10.17.0"
}
},
"node_modules/i18next": {
"version": "21.8.9",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.9.tgz",
"integrity": "sha512-PY9a/8ADVmnju1tETeglbbVQi+nM5pcJQWm9kvKMTE3GPgHHtpDsHy5HQ/hccz2/xtW7j3vuso23JdQSH0EttA==",
"funding": [
{
"type": "individual",
"url": "https://locize.com"
},
{
"type": "individual",
"url": "https://locize.com/i18next.html"
},
{
"type": "individual",
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
"dependencies": {
"@babel/runtime": "^7.17.2"
}
},
"node_modules/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==",
"dependencies": {
"@babel/runtime": "^7.14.6"
}
},
"node_modules/i18next-http-backend": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.4.1.tgz",
"integrity": "sha512-s4Q9hK2jS29iyhniMP82z+yYY8riGTrWbnyvsSzi5TaF7Le4E7b5deTmtuaRuab9fdDcYXtcwdBgawZG+JCEjA==",
"dependencies": {
"cross-fetch": "3.1.5"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -9833,11 +9888,22 @@
"dev": true
},
"node_modules/node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-forge": {
@ -11391,6 +11457,28 @@
"react": ">=16.4.1"
}
},
"node_modules/react-i18next": {
"version": "11.17.1",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.1.tgz",
"integrity": "sha512-4H4fK9vWsQtPP0iAdqzGfdPKLaSXpCjuh1xaGsejX/CO8tx8zCnrOnlQhMgrJf+OlUfzth5YaDPXYGp3RHxV1g==",
"dependencies": {
"@babel/runtime": "^7.14.5",
"html-escaper": "^2.0.2",
"html-parse-stringify": "^3.0.1"
},
"peerDependencies": {
"i18next": ">= 19.0.0",
"react": ">= 16.8.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -13079,6 +13167,11 @@
"node": ">=0.8"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tsconfig-paths": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
@ -13446,6 +13539,14 @@
"node": ">= 0.10"
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@ -13476,6 +13577,11 @@
"minimalistic-assert": "^1.0.0"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/webpack": {
"version": "5.73.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz",
@ -13836,6 +13942,15 @@
"node": ">=0.8.0"
}
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@ -15131,9 +15246,9 @@
}
},
"@babel/runtime": {
"version": "7.16.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
"integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz",
"integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
"requires": {
"regenerator-runtime": "^0.13.4"
},
@ -17511,11 +17626,11 @@
}
},
"cross-fetch": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"requires": {
"node-fetch": "2.6.1"
"node-fetch": "2.6.7"
}
},
"cross-spawn": {
@ -19616,6 +19731,11 @@
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
},
"html-loader": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/html-loader/-/html-loader-3.1.0.tgz",
@ -19641,6 +19761,14 @@
"terser": "^5.10.0"
}
},
"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"
}
},
"html-react-parser": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-1.4.14.tgz",
@ -19741,6 +19869,30 @@
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true
},
"i18next": {
"version": "21.8.9",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.9.tgz",
"integrity": "sha512-PY9a/8ADVmnju1tETeglbbVQi+nM5pcJQWm9kvKMTE3GPgHHtpDsHy5HQ/hccz2/xtW7j3vuso23JdQSH0EttA==",
"requires": {
"@babel/runtime": "^7.17.2"
}
},
"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-http-backend": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.4.1.tgz",
"integrity": "sha512-s4Q9hK2jS29iyhniMP82z+yYY8riGTrWbnyvsSzi5TaF7Le4E7b5deTmtuaRuab9fdDcYXtcwdBgawZG+JCEjA==",
"requires": {
"cross-fetch": "3.1.5"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -21445,9 +21597,12 @@
"dev": true
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"node-forge": {
"version": "1.3.1",
@ -22568,6 +22723,16 @@
"react-async-script": "^1.1.1"
}
},
"react-i18next": {
"version": "11.17.1",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.1.tgz",
"integrity": "sha512-4H4fK9vWsQtPP0iAdqzGfdPKLaSXpCjuh1xaGsejX/CO8tx8zCnrOnlQhMgrJf+OlUfzth5YaDPXYGp3RHxV1g==",
"requires": {
"@babel/runtime": "^7.14.5",
"html-escaper": "^2.0.2",
"html-parse-stringify": "^3.0.1"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -23859,6 +24024,11 @@
"punycode": "^2.1.1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"tsconfig-paths": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
@ -24152,6 +24322,11 @@
"replace-ext": "^1.0.0"
}
},
"void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="
},
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@ -24179,6 +24354,11 @@
"minimalistic-assert": "^1.0.0"
}
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"webpack": {
"version": "5.73.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz",
@ -24430,6 +24610,15 @@
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View file

@ -27,6 +27,9 @@
"flux": "^4.0.3",
"formik": "^2.2.9",
"html-react-parser": "^1.4.14",
"i18next": "^21.8.9",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.1",
"katex": "^0.15.6",
"linkifyjs": "^2.1.9",
"matrix-js-sdk": "^18.0.0",
@ -43,6 +46,7 @@
"react-dnd-html5-backend": "^15.1.3",
"react-dom": "^17.0.2",
"react-google-recaptcha": "^2.1.0",
"react-i18next": "^11.17.1",
"react-modal": "^3.15.1",
"sanitize-html": "^2.7.0",
"tippy.js": "^6.3.7",

View file

@ -0,0 +1,34 @@
{
"common" : {
"close": "Close",
"leave": "Leave",
"options": "Options"
},
"welcome": {
"heading": "Welcome to Cinny!",
"subheading": "Yet another Matrix client"
},
"view_source":{
"title": "View Source",
"original_source": "Original source",
"decrypted_source": "Decrypted source"
},
"space_settings":{
"subtitle": "space settings",
"leave":{
"leave_space": "Leave Space",
"leave_dialog_title": "Leave Space",
"leave_dialog_message": "Are you sure you want to leave {{space}}?"
},
"visibility":{
"header": "Space visibility (who can join)"
},
"addresses": {
"header": "Space addresses"
},
"categorize_subspaces": "Categorize subspaces",
"uncategorize_subspaces": "Uncategorize subspaces",
"pin_sidebar": "Pin to sidebar",
"unpin_sidebar": "Unpin from sidebar"
}
}

View file

@ -0,0 +1,9 @@
{
"common":{
"close": "閉める",
"leave": "残す"
},
"welcome":{
"heading": "いらっしゃいませ"
}
}

23
src/app/i18n.jsx Normal file
View file

@ -0,0 +1,23 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend'
i18n
.use(Backend)
// detect user language
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
debug: true,
fallbackLng: 'en',
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
}
});
export default i18n;

View file

@ -39,6 +39,10 @@ import CategoryFilledIC from '../../../../public/res/ic/filled/category.svg';
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
import { useForceUpdate } from '../../hooks/useForceUpdate';
import '../../i18n.jsx'
import { useTranslation } from 'react-i18next';
const tabText = {
GENERAL: 'General',
MEMBERS: 'Members',
@ -65,10 +69,12 @@ function GeneralSettings({ roomId }) {
const roomName = initMatrix.matrixClient.getRoom(roomId)?.name;
const [, forceUpdate] = useForceUpdate();
const { t } = useTranslation();
return (
<>
<div className="room-settings__card">
<MenuHeader>Options</MenuHeader>
<MenuHeader>{t("common.options")}</MenuHeader>
<MenuItem
onClick={() => {
if (isCategorized) unCategorizeSpace(roomId);
@ -77,7 +83,7 @@ function GeneralSettings({ roomId }) {
}}
iconSrc={isCategorized ? CategoryFilledIC : CategoryIC}
>
{isCategorized ? 'Uncategorize subspaces' : 'Categorize subspaces'}
{isCategorized ? t("space_settings.uncategorize_subspaces") : t("space_settings.categorize_subspaces")}
</MenuItem>
<MenuItem
onClick={() => {
@ -87,30 +93,30 @@ function GeneralSettings({ roomId }) {
}}
iconSrc={isPinned ? PinFilledIC : PinIC}
>
{isPinned ? 'Unpin from sidebar' : 'Pin to sidebar'}
{isPinned ? t("space_settings.unpin_sidebar") : t("space_settings.pin_sidebar")}
</MenuItem>
<MenuItem
variant="danger"
onClick={async () => {
const isConfirmed = await confirmDialog(
'Leave space',
`Are you sure that you want to leave "${roomName}" space?`,
'Leave',
t("space_settings.leave.leave_dialog_title"),
t("space_settings.leave.leave_dialog_message", {space: roomName}),
t("space_settings.leave.leave_space"),
'danger',
);
if (isConfirmed) leave(roomId);
}}
iconSrc={LeaveArrowIC}
>
Leave
{t("space_settings.leave.leave_space")}
</MenuItem>
</div>
<div className="space-settings__card">
<MenuHeader>Space visibility (who can join)</MenuHeader>
<MenuHeader>{t("space_settings.visibility.header")}</MenuHeader>
<RoomVisibility roomId={roomId} />
</div>
<div className="space-settings__card">
<MenuHeader>Space addresses</MenuHeader>
<MenuHeader>{t("space_settings.addresses.header")}</MenuHeader>
<RoomAliases roomId={roomId} />
</div>
</>
@ -154,6 +160,8 @@ function SpaceSettings() {
setSelectedTab(tabItem);
};
const { t } = useTranslation();
return (
<PopupWindow
isOpen={isOpen}
@ -161,10 +169,10 @@ function SpaceSettings() {
title={(
<Text variant="s1" weight="medium" primary>
{isOpen && twemojify(room.name)}
<span style={{ color: 'var(--tc-surface-low)' }}> space settings</span>
<span style={{ color: 'var(--tc-surface-low)' }}> {t("space_settings.subtitle")}</span>
</Text>
)}
contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip="Close" />}
contentOptions={<IconButton src={CrossIC} onClick={requestClose} tooltip={t("common.close")} />}
onRequestClose={requestClose}
>
{isOpen && (

View file

@ -12,6 +12,9 @@ import PopupWindow from '../../molecules/popup-window/PopupWindow';
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
import '../../i18n.jsx'
import { useTranslation } from 'react-i18next';
function ViewSourceBlock({ title, json }) {
return (
<div className="view-source__card">
@ -34,6 +37,7 @@ ViewSourceBlock.propTypes = {
function ViewSource() {
const [isOpen, setIsOpen] = useState(false);
const [event, setEvent] = useState(null);
const { t } = useTranslation();
useEffect(() => {
const loadViewSource = (e) => {
@ -52,18 +56,18 @@ function ViewSource() {
const renderViewSource = () => (
<div className="view-source">
{event.isEncrypted() && <ViewSourceBlock title="Decrypted source" json={event.getEffectiveEvent()} />}
<ViewSourceBlock title="Original source" json={event.event} />
{event.isEncrypted() && <ViewSourceBlock title={t("view_source.decrypted_source")} json={event.getEffectiveEvent()} />}
<ViewSourceBlock title={t("view_source.original_source")} json={event.event} />
</div>
);
return (
<PopupWindow
isOpen={isOpen}
title="View source"
title={t("view_source.title")}
onAfterClose={handleAfterClose}
onRequestClose={() => setIsOpen(false)}
contentOptions={<IconButton src={CrossIC} onClick={() => setIsOpen(false)} tooltip="Close" />}
contentOptions={<IconButton src={CrossIC} onClick={() => setIsOpen(false)} tooltip={t("common.close")} />}
>
{event ? renderViewSource() : <div />}
</PopupWindow>

View file

@ -5,13 +5,19 @@ import Text from '../../atoms/text/Text';
import CinnySvg from '../../../../public/res/svg/cinny.svg';
import '../../i18n.jsx'
import { useTranslation } from 'react-i18next';
function Welcome() {
const { t, i18n } = useTranslation();
return (
<div className="app-welcome flex--center">
<div>
<img className="app-welcome__logo noselect" src={CinnySvg} alt="Cinny logo" />
<Text className="app-welcome__heading" variant="h1" weight="medium" primary>Welcome to Cinny</Text>
<Text className="app-welcome__subheading" variant="s1">Yet another matrix client</Text>
<Text className="app-welcome__heading" variant="h1" weight="medium" primary>{t('welcome.heading')}</Text>
<Text className="app-welcome__subheading" variant="s1">{t('welcome.subheading')}</Text>
</div>
</div>
);