removed polling and added listener behaviour
This commit is contained in:
parent
d8be362ac4
commit
26cf51c11c
3 changed files with 132 additions and 96 deletions
|
|
@ -10,3 +10,8 @@ jukebox_ext: Blueprint = Blueprint(
|
||||||
|
|
||||||
from .views_api import * # noqa
|
from .views_api import * # noqa
|
||||||
from .views import * # noqa
|
from .views import * # noqa
|
||||||
|
from .tasks import register_listeners
|
||||||
|
|
||||||
|
from lnbits.tasks import record_async
|
||||||
|
|
||||||
|
jukebox_ext.record(record_async(register_listeners))
|
||||||
|
|
|
||||||
27
lnbits/extensions/jukebox/tasks.py
Normal file
27
lnbits/extensions/jukebox/tasks.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import json
|
||||||
|
import trio # type: ignore
|
||||||
|
|
||||||
|
from lnbits.core.models import Payment
|
||||||
|
from lnbits.core.crud import create_payment
|
||||||
|
from lnbits.core import db as core_db
|
||||||
|
from lnbits.tasks import register_invoice_listener, internal_invoice_paid
|
||||||
|
from lnbits.helpers import urlsafe_short_hash
|
||||||
|
|
||||||
|
from .crud import get_jukebox, update_jukebox_payment
|
||||||
|
|
||||||
|
|
||||||
|
async def register_listeners():
|
||||||
|
invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
|
||||||
|
register_invoice_listener(invoice_paid_chan_send)
|
||||||
|
await wait_for_paid_invoices(invoice_paid_chan_recv)
|
||||||
|
|
||||||
|
|
||||||
|
async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel):
|
||||||
|
async for payment in invoice_paid_chan:
|
||||||
|
await on_invoice_paid(payment)
|
||||||
|
|
||||||
|
async def on_invoice_paid(payment: Payment) -> None:
|
||||||
|
if "jukebox" != payment.extra.get("tag"):
|
||||||
|
# not a jukebox invoice
|
||||||
|
return
|
||||||
|
await update_jukebox_payment(payment.payment_hash, paid=True)
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
<img style="width: 100px" :src="currentPlay.image" />
|
<img style="width: 100px" :src="currentPlay.image" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<strong style="font-size: 20px">{{ currentPlay.name }}</strong><br />
|
<strong style="font-size: 20px">{{ currentPlay.name }}</strong
|
||||||
|
><br />
|
||||||
<strong style="font-size: 15px">{{ currentPlay.artist }}</strong>
|
<strong style="font-size: 15px">{{ currentPlay.artist }}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -19,15 +20,30 @@
|
||||||
<q-card class="q-mt-lg">
|
<q-card class="q-mt-lg">
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p style="font-size: 22px">Pick a song</p>
|
<p style="font-size: 22px">Pick a song</p>
|
||||||
<q-select outlined v-model="playlist" :options="playlists" label="playlists" @input="selectPlaylist()">
|
<q-select
|
||||||
|
outlined
|
||||||
|
v-model="playlist"
|
||||||
|
:options="playlists"
|
||||||
|
label="playlists"
|
||||||
|
@input="selectPlaylist()"
|
||||||
|
>
|
||||||
</q-select>
|
</q-select>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
<q-virtual-scroll style="max-height: 300px" :items="currentPlaylist" separator>
|
<q-virtual-scroll
|
||||||
|
style="max-height: 300px"
|
||||||
|
:items="currentPlaylist"
|
||||||
|
separator
|
||||||
|
>
|
||||||
<template v-slot="{ item, index }">
|
<template v-slot="{ item, index }">
|
||||||
<q-item :key="index" dense clickable v-ripple
|
<q-item
|
||||||
@click="payForSong(item.id, item.name, item.artist, item.image)">
|
:key="index"
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
v-ripple
|
||||||
|
@click="payForSong(item.id, item.name, item.artist, item.image)"
|
||||||
|
>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>
|
<q-item-label>
|
||||||
{{ item.name }} - ({{ item.artist }})
|
{{ item.name }} - ({{ item.artist }})
|
||||||
|
|
@ -55,7 +71,8 @@
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<br />
|
<br />
|
||||||
<div class="row q-mt-lg q-gutter-sm">
|
<div class="row q-mt-lg q-gutter-sm">
|
||||||
<q-btn outline color="grey" @click="getInvoice(receive.id)">Play for {% endraw %}{{ price }}{% raw %} sats
|
<q-btn outline color="grey" @click="getInvoice(receive.id)"
|
||||||
|
>Play for {% endraw %}{{ price }}{% raw %} sats
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
@ -63,10 +80,16 @@
|
||||||
<q-dialog v-model="receive.dialogues.second" position="top">
|
<q-dialog v-model="receive.dialogues.second" position="top">
|
||||||
<q-card class="q-pa-lg lnbits__dialog-card">
|
<q-card class="q-pa-lg lnbits__dialog-card">
|
||||||
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
|
||||||
<qrcode :value="'lightning:' + receive.paymentReq" :options="{width: 800}" class="rounded-borders"></qrcode>
|
<qrcode
|
||||||
|
:value="'lightning:' + receive.paymentReq"
|
||||||
|
:options="{width: 800}"
|
||||||
|
class="rounded-borders"
|
||||||
|
></qrcode>
|
||||||
</q-responsive>
|
</q-responsive>
|
||||||
<div class="row q-mt-lg q-gutter-sm">
|
<div class="row q-mt-lg q-gutter-sm">
|
||||||
<q-btn outline color="grey" @click="copyText(receive.paymentReq)">Copy invoice</q-btn>
|
<q-btn outline color="grey" @click="copyText(receive.paymentReq)"
|
||||||
|
>Copy invoice</q-btn
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
@ -84,7 +107,7 @@
|
||||||
return {
|
return {
|
||||||
currentPlaylist: [],
|
currentPlaylist: [],
|
||||||
currentlyPlaying: {},
|
currentlyPlaying: {},
|
||||||
cancelListener: () => { },
|
cancelListener: () => {},
|
||||||
playlists: {},
|
playlists: {},
|
||||||
playlist: '',
|
playlist: '',
|
||||||
heavyList: [],
|
heavyList: [],
|
||||||
|
|
@ -111,14 +134,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
cancelPayment: function () {
|
// cancelPayment: function () {
|
||||||
this.paymentReq = null
|
// this.paymentReq = null
|
||||||
clearInterval(this.paymentDialog.checker)
|
//
|
||||||
if (this.paymentDialog.dismissMsg) {
|
// if (this.paymentDialog.dismissMsg) {
|
||||||
this.paymentDialog.dismissMsg()
|
// this.paymentDialog.dismissMsg()
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
closeReceiveDialog() { },
|
// closeReceiveDialog() {},
|
||||||
payForSong(song_id, name, artist, image) {
|
payForSong(song_id, name, artist, image) {
|
||||||
self = this
|
self = this
|
||||||
self.receive.name = name
|
self.receive.name = name
|
||||||
|
|
@ -127,66 +150,68 @@
|
||||||
self.receive.id = song_id
|
self.receive.id = song_id
|
||||||
self.receive.dialogues.first = true
|
self.receive.dialogues.first = true
|
||||||
},
|
},
|
||||||
|
startPaymentNotifier() {
|
||||||
|
this.cancelListener()
|
||||||
|
|
||||||
|
this.cancelListener = LNbits.events.onInvoicePaid(
|
||||||
|
this.selectedWallet,
|
||||||
|
payment => {
|
||||||
|
this.paid = true
|
||||||
|
this.receive.dialogues.first = false
|
||||||
|
this.receive.dialogues.second = false
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'GET',
|
||||||
|
'/jukebox/api/v1/jukebox/jb/invoicep/' +
|
||||||
|
this.receive.id +
|
||||||
|
'/{{ juke_id }}/' +
|
||||||
|
this.receive.paymentHash
|
||||||
|
)
|
||||||
|
.then(response1 => {
|
||||||
|
if (response1.data[2] == this.receive.id) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getCurrent()
|
||||||
|
}, 500)
|
||||||
|
this.$q.notify({
|
||||||
|
color: 'green',
|
||||||
|
message:
|
||||||
|
'Success! "' +
|
||||||
|
this.receive.name +
|
||||||
|
'" will be played soon',
|
||||||
|
timeout: 3000
|
||||||
|
})
|
||||||
|
|
||||||
|
this.paid = false
|
||||||
|
response1 = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
LNbits.utils.notifyApiError(err)
|
||||||
|
self.paid = false
|
||||||
|
response1 = []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
getInvoice(song_id) {
|
getInvoice(song_id) {
|
||||||
self = this
|
self = this
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request(
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/jukebox/api/v1/jukebox/jb/invoice/' +
|
'/jukebox/api/v1/jukebox/jb/invoice/' +
|
||||||
'{{ juke_id }}' +
|
'{{ juke_id }}' +
|
||||||
'/' +
|
'/' +
|
||||||
song_id
|
song_id
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|
||||||
self.receive.paymentReq = response.data[0][1]
|
self.receive.paymentReq = response.data[0][1]
|
||||||
self.receive.paymentHash = response.data[0][0]
|
self.receive.paymentHash = response.data[0][0]
|
||||||
self.receive.dialogues.second = true
|
self.receive.dialogues.second = true
|
||||||
|
self.$q.notify({
|
||||||
var paymentChecker = setInterval(function () {
|
message: 'Processing'
|
||||||
if (!self.paid) {
|
})
|
||||||
self.checkInvoice(self.receive.paymentHash, '{{ juke_id }}')
|
|
||||||
}
|
|
||||||
if (self.paid) {
|
|
||||||
clearInterval(paymentChecker)
|
|
||||||
self.paid = true
|
|
||||||
self.receive.dialogues.first = false
|
|
||||||
self.receive.dialogues.second = false
|
|
||||||
self.$q.notify({
|
|
||||||
message:
|
|
||||||
'Processing',
|
|
||||||
})
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'GET',
|
|
||||||
'/jukebox/api/v1/jukebox/jb/invoicep/' + song_id + '/{{ juke_id }}/' + self.receive.paymentHash)
|
|
||||||
.then(function (response1) {
|
|
||||||
|
|
||||||
if (response1.data[2] == song_id) {
|
|
||||||
setTimeout(function () { self.getCurrent() }, 500)
|
|
||||||
self.$q.notify({
|
|
||||||
color: 'green',
|
|
||||||
message:
|
|
||||||
'Success! "' + self.receive.name + '" will be played soon',
|
|
||||||
timeout: 3000
|
|
||||||
})
|
|
||||||
|
|
||||||
self.paid = false
|
|
||||||
response1 = []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
|
|
||||||
LNbits.utils.notifyApiError(err)
|
|
||||||
self.paid = false
|
|
||||||
response1 = []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, 3000)
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
||||||
self.$q.notify({
|
self.$q.notify({
|
||||||
color: 'warning',
|
color: 'warning',
|
||||||
html: true,
|
html: true,
|
||||||
|
|
@ -196,39 +221,17 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
checkInvoice(juke_id, paymentHash) {
|
|
||||||
|
|
||||||
var self = this
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'GET',
|
|
||||||
'/jukebox/api/v1/jukebox/jb/checkinvoice/' + juke_id + '/' + paymentHash,
|
|
||||||
'filla'
|
|
||||||
)
|
|
||||||
.then(function (response) {
|
|
||||||
|
|
||||||
self.paid = response.data.paid
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getCurrent() {
|
getCurrent() {
|
||||||
|
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request(
|
.request('GET', '/jukebox/api/v1/jukebox/jb/currently/{{juke_id}}')
|
||||||
'GET',
|
|
||||||
'/jukebox/api/v1/jukebox/jb/currently/{{juke_id}}')
|
|
||||||
.then(function (res) {
|
.then(function (res) {
|
||||||
if (res.data.id) {
|
if (res.data.id) {
|
||||||
|
|
||||||
self.currentlyPlaying = res.data
|
self.currentlyPlaying = res.data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
})
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
selectPlaylist() {
|
selectPlaylist() {
|
||||||
self = this
|
self = this
|
||||||
|
|
@ -236,9 +239,9 @@
|
||||||
.request(
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/jukebox/api/v1/jukebox/jb/playlist/' +
|
'/jukebox/api/v1/jukebox/jb/playlist/' +
|
||||||
'{{ juke_id }}' +
|
'{{ juke_id }}' +
|
||||||
'/' +
|
'/' +
|
||||||
self.playlist.split(',')[0].split('-')[1]
|
self.playlist.split(',')[0].split('-')[1]
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
self.currentPlaylist = response.data
|
self.currentPlaylist = response.data
|
||||||
|
|
@ -247,20 +250,21 @@
|
||||||
LNbits.utils.notifyApiError(err)
|
LNbits.utils.notifyApiError(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
currentSong() { }
|
currentSong() {}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getCurrent()
|
this.getCurrent()
|
||||||
this.playlists = JSON.parse('{{ playlists | tojson }}')
|
this.playlists = JSON.parse('{{ playlists | tojson }}')
|
||||||
|
this.selectedWallet.inkey = '{{ inkey }}'
|
||||||
|
this.startPaymentNotifier()
|
||||||
self = this
|
self = this
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request(
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/jukebox/api/v1/jukebox/jb/playlist/' +
|
'/jukebox/api/v1/jukebox/jb/playlist/' +
|
||||||
'{{ juke_id }}' +
|
'{{ juke_id }}' +
|
||||||
'/' +
|
'/' +
|
||||||
self.playlists[0].split(',')[0].split('-')[1]
|
self.playlists[0].split(',')[0].split('-')[1]
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
self.currentPlaylist = response.data
|
self.currentPlaylist = response.data
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue