feat: add language to topmenu + globals cleanup + i18n refactor (#3510)

This commit is contained in:
dni ⚡ 2025-11-12 15:07:53 +01:00 committed by GitHub
parent 5e36bb4fcd
commit b6f533be24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 90 additions and 76 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -66,7 +66,7 @@ window.LNbits = {
}
newWallet.msat = data.balance_msat
newWallet.sat = Math.floor(data.balance_msat / 1000)
newWallet.fsat = new Intl.NumberFormat(window.LOCALE).format(
newWallet.fsat = new Intl.NumberFormat(window.i18n.global.locale).format(
newWallet.sat
)
if (newWallet.walletType === 'lightning-shared') {
@ -105,7 +105,9 @@ window.LNbits = {
obj.msat = obj.amount
obj.sat = obj.msat / 1000
obj.tag = obj.extra?.tag
obj.fsat = new Intl.NumberFormat(window.LOCALE).format(obj.sat)
obj.fsat = new Intl.NumberFormat(window.i18n.global.locale).format(
obj.sat
)
obj.isIn = obj.amount > 0
obj.isOut = obj.amount < 0
obj.isPending = obj.status === 'pending'

View file

@ -0,0 +1,37 @@
window.app.component('lnbits-language-dropdown', {
template: '#lnbits-language-dropdown',
mixins: [window.windowMixin],
methods: {
activeLanguage(lang) {
return window.i18n.global.locale === lang
},
changeLanguage(newValue) {
this.g.locale = newValue
window.i18n.global.locale = newValue
this.$q.localStorage.set('lnbits.lang', newValue)
}
},
data() {
return {
langs: [
{value: 'en', label: 'English', display: '🇬🇧 EN'},
{value: 'de', label: 'Deutsch', display: '🇩🇪 DE'},
{value: 'es', label: 'Español', display: '🇪🇸 ES'},
{value: 'jp', label: '日本語', display: '🇯🇵 JP'},
{value: 'cn', label: '中文', display: '🇨🇳 CN'},
{value: 'fr', label: 'Français', display: '🇫🇷 FR'},
{value: 'it', label: 'Italiano', display: '🇮🇹 IT'},
{value: 'pi', label: 'Pirate', display: '🏴‍☠️ PI'},
{value: 'nl', label: 'Nederlands', display: '🇳🇱 NL'},
{value: 'we', label: 'Cymraeg', display: '🏴󠁧󠁢󠁷󠁬󠁳󠁿 CY'},
{value: 'pl', label: 'Polski', display: '🇵🇱 PL'},
{value: 'pt', label: 'Português', display: '🇵🇹 PT'},
{value: 'br', label: 'Português do Brasil', display: '🇧🇷 BR'},
{value: 'cs', label: 'Česky', display: '🇨🇿 CS'},
{value: 'sk', label: 'Slovensky', display: '🇸🇰 SK'},
{value: 'kr', label: '한국어', display: '🇰🇷 KR'},
{value: 'fi', label: 'Suomi', display: '🇫🇮 FI'}
]
}
}
})

View file

@ -1,33 +1,3 @@
window.langs = [
{value: 'en', label: 'English', display: '🇬🇧 EN'},
{value: 'de', label: 'Deutsch', display: '🇩🇪 DE'},
{value: 'es', label: 'Español', display: '🇪🇸 ES'},
{value: 'jp', label: '日本語', display: '🇯🇵 JP'},
{value: 'cn', label: '中文', display: '🇨🇳 CN'},
{value: 'fr', label: 'Français', display: '🇫🇷 FR'},
{value: 'it', label: 'Italiano', display: '🇮🇹 IT'},
{value: 'pi', label: 'Pirate', display: '🏴‍☠️ PI'},
{value: 'nl', label: 'Nederlands', display: '🇳🇱 NL'},
{value: 'we', label: 'Cymraeg', display: '🏴󠁧󠁢󠁷󠁬󠁳󠁿 CY'},
{value: 'pl', label: 'Polski', display: '🇵🇱 PL'},
{value: 'pt', label: 'Português', display: '🇵🇹 PT'},
{value: 'br', label: 'Português do Brasil', display: '🇧🇷 BR'},
{value: 'cs', label: 'Česky', display: '🇨🇿 CS'},
{value: 'sk', label: 'Slovensky', display: '🇸🇰 SK'},
{value: 'kr', label: '한국어', display: '🇰🇷 KR'},
{value: 'fi', label: 'Suomi', display: '🇫🇮 FI'}
]
window.LOCALE = 'en'
window.dateFormat = 'YYYY-MM-DD HH:mm'
window.i18n = new VueI18n.createI18n({
locale: window.LOCALE,
fallbackLocale: window.LOCALE,
messages: window.localisation
})
const websocketPrefix =
window.location.protocol === 'http:' ? 'ws://' : 'wss://'
const websocketUrl = `${websocketPrefix}${window.location.host}/api/v1/ws`
window.g = Vue.reactive({
offline: !navigator.onLine,
visibleDrawer: false,
@ -39,9 +9,16 @@ window.g = Vue.reactive({
fiatTracking: false,
wallets: [],
payments: [],
langs: [],
walletEventListeners: [],
updatePayments: false,
updatePaymentsHash: '',
walletFlip: Quasar.LocalStorage.getItem('lnbits.walletFlip') ?? false
walletFlip: Quasar.LocalStorage.getItem('lnbits.walletFlip') ?? false,
locale:
Quasar.LocalStorage.getItem('lnbits.lang') ?? navigator.languages[1] ?? 'en'
})
window.dateFormat = 'YYYY-MM-DD HH:mm'
const websocketPrefix =
window.location.protocol === 'http:' ? 'ws://' : 'wss://'
const websocketUrl = `${websocketPrefix}${window.location.host}/api/v1/ws`

View file

@ -225,7 +225,15 @@ window.app.use(Quasar, {
}
}
})
window.i18n = new VueI18n.createI18n({
locale: window.g.locale,
fallbackLocale: 'en',
messages: window.localisation
})
window.app.use(window.i18n)
window.app.provide('g', g)
window.app.use(window.router)
window.app.component('DynamicComponent', DynamicComponent)

View file

@ -168,7 +168,7 @@ window.PagePayments = {
p.timeFrom = moment.utc(p.created_at).local().fromNow()
p.outgoing = p.amount < 0
p.amount =
new Intl.NumberFormat(window.LOCALE).format(p.amount / 1000) +
new Intl.NumberFormat(this.g.locale).format(p.amount / 1000) +
' sats'
if (p.extra?.wallet_fiat_amount) {
p.amountFiat = this.formatCurrency(
@ -180,7 +180,7 @@ window.PagePayments = {
p.internal_memo = p.extra.internal_memo
}
p.fee_sats =
new Intl.NumberFormat(window.LOCALE).format(p.fee / 1000) + ' sats'
new Intl.NumberFormat(this.g.locale).format(p.fee / 1000) + ' sats'
return p
})

View file

@ -41,13 +41,13 @@ window._lnbitsUtils = {
return Quasar.date.formatDate(new Date(isoDateString), window.dateFormat)
},
formatCurrency(value, currency) {
return new Intl.NumberFormat(window.LOCALE, {
return new Intl.NumberFormat(window.i18n.global.locale, {
style: 'currency',
currency: currency || 'sat'
}).format(value)
},
formatSat(value) {
return new Intl.NumberFormat(window.LOCALE).format(value)
return new Intl.NumberFormat(window.i18n.global.locale).format(value)
},
formatMsat(value) {
return this.formatSat(value / 1000)

View file

@ -283,14 +283,6 @@ window.windowMixin = {
}
this.applyBackgroundImage()
let locale = this.$q.localStorage.getItem('lnbits.lang')
if (locale) {
window.LOCALE = locale
window.i18n.global.locale = locale
}
this.g.langs = window.langs ?? []
addEventListener('offline', event => {
console.log('offline', event)
this.g.offline = true

View file

@ -75,6 +75,7 @@
"js/components/lnbits-header.js",
"js/components/lnbits-drawer.js",
"js/components/lnbits-manage-extension-list.js",
"js/components/lnbits-language-dropdown.js",
"js/components/extension-settings.js",
"js/components/data-fields.js",
"js/components/payment-list.js",

View file

@ -15,7 +15,8 @@ include('components/lnbits-footer.vue') %} {%
include('components/lnbits-header.vue') %} {%
include('components/lnbits-drawer.vue') %} {%
include('components/lnbits-home-logos.vue') %} {%
include('components/lnbits-manage-extension-list.vue') %}
include('components/lnbits-manage-extension-list.vue') %} {%
include('components/lnbits-language-dropdown.vue') %}
<template id="lnbits-wallet-list">
<q-list

View file

@ -70,6 +70,8 @@
<span>OFFLINE</span>
</q-badge>
<lnbits-language-dropdown></lnbits-language-dropdown>
<q-btn-dropdown
v-if="g.user || isUserAuthorized"
flat

View file

@ -0,0 +1,19 @@
<template id="lnbits-language-dropdown">
<q-btn-dropdown dense flat rounded size="sm" icon="language" class="q-pl-md">
<q-list v-for="(lang, index) in langs" :key="index">
<q-item
clickable
v-close-popup
:active="activeLanguage(lang.value)"
@click="changeLanguage(lang.value)"
>
<q-item-section>
<q-item-label
v-text="lang.display ?? lang.value.toUpperCase()"
></q-item-label>
<q-tooltip><span v-text="lang.label"></span></q-tooltip>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</template>

View file

@ -366,33 +366,7 @@
<span v-text="$t('language')"></span>
</div>
<div class="col-8">
<q-btn-dropdown
dense
flat
round
size="sm"
icon="language"
class="q-pl-md"
>
<q-list v-for="(lang, index) in g.langs" :key="index">
<q-item
clickable
v-close-popup
:active="activeLanguage(lang.value)"
@click="changeLanguage(lang.value)"
><q-item-section>
<q-item-label
v-text="
lang.display ?? lang.value.toUpperCase()
"
></q-item-label>
<q-tooltip
><span v-text="lang.label"></span
></q-tooltip>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<lnbits-language-dropdown />
</div>
</div>
<div class="row q-mb-md">

View file

@ -127,6 +127,7 @@
"js/components/lnbits-header.js",
"js/components/lnbits-drawer.js",
"js/components/lnbits-manage-extension-list.js",
"js/components/lnbits-language-dropdown.js",
"js/components/extension-settings.js",
"js/components/data-fields.js",
"js/components/payment-list.js",