From 4404812d4f7fb7751acbe36994de74ae76ce839a Mon Sep 17 00:00:00 2001 From: ronaldsg Date: Tue, 30 Apr 2024 02:08:40 -0500 Subject: [PATCH] Internacionalization plugin I've added the i18n plugin in order to correctly switch between the app laguages --- package-lock.json | 227 ++++++++++++++++++++++++++ package.json | 2 + src/common/store/constants.ts | 2 + src/common/store/session/actions.ts | 4 + src/common/store/session/mutations.ts | 8 +- src/common/types/Common.ts | 5 + src/common/views/Home.vue | 2 +- src/i18n.ts | 14 ++ src/locales/en.json | 5 + src/locales/es.json | 5 + src/main.ts | 2 + vue.config.js | 11 ++ 12 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 src/i18n.ts create mode 100644 src/locales/en.json create mode 100644 src/locales/es.json diff --git a/package-lock.json b/package-lock.json index 09cdd57f..e8566094 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,7 @@ "tiny-secp256k1": "^1.1.6", "url": "^0.11.1", "vue": "^3.3.4", + "vue-i18n": "^9.13.1", "vue-router": "^4.2.4", "vuetify": "^3.3.11", "vuex": "^4.1.0", @@ -57,6 +58,7 @@ "web3-eth-contract": "^1.10.0" }, "devDependencies": { + "@intlify/vue-i18n-loader": "^4.2.0", "@ledgerhq/hw-transport-mocker": "^6.28.5", "@mdi/font": "^7.2.96", "@types/big.js": "^6.2.0", @@ -2676,6 +2678,141 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@intlify/bundle-utils": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-2.2.2.tgz", + "integrity": "sha512-vngkvlIVV8ZJoyC5VqMvqJd2nvsx+qMN7pQjPiPjOrVndeiR7Dlue0k86Q8FsFUzyksW3HJZZi833ldxwbFzTA==", + "dev": true, + "dependencies": { + "@intlify/message-compiler": "^9.1.0", + "@intlify/shared": "^9.1.0", + "jsonc-eslint-parser": "^1.0.1", + "source-map": "^0.6.1", + "yaml-eslint-parser": "^0.3.2" + }, + "engines": { + "node": ">= 12" + }, + "peerDependenciesMeta": { + "petite-vue-i18n": { + "optional": true + }, + "vue-i18n": { + "optional": true + } + } + }, + "node_modules/@intlify/core-base": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz", + "integrity": "sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==", + "dependencies": { + "@intlify/message-compiler": "9.13.1", + "@intlify/shared": "9.13.1" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.13.1.tgz", + "integrity": "sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==", + "dependencies": { + "@intlify/shared": "9.13.1", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.13.1.tgz", + "integrity": "sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/vue-i18n-loader": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@intlify/vue-i18n-loader/-/vue-i18n-loader-4.2.0.tgz", + "integrity": "sha512-d7aBmMNWJskcZPT5rJH4h2XHe/PwNoJUaY0PGla9g+NSD4B0UR8LBKrp126nlaUfA74Xt0FEGvzCfG9KdC9KoA==", + "dev": true, + "dependencies": { + "@intlify/bundle-utils": "^2.2.2", + "@intlify/shared": "^9.1.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "petite-vue-i18n": "^9.1.0", + "vue": "^3.0.0", + "vue-i18n": "^9.1.0" + }, + "peerDependenciesMeta": { + "petite-vue-i18n": { + "optional": true + }, + "vue-i18n": { + "optional": true + } + } + }, + "node_modules/@intlify/vue-i18n-loader/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@intlify/vue-i18n-loader/node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/@intlify/vue-i18n-loader/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@intlify/vue-i18n-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "dev": true, @@ -16617,6 +16754,57 @@ "node": ">=6" } }, + "node_modules/jsonc-eslint-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-1.4.1.tgz", + "integrity": "sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==", + "dev": true, + "dependencies": { + "acorn": "^7.4.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^6.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "dev": true, @@ -23158,6 +23346,25 @@ "dev": true, "license": "MIT" }, + "node_modules/vue-i18n": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.13.1.tgz", + "integrity": "sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==", + "dependencies": { + "@intlify/core-base": "9.13.1", + "@intlify/shared": "9.13.1", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue-loader": { "version": "17.2.2", "dev": true, @@ -24800,6 +25007,26 @@ "node": ">= 6" } }, + "node_modules/yaml-eslint-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.3.2.tgz", + "integrity": "sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.3.0", + "lodash": "^4.17.20", + "yaml": "^1.10.0" + } + }, + "node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/yargs": { "version": "16.2.0", "dev": true, diff --git a/package.json b/package.json index 59a30232..bb9def35 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "tiny-secp256k1": "^1.1.6", "url": "^0.11.1", "vue": "^3.3.4", + "vue-i18n": "^9.13.1", "vue-router": "^4.2.4", "vuetify": "^3.3.11", "vuex": "^4.1.0", @@ -61,6 +62,7 @@ "web3-eth-contract": "^1.10.0" }, "devDependencies": { + "@intlify/vue-i18n-loader": "^4.2.0", "@ledgerhq/hw-transport-mocker": "^6.28.5", "@mdi/font": "^7.2.96", "@types/big.js": "^6.2.0", diff --git a/src/common/store/constants.ts b/src/common/store/constants.ts index b93fe7c7..5c314bfc 100644 --- a/src/common/store/constants.ts +++ b/src/common/store/constants.ts @@ -80,6 +80,7 @@ export const SESSION_ADD_BITCOIN_PRICE = 'SESSION_ADD_BITCOIN_PRICE'; export const SESSION_CLEAR = 'SESSION_CLEAR'; export const SESSION_ADD_TERMS_VALUE = 'SESSION_ADD_TERMS_VALUE'; export const SESSION_ADD_TERMS_AND_CONDITIONS_ENABLED = 'SESSION_ADD_TERMS_AND_CONDITIONS_ENABLED'; +export const SESSION_SWITCH_LOCALE = 'SESSION_SWITCH_LOCALE'; // Pegin tx Mutations export const PEGIN_TX_SET_ADDRESS_LIST = 'PEGIN_TX_SET_ADDRESS_LIST'; @@ -136,6 +137,7 @@ export const SESSION_SET_BITCOIN_PRICE = 'SESSION_SET_BITCOIN_PRICE'; export const SESSION_CLEAR_STATE = 'SESSION_CLEAR_STATE'; export const SESSION_SET_TERMS_ACCEPTED = 'SESSION_SET_TERMS_ACCEPTED'; export const SESSION_SET_TERMS_AND_CONDITIONS_ENABLED = 'SESSION_SET_TERMS_AND_CONDITIONS_ENABLED'; +export const SESSION_SET_LOCALE = 'SESSION_SET_LOCALE'; // Pegin tx getters export const WALLET_NAME = 'WALLET_NAME'; diff --git a/src/common/store/session/actions.ts b/src/common/store/session/actions.ts index 46037f7e..7393b916 100644 --- a/src/common/store/session/actions.ts +++ b/src/common/store/session/actions.ts @@ -8,6 +8,7 @@ import axios, { AxiosResponse } from 'axios'; import * as constants from '@/common/store/constants'; import { TransactionType, SessionState, RootState, WeiBig, + AppLocale, } from '@/common/types'; import { EnvironmentAccessorService } from '@/common/services/enviroment-accessor.service'; import { ApiService } from '@/common/services'; @@ -165,4 +166,7 @@ export const actions: ActionTree = { dispatch(constants.SESSION_ADD_TERMS_VALUE, false); } }, + [constants.SESSION_SWITCH_LOCALE]: ({ commit }, locale: AppLocale) => { + commit(constants.SESSION_SET_LOCALE, locale); + }, }; diff --git a/src/common/store/session/mutations.ts b/src/common/store/session/mutations.ts index ddf83eaf..520d0410 100644 --- a/src/common/store/session/mutations.ts +++ b/src/common/store/session/mutations.ts @@ -1,9 +1,10 @@ import { MutationTree } from 'vuex'; import Web3 from 'web3'; import * as constants from '@/common/store/constants'; -import { WeiBig } from '@/common/types'; +import { AppLocale, WeiBig } from '@/common/types'; import { TransactionType, SessionState } from '@/common/types/session'; import { getClearSessionState } from '@/common/utils'; +import i18n from '@/i18n'; export const mutations: MutationTree = { [constants.SESSION_SET_ACCOUNT]: (state, account: string) => { @@ -48,4 +49,9 @@ export const mutations: MutationTree = { [constants.SESSION_SET_TERMS_AND_CONDITIONS_ENABLED]: (state, value) => { state.termsAndConditionsEnabled = value; }, + [constants.SESSION_SET_LOCALE]: (state, newLocale: AppLocale) => { + if (newLocale && i18n.global.availableLocales.includes(newLocale)) { + i18n.global.locale.value = newLocale; + } + }, }; diff --git a/src/common/types/Common.ts b/src/common/types/Common.ts index 9fc98cec..9c6acf85 100644 --- a/src/common/types/Common.ts +++ b/src/common/types/Common.ts @@ -124,3 +124,8 @@ export interface NormalizedSummary { export type AddressType = 'BITCOIN_LEGACY_ADDRESS' | 'BITCOIN_SEGWIT_ADDRESS' | 'BITCOIN_NATIVE_SEGWIT_ADDRESS' | 'BITCOIN_MULTISIGNATURE_ADDRESS' | 'BITCOIN_UNKNOWN_ADDRESS_TYPE'; + +export enum AppLocale { + LOCALE_EN = 'en', + LOCALE_ES = 'es', +} diff --git a/src/common/views/Home.vue b/src/common/views/Home.vue index 8d174fd0..20e6eac0 100644 --- a/src/common/views/Home.vue +++ b/src/common/views/Home.vue @@ -34,7 +34,7 @@ -

Select your token conversion

+

{{ $t('main.subtitle-2') }}

diff --git a/src/i18n.ts b/src/i18n.ts new file mode 100644 index 00000000..ac55ece7 --- /dev/null +++ b/src/i18n.ts @@ -0,0 +1,14 @@ +import { createI18n } from 'vue-i18n'; +import enLocale from './locales/en.json'; +import esLocale from './locales/es.json'; + +export default createI18n({ + locale: 'en', + fallbackLocale: 'es', + legacy: false, + messages: { + en: enLocale, + es: esLocale, + }, + globalInjection: true, +}); diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 00000000..4c1ca4af --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1,5 @@ +{ + "main": { + "subtitle-2": "Select your token conversion" + } +} diff --git a/src/locales/es.json b/src/locales/es.json new file mode 100644 index 00000000..b2a88d9e --- /dev/null +++ b/src/locales/es.json @@ -0,0 +1,5 @@ +{ + "main": { + "subtitle-2": "Selecciona tu conversion de token" + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 612a5b36..32ea8592 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { createApp } from 'vue'; import { AppNetwork } from '@/common/types'; import { EnvironmentAccessorService } from '@/common/services/enviroment-accessor.service'; import * as constants from '@/common/store/constants'; +import i18n from '@/i18n'; import App from './App.vue'; import router from './common/router'; import store from './common/store'; @@ -35,6 +36,7 @@ EnvironmentAccessorService.initializeEnvironmentVariables(defaultEnvironmentVari const app = createApp(App); +app.use(i18n); app.use(router); app.use(vuetify); app.use(store); diff --git a/vue.config.js b/vue.config.js index 5c5e5bc4..d603874e 100644 --- a/vue.config.js +++ b/vue.config.js @@ -31,4 +31,15 @@ module.exports = defineConfig({ devServer: { https: true, }, + pluginOptions: { + i18n: { + locale: 'en', + fallbackLocale: 'en', + localeDir: 'locales', + enableLegacy: false, + runtimeOnly: false, + compositionOnly: false, + fullInstall: true, + }, + }, });