diff --git a/lnbits/extensions/withdraw/README.md b/lnbits/extensions/withdraw/README.md index 0e5939fdb..7bf7c232c 100644 --- a/lnbits/extensions/withdraw/README.md +++ b/lnbits/extensions/withdraw/README.md @@ -26,6 +26,8 @@ LNBits Quick Vouchers allows you to easily create a batch of LNURLw's QR codes t - on details you can print the vouchers\ ![printable vouchers](https://i.imgur.com/2xLHbob.jpg) - every printed LNURLw QR code is unique, it can only be used once +3. Bonus: you can use an LNbits themed voucher, or use a custom one. There's a _template.svg_ file in `static/images` folder if you want to create your own.\ + ![voucher](https://i.imgur.com/qyQoHi3.jpg) #### Advanced diff --git a/lnbits/extensions/withdraw/crud.py b/lnbits/extensions/withdraw/crud.py index ab35fafac..9868b0570 100644 --- a/lnbits/extensions/withdraw/crud.py +++ b/lnbits/extensions/withdraw/crud.py @@ -26,9 +26,10 @@ async def create_withdraw_link( k1, open_time, usescsv, - webhook_url + webhook_url, + custom_url ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( link_id, @@ -44,6 +45,7 @@ async def create_withdraw_link( int(datetime.now().timestamp()) + data.wait_time, usescsv, data.webhook_url, + data.custom_url, ), ) link = await get_withdraw_link(link_id, 0) diff --git a/lnbits/extensions/withdraw/migrations.py b/lnbits/extensions/withdraw/migrations.py index 83f3fc242..5484277a2 100644 --- a/lnbits/extensions/withdraw/migrations.py +++ b/lnbits/extensions/withdraw/migrations.py @@ -115,3 +115,10 @@ async def m004_webhook_url(db): Adds webhook_url """ await db.execute("ALTER TABLE withdraw.withdraw_link ADD COLUMN webhook_url TEXT;") + + +async def m005_add_custom_print_design(db): + """ + Adds custom print design + """ + await db.execute("ALTER TABLE withdraw.withdraw_link ADD COLUMN custom_url TEXT;") diff --git a/lnbits/extensions/withdraw/models.py b/lnbits/extensions/withdraw/models.py index c3ca7c459..2672537fa 100644 --- a/lnbits/extensions/withdraw/models.py +++ b/lnbits/extensions/withdraw/models.py @@ -16,6 +16,7 @@ class CreateWithdrawData(BaseModel): wait_time: int = Query(..., ge=1) is_unique: bool webhook_url: str = Query(None) + custom_url: str = Query(None) class WithdrawLink(BaseModel): @@ -34,6 +35,7 @@ class WithdrawLink(BaseModel): usescsv: str = Query(None) number: int = Query(0) webhook_url: str = Query(None) + custom_url: str = Query(None) @property def is_spent(self) -> bool: diff --git a/lnbits/extensions/withdraw/static/js/index.js b/lnbits/extensions/withdraw/static/js/index.js index 3f484debf..1982d6845 100644 --- a/lnbits/extensions/withdraw/static/js/index.js +++ b/lnbits/extensions/withdraw/static/js/index.js @@ -20,9 +20,12 @@ var mapWithdrawLink = function (obj) { obj.uses_left = obj.uses - obj.used obj.print_url = [locationPath, 'print/', obj.id].join('') obj.withdraw_url = [locationPath, obj.id].join('') + obj._data.use_custom = Boolean(obj.custom_url) return obj } +const CUSTOM_URL = '/static/images/default_voucher.png' + new Vue({ el: '#vue', mixins: [windowMixin], @@ -59,13 +62,15 @@ new Vue({ secondMultiplier: 'seconds', secondMultiplierOptions: ['seconds', 'minutes', 'hours'], data: { - is_unique: false + is_unique: false, + use_custom: false } }, simpleformDialog: { show: false, data: { is_unique: true, + use_custom: true, title: 'Vouchers', min_withdrawable: 0, wait_time: 1 @@ -106,12 +111,14 @@ new Vue({ }, closeFormDialog: function () { this.formDialog.data = { - is_unique: false + is_unique: false, + use_custom: false } }, simplecloseFormDialog: function () { this.simpleformDialog.data = { - is_unique: false + is_unique: false, + use_custom: false } }, openQrCodeDialog: function (linkId) { @@ -133,6 +140,9 @@ new Vue({ id: this.formDialog.data.wallet }) var data = _.omit(this.formDialog.data, 'wallet') + if (data.use_custom && !data?.custom_url) { + data.custom_url = CUSTOM_URL + } data.wait_time = data.wait_time * @@ -141,7 +151,6 @@ new Vue({ minutes: 60, hours: 3600 }[this.formDialog.secondMultiplier] - if (data.id) { this.updateWithdrawLink(wallet, data) } else { @@ -159,6 +168,10 @@ new Vue({ data.title = 'vouchers' data.is_unique = true + if (data.use_custom && !data?.custom_url) { + data.custom_url = '/static/images/default_voucher.png' + } + if (data.id) { this.updateWithdrawLink(wallet, data) } else { @@ -181,7 +194,8 @@ new Vue({ 'uses', 'wait_time', 'is_unique', - 'webhook_url' + 'webhook_url', + 'custom_url' ) ) .then(function (response) { diff --git a/lnbits/extensions/withdraw/templates/withdraw/index.html b/lnbits/extensions/withdraw/templates/withdraw/index.html index 99aa03b2d..9ff428a1d 100644 --- a/lnbits/extensions/withdraw/templates/withdraw/index.html +++ b/lnbits/extensions/withdraw/templates/withdraw/index.html @@ -217,6 +217,32 @@ label="Webhook URL (optional)" hint="A URL to be called whenever this link gets used." > + + + + + + + Use a custom voucher design + You can use an LNbits voucher design or a custom + one + + + + @@ -303,6 +329,32 @@ :default="1" label="Number of vouchers" > + + + + + + + Use a custom voucher design + You can use an LNbits voucher design or a custom + one + + + +
+
+ {% for page in link %} + + {% for one in page %} +
+ ... + {{ amt }} sats +
+ +
+
+ {% endfor %} +
+ {% endfor %} +
+
+{% endblock %} {% block styles %} + +{% endblock %} {% block scripts %} + +{% endblock %} diff --git a/lnbits/extensions/withdraw/views.py b/lnbits/extensions/withdraw/views.py index 1f059a4b0..97fb12717 100644 --- a/lnbits/extensions/withdraw/views.py +++ b/lnbits/extensions/withdraw/views.py @@ -99,6 +99,18 @@ async def print_qr(request: Request, link_id): page_link = list(chunks(links, 2)) linked = list(chunks(page_link, 5)) + if link.custom_url: + return withdraw_renderer().TemplateResponse( + "withdraw/print_qr_custom.html", + { + "request": request, + "link": page_link, + "unique": True, + "custom_url": link.custom_url, + "amt": link.max_withdrawable, + }, + ) + return withdraw_renderer().TemplateResponse( "withdraw/print_qr.html", {"request": request, "link": linked, "unique": True} ) diff --git a/lnbits/static/images/default_voucher.png b/lnbits/static/images/default_voucher.png new file mode 100644 index 000000000..8462b285b Binary files /dev/null and b/lnbits/static/images/default_voucher.png differ diff --git a/lnbits/static/images/voucher_template.svg b/lnbits/static/images/voucher_template.svg new file mode 100644 index 000000000..4347758f2 --- /dev/null +++ b/lnbits/static/images/voucher_template.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + +