Compare commits

...
Author SHA1 Message Date
Tiago Vasconcelos f53fee6896 add onboard to wallet 2024-02-15 12:18:52 +00:00
Tiago Vasconcelos f14dfd2522 user onboarding 2024-02-15 09:23:09 +00:00
7 changed files with 209 additions and 7 deletions
@@ -85,7 +85,7 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="isSuperUser"> <div v-if="isSuperUser" id="funding-sources">
<lnbits-funding-sources <lnbits-funding-sources
:form-data="formData" :form-data="formData"
:allowed-funding-sources="settings.lnbits_allowed_funding_sources" :allowed-funding-sources="settings.lnbits_allowed_funding_sources"
+6
View File
@@ -165,4 +165,10 @@
</q-dialog> </q-dialog>
{% endblock %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block scripts %} {{ window_vars(user) }}
<script src="{{ static_url_for('static', 'js/admin.js') }}"></script> <script src="{{ static_url_for('static', 'js/admin.js') }}"></script>
<style>
.introjs-tooltip-custom .introjs-tooltiptext,
.introjs-tooltip-header {
color: #111;
}
</style>
{% endblock %} {% endblock %}
+13 -2
View File
@@ -4,6 +4,12 @@
<!----> <!---->
{% block scripts %} {{ window_vars(user, wallet) }} {% block scripts %} {{ window_vars(user, wallet) }}
<script src="{{ static_url_for('static', 'js/wallet.js') }}"></script> <script src="{{ static_url_for('static', 'js/wallet.js') }}"></script>
<style>
.introjs-tooltip-custom .introjs-tooltiptext,
.introjs-tooltip-header {
color: #111;
}
</style>
{% endblock %} {% endblock %}
<!----> <!---->
{% block title %} {{ wallet.name }} - {{ SITE_TITLE }} {% endblock %} {% block title %} {{ wallet.name }} - {{ SITE_TITLE }} {% endblock %}
@@ -34,7 +40,7 @@
} : ''" } : ''"
> >
<q-card-section> <q-card-section>
<h3 class="q-my-none text-no-wrap"> <h3 class="q-my-none text-no-wrap" id="wallet-balance">
<strong v-text="formattedBalance"></strong> <strong v-text="formattedBalance"></strong>
<small>{{LNBITS_DENOMINATION}}</small> <small>{{LNBITS_DENOMINATION}}</small>
<lnbits-update-balance <lnbits-update-balance
@@ -68,7 +74,10 @@
</div> </div>
</div> </div>
</q-card-section> </q-card-section>
<div class="row q-pb-md q-px-md q-col-gutter-md gt-sm"> <div
class="row q-pb-md q-px-md q-col-gutter-md gt-sm"
id="wallet-buttons"
>
<div class="col"> <div class="col">
<q-btn <q-btn
unelevated unelevated
@@ -165,6 +174,7 @@
:hide-header="mobileSimple" :hide-header="mobileSimple"
:hide-bottom="mobileSimple" :hide-bottom="mobileSimple"
@request="fetchPayments" @request="fetchPayments"
id="wallet-table"
> >
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
@@ -895,6 +905,7 @@
</q-dialog> </q-dialog>
<q-tabs <q-tabs
id="mobile-wallet-buttons"
class="lt-md fixed-bottom left-0 right-0 bg-primary text-white shadow-2 z-top" class="lt-md fixed-bottom left-0 right-0 bg-primary text-white shadow-2 z-top"
active-class="px-0" active-class="px-0"
indicator-color="transparent" indicator-color="transparent"
+82 -1
View File
@@ -48,7 +48,8 @@ new Vue({
show: false show: false
}, },
tab: 'funding', tab: 'funding',
needsRestart: false needsRestart: false,
introJs: null
} }
}, },
created() { created() {
@@ -56,6 +57,32 @@ new Vue({
this.getAudit() this.getAudit()
this.balance = +'{{ balance|safe }}' this.balance = +'{{ balance|safe }}'
}, },
mounted() {
const url = window.location.href
const queryString = url.split('?')[1]
const queryObject = {}
if (queryString) {
for (const param of queryString.split('&')) {
const [key, value] = param.split('=')
queryObject[key] = value
}
}
if (queryObject.hasOwnProperty('first_use')) {
const scriptTag = document.createElement('script')
scriptTag.src = 'https://unpkg.com/intro.js/intro.js'
const linkTag = document.createElement('link')
linkTag.rel = 'stylesheet'
linkTag.href = 'https://unpkg.com/intro.js/introjs.css'
document.body.appendChild(scriptTag)
document.head.appendChild(linkTag)
scriptTag.onload = () => {
this.runOnboarding()
}
}
},
computed: { computed: {
lnbitsVersion() { lnbitsVersion() {
return LNBITS_VERSION return LNBITS_VERSION
@@ -68,6 +95,60 @@ new Vue({
} }
}, },
methods: { methods: {
runOnboarding() {
introJs()
.onbeforeexit(() => {
return window.history.replaceState(
null,
null,
window.location.pathname
)
})
.setOptions({
disableInteraction: true,
tooltipClass: 'introjs-tooltip-custom',
dontShowAgain: true,
steps: [
{
title: 'Welcome to LNbits',
intro: 'Start your tour!'
},
{
title: 'Add a funding source',
element: document.getElementById('funding-sources'),
intro:
'Select a Lightning Network funding source to add funds to your LNbits.'
},
{
title: 'Access your wallet',
element: document.getElementById('wallet-list'),
position: 'right',
intro:
'Wallets are the core of LNbits. They are the place where you can store your funds.'
},
{
title: 'Manage LNbits',
element: document.getElementById('admin-manage'),
position: 'right',
intro:
'This is the place where you can manage your LNbits. You can configure settings, install extensions, themes, view logs, manage a node, and more.'
},
{
title: 'Access extensions',
element: document.getElementById('extension-list'),
position: 'right',
intro:
'Extensions are the way to add functionality to your LNbits. You view and access them here.'
},
{
title: 'Farewell!',
intro: '<img src="static/images/logos/lnbits.svg" width=100%/>'
}
]
})
.start()
},
addAdminUser() { addAdminUser() {
let addUser = this.formAddAdmin let addUser = this.formAddAdmin
let admin_users = this.formData.lnbits_admin_users let admin_users = this.formData.lnbits_admin_users
+1 -1
View File
@@ -50,7 +50,7 @@ new Vue({
this.password, this.password,
this.passwordRepeat this.passwordRepeat
) )
window.location.href = '/wallet' window.location.href = '/wallet?first_use'
} catch (e) { } catch (e) {
LNbits.utils.notifyApiError(e) LNbits.utils.notifyApiError(e)
} }
+100
View File
@@ -818,6 +818,105 @@ new Vue({
navigator.clipboard.readText().then(text => { navigator.clipboard.readText().then(text => {
this.$refs.textArea.value = text this.$refs.textArea.value = text
}) })
},
checkFirstUse() {
const url = window.location.href
const queryString = url.split('?')[1]
const queryObject = {}
if (queryString) {
for (const param of queryString.split('&')) {
const [key, value] = param.split('=')
queryObject[key] = value
}
}
if (queryObject.hasOwnProperty('first_use')) {
const scriptTag = document.createElement('script')
scriptTag.src = 'https://unpkg.com/intro.js/intro.js'
const linkTag = document.createElement('link')
linkTag.rel = 'stylesheet'
linkTag.href = 'https://unpkg.com/intro.js/introjs.css'
document.body.appendChild(scriptTag)
document.head.appendChild(linkTag)
scriptTag.onload = () => {
if (!this.g.visibleDrawer) {
this.g.visibleDrawer = true
}
this.runOnboarding()
}
}
},
runOnboarding() {
introJs()
.onbeforechange(step => {
if (!step.id || !this.mobileSimple) return
if (step.id === 'wallet-list' || step.id === 'admin-manage') {
this.g.visibleDrawer = true
} else {
this.g.visibleDrawer = false
}
})
// .onbeforeexit(() => {
// return window.history.replaceState(
// null,
// null,
// window.location.pathname
// )
// })
.setOptions({
disableInteraction: true,
tooltipClass: 'introjs-tooltip-custom',
dontShowAgain: true,
steps: [
{
title: 'Welcome to LNbits',
intro: 'Start your tour!'
},
{
title: 'Access your wallet',
element: document.getElementById('wallet-list'),
position: 'right',
intro:
'Wallets are the core of LNbits. They are the place where you can store your funds.'
},
{
title: 'Access extensions',
element: document.getElementById('admin-manage'),
position: 'right',
intro:
'Extensions are the way to add functionality to your LNbits. You view and access them here.'
},
{
title: 'Wallet balance',
element: document.getElementById('wallet-balance'),
position: 'right',
intro: 'Your wallet balance is displayed here.'
},
{
title: 'Send and receive payments',
element: document.getElementById(
this.mobileSimple ? 'mobile-wallet-buttons' : 'wallet-buttons'
),
position: 'bottom',
intro:
'Use these buttons to send and receive payments or scan a QR code.'
},
{
title: 'Transaction details',
element: document.getElementById('wallet-table'),
position: 'bottom',
intro:
'Here you can see all the transactions made in your wallet. You can also export them as a CSV file.'
},
{
title: 'Farewell!',
intro: '<img src="static/images/logos/lnbits.svg" width=100%/>'
}
]
})
.start()
} }
}, },
watch: { watch: {
@@ -865,6 +964,7 @@ new Vue({
this.onPaymentReceived(payment.payment_hash) this.onPaymentReceived(payment.payment_hash)
) )
eventReactionWebocket(wallet.id) eventReactionWebocket(wallet.id)
this.checkFirstUse()
} }
}) })
+6 -2
View File
@@ -168,13 +168,17 @@
show-if-above show-if-above
:elevated="$q.screen.lt.md" :elevated="$q.screen.lt.md"
> >
<lnbits-wallet-list></lnbits-wallet-list> <lnbits-wallet-list id="wallet-list"></lnbits-wallet-list>
<lnbits-manage <lnbits-manage
id="admin-manage"
:show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'" :show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'"
:show-node="'{{LNBITS_NODE_UI}}' == 'True'" :show-node="'{{LNBITS_NODE_UI}}' == 'True'"
></lnbits-manage> ></lnbits-manage>
<lnbits-extension-list class="q-pb-xl"></lnbits-extension-list> <lnbits-extension-list
id="extension-list"
class="q-pb-xl"
></lnbits-extension-list>
</q-drawer> </q-drawer>
{% endblock %} {% block page_container %} {% endblock %} {% block page_container %}
<q-page-container> <q-page-container>