From 641d1b0155e9a48c2fa9f890d315a6c241e4b4b4 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 6 Aug 2019 11:23:34 -0700 Subject: [PATCH 1/9] Still not working --- ui/fuse.js | 5 ++ ui/package.json | 4 +- ui/src/components/main.tsx | 4 +- ui/src/i18n.ts | 32 +++++++++ ui/src/index.tsx | 66 ++++++++++--------- ui/yarn.lock | 131 ++++++++++++++++--------------------- 6 files changed, 133 insertions(+), 109 deletions(-) create mode 100644 ui/src/i18n.ts diff --git a/ui/fuse.js b/ui/fuse.js index 4755d9f5a..cc2a206da 100644 --- a/ui/fuse.js +++ b/ui/fuse.js @@ -24,6 +24,11 @@ Sparky.task('config', _ => { transformers: { before: [transformClasscat(), transformInferno()], }, + alias: { + 'react': 'inferno-compat', + 'react-dom': 'inferno-compat', + 'react-redux': 'inferno-compat', + }, plugins: [ EnvPlugin({ NODE_ENV: isProduction ? 'production' : 'development' }), CSSPlugin(), diff --git a/ui/package.json b/ui/package.json index 20ecdd82a..9ff9ebba0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -20,11 +20,12 @@ "@types/jwt-decode": "^2.2.1", "@types/markdown-it": "^0.0.7", "@types/markdown-it-container": "^2.0.2", + "@types/react-i18next": "^8.1.0", "autosize": "^4.0.2", "classcat": "^1.1.3", "dotenv": "^6.1.0", "inferno": "^7.0.1", - "inferno-router": "^7.0.1", + "inferno-i18next": "nimbusec-oss/inferno-i18next", "js-cookie": "^2.2.0", "jwt-decode": "^2.2.0", "markdown-it": "^8.4.2", @@ -35,6 +36,7 @@ "ws": "^7.0.0" }, "devDependencies": { + "@types/i18next": "^12.1.0", "fuse-box": "^3.1.3", "ts-transform-classcat": "^0.0.2", "ts-transform-inferno": "^4.0.2", diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index fe59ac2c2..c513fc5c7 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -7,6 +7,8 @@ import { WebSocketService, UserService } from '../services'; import { PostListings } from './post-listings'; import { SiteForm } from './site-form'; import { msgOp, repoUrl, mdToHtml, fetchLimit, routeSortTypeToEnum, routeListingTypeToEnum } from '../utils'; +import { useTranslation } from 'react-i18next'; +const { t } = useTranslation(); interface MainState { subscribedCommunities: Array; @@ -147,7 +149,7 @@ export class Main extends Component { trendingCommunities() { return (
-
Trending communities
+
{t('Trending')} communities
    {this.state.trendingCommunities.map(community =>
  • {community.name}
  • diff --git a/ui/src/i18n.ts b/ui/src/i18n.ts new file mode 100644 index 000000000..46604e915 --- /dev/null +++ b/ui/src/i18n.ts @@ -0,0 +1,32 @@ +import i18n from "i18next"; +import { initReactI18next } from "inferno-i18next"; + +// the translations +// (tip move them in a JSON file and import them) +const resources = { + en: { + translation: { + trending: "Trending", + } + }, + es: { + translation: { + trending: "Trending, but in spanish", + } + } +}; + +i18n + .use(initReactI18next) // passes i18n down to react-i18next + .init({ + resources, + lng: "en", + + keySeparator: false, // we do not use keys in form messages.welcome + + interpolation: { + escapeValue: false // react already safes from xss + } + }); + +export default i18n; diff --git a/ui/src/index.tsx b/ui/src/index.tsx index a50bf2a00..a13b84f88 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -1,5 +1,6 @@ import { render, Component } from 'inferno'; import { HashRouter, BrowserRouter, Route, Switch } from 'inferno-router'; +import { Provider } from 'inferno-i18next'; import { Main } from './components/main'; import { Navbar } from './components/navbar'; import { Footer } from './components/footer'; @@ -16,6 +17,7 @@ import { Inbox } from './components/inbox'; import { Search } from './components/search'; import { Sponsors } from './components/sponsors'; import { Symbols } from './components/symbols'; +import './i18n'; import './css/bootstrap.min.css'; import './css/main.css'; @@ -34,37 +36,39 @@ class Index extends Component { render() { return ( - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + ); } diff --git a/ui/yarn.lock b/ui/yarn.lock index c978ef94f..ccec64e99 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/runtime@^7.1.2": +"@babel/runtime@^7.3.1": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -16,6 +16,11 @@ dependencies: "@types/jquery" "*" +"@types/i18next@^12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@types/i18next/-/i18next-12.1.0.tgz#7c3fd3dbe03f9531147033773bbd0ca4f474a180" + integrity sha512-qLyqTkp3ZKHsSoX8CNVYcTyTkxlm0aRCUpaUVetgkSlSpiNCdWryOgaYwgbO04tJIfLgBXPcy0tJ3Nl/RagllA== + "@types/jquery@*": version "3.3.30" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.30.tgz#af4ad612d86d954d74664b2b0ec337a251fddb5b" @@ -59,6 +64,13 @@ dependencies: "@types/linkify-it" "*" +"@types/react-i18next@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/react-i18next/-/react-i18next-8.1.0.tgz#5faacbfe7dc0f24729c1df6914610bfe861a50de" + integrity sha512-d4xhcjX5b3roNMObRNMfb1HinHQlQLPo8xlDj60dnHeeAw2bBymR2cy/l1giJpHzo/ZFgSvgVUvIWr4kCrenCg== + dependencies: + react-i18next "*" + "@types/sizzle@*": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" @@ -1152,22 +1164,12 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -history@^4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca" - integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA== +html-parse-stringify2@2.0.1, html-parse-stringify2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a" + integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o= dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^2.2.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^0.4.0" - -hoist-non-inferno-statics@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hoist-non-inferno-statics/-/hoist-non-inferno-statics-1.1.3.tgz#7d870f4160bfb6a59269b45c343c027f0e30ab35" - integrity sha1-fYcPQWC/tqWSabRcNDwCfw4wqzU= + void-elements "^2.0.1" http-errors@1.7.2: version "1.7.2" @@ -1219,27 +1221,42 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -inferno-router@^7.0.1: +inferno-clone-vnode@^7.1.12: version "7.2.1" - resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-7.2.1.tgz#ebea346a31422ed141df7177fb0b5aeb06cf8fe3" - integrity sha512-8DMIhAvMVfvFSax+uNsTYCWOktqMIM952EsYRn5V0LMYvnJtUczJH77vSCe1DF4o1jK+/kf9KLNfa1QPQC/CQg== + resolved "https://registry.yarnpkg.com/inferno-clone-vnode/-/inferno-clone-vnode-7.2.1.tgz#ae978e6d1cfa07a1616a7b4ecf5ca2f4fe070d5d" + integrity sha512-52ksls/sKFfLLXQW8v7My5QqX2i/CedlQM2JzCtkKMo18FovDt52jHNhfmWAbY9svcyxEzPjZMofHL/LFd7aIA== dependencies: - history "^4.9.0" - hoist-non-inferno-statics "^1.1.3" inferno "7.2.1" - path-to-regexp-es6 "1.7.0" -inferno-shared@7.2.1: +inferno-create-element@^7.1.12: + version "7.2.1" + resolved "https://registry.yarnpkg.com/inferno-create-element/-/inferno-create-element-7.2.1.tgz#6327b7a2195e0b08fab43df702889504845271c0" + integrity sha512-FGnIre6jRfr34bUgPMYWzj5/WA3htX3TQUYGhTVtiaREVxTj952eGcAMvOp4W4V6n2iK1Zl/qcTjrUdD2G3WiQ== + dependencies: + inferno "7.2.1" + +inferno-i18next@nimbusec-oss/inferno-i18next: + version "7.1.12" + resolved "https://codeload.github.com/nimbusec-oss/inferno-i18next/tar.gz/f8c1403e60be70141c558e36f12f22c106cb7463" + dependencies: + html-parse-stringify2 "^2.0.1" + inferno "^7.1.12" + inferno-clone-vnode "^7.1.12" + inferno-create-element "^7.1.12" + inferno-shared "^7.1.12" + inferno-vnode-flags "^7.1.12" + +inferno-shared@7.2.1, inferno-shared@^7.1.12: version "7.2.1" resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-7.2.1.tgz#7512d626e252a4e0e3ea28f0396a815651226ed6" integrity sha512-QSzHVcjAy38bQWmk1nrfNsrjdrWtxleojYYg00RyuF4K6s4KCPMEch5MD7C4fCydzeBMGcZUliSoUZXpm3DVwQ== -inferno-vnode-flags@7.2.1: +inferno-vnode-flags@7.2.1, inferno-vnode-flags@^7.1.12: version "7.2.1" resolved "https://registry.yarnpkg.com/inferno-vnode-flags/-/inferno-vnode-flags-7.2.1.tgz#833c39a16116dce86430c0bb7fedbd054ee32790" integrity sha512-xYK45KNhlsKZtW60b9ahF9eICK45NtUJDGZxwxBegW98/hdL7/TyUP0gARKd4vmrwxdgwbupU6VAXPVbv7Wwgw== -inferno@7.2.1, inferno@^7.0.1: +inferno@7.2.1, inferno@^7.0.1, inferno@^7.1.12: version "7.2.1" resolved "https://registry.yarnpkg.com/inferno/-/inferno-7.2.1.tgz#d82c14a237a004335ed03dd44395a4e0fe0d3729" integrity sha512-+HGUvismTfy1MDRkfOxbD8nriu+lmajo/Z1JQckuisJPMJpspzxBaR9sxaWpVytjexi0Pcrh194COso4t3gAIQ== @@ -1453,11 +1470,6 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1485,11 +1497,6 @@ js-cookie@^2.2.0: resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.0.tgz#1b2c279a6eece380a12168b92485265b35b1effb" integrity sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s= -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -1588,13 +1595,6 @@ lodash@^4.3.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -loose-envify@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -2017,25 +2017,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-to-regexp-es6@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp-es6/-/path-to-regexp-es6-1.7.0.tgz#965657c9f8ea8f660e103ccb839abf038cba4caf" - integrity sha512-QdT7okCAMGv7FR7w6KWFH9OSMivOgtXAGKodD6MDZBNR/XNL16W+hHoj6qBmV6cy/7eR1fr0Qujrg9OhBf5QPw== - dependencies: - path-to-regexp "1.7.0" - path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= - dependencies: - isarray "0.0.1" - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -2150,6 +2136,14 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-i18next@*: + version "10.11.5" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-10.11.5.tgz#10d0726a6c63c2d928078a7e7ec3db708246be04" + integrity sha512-+LXYehLGWbOzM4on9pgeCMTmo7J24Pm2rio4S8OSVdYudUKxLSYzoMDgJect0SQbTlIiK6b6+OTgTGY4YKPECw== + dependencies: + "@babel/runtime" "^7.3.1" + html-parse-stringify2 "2.0.1" + readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -2277,11 +2271,6 @@ request@^2.79.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -resolve-pathname@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" - integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg== - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -2625,16 +2614,6 @@ through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tiny-invariant@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.6.tgz#b3f9b38835e36a41c843a3b0907a5a7b3755de73" - integrity sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA== - -tiny-warning@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -2832,11 +2811,6 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== -value-equal@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" - integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw== - vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -2851,6 +2825,11 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +void-elements@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + watch@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c" From 9fe4f11b92df608e63e1404a64693da5a78e6bb6 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 7 Aug 2019 11:01:26 -0700 Subject: [PATCH 2/9] Starting to work on internationalization --- ui/fuse.js | 5 -- ui/package.json | 3 +- ui/src/components/main.tsx | 48 +++++++++-------- ui/src/i18n.ts | 32 ------------ ui/src/i18next.ts | 40 ++++++++++++++ ui/src/index.tsx | 6 +-- ui/yarn.lock | 104 +++++++++++++++++++++++++++++++------ 7 files changed, 159 insertions(+), 79 deletions(-) delete mode 100644 ui/src/i18n.ts create mode 100644 ui/src/i18next.ts diff --git a/ui/fuse.js b/ui/fuse.js index cc2a206da..4755d9f5a 100644 --- a/ui/fuse.js +++ b/ui/fuse.js @@ -24,11 +24,6 @@ Sparky.task('config', _ => { transformers: { before: [transformClasscat(), transformInferno()], }, - alias: { - 'react': 'inferno-compat', - 'react-dom': 'inferno-compat', - 'react-redux': 'inferno-compat', - }, plugins: [ EnvPlugin({ NODE_ENV: isProduction ? 'production' : 'development' }), CSSPlugin(), diff --git a/ui/package.json b/ui/package.json index 9ff9ebba0..180d80ef1 100644 --- a/ui/package.json +++ b/ui/package.json @@ -20,11 +20,12 @@ "@types/jwt-decode": "^2.2.1", "@types/markdown-it": "^0.0.7", "@types/markdown-it-container": "^2.0.2", - "@types/react-i18next": "^8.1.0", "autosize": "^4.0.2", "classcat": "^1.1.3", "dotenv": "^6.1.0", "inferno": "^7.0.1", + "inferno-router": "^7.0.1", + "i18next": "^17.0.9", "inferno-i18next": "nimbusec-oss/inferno-i18next", "js-cookie": "^2.2.0", "jwt-decode": "^2.2.0", diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index c513fc5c7..73d6deacc 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -7,8 +7,6 @@ import { WebSocketService, UserService } from '../services'; import { PostListings } from './post-listings'; import { SiteForm } from './site-form'; import { msgOp, repoUrl, mdToHtml, fetchLimit, routeSortTypeToEnum, routeListingTypeToEnum } from '../utils'; -import { useTranslation } from 'react-i18next'; -const { t } = useTranslation(); interface MainState { subscribedCommunities: Array; @@ -122,34 +120,42 @@ export class Main extends Component { {this.posts()}
- {!this.state.loading && -
- {this.trendingCommunities()} - {UserService.Instance.user && this.state.subscribedCommunities.length > 0 && -
-
Subscribed communities
-
    - {this.state.subscribedCommunities.map(community => -
  • {community.community_name}
  • - )} -
-
- } - Create a Community - {this.sidebar()} -
- } + {this.my_sidebar()}
) } + + my_sidebar() { + return( +
+ {!this.state.loading && +
+ {this.trendingCommunities()} + {UserService.Instance.user && this.state.subscribedCommunities.length > 0 && +
+
##
+
    + {this.state.subscribedCommunities.map(community => +
  • {community.community_name}
  • + )} +
+
+ } + + {this.sidebar()} +
+ } +
+ ) + } trendingCommunities() { return (
-
{t('Trending')} communities
+ {/*
{t('Trending')} communities
*/}
    {this.state.trendingCommunities.map(community =>
  • {community.name}
  • diff --git a/ui/src/i18n.ts b/ui/src/i18n.ts deleted file mode 100644 index 46604e915..000000000 --- a/ui/src/i18n.ts +++ /dev/null @@ -1,32 +0,0 @@ -import i18n from "i18next"; -import { initReactI18next } from "inferno-i18next"; - -// the translations -// (tip move them in a JSON file and import them) -const resources = { - en: { - translation: { - trending: "Trending", - } - }, - es: { - translation: { - trending: "Trending, but in spanish", - } - } -}; - -i18n - .use(initReactI18next) // passes i18n down to react-i18next - .init({ - resources, - lng: "en", - - keySeparator: false, // we do not use keys in form messages.welcome - - interpolation: { - escapeValue: false // react already safes from xss - } - }); - -export default i18n; diff --git a/ui/src/i18next.ts b/ui/src/i18next.ts new file mode 100644 index 000000000..b2eb96889 --- /dev/null +++ b/ui/src/i18next.ts @@ -0,0 +1,40 @@ +import * as i18next from 'i18next'; + +const resources = { + en: { + translation: { + trending: 'NO', + subscribed_to_communities:'Subscribed to <1>communities', + create_a_community: 'Create a community', + + + + + + + foo: 'foo', + bar: '<1>bar', + baz: '<1>{{count}}', + qux: 'qux<1>', + qux_plural: 'quxes<1>', + quux: '<1>{{name, uppercase}}', + userMessagesUnread: 'Hello <1>{{name}}, you have {{count}} unread messages. <3>Go to messages.', + userMessagesUnread_plural: 'Hello <1>{{name}}, you have {{count}} unread messages. <3>Go to messages.' + }, + }, +}; + +function format(value: any, format: any, lng: any) { + if (format === 'uppercase') return value.toUpperCase(); + return value; +} + +i18next.init({ + lng: 'en', + resources, + interpolation: { + format: format + } +}); + +export { i18next, resources }; diff --git a/ui/src/index.tsx b/ui/src/index.tsx index a13b84f88..2067c06ba 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -1,5 +1,5 @@ import { render, Component } from 'inferno'; -import { HashRouter, BrowserRouter, Route, Switch } from 'inferno-router'; +import { BrowserRouter, Route, Switch } from 'inferno-router'; import { Provider } from 'inferno-i18next'; import { Main } from './components/main'; import { Navbar } from './components/navbar'; @@ -17,7 +17,7 @@ import { Inbox } from './components/inbox'; import { Search } from './components/search'; import { Sponsors } from './components/sponsors'; import { Symbols } from './components/symbols'; -import './i18n'; +import { i18next } from './i18next'; import './css/bootstrap.min.css'; import './css/main.css'; @@ -36,7 +36,7 @@ class Index extends Component { render() { return ( - +
    diff --git a/ui/yarn.lock b/ui/yarn.lock index ccec64e99..f47c16c45 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/runtime@^7.3.1": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== @@ -64,13 +64,6 @@ dependencies: "@types/linkify-it" "*" -"@types/react-i18next@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@types/react-i18next/-/react-i18next-8.1.0.tgz#5faacbfe7dc0f24729c1df6914610bfe861a50de" - integrity sha512-d4xhcjX5b3roNMObRNMfb1HinHQlQLPo8xlDj60dnHeeAw2bBymR2cy/l1giJpHzo/ZFgSvgVUvIWr4kCrenCg== - dependencies: - react-i18next "*" - "@types/sizzle@*": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" @@ -1164,7 +1157,24 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -html-parse-stringify2@2.0.1, html-parse-stringify2@^2.0.1: +history@^4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca" + integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^2.2.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^0.4.0" + +hoist-non-inferno-statics@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hoist-non-inferno-statics/-/hoist-non-inferno-statics-1.1.3.tgz#7d870f4160bfb6a59269b45c343c027f0e30ab35" + integrity sha1-fYcPQWC/tqWSabRcNDwCfw4wqzU= + +html-parse-stringify2@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a" integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o= @@ -1202,6 +1212,13 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +i18next@^17.0.9: + version "17.0.9" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.9.tgz#5f835e91a34fa5e7da1e5ae4c4586c81d7c4b17f" + integrity sha512-fCYpm3TDzcfPIPN3hmgvC/QJx17QHI+Ul88qbixwIrifN9nBmk2c2oVxVYSDxnV5FgBXZJJ0O4yBYiZ8v1bX2A== + dependencies: + "@babel/runtime" "^7.3.1" + iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1246,6 +1263,16 @@ inferno-i18next@nimbusec-oss/inferno-i18next: inferno-shared "^7.1.12" inferno-vnode-flags "^7.1.12" +inferno-router@^7.0.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/inferno-router/-/inferno-router-7.2.1.tgz#ebea346a31422ed141df7177fb0b5aeb06cf8fe3" + integrity sha512-8DMIhAvMVfvFSax+uNsTYCWOktqMIM952EsYRn5V0LMYvnJtUczJH77vSCe1DF4o1jK+/kf9KLNfa1QPQC/CQg== + dependencies: + history "^4.9.0" + hoist-non-inferno-statics "^1.1.3" + inferno "7.2.1" + path-to-regexp-es6 "1.7.0" + inferno-shared@7.2.1, inferno-shared@^7.1.12: version "7.2.1" resolved "https://registry.yarnpkg.com/inferno-shared/-/inferno-shared-7.2.1.tgz#7512d626e252a4e0e3ea28f0396a815651226ed6" @@ -1470,6 +1497,11 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1497,6 +1529,11 @@ js-cookie@^2.2.0: resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.0.tgz#1b2c279a6eece380a12168b92485265b35b1effb" integrity sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s= +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -1595,6 +1632,13 @@ lodash@^4.3.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +loose-envify@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -2017,11 +2061,25 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-to-regexp-es6@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp-es6/-/path-to-regexp-es6-1.7.0.tgz#965657c9f8ea8f660e103ccb839abf038cba4caf" + integrity sha512-QdT7okCAMGv7FR7w6KWFH9OSMivOgtXAGKodD6MDZBNR/XNL16W+hHoj6qBmV6cy/7eR1fr0Qujrg9OhBf5QPw== + dependencies: + path-to-regexp "1.7.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-to-regexp@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -2136,14 +2194,6 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-i18next@*: - version "10.11.5" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-10.11.5.tgz#10d0726a6c63c2d928078a7e7ec3db708246be04" - integrity sha512-+LXYehLGWbOzM4on9pgeCMTmo7J24Pm2rio4S8OSVdYudUKxLSYzoMDgJect0SQbTlIiK6b6+OTgTGY4YKPECw== - dependencies: - "@babel/runtime" "^7.3.1" - html-parse-stringify2 "2.0.1" - readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -2271,6 +2321,11 @@ request@^2.79.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +resolve-pathname@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" + integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -2614,6 +2669,16 @@ through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +tiny-invariant@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.6.tgz#b3f9b38835e36a41c843a3b0907a5a7b3755de73" + integrity sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA== + +tiny-warning@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -2811,6 +2876,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +value-equal@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" + integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From 8646347bc3fdda0bca94356ad649f4c81a6f1e0e Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 7 Aug 2019 12:12:53 -0700 Subject: [PATCH 3/9] Main done. --- ui/src/components/main.tsx | 55 ++++++++++++++++++++++++++------------ ui/src/i18next.ts | 15 +++++++---- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index 73d6deacc..c6d3808b6 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -7,6 +7,7 @@ import { WebSocketService, UserService } from '../services'; import { PostListings } from './post-listings'; import { SiteForm } from './site-form'; import { msgOp, repoUrl, mdToHtml, fetchLimit, routeSortTypeToEnum, routeListingTypeToEnum } from '../utils'; +import { T } from 'inferno-i18next'; interface MainState { subscribedCommunities: Array; @@ -135,7 +136,9 @@ export class Main extends Component { {this.trendingCommunities()} {UserService.Instance.user && this.state.subscribedCommunities.length > 0 &&
    -
    ##
    +
    + ## +
      {this.state.subscribedCommunities.map(community =>
    • {community.community_name}
    • @@ -144,7 +147,9 @@ export class Main extends Component {
    } + to="/create_community"> + # + {this.sidebar()}
    } @@ -155,7 +160,9 @@ export class Main extends Component { trendingCommunities() { return (
    - {/*
    {t('Trending')} communities
    */} +
    + ## +
      {this.state.trendingCommunities.map(community =>
    • {community.name}
    • @@ -193,18 +200,32 @@ export class Main extends Component { {this.canAdmin &&
      • - edit + + # +
      }
        -
      • {this.state.site.site.number_of_users} Users
      • -
      • {this.state.site.site.number_of_posts} Posts
      • -
      • {this.state.site.site.number_of_comments} Comments
      • -
      • Modlog
      • +
      • + # +
      • +
      • + # +
      • +
      • + # +
      • +
      • + + # + +
        -
      • admins:
      • +
      • + #: +
      • {this.state.site.admins.map(admin =>
      • {admin.name}
      • )} @@ -223,15 +244,15 @@ export class Main extends Component { landing() { return (
        -
        Powered by - - LemmyBeta +
        + # + # + Lemmybeta
        -

        Lemmy is a link aggregator / reddit alternative, intended to work in the fediverse.

        -

        Its self-hostable, has live-updating comment threads, and is tiny (~80kB). Federation into the ActivityPub network is on the roadmap.

        -

        This is a very early beta version, and a lot of features are currently broken or missing.

        -

        Suggest new features or report bugs here.

        -

        Made with Rust, Actix, Inferno, Typescript.

        +

        + ###

        #

        #

        #

        #### +
        +

        ) } diff --git a/ui/src/i18next.ts b/ui/src/i18next.ts index b2eb96889..0af984235 100644 --- a/ui/src/i18next.ts +++ b/ui/src/i18next.ts @@ -1,15 +1,20 @@ import * as i18next from 'i18next'; +// https://github.com/nimbusec-oss/inferno-i18next/blob/master/tests/T.test.js#L66 const resources = { en: { translation: { - trending: 'NO', subscribed_to_communities:'Subscribed to <1>communities', create_a_community: 'Create a community', - - - - + trending_communities:'Trending <1>communities', + edit: 'edit', + number_of_users:'{{count}} Users', + number_of_posts:'{{count}} Posts', + number_of_comments:'{{count}} Comments', + modlog: 'Modlog', + admins: 'admins', + powered_by: 'Powered by', + landing_0: 'Lemmy is a <1>link aggregator / reddit alternative, intended to work in the <2>fediverse.<3>Its self-hostable, has live-updating comment threads, and is tiny (<4>~80kB). Federation into the ActivityPub network is on the roadmap. <5>This is a <6>very early beta version, and a lot of features are currently broken or missing. <7>Suggest new features or report bugs <8>here.<9>Made with <10>Rust, <11>Actix, <12>Inferno, <13>Typescript.', foo: 'foo', From 50ee0e9d82ebf649d916b46a5d8f731cfea57a31 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 8 Aug 2019 18:58:04 -0700 Subject: [PATCH 4/9] i18n translations first pass. --- ui/src/components/comment-form.tsx | 8 +- ui/src/components/comment-node.tsx | 44 ++++---- ui/src/components/communities.tsx | 23 +++-- ui/src/components/community-form.tsx | 18 ++-- ui/src/components/community.tsx | 23 +++-- ui/src/components/create-community.tsx | 6 +- ui/src/components/create-post.tsx | 6 +- ui/src/components/footer.tsx | 9 +- ui/src/components/inbox.tsx | 34 ++++--- ui/src/components/login.tsx | 23 +++-- ui/src/components/moment-time.tsx | 3 +- ui/src/components/navbar.tsx | 20 ++-- ui/src/components/post-form.tsx | 20 ++-- ui/src/components/post-listing.tsx | 32 +++--- ui/src/components/post-listings.tsx | 7 +- ui/src/components/post.tsx | 10 +- ui/src/components/search.tsx | 34 ++++--- ui/src/components/setup.tsx | 20 ++-- ui/src/components/sidebar.tsx | 36 +++---- ui/src/components/site-form.tsx | 13 ++- ui/src/components/sponsors.tsx | 18 ++-- ui/src/components/user.tsx | 44 ++++---- ui/src/i18next.ts | 136 +++++++++++++++++++++++-- ui/src/index.tsx | 4 +- 24 files changed, 378 insertions(+), 213 deletions(-) diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index 5181e45e1..9f3476a8b 100644 --- a/ui/src/components/comment-form.tsx +++ b/ui/src/components/comment-form.tsx @@ -1,7 +1,10 @@ import { Component, linkEvent } from 'inferno'; import { CommentNode as CommentNodeI, CommentForm as CommentFormI } from '../interfaces'; +import { capitalizeFirstLetter } from '../utils'; import { WebSocketService, UserService } from '../services'; import * as autosize from 'autosize'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; interface CommentFormProps { postId?: number; @@ -25,12 +28,13 @@ export class CommentForm extends Component { post_id: this.props.node ? this.props.node.comment.post_id : this.props.postId, creator_id: UserService.Instance.user ? UserService.Instance.user.id : null, }, - buttonTitle: !this.props.node ? "Post" : this.props.edit ? "Edit" : "Reply", + buttonTitle: !this.props.node ? capitalizeFirstLetter(i18n.t('post')) : this.props.edit ? capitalizeFirstLetter(i18n.t('edit')) : capitalizeFirstLetter(i18n.t('reply')), } constructor(props: any, context: any) { super(props, context); + this.state = this.emptyState; if (this.props.node) { @@ -62,7 +66,7 @@ export class CommentForm extends Component {
        - {this.props.node && } + {this.props.node && }
        diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx index a201ddd6b..a05286ed3 100644 --- a/ui/src/components/comment-node.tsx +++ b/ui/src/components/comment-node.tsx @@ -7,6 +7,8 @@ import * as moment from 'moment'; import { MomentTime } from './moment-time'; import { CommentForm } from './comment-form'; import { CommentNodes } from './comment-nodes'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; enum BanType {Community, Site}; @@ -74,10 +76,10 @@ export class CommentNode extends Component { {node.comment.creator_name} {this.isMod && -
      • mod
      • +
      • #
      • } {this.isAdmin && -
      • admin
      • +
      • #
      • }
      • ( @@ -97,24 +99,24 @@ export class CommentNode extends Component { {this.state.showEdit && } {!this.state.showEdit && !this.state.collapsed &&
        -
        +
          {UserService.Instance.user && !this.props.viewOnly && <>
        • - reply + #
        • - {node.comment.saved ? 'unsave' : 'save'} + {node.comment.saved ? i18n.t('unsave') : i18n.t('save')}
        • {this.myComment && <>
        • - edit + #
        • - {!this.props.node.comment.deleted ? 'delete' : 'restore'} + {!this.props.node.comment.deleted ? i18n.t('delete') : i18n.t('restore')}
        • @@ -123,8 +125,8 @@ export class CommentNode extends Component { {this.canMod &&
        • {!this.props.node.comment.removed ? - remove : - restore + # : + # }
        • } @@ -134,14 +136,14 @@ export class CommentNode extends Component { {!this.isMod &&
        • {!this.props.node.comment.banned_from_community ? - ban : - unban + # : + # }
        • } {!this.props.node.comment.banned_from_community &&
        • - {`${this.isMod ? 'remove' : 'appoint'} as mod`} + {this.isMod ? i18n.t('remove_as_mod') : i18n.t('appoint_as_mod')}
        • } @@ -152,14 +154,14 @@ export class CommentNode extends Component { {!this.isAdmin &&
        • {!this.props.node.comment.banned ? - ban from site : - unban from site + # : + # }
        • } {!this.props.node.comment.banned &&
        • - {`${this.isAdmin ? 'remove' : 'appoint'} as admin`} + {this.isAdmin ? i18n.t('remove_as_admin') : i18n.t('appoint_as_admin')}
        • } @@ -167,11 +169,11 @@ export class CommentNode extends Component { }
        • - link + #
        • {this.props.markable &&
        • - {`mark as ${node.comment.read ? 'unread' : 'read'}`} + {node.comment.read ? i18n.t('mark_as_unread') : i18n.t('mark_as_read')}
        • }
        @@ -180,15 +182,15 @@ export class CommentNode extends Component {
        {this.state.showRemoveDialog &&
        - - + +
        } {this.state.showBanDialog &&
        - - + +
        {/* TODO hold off on expires until later */} {/*
        */} diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx index c4efe1fbe..066d524a2 100644 --- a/ui/src/components/communities.tsx +++ b/ui/src/components/communities.tsx @@ -5,6 +5,7 @@ import { retryWhen, delay, take } from 'rxjs/operators'; import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm, ListCommunitiesForm, SortType } from '../interfaces'; import { WebSocketService } from '../services'; import { msgOp } from '../utils'; +import { T } from 'inferno-i18next'; declare const Sortable: any; @@ -64,17 +65,17 @@ export class Communities extends Component { {this.state.loading ?
        :
        -
        List of communities
        +
        #
        - - - - - - + + + + + + @@ -89,8 +90,8 @@ export class Communities extends Component { @@ -109,9 +110,9 @@ export class Communities extends Component { return (
        {this.state.page > 1 && - + } - +
        ); } diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx index e295dcbed..f6520fc6b 100644 --- a/ui/src/components/community-form.tsx +++ b/ui/src/components/community-form.tsx @@ -3,8 +3,10 @@ import { Subscription } from "rxjs"; import { retryWhen, delay, take } from 'rxjs/operators'; import { CommunityForm as CommunityFormI, UserOperation, Category, ListCategoriesResponse, CommunityResponse } from '../interfaces'; import { WebSocketService } from '../services'; -import { msgOp } from '../utils'; +import { msgOp, capitalizeFirstLetter } from '../utils'; import * as autosize from 'autosize'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; import { Community } from '../interfaces'; @@ -74,25 +76,25 @@ export class CommunityForm extends Component
        - +
        - +
        - +
        - +
        NameTitleCategorySubscribersPostsComments######
        {community.number_of_comments} {community.subscribed ? - Unsubscribe : - Subscribe + # : + # }