Changed so user can use multiple animations

This commit is contained in:
Ben Arc
2021-04-12 22:05:54 +01:00
parent e4c893c1f2
commit 167c31f778
7 changed files with 220 additions and 132 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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
> >

View File

@@ -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>

View File

@@ -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: