mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-10 20:42:32 +02:00
Changed so user can use multiple animations
This commit is contained in:
@@ -3,11 +3,9 @@ from lnbits.db import Database
|
|||||||
|
|
||||||
db = Database("ext_copilot")
|
db = Database("ext_copilot")
|
||||||
|
|
||||||
|
|
||||||
copilot_ext: Blueprint = Blueprint(
|
copilot_ext: Blueprint = Blueprint(
|
||||||
"copilot", __name__, static_folder="static", template_folder="templates"
|
"copilot", __name__, static_folder="static", template_folder="templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
from .views_api import * # noqa
|
from .views_api import * # noqa
|
||||||
from .views import * # noqa
|
from .views import * # noqa
|
||||||
|
@@ -15,9 +15,14 @@ from quart import jsonify
|
|||||||
async def create_copilot(
|
async def create_copilot(
|
||||||
title: str,
|
title: str,
|
||||||
user: str,
|
user: str,
|
||||||
animation: str = None,
|
animation1: Optional[str] = None,
|
||||||
|
animation2: Optional[str] = None,
|
||||||
|
animation3: Optional[str] = None,
|
||||||
|
animation1threshold: Optional[int] = None,
|
||||||
|
animation2threshold: Optional[int] = None,
|
||||||
|
animation3threshold: Optional[int] = None,
|
||||||
show_message: Optional[str] = None,
|
show_message: Optional[str] = None,
|
||||||
amount: Optional[str] = None,
|
amount: Optional[int] = None,
|
||||||
lnurl_title: Optional[str] = None,
|
lnurl_title: Optional[str] = None,
|
||||||
) -> Copilots:
|
) -> Copilots:
|
||||||
copilot_id = urlsafe_short_hash()
|
copilot_id = urlsafe_short_hash()
|
||||||
@@ -28,18 +33,28 @@ async def create_copilot(
|
|||||||
id,
|
id,
|
||||||
user,
|
user,
|
||||||
title,
|
title,
|
||||||
animation,
|
animation1,
|
||||||
|
animation2,
|
||||||
|
animation3,
|
||||||
|
animation1threshold,
|
||||||
|
animation2threshold,
|
||||||
|
animation3threshold,
|
||||||
show_message,
|
show_message,
|
||||||
amount,
|
amount,
|
||||||
lnurl_title
|
lnurl_title
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
copilot_id,
|
copilot_id,
|
||||||
user,
|
user,
|
||||||
title,
|
title,
|
||||||
animation,
|
animation1,
|
||||||
|
animation2,
|
||||||
|
animation3,
|
||||||
|
animation1threshold,
|
||||||
|
animation2threshold,
|
||||||
|
animation3threshold,
|
||||||
show_message,
|
show_message,
|
||||||
amount,
|
amount,
|
||||||
lnurl_title
|
lnurl_title
|
||||||
|
@@ -9,7 +9,12 @@ async def m001_initial(db):
|
|||||||
id TEXT NOT NULL PRIMARY KEY,
|
id TEXT NOT NULL PRIMARY KEY,
|
||||||
user TEXT,
|
user TEXT,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
animation INTEGER,
|
animation1 TEXT,
|
||||||
|
animation2 TEXT,
|
||||||
|
animation3 TEXT,
|
||||||
|
animation1threshold INTEGER,
|
||||||
|
animation2threshold INTEGER,
|
||||||
|
animation3threshold INTEGER,
|
||||||
show_message TEXT,
|
show_message TEXT,
|
||||||
amount INTEGER,
|
amount INTEGER,
|
||||||
lnurl_title TEXT,
|
lnurl_title TEXT,
|
||||||
|
@@ -7,13 +7,18 @@ class Copilots(NamedTuple):
|
|||||||
id: str
|
id: str
|
||||||
user: str
|
user: str
|
||||||
title: str
|
title: str
|
||||||
animation: str
|
animation1: str
|
||||||
|
animation2: str
|
||||||
|
animation3: str
|
||||||
|
animation1threshold: int
|
||||||
|
animation2threshold: int
|
||||||
|
animation3threshold: int
|
||||||
show_message: bool
|
show_message: bool
|
||||||
amount: int
|
amount: int
|
||||||
lnurl_title: str
|
lnurl_title: str
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_row(cls, row: Row) -> "Charges":
|
def from_row(cls, row: Row) -> "Copilots":
|
||||||
return cls(**dict(row))
|
return cls(**dict(row))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p>
|
<p>
|
||||||
StreamCopilot: get tips and show an animation<br />
|
StreamCopilot: get tips via static QR (lnurl-pay) and show an animation<br />
|
||||||
<small>
|
<small>
|
||||||
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
||||||
>
|
>
|
||||||
|
@@ -131,11 +131,78 @@
|
|||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogCopilot.data.description"
|
v-model.trim="formDialogCopilot.data.title"
|
||||||
type="text"
|
type="text"
|
||||||
label="*Description"
|
label="*Title"
|
||||||
></q-input>
|
></q-input>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation1"
|
||||||
|
:options="options"
|
||||||
|
label="Animation 1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col q-pl-xs">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation1threshold"
|
||||||
|
type="number"
|
||||||
|
label="Threshold (at least)"
|
||||||
|
>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation2"
|
||||||
|
:options="options"
|
||||||
|
label="Animation 2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col q-pl-sm">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation2threshold"
|
||||||
|
type="number"
|
||||||
|
label="Threshold (at least)"
|
||||||
|
>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation3"
|
||||||
|
:options="options"
|
||||||
|
label="Animation 3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col q-pl-sm">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogCopilot.data.animation3threshold"
|
||||||
|
type="number"
|
||||||
|
label="Threshold (at least)"
|
||||||
|
>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
@@ -147,92 +214,24 @@
|
|||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogCopilot.data.time"
|
v-model.trim="formDialogCopilot.data.lnurl_title"
|
||||||
type="number"
|
|
||||||
max="1440"
|
|
||||||
label="*Mins valid for (max 1440)"
|
|
||||||
>
|
|
||||||
</q-input>
|
|
||||||
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
v-model.trim="formDialogCopilot.data.webhook"
|
|
||||||
type="url"
|
|
||||||
label="Webhook (URL to send transaction data to once paid)"
|
|
||||||
>
|
|
||||||
</q-input>
|
|
||||||
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
v-model.trim="formDialogCopilot.data.completelink"
|
|
||||||
type="url"
|
|
||||||
label="Completed button URL"
|
|
||||||
>
|
|
||||||
</q-input>
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
v-model.trim="formDialogCopilot.data.completelinktext"
|
|
||||||
type="text"
|
type="text"
|
||||||
label="Completed button text (ie 'Back to merchant')"
|
max="1440"
|
||||||
|
label="Lnurl title (message with QR code)"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
<div class="q-gutter-sm">
|
||||||
<div class="row">
|
<q-checkbox
|
||||||
<div class="col">
|
v-model="formDialogCopilot.data.show_message"
|
||||||
<div v-if="walletLinks.length > 0">
|
left-label
|
||||||
<q-checkbox
|
label="Show lnurl-pay messages? (available in some wallets)"
|
||||||
v-model="formDialogCopilot.data.onchain"
|
|
||||||
label="Onchain"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<q-checkbox :value="false" label="Onchain" disabled>
|
|
||||||
<q-tooltip>
|
|
||||||
Watch-Only extension MUST be activated and have a wallet
|
|
||||||
</q-tooltip>
|
|
||||||
</q-checkbox>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<div>
|
|
||||||
<q-checkbox
|
|
||||||
v-model="formDialogCopilot.data.lnbits"
|
|
||||||
label="LNbits wallet"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="formDialogCopilot.data.onchain">
|
|
||||||
<q-select
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
emit-value
|
|
||||||
v-model="formDialogCopilot.data.onchainwallet"
|
|
||||||
:options="walletLinks"
|
|
||||||
label="Onchain Wallet"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-select
|
|
||||||
v-if="formDialogCopilot.data.lnbits"
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
emit-value
|
|
||||||
v-model="formDialogCopilot.data.lnbitswallet"
|
|
||||||
:options="g.user.walletOptions"
|
|
||||||
label="Wallet *"
|
|
||||||
>
|
|
||||||
</q-select>
|
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
color="deep-purple"
|
color="deep-purple"
|
||||||
:disable="
|
:disable="
|
||||||
formDialogCopilot.data.time == null ||
|
|
||||||
formDialogCopilot.data.amount == null"
|
formDialogCopilot.data.amount == null"
|
||||||
type="submit"
|
type="submit"
|
||||||
>Create Copilot</q-btn
|
>Create Copilot</q-btn
|
||||||
@@ -295,62 +294,68 @@
|
|||||||
{
|
{
|
||||||
name: 'theId',
|
name: 'theId',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'ID',
|
label: 'id',
|
||||||
field: 'id'
|
field: 'id'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'description',
|
name: 'title',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Title',
|
label: 'title',
|
||||||
field: 'description'
|
field: 'title'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'timeleft',
|
name: 'animation_1',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Time left',
|
label: 'animation 1',
|
||||||
field: 'date'
|
field: 'animation_1'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'time to pay',
|
name: 'animation_2',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Time to Pay',
|
label: 'animation 2',
|
||||||
field: 'time'
|
field: 'animation_2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'animation_3',
|
||||||
|
align: 'left',
|
||||||
|
label: 'animation 3',
|
||||||
|
field: 'animation_3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'animation_1_threshold',
|
||||||
|
align: 'left',
|
||||||
|
label: '1 threshold',
|
||||||
|
field: 'animation_1_threshold'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'animation_2_threshold',
|
||||||
|
align: 'left',
|
||||||
|
label: '2 threshold',
|
||||||
|
field: 'animation_2_threshold'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'animation_3_threshold',
|
||||||
|
align: 'left',
|
||||||
|
label: '3 threshold',
|
||||||
|
field: 'animation_3_threshold'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'lnurl_title',
|
||||||
|
align: 'left',
|
||||||
|
label: 'lnurl message',
|
||||||
|
field: 'lnurl_title'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Amount to pay',
|
label: 'amount to pay',
|
||||||
field: 'amount'
|
field: 'amount'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'balance',
|
name: 'show_message',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Balance',
|
label: 'show comments?',
|
||||||
field: 'balance'
|
field: 'show_message'
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'onchain address',
|
|
||||||
align: 'left',
|
|
||||||
label: 'Onchain Address',
|
|
||||||
field: 'onchainaddress'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'LNbits wallet',
|
|
||||||
align: 'left',
|
|
||||||
label: 'LNbits wallet',
|
|
||||||
field: 'lnbitswallet'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Webhook link',
|
|
||||||
align: 'left',
|
|
||||||
label: 'Webhook link',
|
|
||||||
field: 'webhook'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Paid link',
|
|
||||||
align: 'left',
|
|
||||||
label: 'Paid link',
|
|
||||||
field: 'completelink'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
pagination: {
|
pagination: {
|
||||||
@@ -364,8 +369,7 @@
|
|||||||
formDialogCopilot: {
|
formDialogCopilot: {
|
||||||
show: false,
|
show: false,
|
||||||
data: {
|
data: {
|
||||||
onchain: false,
|
show_message: false,
|
||||||
lnbits: false,
|
|
||||||
description: '',
|
description: '',
|
||||||
time: null,
|
time: null,
|
||||||
amount: null
|
amount: null
|
||||||
@@ -377,7 +381,63 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {
|
||||||
|
createCopilot: function (wallet, data) {
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
LNbits.api
|
||||||
|
.request('POST', '/copilot/api/v1/copilot', wallet, data)
|
||||||
|
.then(function (response) {
|
||||||
|
self.CopilotLinks.push(mapCopilot(response.data))
|
||||||
|
self.formDialogCopilot.show = false
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getCopilots: function () {
|
||||||
|
var self = this
|
||||||
|
var getAddressBalance = this.getAddressBalance
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'GET',
|
||||||
|
'/copilot/api/v1/copilot',
|
||||||
|
this.g.user.wallets[0].inkey
|
||||||
|
)
|
||||||
|
.then(function (response) {
|
||||||
|
self.CopilotLinks = response.data.map(mapCopilot)
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteCopilotLink: function (chargeId) {
|
||||||
|
var self = this
|
||||||
|
var link = _.findWhere(this.CopilotLinks, {id: chargeId})
|
||||||
|
LNbits.utils
|
||||||
|
.confirmDialog('Are you sure you want to delete this pay link?')
|
||||||
|
.onOk(function () {
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'DELETE',
|
||||||
|
'/copilot/api/v1/copilot/' + chargeId,
|
||||||
|
self.g.user.wallets[0].adminkey
|
||||||
|
)
|
||||||
|
.then(function (response) {
|
||||||
|
self.CopilotLinks = _.reject(self.CopilotLinks, function (obj) {
|
||||||
|
return obj.id === chargeId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportchargeCSV: function () {
|
||||||
|
var self = this
|
||||||
|
LNbits.utils.exportCSV(self.CopilotsTable.columns, this.CopilotLinks)
|
||||||
|
}
|
||||||
|
},
|
||||||
created: function () {}
|
created: function () {}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@@ -24,7 +24,12 @@ from .crud import (
|
|||||||
@api_validate_post_request(
|
@api_validate_post_request(
|
||||||
schema={
|
schema={
|
||||||
"title": {"type": "string", "empty": False, "required": True},
|
"title": {"type": "string", "empty": False, "required": True},
|
||||||
"animation": {"type": "string", "empty": False, "required": True},
|
"animation1": {"type": "string"},
|
||||||
|
"animation2": {"type": "string"},
|
||||||
|
"animation3": {"type": "string"},
|
||||||
|
"animation1threshold": {"type": "integer"},
|
||||||
|
"animation2threshold": {"type": "integer"},
|
||||||
|
"animation3threshold": {"type": "integer"},
|
||||||
"show_message": {"type": "integer", "empty": False, "required": True},
|
"show_message": {"type": "integer", "empty": False, "required": True},
|
||||||
"amount": {"type": "integer", "empty": False, "required": True},
|
"amount": {"type": "integer", "empty": False, "required": True},
|
||||||
}
|
}
|
||||||
@@ -40,7 +45,7 @@ async def api_copilot_create_or_update(copilot_id=None):
|
|||||||
|
|
||||||
@copilot_ext.route("/api/v1/copilot", methods=["GET"])
|
@copilot_ext.route("/api/v1/copilot", methods=["GET"])
|
||||||
@api_check_wallet_key("invoice")
|
@api_check_wallet_key("invoice")
|
||||||
async def api_copilot_retrieve(copilot_id):
|
async def api_copilots_retrieve(copilot_id):
|
||||||
copilots = await get_copilots(user=g.wallet.user)
|
copilots = await get_copilots(user=g.wallet.user)
|
||||||
|
|
||||||
if not copilots:
|
if not copilots:
|
||||||
|
Reference in New Issue
Block a user