mirror of
https://github.com/lnbits/lnbits.git
synced 2025-09-27 20:36:16 +02:00
Now you can have multiple themes
This commit is contained in:
@@ -2,7 +2,5 @@
|
|||||||
"name": "SatsPay Server",
|
"name": "SatsPay Server",
|
||||||
"short_description": "Create onchain and LN charges",
|
"short_description": "Create onchain and LN charges",
|
||||||
"icon": "payment",
|
"icon": "payment",
|
||||||
"contributors": [
|
"contributors": ["arcbtc"]
|
||||||
"arcbtc"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,8 @@ from lnbits.helpers import urlsafe_short_hash
|
|||||||
from ..watchonly.crud import get_config, get_fresh_address
|
from ..watchonly.crud import get_config, get_fresh_address
|
||||||
from . import db
|
from . import db
|
||||||
from .helpers import fetch_onchain_balance
|
from .helpers import fetch_onchain_balance
|
||||||
from .models import Charges, CreateCharge, SatsPaySettings
|
from .models import Charges, CreateCharge, SatsPayThemes
|
||||||
|
|
||||||
|
|
||||||
###############CHARGES##########################
|
###############CHARGES##########################
|
||||||
|
|
||||||
@@ -53,7 +54,8 @@ async def create_charge(user: str, data: CreateCharge) -> Charges:
|
|||||||
time,
|
time,
|
||||||
amount,
|
amount,
|
||||||
balance,
|
balance,
|
||||||
extra
|
extra,
|
||||||
|
custom_css,
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
@@ -71,6 +73,7 @@ async def create_charge(user: str, data: CreateCharge) -> Charges:
|
|||||||
data.completelinktext,
|
data.completelinktext,
|
||||||
data.time,
|
data.time,
|
||||||
data.amount,
|
data.amount,
|
||||||
|
data.custom_css,
|
||||||
0,
|
0,
|
||||||
data.extra,
|
data.extra,
|
||||||
),
|
),
|
||||||
@@ -124,41 +127,51 @@ async def check_address_balance(charge_id: str) -> Optional[Charges]:
|
|||||||
|
|
||||||
|
|
||||||
################## SETTINGS ###################
|
################## SETTINGS ###################
|
||||||
async def save_settings(user_id: str, data: SatsPaySettings):
|
|
||||||
|
|
||||||
|
async def save_theme(data: SatsPayThemes, css_id: str = None):
|
||||||
# insert or update
|
# insert or update
|
||||||
row = await db.fetchone(
|
if css_id:
|
||||||
"""SELECT user_id FROM satspay.settings WHERE user_id = ?""", (user_id,)
|
|
||||||
)
|
|
||||||
if row:
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
UPDATE satspay.settings SET custom_css = ? WHERE user_id = ?
|
UPDATE satspay.themes SET custom_css = ?, title = ? WHERE css_id = ?
|
||||||
""",
|
""",
|
||||||
(data.custom_css, user_id),
|
(data.custom_css, data.title, css_id),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
css_id = urlsafe_short_hash()
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO satspay.settings (
|
INSERT INTO satspay.themes (
|
||||||
user_id,
|
css_id,
|
||||||
|
title,
|
||||||
|
user,
|
||||||
custom_css
|
custom_css
|
||||||
)
|
)
|
||||||
VALUES (?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
user_id,
|
css_id,
|
||||||
|
data.title,
|
||||||
|
data.user,
|
||||||
data.custom_css,
|
data.custom_css,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return True
|
return await get_theme(css_id)
|
||||||
|
|
||||||
|
|
||||||
async def get_settings(user_id: str) -> SatsPaySettings:
|
async def get_theme(css_id: str) -> SatsPayThemes:
|
||||||
row = await db.fetchone(
|
row = await db.fetchone("SELECT * FROM satspay.themes WHERE css_id = ?", (css_id,))
|
||||||
"""SELECT * FROM satspay.settings WHERE user_id = ?""",
|
return SatsPayThemes.from_row(row) if row else None
|
||||||
|
|
||||||
|
|
||||||
|
async def get_themes(user_id: str) -> List[SatsPayThemes]:
|
||||||
|
rows = await db.fetchall(
|
||||||
|
"""SELECT * FROM satspay.themes WHERE "user" = ? ORDER BY "timestamp" DESC """,
|
||||||
(user_id,),
|
(user_id,),
|
||||||
)
|
)
|
||||||
if row:
|
return [SatsPayThemes.from_row(row) for row in rows]
|
||||||
return SatsPaySettings.from_row(row)
|
|
||||||
else:
|
|
||||||
return None
|
async def delete_theme(theme_id: str) -> None:
|
||||||
|
await db.execute("DELETE FROM satspay.themes WHERE css_id = ?", (theme_id,))
|
||||||
|
@@ -38,16 +38,26 @@ async def m002_add_charge_extra_data(db):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
async def m002_add_settings_table(db):
|
async def m002_add_themes_table(db):
|
||||||
"""
|
"""
|
||||||
Settings table
|
Themes table
|
||||||
"""
|
"""
|
||||||
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
CREATE TABLE satspay.settings (
|
CREATE TABLE satspay.themes (
|
||||||
user_id TEXT,
|
css_id TEXT,
|
||||||
|
user TEXT,
|
||||||
|
title TEXT,
|
||||||
custom_css TEXT
|
custom_css TEXT
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def m003_add_custom_css_to_charges(db):
|
||||||
|
"""
|
||||||
|
Add custom css option column to the 'charges' table
|
||||||
|
"""
|
||||||
|
|
||||||
|
await db.execute("ALTER TABLE satspay.charges ADD COLUMN custom_css TEXT;")
|
||||||
|
@@ -14,6 +14,7 @@ class CreateCharge(BaseModel):
|
|||||||
webhook: str = Query(None)
|
webhook: str = Query(None)
|
||||||
completelink: str = Query(None)
|
completelink: str = Query(None)
|
||||||
completelinktext: str = Query(None)
|
completelinktext: str = Query(None)
|
||||||
|
custom_css: Optional[str]
|
||||||
time: int = Query(..., ge=1)
|
time: int = Query(..., ge=1)
|
||||||
amount: int = Query(..., ge=1)
|
amount: int = Query(..., ge=1)
|
||||||
extra: str = "{}"
|
extra: str = "{}"
|
||||||
@@ -38,6 +39,7 @@ class Charges(BaseModel):
|
|||||||
completelink: Optional[str]
|
completelink: Optional[str]
|
||||||
completelinktext: Optional[str] = "Back to Merchant"
|
completelinktext: Optional[str] = "Back to Merchant"
|
||||||
extra: str = "{}"
|
extra: str = "{}"
|
||||||
|
custom_css: Optional[str]
|
||||||
time: int
|
time: int
|
||||||
amount: int
|
amount: int
|
||||||
balance: int
|
balance: int
|
||||||
@@ -73,9 +75,12 @@ class Charges(BaseModel):
|
|||||||
def must_call_webhook(self):
|
def must_call_webhook(self):
|
||||||
return self.webhook and self.paid and self.config.webhook_success == False
|
return self.webhook and self.paid and self.config.webhook_success == False
|
||||||
|
|
||||||
class SatsPaySettings(BaseModel):
|
class SatsPayThemes(BaseModel):
|
||||||
|
css_id: str = Query(None)
|
||||||
|
title: str = Query(None)
|
||||||
custom_css: str = Query(None)
|
custom_css: str = Query(None)
|
||||||
|
user: Optional[str]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_row(cls, row: Row) -> "SatsPaySettings":
|
def from_row(cls, row: Row) -> "SatsPayThemes":
|
||||||
return cls(**dict(row))
|
return cls(**dict(row))
|
||||||
|
@@ -26,5 +26,10 @@ const mapCharge = (obj, oldObj = {}) => {
|
|||||||
return charge
|
return charge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapCSS = (obj, oldObj = {}) => {
|
||||||
|
const theme = _.clone(obj)
|
||||||
|
return theme
|
||||||
|
}
|
||||||
|
|
||||||
const minutesToTime = min =>
|
const minutesToTime = min =>
|
||||||
min > 0 ? new Date(min * 1000).toISOString().substring(14, 19) : ''
|
min > 0 ? new Date(min * 1000).toISOString().substring(14, 19) : ''
|
||||||
|
@@ -5,7 +5,13 @@
|
|||||||
WatchOnly extension, we highly reccomend using a fresh extended public Key
|
WatchOnly extension, we highly reccomend using a fresh extended public Key
|
||||||
specifically for SatsPayServer!<br />
|
specifically for SatsPayServer!<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>,
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
style="color: unset"
|
||||||
|
href="https://github.com/motorina0"
|
||||||
|
>motorina0</a
|
||||||
|
></small
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
|
@@ -299,7 +299,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endblock %} {% block styles %}
|
{% endblock %} {% block styles %}
|
||||||
<link
|
<link
|
||||||
href="/satspay/css/{{ charge_data.id }}"
|
href="/satspay/css/{{ charge_data.custom_css }}"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
type="text/css"
|
type="text/css"
|
||||||
/>
|
/>
|
||||||
@@ -324,6 +324,7 @@
|
|||||||
charge: JSON.parse('{{charge_data | tojson}}'),
|
charge: JSON.parse('{{charge_data | tojson}}'),
|
||||||
mempoolEndpoint: '{{mempool_endpoint}}',
|
mempoolEndpoint: '{{mempool_endpoint}}',
|
||||||
network: '{{network}}',
|
network: '{{network}}',
|
||||||
|
css_id: '{{ charge_data.css_id }}',
|
||||||
pendingFunds: 0,
|
pendingFunds: 0,
|
||||||
ws: null,
|
ws: null,
|
||||||
newProgress: 0.4,
|
newProgress: 0.4,
|
||||||
@@ -462,8 +463,10 @@
|
|||||||
await this.getCustomCss()
|
await this.getCustomCss()
|
||||||
if (this.charge.payment_request) this.payInvoice()
|
if (this.charge.payment_request) this.payInvoice()
|
||||||
// Remove a user defined theme
|
// Remove a user defined theme
|
||||||
document.body.setAttribute('data-theme', '')
|
console.log(this.charge.custom_css)
|
||||||
|
if (this.charge.custom_css) {
|
||||||
|
document.body.setAttribute('data-theme', '')
|
||||||
|
}
|
||||||
if (this.charge.lnbitswallet) this.payInvoice()
|
if (this.charge.lnbitswallet) this.payInvoice()
|
||||||
else this.payOnchain()
|
else this.payOnchain()
|
||||||
|
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
color="primary"
|
color="primary"
|
||||||
@click="getSettings();formDialogSettings.show = true"
|
@click="getThemes();formDialogThemes.show = true"
|
||||||
>SatsPay settings
|
>New CSS Theme
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
@@ -266,6 +266,63 @@
|
|||||||
</q-table>
|
</q-table>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row items-center no-wrap q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<h5 class="text-subtitle1 q-my-none">Themes</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-table
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
:data="themeLinks"
|
||||||
|
row-key="id"
|
||||||
|
:columns="customCSSTable.columns"
|
||||||
|
:pagination.sync="customCSSTable.pagination"
|
||||||
|
>
|
||||||
|
{% raw %}
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
{{ col.label }}
|
||||||
|
</q-th>
|
||||||
|
<q-th auto-width></q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
{{ col.value }}
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="updateformDialog(props.row.css_id)"
|
||||||
|
icon="edit"
|
||||||
|
color="light-blue"
|
||||||
|
></q-btn>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="xs"
|
||||||
|
@click="deleteTheme(props.row.css_id)"
|
||||||
|
icon="cancel"
|
||||||
|
color="pink"
|
||||||
|
></q-btn>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
{% endraw %}
|
||||||
|
</q-table>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-5 q-gutter-y-md">
|
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||||
@@ -384,6 +441,15 @@
|
|||||||
label="Wallet *"
|
label="Wallet *"
|
||||||
>
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialogCharge.data.custom_css"
|
||||||
|
:options="themeOptions"
|
||||||
|
label="Custom CSS theme (optional)"
|
||||||
|
>
|
||||||
|
</q-select>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
unelevated
|
unelevated
|
||||||
@@ -402,23 +468,36 @@
|
|||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
<q-dialog v-model="formDialogSettings.show" position="top">
|
<q-dialog v-model="formDialogThemes.show" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<q-form @submit="sendFormDataSettings" class="q-gutter-md">
|
<q-form @submit="sendFormDataThemes" class="q-gutter-md">
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogSettings.data.custom_css"
|
v-model.trim="formDialogThemes.data.title"
|
||||||
|
type="text"
|
||||||
|
label="*Title"
|
||||||
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model.trim="formDialogThemes.data.custom_css"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
label="Custom CSS"
|
label="Custom CSS"
|
||||||
>
|
>
|
||||||
<q-tooltip
|
|
||||||
>Custom CSS to apply styles to your SatsPay invoice</q-tooltip
|
|
||||||
>
|
|
||||||
</q-input>
|
</q-input>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn unelevated color="primary" type="submit">Save Settings</q-btn>
|
<q-btn
|
||||||
<q-btn @click="cancelSettings" flat color="grey" class="q-ml-auto"
|
v-if="formDialogThemes.data.css_id"
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
type="submit"
|
||||||
|
>Update CSS theme</q-btn
|
||||||
|
>
|
||||||
|
<q-btn v-else unelevated color="primary" type="submit"
|
||||||
|
>Save CSS theme</q-btn
|
||||||
|
>
|
||||||
|
<q-btn @click="cancelThemes" flat color="grey" class="q-ml-auto"
|
||||||
>Cancel</q-btn
|
>Cancel</q-btn
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -446,7 +525,9 @@
|
|||||||
balance: null,
|
balance: null,
|
||||||
walletLinks: [],
|
walletLinks: [],
|
||||||
chargeLinks: [],
|
chargeLinks: [],
|
||||||
onchainwallet: null,
|
themeLinks: [],
|
||||||
|
themeOptions: [],
|
||||||
|
onchainwallet: '',
|
||||||
rescanning: false,
|
rescanning: false,
|
||||||
mempool: {
|
mempool: {
|
||||||
endpoint: '',
|
endpoint: '',
|
||||||
@@ -526,7 +607,25 @@
|
|||||||
rowsPerPage: 10
|
rowsPerPage: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
customCSSTable: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'css_id',
|
||||||
|
align: 'left',
|
||||||
|
label: 'ID',
|
||||||
|
field: 'css_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Title',
|
||||||
|
field: 'title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
rowsPerPage: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
formDialogCharge: {
|
formDialogCharge: {
|
||||||
show: false,
|
show: false,
|
||||||
data: {
|
data: {
|
||||||
@@ -534,11 +633,12 @@
|
|||||||
onchainwallet: '',
|
onchainwallet: '',
|
||||||
lnbits: false,
|
lnbits: false,
|
||||||
description: '',
|
description: '',
|
||||||
|
custom_css: '',
|
||||||
time: null,
|
time: null,
|
||||||
amount: null
|
amount: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
formDialogSettings: {
|
formDialogThemes: {
|
||||||
show: false,
|
show: false,
|
||||||
data: {
|
data: {
|
||||||
custom_css: ''
|
custom_css: ''
|
||||||
@@ -547,9 +647,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
cancelSettings: function (data) {
|
cancelThemes: function (data) {
|
||||||
this.formDialogCharge.data.custom_css = ''
|
this.formDialogCharge.data.custom_css = ''
|
||||||
this.formDialogSettings.show = false
|
this.formDialogThemes.show = false
|
||||||
},
|
},
|
||||||
cancelCharge: function (data) {
|
cancelCharge: function (data) {
|
||||||
this.formDialogCharge.data.description = ''
|
this.formDialogCharge.data.description = ''
|
||||||
@@ -559,6 +659,7 @@
|
|||||||
this.formDialogCharge.data.time = null
|
this.formDialogCharge.data.time = null
|
||||||
this.formDialogCharge.data.amount = null
|
this.formDialogCharge.data.amount = null
|
||||||
this.formDialogCharge.data.webhook = ''
|
this.formDialogCharge.data.webhook = ''
|
||||||
|
this.formDialogCharge.data.custom_css = ''
|
||||||
this.formDialogCharge.data.completelink = ''
|
this.formDialogCharge.data.completelink = ''
|
||||||
this.formDialogCharge.show = false
|
this.formDialogCharge.show = false
|
||||||
},
|
},
|
||||||
@@ -623,30 +724,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSettings: async function () {
|
getThemes: async function () {
|
||||||
try {
|
try {
|
||||||
const {data} = await LNbits.api.request(
|
const {data} = await LNbits.api.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/satspay/api/v1/settings',
|
'/satspay/api/v1/themes',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
)
|
)
|
||||||
if (data) {
|
console.log(data)
|
||||||
this.formDialogSettings.data.custom_css = data.custom_css
|
this.themeLinks = data.map(c =>
|
||||||
}
|
mapCSS(
|
||||||
|
c,
|
||||||
|
this.themeLinks.find(old => old.css_id === c.css_id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
this.themeOptions = data.map(w => ({
|
||||||
|
id: w.css_id,
|
||||||
|
label: w.title + ' - ' + w.css_id
|
||||||
|
}))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sendFormDataSettings: function () {
|
sendFormDataThemes: function () {
|
||||||
const wallet = this.g.user.wallets[0].inkey
|
const wallet = this.g.user.wallets[0].inkey
|
||||||
const data = this.formDialogSettings.data
|
const data = this.formDialogThemes.data
|
||||||
data.custom_css = data.custom_css
|
this.createTheme(wallet, data)
|
||||||
this.saveSettings(wallet, data)
|
|
||||||
},
|
},
|
||||||
sendFormDataCharge: function () {
|
sendFormDataCharge: function () {
|
||||||
const wallet = this.g.user.wallets[0].inkey
|
this.formDialogCharge.data.custom_css = this.formDialogCharge.data.custom_css.id
|
||||||
const data = this.formDialogCharge.data
|
const data = this.formDialogCharge.data
|
||||||
|
const wallet = this.g.user.wallets[0].inkey
|
||||||
data.amount = parseInt(data.amount)
|
data.amount = parseInt(data.amount)
|
||||||
data.time = parseInt(data.time)
|
data.time = parseInt(data.time)
|
||||||
data.lnbitswallet = data.lnbits ? data.lnbitswallet : null
|
data.lnbitswallet = data.lnbits ? data.lnbitswallet : null
|
||||||
@@ -715,23 +824,68 @@
|
|||||||
this.rescanning = false
|
this.rescanning = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
saveSettings: async function (wallet, data) {
|
updateformDialog: function (themeId) {
|
||||||
|
const theme = _.findWhere(this.themeLinks, {css_id: themeId})
|
||||||
|
console.log(theme.css_id)
|
||||||
|
this.formDialogThemes.data.css_id = theme.css_id
|
||||||
|
this.formDialogThemes.data.title = theme.title
|
||||||
|
this.formDialogThemes.data.custom_css = theme.custom_css
|
||||||
|
this.formDialogThemes.show = true
|
||||||
|
},
|
||||||
|
createTheme: async function (wallet, data) {
|
||||||
|
console.log(data.css_id)
|
||||||
try {
|
try {
|
||||||
const resp = await LNbits.api.request(
|
if (data.css_id) {
|
||||||
'POST',
|
const resp = await LNbits.api.request(
|
||||||
'/satspay/api/v1/settings',
|
'POST',
|
||||||
wallet,
|
'/satspay/api/v1/themes/' + data.css_id,
|
||||||
data
|
wallet,
|
||||||
)
|
data
|
||||||
|
)
|
||||||
this.formDialogSettings.show = false
|
this.themeLinks = _.reject(this.themeLinks, function (obj) {
|
||||||
this.formDialogSettings.data = {
|
return obj.css_id === data.css_id
|
||||||
|
})
|
||||||
|
this.themeLinks.unshift(mapCSS(resp.data))
|
||||||
|
} else {
|
||||||
|
const resp = await LNbits.api.request(
|
||||||
|
'POST',
|
||||||
|
'/satspay/api/v1/themes',
|
||||||
|
wallet,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
this.themeLinks.unshift(mapCSS(resp.data))
|
||||||
|
}
|
||||||
|
this.formDialogThemes.show = false
|
||||||
|
this.formDialogThemes.data = {
|
||||||
|
title: '',
|
||||||
custom_css: ''
|
custom_css: ''
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log('cun')
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deleteTheme: function (themeId) {
|
||||||
|
const theme = _.findWhere(this.themeLinks, {id: themeId})
|
||||||
|
LNbits.utils
|
||||||
|
.confirmDialog('Are you sure you want to delete this theme?')
|
||||||
|
.onOk(async () => {
|
||||||
|
try {
|
||||||
|
const response = await LNbits.api.request(
|
||||||
|
'DELETE',
|
||||||
|
'/satspay/api/v1/themes/' + themeId,
|
||||||
|
this.g.user.wallets[0].adminkey
|
||||||
|
)
|
||||||
|
|
||||||
|
this.themeLinks = _.reject(this.themeLinks, function (obj) {
|
||||||
|
return obj.css_id === themeId
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
createCharge: async function (wallet, data) {
|
createCharge: async function (wallet, data) {
|
||||||
try {
|
try {
|
||||||
const resp = await LNbits.api.request(
|
const resp = await LNbits.api.request(
|
||||||
@@ -784,7 +938,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
await this.getSettings()
|
await this.getThemes()
|
||||||
await this.getCharges()
|
await this.getCharges()
|
||||||
await this.getWalletConfig()
|
await this.getWalletConfig()
|
||||||
await this.getWalletLinks()
|
await this.getWalletLinks()
|
||||||
|
@@ -12,7 +12,7 @@ from lnbits.decorators import check_user_exists
|
|||||||
from lnbits.extensions.satspay.helpers import public_charge
|
from lnbits.extensions.satspay.helpers import public_charge
|
||||||
|
|
||||||
from . import satspay_ext, satspay_renderer
|
from . import satspay_ext, satspay_renderer
|
||||||
from .crud import get_charge, get_charge_config, get_settings
|
from .crud import get_charge, get_charge_config, get_themes, get_theme
|
||||||
|
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
@@ -43,16 +43,10 @@ async def display(request: Request, charge_id: str):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@satspay_ext.get("/css/{charge_id}")
|
@satspay_ext.get("/css/{css_id}")
|
||||||
async def display(charge_id: str, response: Response):
|
async def display(css_id: str, response: Response):
|
||||||
charge = await get_charge(charge_id)
|
theme = await get_theme(css_id)
|
||||||
if not charge:
|
if theme:
|
||||||
raise HTTPException(
|
return Response(content=theme.custom_css, media_type="text/css")
|
||||||
status_code=HTTPStatus.NOT_FOUND, detail="Charge link does not exist."
|
|
||||||
)
|
|
||||||
wallet = await get_wallet(charge.lnbitswallet)
|
|
||||||
settings = await get_settings(wallet.user)
|
|
||||||
if settings:
|
|
||||||
return Response(content=settings.custom_css, media_type="text/css")
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@@ -21,13 +21,15 @@ from .crud import (
|
|||||||
delete_charge,
|
delete_charge,
|
||||||
get_charge,
|
get_charge,
|
||||||
get_charges,
|
get_charges,
|
||||||
get_settings,
|
get_theme,
|
||||||
save_settings,
|
get_themes,
|
||||||
|
delete_theme,
|
||||||
|
save_theme,
|
||||||
update_charge,
|
update_charge,
|
||||||
)
|
)
|
||||||
from .helpers import call_webhook, public_charge
|
from .helpers import call_webhook, public_charge
|
||||||
from .helpers import compact_charge
|
from .helpers import compact_charge
|
||||||
from .models import CreateCharge, SatsPaySettings
|
from .models import CreateCharge, SatsPayThemes
|
||||||
|
|
||||||
#############################CHARGES##########################
|
#############################CHARGES##########################
|
||||||
|
|
||||||
@@ -145,22 +147,42 @@ async def api_charge_balance(charge_id):
|
|||||||
return {**public_charge(charge)}
|
return {**public_charge(charge)}
|
||||||
|
|
||||||
|
|
||||||
#############################CHARGES##########################
|
#############################THEMES##########################
|
||||||
|
|
||||||
|
|
||||||
@satspay_ext.post("/api/v1/settings")
|
@satspay_ext.post("/api/v1/themes")
|
||||||
async def api_settings_save(
|
@satspay_ext.post("/api/v1/themes/{css_id}")
|
||||||
data: SatsPaySettings, wallet: WalletTypeInfo = Depends(require_invoice_key)
|
async def api_themes_save(
|
||||||
|
data: SatsPayThemes,
|
||||||
|
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||||
|
css_id: str = None,
|
||||||
):
|
):
|
||||||
await save_settings(user_id=wallet.wallet.user, data=data)
|
if css_id:
|
||||||
return True
|
theme = await save_theme(css_id=css_id, data=data)
|
||||||
|
else:
|
||||||
|
data.user = wallet.wallet.user
|
||||||
|
theme = await save_theme(data=data)
|
||||||
|
return theme
|
||||||
|
|
||||||
|
|
||||||
@satspay_ext.get("/api/v1/settings")
|
@satspay_ext.get("/api/v1/themes")
|
||||||
async def api_settings_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)):
|
async def api_themes_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
try:
|
try:
|
||||||
return await get_settings(wallet.wallet.user)
|
return await get_themes(wallet.wallet.user)
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
logger.error("Error loading satspay settings")
|
logger.error("Error loading satspay themes")
|
||||||
logger.error(HTTPException)
|
logger.error(HTTPException)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
@satspay_ext.delete("/api/v1/themes/{theme_id}")
|
||||||
|
async def api_charge_delete(theme_id, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
|
theme = await get_theme(theme_id)
|
||||||
|
|
||||||
|
if not theme:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND, detail="Theme does not exist."
|
||||||
|
)
|
||||||
|
|
||||||
|
await delete_theme(theme_id)
|
||||||
|
return "", HTTPStatus.NO_CONTENT
|
||||||
|
Reference in New Issue
Block a user