Localization (Transloco) (#457)
* first transloco * config * app settings * appsettings * settings html * first translations * fix default loading * lint * use webpack * some translations * german terms + disable * fix lint
This commit is contained in:
parent
ed477854e3
commit
4639315ff5
21 changed files with 596 additions and 78 deletions
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"lokalise.i18n-ally"
|
||||
]
|
||||
}
|
||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
|
|
@ -2,5 +2,11 @@
|
|||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true
|
||||
},
|
||||
"tslint.autoFixOnSave": true
|
||||
"tslint.autoFixOnSave": true,
|
||||
"i18n-ally.localesPaths": "src/assets/i18n",
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"i18n-ally.sourceLanguage": "en",
|
||||
"i18n-ally.extract.keyPrefix": "{fileNameWithoutExt}.",
|
||||
"i18n-ally.sortKeys": true,
|
||||
"i18n-ally.extract.keyMaxLength": 60
|
||||
}
|
||||
|
|
|
|||
340
package-lock.json
generated
340
package-lock.json
generated
|
|
@ -2191,6 +2191,143 @@
|
|||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@ngneat/transloco": {
|
||||
"version": "2.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngneat/transloco/-/transloco-2.22.0.tgz",
|
||||
"integrity": "sha512-mJ8KVm3nPoSyKlMqsP4D3nNClugwnwxmVrP3QtO16jEiLn8U0ipsAlj7SyQqjIWKSLxxVZuJX25lmk6Ye9iYoA==",
|
||||
"requires": {
|
||||
"@ngneat/transloco-utils": "^1.0.6",
|
||||
"flat": "5.0.2",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"ora": "^3.4.0",
|
||||
"replace-in-file": "^4.1.2",
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
|
||||
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
|
||||
"requires": {
|
||||
"restore-cursor": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
|
||||
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
|
||||
"requires": {
|
||||
"chalk": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
|
||||
"requires": {
|
||||
"mimic-fn": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ora": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
|
||||
"integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"cli-cursor": "^2.1.0",
|
||||
"cli-spinners": "^2.0.0",
|
||||
"log-symbols": "^2.2.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wcwidth": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
|
||||
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
|
||||
"requires": {
|
||||
"onetime": "^2.0.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@ngneat/transloco-utils": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@ngneat/transloco-utils/-/transloco-utils-1.1.2.tgz",
|
||||
"integrity": "sha512-yljMAoRNr+qr1z+DTUlY98SWm/ldbssCNmI3tE+A1183ppYKcnpdfSJQKrx1rg4rmwNfyKyexlmZ6EubosqZ8A==",
|
||||
"requires": {
|
||||
"cosmiconfig": "6.0.0",
|
||||
"tslib": "^1.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"cosmiconfig": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
||||
"integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
|
||||
"requires": {
|
||||
"@types/parse-json": "^4.0.0",
|
||||
"import-fresh": "^3.1.0",
|
||||
"parse-json": "^5.0.0",
|
||||
"path-type": "^4.0.0",
|
||||
"yaml": "^1.7.2"
|
||||
}
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||
"requires": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
|
||||
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"error-ex": "^1.3.1",
|
||||
"json-parse-even-better-errors": "^2.3.0",
|
||||
"lines-and-columns": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@ngtools/webpack": {
|
||||
"version": "10.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.0.5.tgz",
|
||||
|
|
@ -2414,6 +2551,11 @@
|
|||
"integrity": "sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"@types/q": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
|
||||
|
|
@ -4368,8 +4510,7 @@
|
|||
"cli-spinners": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz",
|
||||
"integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA=="
|
||||
},
|
||||
"cli-width": {
|
||||
"version": "2.2.1",
|
||||
|
|
@ -5435,7 +5576,6 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
|
||||
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone": "^1.0.2"
|
||||
},
|
||||
|
|
@ -5443,8 +5583,7 @@
|
|||
"clone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -6366,7 +6505,6 @@
|
|||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
|
|
@ -7081,6 +7219,11 @@
|
|||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"flat": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="
|
||||
},
|
||||
"flatted": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||
|
|
@ -8299,8 +8442,7 @@
|
|||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
|
|
@ -8846,6 +8988,11 @@
|
|||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
||||
"dev": true
|
||||
},
|
||||
"json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
|
|
@ -9286,6 +9433,11 @@
|
|||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"lines-and-columns": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
|
||||
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA="
|
||||
},
|
||||
"loader-runner": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
|
||||
|
|
@ -9338,6 +9490,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||
},
|
||||
"lodash.kebabcase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
|
||||
"integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY="
|
||||
},
|
||||
"lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
|
|
@ -11061,6 +11218,21 @@
|
|||
"readable-stream": "^2.1.5"
|
||||
}
|
||||
},
|
||||
"parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"requires": {
|
||||
"callsites": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"parse-asn1": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
|
||||
|
|
@ -11157,8 +11329,7 @@
|
|||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
||||
},
|
||||
"pbkdf2": {
|
||||
"version": "3.1.1",
|
||||
|
|
@ -12789,6 +12960,149 @@
|
|||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
|
||||
"dev": true
|
||||
},
|
||||
"replace-in-file": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-4.3.1.tgz",
|
||||
"integrity": "sha512-FqVvfmpqGTD2JRGI1JjJ86b24P17x/WWwGdxExeyJxnh/2rVQz2+jXfD1507UnnhEQw092X0u0DPCBf1WC4ooQ==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"glob": "^7.1.6",
|
||||
"yargs": "^15.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"requires": {
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
|
||||
"integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
|
|
@ -15764,7 +16078,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
|
|
@ -16720,6 +17033,11 @@
|
|||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yaml": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
"@ledgerhq/hw-transport-webusb": "^5.39.0",
|
||||
"@ledgerhq/logs": "^5.39.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
|
||||
"@ngneat/transloco": "^2.22.0",
|
||||
"@types/crypto-js": "^3.1.38",
|
||||
"@zxing/ngx-scanner": "^3.0.0",
|
||||
"angular-password-strength-meter": "^3.0.0",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<div class="header">Currently Selected</div>
|
||||
<div class="account active" *ngIf="wallet.selectedAccount !== null"> <!-- active nano_ account -->
|
||||
<div class="name-column">
|
||||
<div class="name">{{ wallet.selectedAccount.addressBookName ? wallet.selectedAccount.addressBookName : ('Account #' + wallet.selectedAccount.index) }}</div>
|
||||
<div class="name">{{ wallet.selectedAccount.addressBookName ? wallet.selectedAccount.addressBookName : (('general.account' | transloco) + ' #' + wallet.selectedAccount.index) }}</div>
|
||||
<div class="address nano-address-monospace">{{ wallet.selectedAccount.id }}</div>
|
||||
</div>
|
||||
<div class="balance-column">
|
||||
|
|
@ -55,14 +55,14 @@
|
|||
<ng-container *ngFor="let account of wallet.accounts"> <!-- inactive accounts -->
|
||||
<div class="account inactive" (click)="selectAccount(account)" *ngIf="( (wallet.selectedAccount === null) || (wallet.selectedAccount.id !== account.id) )">
|
||||
<div class="name-column">
|
||||
<div class="name">{{ account.addressBookName ? account.addressBookName : ('Account #' + account.index) }}</div>
|
||||
<div class="name">{{ account.addressBookName ? account.addressBookName : (('general.account' | transloco) + ' #' + account.index) }}</div>
|
||||
<div class="address nano-address-monospace">{{ account.id }}</div>
|
||||
</div>
|
||||
<div class="balance-column">
|
||||
<ng-container *ngIf="(walletService.wallet.updatingBalance === false) else balanceLoading">
|
||||
<div class="balance primary">
|
||||
<span class="incoming-label" *ngIf="account.pending.gt(0)">
|
||||
<span class="text-snippet">New</span>
|
||||
<span class="text-snippet">{{ 'general.new' | transloco }}</span>
|
||||
<span class="text-full">+{{ account.pending | rai: 'mnano,true' | amountsplit: 0 }}{{ account.pending | rai: 'mnano,true' | amountsplit: 1 }} NANO</span>
|
||||
</span>
|
||||
{{ account.balance | rai: 'mnano,true' | amountsplit: 0 }}{{ account.balance | rai: 'mnano,true' | amountsplit: 1 }} NANO
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
? (
|
||||
wallet.selectedAccount.addressBookName
|
||||
? wallet.selectedAccount.addressBookName
|
||||
: ('Account #' + wallet.selectedAccount.index)
|
||||
: (('general.account' | transloco) + '#' + wallet.selectedAccount.index)
|
||||
)
|
||||
: 'Total Balance'
|
||||
}}</a>
|
||||
|
|
@ -218,27 +218,27 @@
|
|||
</div>
|
||||
|
||||
<ul class="uk-nav uk-nav-default uk-nav-parent-icon left-nav" uk-nav>
|
||||
<li><a routerLink="/accounts" routerLinkActive="active"><div class="label">Accounts</div></a></li>
|
||||
<li><a routerLink="/send" routerLinkActive="active"><div class="label">Send</div></a></li>
|
||||
<li><a routerLink="/accounts" routerLinkActive="active"><div class="label">{{ 'general.accounts' | transloco }}</div></a></li>
|
||||
<li><a routerLink="/send" routerLinkActive="active"><div class="label">{{ 'general.send' | transloco }}</div></a></li>
|
||||
<li>
|
||||
<a routerLink="/receive" routerLinkActive="active">
|
||||
<div uk-grid>
|
||||
<div class="uk-width-3-4">
|
||||
<div class="label">Receive</div>
|
||||
<div class="label">{{ 'general.receive' | transloco }}</div>
|
||||
</div>
|
||||
<div class="uk-width-1-4 uk-text-center label-new">
|
||||
<span *ngIf="walletService.hasPendingTransactions()" class="uk-badge uk-text-top uk-align-center"><div class="label">New</div></span>
|
||||
<span *ngIf="walletService.hasPendingTransactions()" class="uk-badge uk-text-top uk-align-center"><div class="label">{{ 'general.new' | transloco }}</div></span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li><a routerLink="/address-book" routerLinkActive="active"><div class="label">Address Book</div></a></li>
|
||||
<li><a routerLink="/qr-scan" routerLinkActive="active"><div class="label">Scan QR Code</div></a></li>
|
||||
<li><a routerLink="/address-book" routerLinkActive="active"><div class="label">{{ 'general.address-book' | transloco }}</div></a></li>
|
||||
<li><a routerLink="/qr-scan" routerLinkActive="active"><div class="label">{{ 'general.scan-qr-code' | transloco }}</div></a></li>
|
||||
<li class="uk-parent">
|
||||
<a href="#">Settings</a>
|
||||
<a href="#">{{ 'general.settings' | transloco }}</a>
|
||||
<ul class="uk-nav-sub">
|
||||
<li><a routerLink="/representatives" [queryParams]="" routerLinkActive="active"><div class="label">Representatives</div></a></li>
|
||||
<li><a routerLink="/configure-app" routerLinkActive="active"><div class="label">App Settings</div></a></li>
|
||||
<li><a routerLink="/representatives" [queryParams]="" routerLinkActive="active"><div class="label">{{ 'general.representatives' | transloco }}</div></a></li>
|
||||
<li><a routerLink="/configure-app" routerLinkActive="active"><div class="label">{{ 'general.app-settings' | transloco }}</div></a></li>
|
||||
<li *ngIf="isConfigured()"><a routerLink="/manage-wallet" routerLinkActive="active"><div class="label">Manage Wallet</div></a></li>
|
||||
<li><a routerLink="/configure-wallet" routerLinkActive="active"><div class="label">Configure New Wallet</div></a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {NodeService} from './services/node.service';
|
|||
import { DesktopService, LedgerService } from './services';
|
||||
import { environment } from 'environments/environment';
|
||||
import { DeeplinkService } from './services/deeplink.service';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -39,7 +40,8 @@ export class AppComponent implements OnInit {
|
|||
private desktop: DesktopService,
|
||||
private ledger: LedgerService,
|
||||
private renderer: Renderer2,
|
||||
private deeplinkService: DeeplinkService) {
|
||||
private deeplinkService: DeeplinkService,
|
||||
private translate: TranslocoService) {
|
||||
router.events.subscribe(() => {
|
||||
this.closeNav();
|
||||
});
|
||||
|
|
@ -86,6 +88,9 @@ export class AppComponent implements OnInit {
|
|||
// New for v19: Patch saved xrb_ prefixes to nano_
|
||||
await this.patchXrbToNanoPrefixData();
|
||||
|
||||
// set translation language
|
||||
this.translate.setActiveLang(this.settings.settings.language);
|
||||
|
||||
this.addressBook.loadAddressBook();
|
||||
this.workPool.loadWorkCache();
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ import { environment } from '../environments/environment';
|
|||
import { MultisigComponent } from './components/multisig/multisig.component';
|
||||
import { KeygeneratorComponent } from './components/keygenerator/keygenerator.component';
|
||||
import { NanoTransactionMobileComponent } from './components/helpers/nano-transaction-mobile/nano-transaction-mobile.component';
|
||||
import { TranslocoRootModule } from './transloco/transloco-root.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
|
@ -122,6 +123,7 @@ import { NanoTransactionMobileComponent } from './components/helpers/nano-transa
|
|||
NgbModule,
|
||||
PasswordStrengthMeterModule,
|
||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production && !environment.desktop }),
|
||||
TranslocoRootModule,
|
||||
],
|
||||
providers: [
|
||||
UtilService,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div class="name">{{
|
||||
addressBookEntry
|
||||
? addressBookEntry
|
||||
: ('Account #' + walletAccount.index)
|
||||
: (('general.account' | transloco) + '#' + walletAccount.index)
|
||||
}}</div>
|
||||
<div #selectButton class="select-button closed" (click)="mobileAccountMenuModal.show()">
|
||||
<div class="circle"></div>
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
class="account-type-label"
|
||||
[class.editing-name]="showEditAddressBook"
|
||||
>
|
||||
{{ 'Account #' + walletAccount.index }}
|
||||
{{ ('general.account' | transloco) + '#' + walletAccount.index }}
|
||||
</div>
|
||||
<div
|
||||
*ngIf="!walletAccount"
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
? addressBookEntry
|
||||
: (
|
||||
walletAccount
|
||||
? ('Account #' + walletAccount.index)
|
||||
? (('general.account' | transloco) + '#' + walletAccount.index)
|
||||
: 'No label set'
|
||||
)
|
||||
}}</h3>
|
||||
|
|
@ -693,7 +693,7 @@
|
|||
? addressBookEntry
|
||||
: (
|
||||
walletAccount
|
||||
? ('Account #' + walletAccount.index)
|
||||
? (('general.account' | transloco) + '#' + walletAccount.index)
|
||||
: 'External address'
|
||||
)
|
||||
}}</div>
|
||||
|
|
@ -723,7 +723,7 @@
|
|||
? addressBookEntry
|
||||
: (
|
||||
walletAccount
|
||||
? ('Account #' + walletAccount.index)
|
||||
? (('general.account' | transloco) + '#' + walletAccount.index)
|
||||
: 'External address'
|
||||
)
|
||||
}}</h3>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {BehaviorSubject} from 'rxjs';
|
|||
import * as nanocurrency from 'nanocurrency';
|
||||
import {NinjaService} from '../../services/ninja.service';
|
||||
import { QrModalService } from '../../services/qr-modal.service';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-details',
|
||||
|
|
@ -116,7 +117,8 @@ export class AccountDetailsComponent implements OnInit, OnDestroy {
|
|||
public settings: AppSettingsService,
|
||||
private nanoBlock: NanoBlockService,
|
||||
private qrModalService: QrModalService,
|
||||
private ninja: NinjaService) {
|
||||
private ninja: NinjaService,
|
||||
private translocoService: TranslocoService) {
|
||||
// to detect when the account changes if the view is already active
|
||||
route.events.subscribe((val) => {
|
||||
if (val instanceof NavigationEnd) {
|
||||
|
|
@ -391,7 +393,7 @@ export class AccountDetailsComponent implements OnInit, OnDestroy {
|
|||
return defaultLabel;
|
||||
}
|
||||
|
||||
return ('Account #' + walletAccount.index);
|
||||
return (this.translocoService.translate('general.account') + '#' + walletAccount.index);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
: (
|
||||
viewAdvanced
|
||||
? 'Account'
|
||||
: 'Account #' + account.index
|
||||
: ('general.account' | transloco) + '#' + account.index
|
||||
)
|
||||
}}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,87 +1,86 @@
|
|||
<div class="nav-representative-info" *ngIf="(displayedRepresentatives.length > 0) else noRepresentatives">
|
||||
<div class="representative" *ngFor="let rep of displayedRepresentatives; let repIdx = index" (mouseover)="showRepHelp=rep.id" (mouseout)="showRepHelp=null">
|
||||
<h2>Representative{{
|
||||
<h2>{{
|
||||
(repIdx !== 0)
|
||||
? (
|
||||
' for '
|
||||
+ (
|
||||
'change-rep-widget.representative-for-account' | transloco: { account: (
|
||||
rep.accounts[0].addressBookName
|
||||
? ( '"' + rep.accounts[0].addressBookName + '"' )
|
||||
: ( rep.accounts[0].id.slice(0, 10) + '...' )
|
||||
)
|
||||
)}
|
||||
)
|
||||
: ''
|
||||
: ('general.representative' | transloco)
|
||||
}}</h2>
|
||||
<div class="representative-name-row">
|
||||
<a (click)="showRepSelectionForSpecificRep(rep)" class="name">{{ rep.label || 'Unknown Rep' }}</a>
|
||||
<a (click)="showRepSelectionForSpecificRep(rep)" class="name">{{ rep.label || ('general.unknown' | transloco) }}</a>
|
||||
<div class="weight-total" *ngIf="!rep.percent.isZero()">{{ rep.percent.toFixed(2) }}%</div>
|
||||
</div>
|
||||
<ng-container [ngSwitch]="true">
|
||||
<div class="representative-health-row health-green" *ngSwitchCase="(rep.statusText == 'trusted')">
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Good Representative</div>
|
||||
<div class="label">{{ 'change-rep-widget.good-representative' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-green" *ngSwitchCase="(rep.statusText == 'ok')">
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Good Representative</div>
|
||||
<div class="label">{{ 'change-rep-widget.good-representative' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-yellow" *ngSwitchCase="(rep.statusText == 'warn')">
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Acceptable Representative</div>
|
||||
<div class="label">{{ 'change-rep-widget.acceptable-representative' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-red" *ngSwitchCase="(rep.statusText == 'alert')">
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Bad Representative</div>
|
||||
<div class="label">{{ 'change-rep-widget.bad-representative' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-unknown" *ngSwitchDefault>
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Unknown Status</div>
|
||||
<div class="label">{{ 'change-rep-widget.unknown-status' | transloco }}</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div [class]="[ 'representative-help-tooltip', showRepHelp==rep.id ? 'visible' : 'hidden' ]">
|
||||
<p class="primary"><b>{{ rep.label || 'Unknown Rep' }}</b> represents you in the Nano consensus protocol by voting on your behalf.</p>
|
||||
<p>You can change representative at any time by clicking on its name above.</p>
|
||||
<p class="primary">{{ 'change-rep-widget.rep-represents-you' | transloco: { name: (rep.label || ('general.unknown' | transloco)) } }}</p>
|
||||
<p>{{ 'change-rep-widget.you-can-change-representative-at-any-time' | transloco }}</p>
|
||||
<div class="header-row">
|
||||
<div class="separator"></div>
|
||||
<h2>Health</h2>
|
||||
<h2>{{ 'change-rep-widget.health' | transloco }}</h2>
|
||||
<div class="separator"></div>
|
||||
</div>
|
||||
<p class="uk-text-danger" *ngIf="rep.status.markedToAvoid">
|
||||
<span uk-icon="icon: warning;"></span>This representative is <b>marked as "avoid"</b> in the list of known reps.
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-is-marked-as-avoid' | transloco }}
|
||||
</p>
|
||||
<p class="uk-text-danger" *ngIf="rep.status.closing">
|
||||
<span uk-icon="icon: warning;"></span>This representative has announced plans to <b>permanently shutdown</b>.
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-has-announced-plans-to-permanently-shutdown' | transloco }}
|
||||
</p>
|
||||
<p class="uk-text-danger" *ngIf="rep.status.veryHighWeight">
|
||||
<span uk-icon="icon: warning;"></span>This representative has a <b>very high voting weight</b> (over 3%).
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-has-a-very-high-voting-weight' | transloco: { percent: 5 } }}
|
||||
</p>
|
||||
<p class="uk-text-warning" *ngIf="rep.status.highWeight">
|
||||
<span uk-icon="icon: warning;"></span>This representative has a <b>high voting weight</b> (over 2%).
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-has-a-high-voting-weight' | transloco: { percent: 3 } }}
|
||||
</p>
|
||||
<p class="uk-text-danger" *ngIf="rep.status.veryLowUptime && rep.status.uptime > 0">
|
||||
<span uk-icon="icon: warning;"></span>This representative is <b>often offline</b> ({{ rep.status.uptime.toFixed(1) }}% uptime).
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-is-often-offline' | transloco: { percent: rep.status.uptime.toFixed(1) } }}
|
||||
</p>
|
||||
<p class="uk-text-warning" *ngIf="rep.status.lowUptime && rep.status.uptime > 0">
|
||||
<span uk-icon="icon: warning;"></span>This representative is <b>sometimes offline</b> ({{ rep.status.uptime.toFixed(1) }}% uptime).
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-is-sometimes-offline' | transloco: { percent: rep.status.uptime.toFixed(1) } }}
|
||||
</p>
|
||||
<p class="uk-text-danger" *ngIf="!rep.status.online && rep.status.uptime === 0">
|
||||
<span uk-icon="icon: warning;"></span>This representative has been <b>offline for the past {{ rep.status.daysSinceLastVoted }} days</b>.
|
||||
<span uk-icon="icon: warning;"></span>{{ 'change-rep-widget.this-representative-has-been-offline-for-the-past-days' | transloco: { days: rep.status.daysSinceLastVoted } }}
|
||||
</p>
|
||||
<ng-container [ngSwitch]="true">
|
||||
<p *ngSwitchCase="(rep.statusText == 'trusted')">
|
||||
You have marked this representative as trusted, meaning its status will remain "Good" even in case of severe issues with uptime or weight distribution.
|
||||
{{ 'change-rep-widget.you-have-marked-this-representative-as-trusted' | transloco }}
|
||||
</p>
|
||||
<p class="uk-text-success" *ngSwitchCase="(rep.statusText == 'ok')">
|
||||
<span uk-icon="icon: check;"></span>We found no issues with uptime or weight distribution of your current representative.
|
||||
<span uk-icon="icon: check;"></span>{{ 'change-rep-widget.we-found-no-issues-with-uptime-or-weight' | transloco }}
|
||||
</p>
|
||||
<p *ngSwitchCase="(rep.statusText == 'warn')">
|
||||
Switching to a different representative could improve security and decentralization of the Nano network.
|
||||
{{ 'change-rep-widget.switching-to-a-different-representative-could-improve' | transloco }}
|
||||
</p>
|
||||
<p *ngSwitchCase="(rep.statusText == 'alert')">
|
||||
It is <b>highly advised</b> to switch to a different representative, in order to improve security and decentralization of the Nano network.
|
||||
{{ 'change-rep-widget.it-is-highly-advised-to-switch-to-a-different-representative' | transloco }}
|
||||
</p>
|
||||
<p *ngSwitchDefault>
|
||||
<span uk-icon="icon: question;"></span>We could not determine status of this representative.
|
||||
<span uk-icon="icon: question;"></span>{{ 'change-rep-widget.we-could-not-determine-status-of-this-representative' | transloco }}
|
||||
</p>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
|
@ -90,26 +89,26 @@
|
|||
<ng-template #noRepresentatives>
|
||||
<div class="nav-representative-info" *ngIf="(!initialLoadComplete || selectedAccountHasRepresentative) else selectedAccountHasNoRep">
|
||||
<div class="representative">
|
||||
<h2>Representative</h2>
|
||||
<h2>{{ 'general.representative' | transloco }}</h2>
|
||||
<div class="representative-name-row">
|
||||
<div class="name no-interact">Loading...</div>
|
||||
<div class="name no-interact">{{ 'general.loading' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-unknown health-loading">
|
||||
<div uk-spinner="ratio: 0.5;"></div>
|
||||
<div class="label">Checking Status...</div>
|
||||
<div class="label">{{ 'change-rep-widget.checking-status' | transloco }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #selectedAccountHasNoRep>
|
||||
<div class="nav-representative-info">
|
||||
<div class="representative">
|
||||
<h2>Representative</h2>
|
||||
<h2>{{ 'general.representative' | transloco }}</h2>
|
||||
<div class="representative-name-row">
|
||||
<div class="name no-interact">None</div>
|
||||
<div class="name no-interact">{{ 'change-rep-widget.representative-none' | transloco }}</div>
|
||||
</div>
|
||||
<div class="representative-health-row health-unknown">
|
||||
<div class="health-icon"></div>
|
||||
<div class="label">Receive a transaction to configure</div>
|
||||
<div class="label">{{ 'change-rep-widget.receive-a-transaction-to-configure' | transloco }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -121,6 +120,6 @@
|
|||
<span class="uk-text-warning" uk-icon="icon: warning; ratio: 1.2;"></span>
|
||||
</div>
|
||||
<div class="status-labels">
|
||||
<div class="label primary uk-text-warning">Representative Change Required</div>
|
||||
<div class="label primary uk-text-warning">{{ 'change-rep-widget.representative-change-required' | transloco }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,23 @@
|
|||
</div>
|
||||
<div class="uk-card-body">
|
||||
<div uk-grid>
|
||||
|
||||
<div class="uk-width-1-1">
|
||||
<div class="uk-form-horizontal">
|
||||
|
||||
<div class="uk-margin">
|
||||
<label class="uk-form-label" for="languageselector">
|
||||
{{ 'configure-app.language' | transloco }}
|
||||
</label>
|
||||
<div class="uk-form-controls">
|
||||
<select class="uk-select" [(ngModel)]="selectedLanguage" id="languageselector">
|
||||
<option *ngFor="let language of languages" [value]="language.id">{{ language.label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-width-1-1">
|
||||
<div class="uk-form-horizontal">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {BehaviorSubject} from 'rxjs';
|
|||
import {RepresentativeService} from '../../services/representative.service';
|
||||
import {NinjaService} from '../../services/ninja.service';
|
||||
import {QrModalService} from '../../services/qr-modal.service';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
@Component({
|
||||
selector: 'app-configure-app',
|
||||
|
|
@ -38,9 +39,13 @@ export class ConfigureAppComponent implements OnInit {
|
|||
private price: PriceService,
|
||||
private ninja: NinjaService,
|
||||
private renderer: Renderer2,
|
||||
private qrModalService: QrModalService) { }
|
||||
private qrModalService: QrModalService,
|
||||
private translate: TranslocoService) { }
|
||||
wallet = this.walletService.wallet;
|
||||
|
||||
languages = this.translate.getAvailableLangs() as [{id: string, label: string}];
|
||||
selectedLanguage = this.languages[0].id;
|
||||
|
||||
denominations = [
|
||||
{ name: 'NANO', value: 'mnano' },
|
||||
{ name: 'knano', value: 'knano' },
|
||||
|
|
@ -247,6 +252,9 @@ export class ConfigureAppComponent implements OnInit {
|
|||
loadFromSettings() {
|
||||
const settings = this.appSettings.settings;
|
||||
|
||||
const matchingLanguage = this.languages.find(language => language.id === settings.language);
|
||||
this.selectedLanguage = matchingLanguage.id || this.languages[0].id;
|
||||
|
||||
const matchingCurrency = this.currencies.find(d => d.value === settings.displayCurrency);
|
||||
this.selectedCurrency = matchingCurrency.value || this.currencies[0].value;
|
||||
|
||||
|
|
@ -313,6 +321,9 @@ export class ConfigureAppComponent implements OnInit {
|
|||
this.walletService.reloadFiatBalances();
|
||||
}
|
||||
|
||||
this.appSettings.setAppSetting('language', this.selectedLanguage);
|
||||
this.translate.setActiveLang(this.selectedLanguage);
|
||||
|
||||
// if (updatePrefixes) {
|
||||
// this.appSettings.setAppSetting('displayPrefix', this.selectedPrefix);
|
||||
// Go through accounts?
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {PriceService} from '../../services/price.service';
|
|||
import {WebsocketService} from '../../services/websocket.service';
|
||||
import * as QRCode from 'qrcode';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
@Component({
|
||||
selector: 'app-receive',
|
||||
|
|
@ -61,7 +62,8 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
private nanoBlock: NanoBlockService,
|
||||
public price: PriceService,
|
||||
private websocket: WebsocketService,
|
||||
private util: UtilService) { }
|
||||
private util: UtilService,
|
||||
private translocoService: TranslocoService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
const UIkit = window['UIkit'];
|
||||
|
|
@ -174,7 +176,7 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
return defaultLabel;
|
||||
}
|
||||
|
||||
return ('Account #' + walletAccount.index);
|
||||
return (this.translocoService.translate('general.account') + '#' + walletAccount.index);
|
||||
}
|
||||
|
||||
async getPending() {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
WalletService,
|
||||
NinjaService
|
||||
} from '../../services';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
@Component({
|
||||
selector: 'app-representatives',
|
||||
|
|
@ -61,7 +62,8 @@ export class RepresentativesComponent implements OnInit {
|
|||
private representativeService: RepresentativeService,
|
||||
public settings: AppSettingsService,
|
||||
private ninja: NinjaService,
|
||||
private qrModalService: QrModalService) { }
|
||||
private qrModalService: QrModalService,
|
||||
private translocoService: TranslocoService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.representativeService.loadRepresentativeList();
|
||||
|
|
@ -131,10 +133,10 @@ export class RepresentativesComponent implements OnInit {
|
|||
const walletAccount = this.walletService.wallet.accounts.find(a => a.id === account.id);
|
||||
|
||||
if (walletAccount == null) {
|
||||
return 'Account';
|
||||
return this.translocoService.translate('general.account');
|
||||
}
|
||||
|
||||
return ('Account #' + walletAccount.index);
|
||||
return (this.translocoService.translate('general.account') + '#' + walletAccount.index);
|
||||
}
|
||||
|
||||
addSelectedAccounts(accounts) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {PriceService} from '../../services/price.service';
|
|||
import {NanoBlockService} from '../../services/nano-block.service';
|
||||
import { QrModalService } from '../../services/qr-modal.service';
|
||||
import { environment } from 'environments/environment';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
const nacl = window['nacl'];
|
||||
|
||||
|
|
@ -67,7 +68,8 @@ export class SendComponent implements OnInit {
|
|||
private workPool: WorkPoolService,
|
||||
public settings: AppSettingsService,
|
||||
private util: UtilService,
|
||||
private qrModalService: QrModalService, ) { }
|
||||
private qrModalService: QrModalService,
|
||||
private translocoService: TranslocoService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
const params = this.router.snapshot.queryParams;
|
||||
|
|
@ -250,7 +252,7 @@ export class SendComponent implements OnInit {
|
|||
return defaultLabel;
|
||||
}
|
||||
|
||||
return ('Account #' + walletAccount.index);
|
||||
return (this.translocoService.translate('general.account') + '#' + walletAccount.index);
|
||||
}
|
||||
|
||||
validateAmount() {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {NotificationService} from '../../services/notification.service';
|
|||
import {AppSettingsService} from '../../services/app-settings.service';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {AddressBookService} from '../../services/address-book.service';
|
||||
import { TranslocoService } from '@ngneat/transloco';
|
||||
|
||||
@Component({
|
||||
selector: 'app-transaction-details',
|
||||
|
|
@ -41,7 +42,8 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
private addressBook: AddressBookService,
|
||||
private api: ApiService,
|
||||
private notifications: NotificationService,
|
||||
public settings: AppSettingsService
|
||||
public settings: AppSettingsService,
|
||||
private translocoService: TranslocoService
|
||||
) { }
|
||||
|
||||
async ngOnInit() {
|
||||
|
|
@ -171,7 +173,7 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
return defaultLabel;
|
||||
}
|
||||
|
||||
return ('Account #' + walletAccount.index);
|
||||
return (this.translocoService.translate('general.account') + '#' + walletAccount.index);
|
||||
}
|
||||
|
||||
getBalanceFromHex(balance) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import * as url from 'url';
|
||||
import { TranslocoService, getBrowserCultureLang, getBrowserLang } from '@ngneat/transloco';
|
||||
|
||||
export type WalletStore = 'localStorage'|'none';
|
||||
export type PoWSource = 'server'|'clientCPU'|'clientWebGL'|'best'|'custom';
|
||||
export type LedgerConnectionType = 'usb'|'bluetooth';
|
||||
|
||||
interface AppSettings {
|
||||
language: string;
|
||||
displayDenomination: string;
|
||||
// displayPrefix: string | null;
|
||||
walletStore: string;
|
||||
|
|
@ -33,6 +35,7 @@ export class AppSettingsService {
|
|||
storeKey = `nanovault-appsettings`;
|
||||
|
||||
settings: AppSettings = {
|
||||
language: null,
|
||||
displayDenomination: 'mnano',
|
||||
// displayPrefix: 'xrb',
|
||||
walletStore: 'localStorage',
|
||||
|
|
@ -140,7 +143,9 @@ export class AppSettingsService {
|
|||
'node.somenano.com'
|
||||
]);
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private translate: TranslocoService
|
||||
) { }
|
||||
|
||||
loadAppSettings() {
|
||||
let settings: AppSettings = this.settings;
|
||||
|
|
@ -150,6 +155,23 @@ export class AppSettingsService {
|
|||
}
|
||||
this.settings = Object.assign(this.settings, settings);
|
||||
|
||||
if (this.settings.language === null) {
|
||||
const browserCultureLang = getBrowserCultureLang();
|
||||
const browserLang = getBrowserLang();
|
||||
|
||||
if (this.translate.getAvailableLangs().some(lang => lang['id'] === browserCultureLang)) {
|
||||
this.settings.language = browserCultureLang;
|
||||
} else if (this.translate.getAvailableLangs().some(lang => lang['id'] === browserCultureLang)) {
|
||||
this.settings.language = browserLang;
|
||||
} else {
|
||||
this.settings.language = this.translate.getDefaultLang();
|
||||
}
|
||||
|
||||
console.log('No language configured, setting to: ' + this.settings.language);
|
||||
console.log('Browser culture language: ' + browserCultureLang);
|
||||
console.log('Browser language: ' + browserLang);
|
||||
}
|
||||
|
||||
this.loadServerSettings();
|
||||
|
||||
return this.settings;
|
||||
|
|
@ -206,6 +228,7 @@ export class AppSettingsService {
|
|||
clearAppSettings() {
|
||||
localStorage.removeItem(this.storeKey);
|
||||
this.settings = {
|
||||
language: 'en',
|
||||
displayDenomination: 'mnano',
|
||||
// displayPrefix: 'xrb',
|
||||
walletStore: 'localStorage',
|
||||
|
|
|
|||
44
src/app/transloco/transloco-root.module.ts
Normal file
44
src/app/transloco/transloco-root.module.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import {
|
||||
TRANSLOCO_LOADER,
|
||||
TranslocoLoader,
|
||||
TRANSLOCO_CONFIG,
|
||||
translocoConfig,
|
||||
TranslocoModule
|
||||
} from '@ngneat/transloco';
|
||||
import { Injectable, NgModule } from '@angular/core';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class TranslocoHttpLoader implements TranslocoLoader {
|
||||
constructor() {}
|
||||
|
||||
getTranslation(lang: string) {
|
||||
return import(/* webpackChunkName: "translation" */ `../../assets/i18n/${lang}.json`).then(res => res.default);
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
exports: [ TranslocoModule ],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLOCO_CONFIG,
|
||||
useValue: translocoConfig({
|
||||
availableLangs: [
|
||||
{ id: 'en', label: 'English' },
|
||||
// { id: 'de', label: 'Deutsch' }
|
||||
],
|
||||
defaultLang: 'en',
|
||||
fallbackLang: 'en',
|
||||
missingHandler: {
|
||||
// It will use the first language set in the `fallbackLang` property
|
||||
useFallbackTranslation: true
|
||||
},
|
||||
// Remove this option if your application doesn't support changing language in runtime.
|
||||
reRenderOnLangChange: true,
|
||||
prodMode: environment.production,
|
||||
})
|
||||
},
|
||||
{ provide: TRANSLOCO_LOADER, useClass: TranslocoHttpLoader }
|
||||
]
|
||||
})
|
||||
export class TranslocoRootModule {}
|
||||
31
src/assets/i18n/de.json
Normal file
31
src/assets/i18n/de.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"change-rep-widget": {
|
||||
"acceptable-representative": "Akzeptabler Vertreter",
|
||||
"bad-representative": "Schlechter Vertreter",
|
||||
"checking-status": "Prüfe Status...",
|
||||
"good-representative": "Guter Vertreter",
|
||||
"health": "Status",
|
||||
"representative-change-required": "Vetreterwechsel nötig",
|
||||
"representative-for-account": "Vetreter für {{ account }}",
|
||||
"representative-none": "Keinen",
|
||||
"unknown-status": "Unbekannter Status"
|
||||
},
|
||||
"configure-app": {
|
||||
"language": "Sprache"
|
||||
},
|
||||
"general": {
|
||||
"account": "Konto",
|
||||
"accounts": "Konten",
|
||||
"address-book": "Adressbuch",
|
||||
"app-settings": "App Einstellungen",
|
||||
"loading": "Lade...",
|
||||
"new": "Neu",
|
||||
"receive": "Empfangen",
|
||||
"representative": "Vertreter",
|
||||
"representatives": "Vertreter",
|
||||
"scan-qr-code": "QR Code scannen",
|
||||
"send": "Senden",
|
||||
"settings": "Einstellungen",
|
||||
"unknown": "Unbekannt"
|
||||
}
|
||||
}
|
||||
46
src/assets/i18n/en.json
Normal file
46
src/assets/i18n/en.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"change-rep-widget": {
|
||||
"acceptable-representative": "Acceptable Representative",
|
||||
"bad-representative": "Bad Representative",
|
||||
"checking-status": "Checking Status...",
|
||||
"good-representative": "Good Representative",
|
||||
"health": "Health",
|
||||
"it-is-highly-advised-to-switch-to-a-different-representative": "It is highly advised to switch to a different representative, in order to improve security and decentralization of the Nano network.",
|
||||
"receive-a-transaction-to-configure": "Receive a transaction to configure",
|
||||
"rep-represents-you": "{{ name }} represents you in the Nano consensus protocol by voting on your behalf.",
|
||||
"representative-change-required": "Representative Change Required",
|
||||
"representative-for-account": "Representative for {{ account }}",
|
||||
"representative-none": "None",
|
||||
"switching-to-a-different-representative-could-improve": "Switching to a different representative could improve security and decentralization of the Nano network.",
|
||||
"this-representative-has-a-high-voting-weight": "This representative has a high voting weight (over {{ percent }}%).",
|
||||
"this-representative-has-a-very-high-voting-weight": "This representative has a very high voting weight (over {{ percent }}%).",
|
||||
"this-representative-has-announced-plans-to-permanently-shutdown": "This representative has announced plans to permanently shutdown.",
|
||||
"this-representative-has-been-offline-for-the-past-days": "This representative has been offline for the past {{ days }} days.",
|
||||
"this-representative-is-marked-as-avoid": "This representative is marked as \"avoid\" in the list of known reps.",
|
||||
"this-representative-is-often-offline": "This representative is often offline ({{ percent }}% uptime)",
|
||||
"this-representative-is-sometimes-offline": "This representative is sometimes offline ({{ percent }}% uptime).",
|
||||
"unknown-status": "Unknown Status",
|
||||
"we-could-not-determine-status-of-this-representative": "We could not determine status of this representative.",
|
||||
"we-found-no-issues-with-uptime-or-weight": "We found no issues with uptime or weight distribution of your current representative.",
|
||||
"you-can-change-representative-at-any-time": "You can change representative at any time by clicking on its name above.",
|
||||
"you-have-marked-this-representative-as-trusted": "You have marked this representative as trusted, meaning its status will remain \"Good\" even in case of severe issues with uptime or weight distribution."
|
||||
},
|
||||
"configure-app": {
|
||||
"language": "Language"
|
||||
},
|
||||
"general": {
|
||||
"account": "Account",
|
||||
"accounts": "Accounts",
|
||||
"address-book": "Address Book",
|
||||
"app-settings": "App Settings",
|
||||
"loading": "Loading...",
|
||||
"new": "New",
|
||||
"receive": "Receive",
|
||||
"representative": "Representative",
|
||||
"representatives": "Representatives",
|
||||
"scan-qr-code": "Scan QR Code",
|
||||
"send": "Send",
|
||||
"settings": "Settings",
|
||||
"unknown": "Unknown"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue