refactor: lnbits-wallet-extra the expandables in the sidebar (#3550)

This commit is contained in:
dni ⚡ 2025-11-24 10:44:57 +01:00 committed by GitHub
parent 152c1dbb74
commit 233398b512
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 385 additions and 387 deletions

View file

@ -13,16 +13,11 @@
<div class="col-12 col-md-7 q-gutter-y-md wallet-wrapper">
{% endif %}
<q-card class="wallet-card">
<q-card-section style="height: 130px">
<div class="row q-gutter-md">
<div
v-if="g.isSatsDenomination"
class="col-1"
style="max-width: 30px"
>
<q-card-section>
<div class="row q-gutter-sm">
<div v-if="g.fiatTracking" class="col-auto">
<q-btn
v-if="g.fiatTracking"
@click="swapBalancePriority"
@click="g.isFiatPriority = !g.isFiatPriority"
style="height: 50px"
class="q-mt-lg"
color="primary"
@ -33,12 +28,12 @@
</div>
<div class="col">
<div
v-if="!g.isFiatPriority || !g.fiatTracking"
class="column"
:class="{
'q-pt-sm': g.fiatTracking,
'q-pt-lg': !g.fiatTracking
}"
v-if="!g.isFiatPriority || !g.fiatTracking"
style="height: 100px"
>
<div class="col-7">
@ -136,8 +131,10 @@
></q-btn>
</div>
</div>
</q-card-section>
<div class="row q-pb-md q-px-md q-col-gutter-md gt-sm">
<div
v-if="!g.mobileSimple || !$q.screen.lt.md"
class="lnbits-wallet-buttons row q-gutter-md"
>
<div class="col">
<q-btn
unelevated
@ -174,6 +171,7 @@
></lnbits-update-balance>
</div>
</div>
</q-card-section>
</q-card>
<q-card class="wallet-card">
@ -193,239 +191,11 @@
v-if="!g.mobileSimple || !$q.screen.lt.md"
class="col-12 col-md-5 q-gutter-y-md"
>
<q-card>
<q-card-section class="q-pb-xs">
<div class="row items-center">
<q-avatar
size="lg"
:icon="g.wallet.extra.icon"
:text-color="$q.dark.isActive ? 'black' : 'grey-3'"
:color="g.wallet.extra.color"
>
</q-avatar>
<lnbits-wallet-icon
<lnbits-wallet-extra
@update-wallet="updateWallet"
></lnbits-wallet-icon>
<div class="text-subtitle1 q-mt-none q-mb-none">
<span v-text="$t('wallet')"></span>
<strong><em v-text="g.wallet.name"></em></strong>
</div>
<q-space></q-space>
<div class="float-right">
<q-btn
@click="updateWallet({ pinned: !g.wallet.extra.pinned })"
round
class="float-right"
:color="g.wallet.extra.pinned ? 'primary' : 'grey-5'"
text-color="black"
size="sm"
icon="push_pin"
style="transform: rotate(30deg)"
>
<q-tooltip
><span v-text="$t('pin_wallet')"></span
></q-tooltip>
</q-btn>
</div>
</div>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list>
<lnbits-wallet-paylinks
@send-lnurl="handleSendLnurl"
></lnbits-wallet-paylinks>
<q-separator></q-separator>
<lnbits-wallet-share></lnbits-wallet-share>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="phone_android"
:label="$t('access_wallet_on_mobile')"
>
<q-card>
<q-card-section>
You can connect to this wallet from a mobile app:
<ul>
<li>
Download
<a class="text-secondary" href="https://zeusln.app"
>Zeus</a
>
or
<a
class="text-secondary"
href="https://bluewallet.io/"
>BlueWallet</a
>
from App Store or Google Play
</li>
<li>
Enable the
<a class="text-secondary" href="/lndhub">LndHub </a>
extension for this account
</li>
<li>
Scan the QR code in the
<a class="text-secondary" href="/lndhub">LndHub </a>
extensions with your mobile app
</li>
</ul>
</q-card-section>
<q-card-section>
Or you can access the wallet directly from your mobile
browser using:
<q-expansion-item
icon="mobile_friendly"
:label="$t('export_to_phone')"
>
<q-card>
<q-card-section>
<p
class="text-center"
v-text="$t('export_to_phone_desc')"
></p>
<lnbits-qrcode
:value="`${baseUrl}wallet?usr=${g.user.id}&wal=${g.wallet.id}`"
></lnbits-qrcode>
</q-card-section>
</q-card>
</q-expansion-item>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="settings"
:label="$t('wallet_config')"
>
<q-card>
<q-card-section>
<div class="row">
<div class="col-6">
<q-input
filled
v-model.trim="update.name"
label="Name"
dense
/>
</div>
<div class="col-4 q-pl-sm">
<q-btn
:disable="!update.name.length"
unelevated
class="q-mt-xs full-width"
color="primary"
:label="$t('update_name')"
dense
@click="updateWallet({ name: update.name })"
></q-btn>
</div>
<div class="col-2"></div>
</div>
</q-card-section>
<q-card-section v-if="g.isSatsDenomination">
<div class="row">
<div class="col-6">
<q-select
filled
dense
v-model="update.currency"
type="text"
:disable="g.fiatTracking"
:options="receive.units.filter((u) => u !== 'sat')"
:label="$t('currency_settings')"
></q-select>
</div>
<div class="col-4 q-pl-sm">
<q-btn
dense
color="primary"
class="q-mt-xs full-width"
@click="handleFiatTracking()"
:disable="update.currency == ''"
:label="g.fiatTracking ? 'Remove' : 'Add'"
></q-btn>
</div>
<div class="col-2">
<q-btn
v-if="g.user.admin"
flat
round
icon="settings"
class="float-right q-mb-lg"
to="/admin#exchange_providers"
><q-tooltip
v-text="$t('exchange_providers')"
></q-tooltip
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-6">
<p v-text="$t('delete_wallet_desc')"></p>
</div>
<div class="col-4 q-pl-sm">
<q-btn
unelevated
color="red-10"
class="full-width"
@click="deleteWallet()"
:label="$t('delete_wallet')"
></q-btn>
</div>
<div class="col-2"></div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="insights"
:label="$t('wallet_charts')"
>
<q-card>
<q-card-section>
<div class="row">
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showBalanceChart"
:label="$t('payments_balance_chart')"
>
</q-checkbox>
</div>
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showBalanceInOutChart"
:label="$t('payments_balance_in_out_chart')"
>
</q-checkbox>
</div>
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showPaymentInOutChart"
:label="$t('payments_count_in_out_chart')"
>
</q-checkbox>
</div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<lnbits-wallet-api-docs></lnbits-wallet-api-docs>
</q-list>
</q-card-section>
</q-card>
:chart-config="chartConfig"
></lnbits-wallet-extra>
{% endif %}
<q-card class="lnbits-wallet-ads" v-if="AD_SPACE_ENABLED">
<q-card-section class="text-subtitle1">
@ -488,7 +258,7 @@
<div class="col-2">
<q-btn
v-if="g.fiatTracking"
@click="swapBalancePriority"
@click="g.isFiatPriority = !g.isFiatPriority"
class="float-right"
color="primary"
flat
@ -691,7 +461,7 @@
<div class="q-my-md absolute">
<q-btn
v-if="g.fiatTracking"
@click="swapBalancePriority"
@click="g.isFiatPriority = !g.isFiatPriority"
flat
dense
icon="swap_vert"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,80 @@
window.app.component('lnbits-wallet-extra', {
template: '#lnbits-wallet-extra',
mixins: [window.windowMixin],
props: ['chartConfig'],
data() {
return {}
},
methods: {
handleSendLnurl(lnurl) {
this.$emit('send-lnurl', lnurl)
},
updateWallet(wallet) {
this.$emit('update-wallet', wallet)
},
handleFiatTracking() {
this.g.fiatTracking = !this.g.fiatTracking
if (!this.g.fiatTracking) {
this.g.isFiatPriority = false
this.g.wallet.currency = ''
this.updateWallet({currency: ''})
} else {
this.updateWallet({currency: this.g.wallet.currency})
this.updateFiatBalance()
}
},
deleteWallet() {
LNbits.utils
.confirmDialog('Are you sure you want to delete this wallet?')
.onOk(() => {
LNbits.api
.deleteWallet(this.g.wallet)
.then(_ => {
Quasar.Notify.create({
timeout: 3000,
message: `Wallet deleted!`,
spinner: true
})
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
})
},
updateFiatBalance() {
// set rate from local storage to avoid clunky api calls
if (
this.$q.localStorage.getItem(
'lnbits.exchangeRate.' + this.g.wallet.currency
)
) {
this.g.exchangeRate = this.$q.localStorage.getItem(
'lnbits.exchangeRate.' + this.g.wallet.currency
)
this.g.fiatBalance =
(this.g.exchangeRate / 100000000) * this.g.wallet.sat
}
LNbits.api
.request('GET', `/api/v1/rate/` + this.g.wallet.currency, null)
.then(response => {
this.g.fiatBalance =
(response.data.price / 100000000) * this.g.wallet.sat
this.g.exchangeRate = response.data.price.toFixed(2)
this.g.fiatTracking = true
this.$q.localStorage.set(
'lnbits.exchangeRate.' + this.g.wallet.currency,
this.g.exchangeRate
)
})
.catch(e => console.error(e))
}
},
created() {
if (this.g.wallet.currency !== '' && this.g.isSatsDenomination) {
this.g.fiatTracking = true
this.updateFiatBalance()
} else {
this.g.fiatTracking = false
}
}
})

View file

@ -2,9 +2,6 @@ window.WalletPageLogic = {
mixins: [window.windowMixin],
data() {
return {
origin: window.location.origin,
baseUrl: `${window.location.protocol}//${window.location.host}/`,
websocketUrl: `${'http:' ? 'ws://' : 'wss://'}${window.location.host}/api/v1/ws`,
parse: {
show: false,
invoice: null,
@ -34,7 +31,7 @@ window.WalletPageLogic = {
amountMsat: null,
minMax: [0, 2100000000000000],
lnurl: null,
units: ['sat'],
units: ['sat', ...(this.currencies || [])],
unit: 'sat',
fiatProvider: '',
data: {
@ -98,17 +95,6 @@ window.WalletPageLogic = {
this.parse.show = true
this.lnurlScan()
},
formatFiatAmount(amount, currency) {
this.update.currency = currency
this.formattedFiatAmount = LNbits.utils.formatCurrency(
amount.toFixed(2),
currency
)
this.formattedExchange = LNbits.utils.formatCurrency(
this.g.exchangeRate,
currency
)
},
msatoshiFormat(value) {
return LNbits.utils.formatSat(value / 1000)
},
@ -548,51 +534,6 @@ window.WalletPageLogic = {
LNbits.utils.notifyApiError(err)
})
},
deleteWallet() {
LNbits.utils
.confirmDialog('Are you sure you want to delete this wallet?')
.onOk(() => {
LNbits.api
.deleteWallet(this.g.wallet)
.then(_ => {
Quasar.Notify.create({
timeout: 3000,
message: `Wallet deleted!`,
spinner: true
})
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
})
},
updateFiatBalance(currency) {
// set rate from local storage to avoid clunky api calls
if (this.$q.localStorage.getItem('lnbits.exchangeRate.' + currency)) {
this.g.exchangeRate = this.$q.localStorage.getItem(
'lnbits.exchangeRate.' + currency
)
this.g.fiatBalance =
(this.g.exchangeRate / 100000000) * this.g.wallet.sat
this.formatFiatAmount(this.g.fiatBalance, currency)
}
if (currency && this.g.wallet.currency == currency) {
LNbits.api
.request('GET', `/api/v1/rate/` + currency, null)
.then(response => {
this.g.fiatBalance =
(response.data.price / 100000000) * this.g.wallet.sat
this.g.exchangeRate = response.data.price.toFixed(2)
this.g.fiatTracking = true
this.formatFiatAmount(this.g.fiatBalance, this.g.wallet.currency)
this.$q.localStorage.set(
'lnbits.exchangeRate.' + currency,
this.g.exchangeRate
)
})
.catch(e => console.error(e))
}
},
pasteToTextArea() {
this.$refs.textArea.focus()
navigator.clipboard.readText().then(text => {
@ -694,36 +635,6 @@ window.WalletPageLogic = {
dismissPaymentMsg()
LNbits.utils.notifyApiError(err)
})
},
swapBalancePriority() {
this.g.isFiatPriority = !this.g.isFiatPriority
this.receive.unit = this.g.isFiatPriority
? this.g.wallet.currency || 'sat'
: 'sat'
},
handleFiatTracking() {
this.g.fiatTracking = !this.g.fiatTracking
if (!this.g.fiatTracking) {
this.g.isFiatPriority = false
this.update.currency = ''
this.g.wallet.currency = ''
this.updateWallet({currency: ''})
} else {
this.g.wallet.currency = this.update.currency
this.updateWallet({currency: this.update.currency})
this.updateFiatBalance(this.update.currency)
}
},
createdTasks() {
this.update.name = this.g.wallet.name
this.receive.units = ['sat', ...(window.currencies || [])]
if (this.g.wallet.currency != '' && LNBITS_DENOMINATION == 'sats') {
this.g.fiatTracking = true
this.updateFiatBalance(this.g.wallet.currency)
} else {
this.update.currency = ''
this.g.fiatTracking = false
}
}
},
created() {
@ -734,10 +645,9 @@ window.WalletPageLogic = {
this.decodeRequest()
this.parse.show = true
}
this.createdTasks()
},
watch: {
'g.updatePayments'(newVal, oldVal) {
'g.updatePayments'() {
this.parse.show = false
if (this.receive.paymentHash === this.g.updatePaymentsHash) {
this.receive.show = false
@ -754,18 +664,32 @@ window.WalletPageLogic = {
)
this.g.fiatBalance =
(this.g.exchangeRate / 100000000) * this.g.wallet.sat
this.formatFiatAmount(this.g.fiatBalance, this.g.wallet.currency)
}
},
'g.wallet': {
handler() {
try {
this.createdTasks()
} catch (error) {
console.warn(`Chart creation failed: ${error}`)
'g.wallet'() {
if (this.g.wallet.currency && this.g.fiatTracking) {
this.g.fiatBalance =
(this.g.exchangeRate / 100000000) * this.g.wallet.sat
}
},
deep: true
'g.isFiatPriority'() {
this.receive.unit = this.g.isFiatPriority ? this.g.wallet.currency : 'sat'
},
'g.fiatBalance'() {
this.formattedFiatAmount = LNbits.utils.formatCurrency(
this.g.fiatBalance.toFixed(2),
this.g.wallet.currency
)
},
'g.exchangeRate'() {
if (this.g.fiatTracking && this.g.wallet.currency) {
this.g.fiatBalance =
(this.g.exchangeRate / 100000000) * this.g.wallet.sat
this.formattedExchange = LNbits.utils.formatCurrency(
this.g.exchangeRate,
this.g.wallet.currency
)
}
}
}
}

View file

@ -5,6 +5,7 @@ window.windowMixin = {
api: window._lnbitsApi,
utils: window._lnbitsUtils,
g: window.g,
currencies: window.currencies,
...WINDOW_SETTINGS
}
},

View file

@ -73,6 +73,7 @@
"js/components/lnbits-wallet-new.js",
"js/components/lnbits-wallet-share.js",
"js/components/lnbits-wallet-paylinks.js",
"js/components/lnbits-wallet-extra.js",
"js/components/lnbits-home-logos.js",
"js/components/lnbits-qrcode.js",
"js/components/lnbits-qrcode-lnurl.js",

View file

@ -26,7 +26,8 @@ include('components/lnbits-label-selector.vue') %} {%
include('components/lnbits-wallet-api-docs.vue') %} {%
include('components/lnbits-wallet-share.vue') %} {%
include('components/lnbits-wallet-charts.vue') %} {%
include('components/lnbits-wallet-paylinks.vue') %}
include('components/lnbits-wallet-paylinks.vue') %} {%
include('components/lnbits-wallet-extra.vue') %}
<template id="lnbits-manage">
<q-list v-if="g.user" dense class="lnbits-drawer__q-list">

View file

@ -0,0 +1,220 @@
<template id="lnbits-wallet-extra">
<q-card class="wallet-extra">
<q-card-section class="q-pb-xs">
<div class="row items-center">
<q-avatar
size="lg"
:icon="g.wallet.extra.icon"
:text-color="$q.dark.isActive ? 'black' : 'grey-3'"
:color="g.wallet.extra.color"
>
</q-avatar>
<lnbits-wallet-icon @update-wallet="updateWallet"></lnbits-wallet-icon>
<div class="text-subtitle1 q-mt-none q-mb-none">
<span v-text="$t('wallet')"></span>
<strong><em v-text="g.wallet.name"></em></strong>
</div>
<q-space></q-space>
<div class="float-right">
<q-btn
@click="updateWallet({pinned: !g.wallet.extra.pinned})"
round
class="float-right"
:color="g.wallet.extra.pinned ? 'primary' : 'grey-5'"
text-color="black"
size="sm"
icon="push_pin"
style="transform: rotate(30deg)"
>
<q-tooltip><span v-text="$t('pin_wallet')"></span></q-tooltip>
</q-btn>
</div>
</div>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list>
<lnbits-wallet-paylinks
@send-lnurl="handleSendLnurl"
></lnbits-wallet-paylinks>
<q-separator></q-separator>
<lnbits-wallet-share></lnbits-wallet-share>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="phone_android"
:label="$t('access_wallet_on_mobile')"
>
<q-card>
<q-card-section>
You can connect to this wallet from a mobile app:
<ul>
<li>
Download
<a class="text-secondary" href="https://zeusln.app">Zeus</a>
or
<a class="text-secondary" href="https://bluewallet.io/"
>BlueWallet</a
>
from App Store or Google Play
</li>
<li>
Enable the
<a class="text-secondary" href="/lndhub">LndHub </a>
extension for this account
</li>
<li>
Scan the QR code in the
<a class="text-secondary" href="/lndhub">LndHub </a>
extensions with your mobile app
</li>
</ul>
</q-card-section>
<q-card-section>
Or you can access the wallet directly from your mobile browser
using:
<q-expansion-item
icon="mobile_friendly"
:label="$t('export_to_phone')"
>
<q-card>
<q-card-section>
<p
class="text-center"
v-text="$t('export_to_phone_desc')"
></p>
<lnbits-qrcode
:value="`${baseUrl}wallet?usr=${g.user.id}&wal=${g.wallet.id}`"
></lnbits-qrcode>
</q-card-section>
</q-card>
</q-expansion-item>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="settings"
:label="$t('wallet_config')"
>
<q-card>
<q-card-section>
<div class="row">
<div class="col-6">
<q-input filled v-model="g.wallet.name" label="Name" dense />
</div>
<div class="col-4 q-pl-sm">
<q-btn
:disable="!g.wallet.name.length"
unelevated
class="q-mt-xs full-width"
color="primary"
:label="$t('update_name')"
dense
@click="updateWallet({name: g.wallet.name})"
></q-btn>
</div>
<div class="col-2"></div>
</div>
</q-card-section>
<q-card-section v-if="g.isSatsDenomination">
<div class="row">
<div class="col-6">
<q-select
filled
dense
v-model="g.wallet.currency"
@change="updateWallet({currency: g.wallet.currency})"
type="text"
:disable="g.fiatTracking"
:options="currencies"
:label="$t('currency_settings')"
></q-select>
</div>
<div class="col-4 q-pl-sm">
<q-btn
dense
color="primary"
class="q-mt-xs full-width"
@click="handleFiatTracking()"
:disable="g.wallet.currency == ''"
:label="g.fiatTracking ? 'Remove' : 'Add'"
></q-btn>
</div>
<div class="col-2">
<q-btn
v-if="g.user.admin"
flat
round
icon="settings"
class="float-right q-mb-lg"
to="/admin#exchange_providers"
><q-tooltip v-text="$t('exchange_providers')"></q-tooltip
></q-btn>
</div>
</div>
</q-card-section>
<q-card-section>
<div class="row">
<div class="col-6">
<p v-text="$t('delete_wallet_desc')"></p>
</div>
<div class="col-4 q-pl-sm">
<q-btn
unelevated
color="red-10"
class="full-width"
@click="deleteWallet()"
:label="$t('delete_wallet')"
></q-btn>
</div>
<div class="col-2"></div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<q-expansion-item
group="extras"
icon="insights"
:label="$t('wallet_charts')"
>
<q-card>
<q-card-section>
<div class="row">
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showBalanceChart"
:label="$t('payments_balance_chart')"
>
</q-checkbox>
</div>
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showBalanceInOutChart"
:label="$t('payments_balance_in_out_chart')"
>
</q-checkbox>
</div>
<div class="col-md-4 col-sm-12">
<q-checkbox
dense
v-model="chartConfig.showPaymentInOutChart"
:label="$t('payments_count_in_out_chart')"
>
</q-checkbox>
</div>
</div>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator></q-separator>
<lnbits-wallet-api-docs></lnbits-wallet-api-docs>
</q-list>
</q-card-section>
</q-card>
</template>

View file

@ -125,6 +125,7 @@
"js/components/lnbits-wallet-new.js",
"js/components/lnbits-wallet-share.js",
"js/components/lnbits-wallet-paylinks.js",
"js/components/lnbits-wallet-extra.js",
"js/components/lnbits-home-logos.js",
"js/components/lnbits-qrcode.js",
"js/components/lnbits-qrcode-lnurl.js",