Merge branch 'master' into jukebox/addlistener

This commit is contained in:
Arc
2021-07-01 00:42:34 +01:00
committed by GitHub
104 changed files with 3109 additions and 684 deletions
+33 -2
View File
@@ -1,5 +1,36 @@
# Jukebox
To use this extension you need a Spotify client ID and client secret. You get these by creating an app in the Spotify developers dashboard here https://developer.spotify.com/dashboard/applications
## An actual Jukebox where users pay sats to play their favourite music from your playlists
Select the playlists you want people to be able to pay for, share the frontend page, profit :)
**Note:** To use this extension you need a Premium Spotify subscription.
## Usage
1. Click on "ADD SPOTIFY JUKEBOX"\
![add jukebox](https://i.imgur.com/NdVoKXd.png)
2. Follow the steps required on the form\
- give your jukebox a name
- select a wallet to receive payment
- define the price a user must pay to select a song\
![pick wallet price](https://i.imgur.com/4bJ8mb9.png)
- follow the steps to get your Spotify App and get the client ID and secret key\
![spotify keys](https://i.imgur.com/w2EzFtB.png)
- paste the codes in the form\
![api keys](https://i.imgur.com/6b9xauo.png)
- copy the _Redirect URL_ presented on the form\
![redirect url](https://i.imgur.com/GMzl0lG.png)
- on Spotify click the "EDIT SETTINGS" button and paste the copied link in the _Redirect URI's_ prompt
![spotify app setting](https://i.imgur.com/vb0x4Tl.png)
- back on LNBits, click "AUTORIZE ACCESS" and "Agree" on the page that will open
- choose on which device the LNBits Jukebox extensions will stream to, you may have to be logged in in order to select the device (browser, smartphone app, etc...)
- and select what playlist will be available for users to choose songs (you need to have already playlist on Spotify)\
![select playlists](https://i.imgur.com/g4dbtED.png)
3. After Jukebox is created, click the icon to open the dialog with the shareable QR, open the Jukebox page, etc...\
![shareable jukebox](https://i.imgur.com/EAh9PI0.png)
4. The users will see the Jukebox page and choose a song from the selected playlist\
![select song](https://i.imgur.com/YYjeQAs.png)
5. After selecting a song they'd like to hear next a dialog will show presenting the music\
![play for sats](https://i.imgur.com/eEHl3o8.png)
6. After payment, the song will automatically start playing on the device selected or enter the queue if some other music is already playing
+43 -45
View File
@@ -46,12 +46,6 @@ new Vue({
align: 'left',
label: 'Price',
field: 'price'
},
{
name: 'profit',
align: 'left',
label: 'Profit',
field: 'profit'
}
],
pagination: {
@@ -93,7 +87,11 @@ new Vue({
getJukeboxes() {
self = this
LNbits.api
.request('GET', '/jukebox/api/v1/jukebox', self.g.user.wallets[0].adminkey)
.request(
'GET',
'/jukebox/api/v1/jukebox',
self.g.user.wallets[0].adminkey
)
.then(function (response) {
self.JukeboxLinks = response.data.map(mapJukebox)
})
@@ -165,10 +163,10 @@ new Vue({
LNbits.utils.notifyApiError(err)
})
},
authAccess() {
authAccess() {
self = this
self.requestAuthorization()
self.getSpotifyTokens()
self.requestAuthorization()
self.getSpotifyTokens()
self.$q.notify({
spinner: true,
message: 'Processing',
@@ -195,37 +193,37 @@ new Vue({
if (self.jukeboxDialog.data.sp_access_token) {
self.refreshPlaylists()
self.refreshDevices()
console.log("this.devices")
console.log('this.devices')
console.log(self.devices)
console.log("this.devices")
console.log('this.devices')
setTimeout(function () {
if (self.devices.length < 1 || self.playlists.length < 1) {
self.$q.notify({
spinner: true,
color: 'red',
message:
'Error! Make sure Spotify is open on the device you wish to use, has playlists, and is playing something',
timeout: 10000
})
LNbits.api
.request(
'DELETE',
'/jukebox/api/v1/jukebox/' + response.data.id,
self.g.user.wallets[0].adminkey
)
.then(function (response) {
self.getJukeboxes()
if (self.devices.length < 1 || self.playlists.length < 1) {
self.$q.notify({
spinner: true,
color: 'red',
message:
'Error! Make sure Spotify is open on the device you wish to use, has playlists, and is playing something',
timeout: 10000
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
clearInterval(timerId)
self.closeFormDialog()
} else {
self.step = 4
clearInterval(timerId)
}
}, 2000)
LNbits.api
.request(
'DELETE',
'/jukebox/api/v1/jukebox/' + response.data.id,
self.g.user.wallets[0].adminkey
)
.then(function (response) {
self.getJukeboxes()
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
clearInterval(timerId)
self.closeFormDialog()
} else {
self.step = 4
clearInterval(timerId)
}
}, 2000)
}
}
})
@@ -347,15 +345,15 @@ new Vue({
}
}
},
refreshDevices() {
refreshDevices() {
self = this
self.deviceApi(
self.deviceApi(
'GET',
'https://api.spotify.com/v1/me/player/devices',
null
)
},
fetchAccessToken(code) {
fetchAccessToken(code) {
self = this
let body = 'grant_type=authorization_code'
body += '&code=' + code
@@ -363,16 +361,16 @@ new Vue({
'&redirect_uri=' +
encodeURI(self.locationcbPath + self.jukeboxDialog.data.sp_id)
self.callAuthorizationApi(body)
self.callAuthorizationApi(body)
},
refreshAccessToken() {
refreshAccessToken() {
self = this
let body = 'grant_type=refresh_token'
body += '&refresh_token=' + self.jukeboxDialog.data.sp_refresh_token
body += '&client_id=' + self.jukeboxDialog.data.sp_user
self.callAuthorizationApi(body)
self.callAuthorizationApi(body)
},
callAuthorizationApi(body) {
callAuthorizationApi(body) {
self = this
console.log(
btoa(
@@ -6,14 +6,9 @@ new Vue({
el: '#vue',
mixins: [windowMixin],
data() {
return {
}
return {}
},
computed: {},
methods: {
},
created() {
}
methods: {},
created() {}
})
@@ -1,24 +1,33 @@
<q-card-section>
To use this extension you need a Spotify client ID and client secret. You
get these by creating an app in the Spotify developers dashboard
<a style="color:#43a047" href="https://developer.spotify.com/dashboard/applications">here </a>
<br /><br />Select the playlists you want people to be able to pay for,
share the frontend page, profit :) <br /><br />
Made by, <a style="color:#43a047" href="https://twitter.com/arcbtc">benarc</a>. Inspired by,
<a style="color:#43a047" href="https://twitter.com/pirosb3/status/1056263089128161280">pirosb3</a>.
To use this extension you need a Spotify client ID and client secret. You get
these by creating an app in the Spotify developers dashboard
<a
style="color: #43a047"
href="https://developer.spotify.com/dashboard/applications"
>here
</a>
<br /><br />Select the playlists you want people to be able to pay for, share
the frontend page, profit :) <br /><br />
Made by,
<a style="color: #43a047" href="https://twitter.com/arcbtc">benarc</a>.
Inspired by,
<a
style="color: #43a047"
href="https://twitter.com/pirosb3/status/1056263089128161280"
>pirosb3</a
>.
</q-card-section>
<q-expansion-item group="extras" icon="swap_vertical_circle" label="API info" :content-inset-level="0.5">
<q-expansion-item
group="extras"
icon="swap_vertical_circle"
label="API info"
:content-inset-level="0.5"
>
<q-expansion-item group="api" dense expand-separator label="List jukeboxes">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span>
/jukebox/api/v1/jukebox</code>
<code><span class="text-blue">GET</span> /jukebox/api/v1/jukebox</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@@ -27,7 +36,8 @@
</h5>
<code>[&lt;jukebox_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code>curl -X GET {{ request.url_root }}api/v1/jukebox -H "X-Api-Key: {{
<code
>curl -X GET {{ request.url_root }}api/v1/jukebox -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
@@ -36,8 +46,10 @@
<q-expansion-item group="api" dense expand-separator label="Get jukebox">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span>
/jukebox/api/v1/jukebox/&lt;juke_id&gt;</code>
<code
><span class="text-blue">GET</span>
/jukebox/api/v1/jukebox/&lt;juke_id&gt;</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@@ -46,36 +58,44 @@
</h5>
<code>&lt;jukebox_object&gt;</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code>curl -X GET {{ request.url_root }}api/v1/jukebox/&lt;juke_id&gt; -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
<code
>curl -X GET {{ request.url_root }}api/v1/jukebox/&lt;juke_id&gt; -H
"X-Api-Key: {{ g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Create/update track">
<q-expansion-item
group="api"
dense
expand-separator
label="Create/update track"
>
<q-card>
<q-card-section>
<code><span class="text-green">POST/PUT</span>
/jukebox/api/v1/jukebox/</code>
<code
><span class="text-green">POST/PUT</span>
/jukebox/api/v1/jukebox/</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">
Body (application/json)
</h5>
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<code>&lt;jukbox_object&gt;</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code>curl -X POST {{ request.url_root }}api/v1/jukebox/ -d
'{"user": &lt;string, user_id&gt;,
"title": &lt;string&gt;, "wallet":&lt;string&gt;, "sp_user":
&lt;string, spotify_user_account&gt;, "sp_secret": &lt;string, spotify_user_secret&gt;, "sp_access_token":
&lt;string, not_required&gt;, "sp_refresh_token":
&lt;string, not_required&gt;, "sp_device": &lt;string, spotify_user_secret&gt;, "sp_playlists":
&lt;string, not_required&gt;, "price":
&lt;integer, not_required&gt;}' -H "Content-type:
application/json" -H "X-Api-Key: {{g.user.wallets[0].adminkey }}"
<code
>curl -X POST {{ request.url_root }}api/v1/jukebox/ -d '{"user":
&lt;string, user_id&gt;, "title": &lt;string&gt;,
"wallet":&lt;string&gt;, "sp_user": &lt;string,
spotify_user_account&gt;, "sp_secret": &lt;string,
spotify_user_secret&gt;, "sp_access_token": &lt;string,
not_required&gt;, "sp_refresh_token": &lt;string, not_required&gt;,
"sp_device": &lt;string, spotify_user_secret&gt;, "sp_playlists":
&lt;string, not_required&gt;, "price": &lt;integer, not_required&gt;}'
-H "Content-type: application/json" -H "X-Api-Key:
{{g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
@@ -83,8 +103,10 @@
<q-expansion-item group="api" dense expand-separator label="Delete jukebox">
<q-card>
<q-card-section>
<code><span class="text-red">DELETE</span>
/jukebox/api/v1/jukebox/&lt;juke_id&gt;</code>
<code
><span class="text-red">DELETE</span>
/jukebox/api/v1/jukebox/&lt;juke_id&gt;</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@@ -93,9 +115,11 @@
</h5>
<code>&lt;jukebox_object&gt;</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code>curl -X DELETE {{ request.url_root }}api/v1/jukebox/&lt;juke_id&gt; -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
<code
>curl -X DELETE {{ request.url_root }}api/v1/jukebox/&lt;juke_id&gt;
-H "X-Api-Key: {{ g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
</q-expansion-item></q-expansion-item
>
@@ -12,7 +12,9 @@
style="font-size: 20rem"
></q-icon>
<h5 class="q-my-none">Ask the host to turn on the device and launch spotify</h5>
<h5 class="q-my-none">
Ask the host to turn on the device and launch spotify
</h5>
<br />
</center>
</q-card-section>
@@ -4,18 +4,36 @@
<div class="col-12 col-md-7 q-gutter-y-md">
<q-card>
<q-card-section>
<q-btn unelevated color="green-7" class="q-ma-lg" @click="openNewDialog()">Add Spotify Jukebox</q-btn>
<q-btn
unelevated
color="primary"
class="q-ma-lg"
@click="openNewDialog()"
>Add Spotify Jukebox</q-btn
>
{% raw %}
<q-table flat dense :data="JukeboxLinks" row-key="id" :columns="JukeboxTable.columns"
:pagination.sync="JukeboxTable.pagination" :filter="filter">
<q-table
flat
dense
:data="JukeboxLinks"
row-key="id"
:columns="JukeboxTable.columns"
:pagination.sync="JukeboxTable.pagination"
:filter="filter"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width></q-th>
<q-th auto-width></q-th>
<q-th v-for="col in props.cols" :key="col.name" :props="props" auto-width>
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
auto-width
>
<div v-if="col.name == 'id'"></div>
<div v-else>{{ col.label }}</div>
</q-th>
@@ -26,18 +44,43 @@
<template v-slot:body="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn unelevated dense size="xs" icon="launch" :color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
@click="openQrCodeDialog(props.row.sp_id)">
<q-btn
unelevated
dense
size="xs"
icon="launch"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
@click="openQrCodeDialog(props.row.sp_id)"
>
<q-tooltip> Jukebox QR </q-tooltip>
</q-btn>
</q-td>
<q-td auto-width>
<q-btn flat dense size="xs" @click="updateJukebox(props.row.id)" icon="edit" color="light-blue"></q-btn>
<q-btn flat dense size="xs" @click="deleteJukebox(props.row.id)" icon="cancel" color="pink">
<q-btn
flat
dense
size="xs"
@click="updateJukebox(props.row.id)"
icon="edit"
color="light-blue"
></q-btn>
<q-btn
flat
dense
size="xs"
@click="deleteJukebox(props.row.id)"
icon="cancel"
color="pink"
>
<q-tooltip> Delete Jukebox </q-tooltip>
</q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props" auto-width>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
auto-width
>
<div v-if="col.name == 'id'"></div>
<div v-else>{{ col.value }}</div>
</q-td>
@@ -63,23 +106,62 @@
<q-dialog v-model="jukeboxDialog.show" position="top" @hide="closeFormDialog">
<q-card class="q-pa-md q-pt-lg q-mt-md" style="width: 100%">
<q-stepper v-model="step" active-color="green-7" inactive-color="green-10" vertical animated>
<q-step :name="1" title="Pick wallet, price" icon="account_balance_wallet" :done="step > 1">
<q-input filled class="q-pt-md" dense v-model.trim="jukeboxDialog.data.title" label="Jukebox name"></q-input>
<q-select class="q-pb-md q-pt-md" filled dense emit-value v-model="jukeboxDialog.data.wallet"
:options="g.user.walletOptions" label="Wallet to use"></q-select>
<q-input filled dense v-model.trim="jukeboxDialog.data.price" type="number" max="1440" label="Price per track"
class="q-pb-lg">
<q-stepper
v-model="step"
active-color="primary"
inactive-color="secondary"
vertical
animated
>
<q-step
:name="1"
title="Pick wallet, price"
icon="account_balance_wallet"
:done="step > 1"
>
<q-input
filled
class="q-pt-md"
dense
v-model.trim="jukeboxDialog.data.title"
label="Jukebox name"
></q-input>
<q-select
class="q-pb-md q-pt-md"
filled
dense
emit-value
v-model="jukeboxDialog.data.wallet"
:options="g.user.walletOptions"
label="Wallet to use"
></q-select>
<q-input
filled
dense
v-model.trim="jukeboxDialog.data.price"
type="number"
max="1440"
label="Price per track"
class="q-pb-lg"
>
</q-input>
<div class="row">
<div class="col-4">
<q-btn
v-if="jukeboxDialog.data.title != null && jukeboxDialog.data.price != null && jukeboxDialog.data.wallet != null"
color="green-7" @click="step = 2">Continue</q-btn>
<q-btn v-else color="green-7" disable>Continue</q-btn>
color="primary"
@click="step = 2"
>Continue</q-btn
>
<q-btn v-else color="primary" disable>Continue</q-btn>
</div>
<div class="col-8">
<q-btn color="green-7" class="float-right" @click="closeFormDialog">Cancel</q-btn>
<q-btn
color="primary"
class="float-right"
@click="closeFormDialog"
>Cancel</q-btn
>
</div>
</div>
@@ -90,26 +172,57 @@
<img src="/jukebox/static/spotapi.gif" />
To use this extension you need a Spotify client ID and client secret.
You get these by creating an app in the Spotify developers dashboard
<a target="_blank" style="color:#43a047" href="https://developer.spotify.com/dashboard/applications">here</a>.
<q-input filled class="q-pb-md q-pt-md" dense v-model.trim="jukeboxDialog.data.sp_user" label="Client ID">
<a
target="_blank"
style="color: #43a047"
href="https://developer.spotify.com/dashboard/applications"
>here</a
>.
<q-input
filled
class="q-pb-md q-pt-md"
dense
v-model.trim="jukeboxDialog.data.sp_user"
label="Client ID"
>
</q-input>
<q-input dense v-model="jukeboxDialog.data.sp_secret" filled :type="isPwd ? 'password' : 'text'"
label="Client secret">
<q-input
dense
v-model="jukeboxDialog.data.sp_secret"
filled
:type="isPwd ? 'password' : 'text'"
label="Client secret"
>
<template #append>
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer" @click="isPwd = !isPwd">
<q-icon
:name="isPwd ? 'visibility_off' : 'visibility'"
class="cursor-pointer"
@click="isPwd = !isPwd"
>
</q-icon>
</template>
</q-input>
<div class="row q-mt-md">
<div class="col-4">
<q-btn v-if="jukeboxDialog.data.sp_secret != null && jukeboxDialog.data.sp_user != null && tokenFetched"
color="green-7" @click="submitSpotifyKeys">Submit keys</q-btn>
<q-btn v-else color="green-7" disable color="green-7">Submit keys</q-btn>
<q-btn
v-if="jukeboxDialog.data.sp_secret != null && jukeboxDialog.data.sp_user != null && tokenFetched"
color="primary"
@click="submitSpotifyKeys"
>Submit keys</q-btn
>
<q-btn v-else color="primary" disable color="primary"
>Submit keys</q-btn
>
</div>
<div class="col-8">
<q-btn color="green-7" class="float-right" @click="closeFormDialog">Cancel</q-btn>
<q-btn
color="primary"
class="float-right"
@click="closeFormDialog"
>Cancel</q-btn
>
</div>
</div>
@@ -120,42 +233,93 @@
<img src="/jukebox/static/spotapi1.gif" />
In the app go to edit-settings, set the redirect URI to this link
<br />
<q-btn dense outline unelevated color="green-7" size="xs"
@click="copyText(locationcb + jukeboxDialog.data.sp_id, 'Link copied to clipboard!')">{% raw %}{{ locationcb
}}{{ jukeboxDialog.data.sp_id }}{% endraw
<q-btn
dense
outline
unelevated
color="primary"
size="xs"
@click="copyText(locationcb + jukeboxDialog.data.sp_id, 'Link copied to clipboard!')"
>{% raw %}{{ locationcb }}{{ jukeboxDialog.data.sp_id }}{% endraw
%}<q-tooltip> Click to copy URL </q-tooltip>
</q-btn>
<br />
Settings can be found
<a target="_blank" style="color:#43a047" href="https://developer.spotify.com/dashboard/applications">here</a>.
<a
target="_blank"
style="color: #43a047"
href="https://developer.spotify.com/dashboard/applications"
>here</a
>.
<div class="row q-mt-md">
<div class="col-4">
<q-btn v-if="jukeboxDialog.data.sp_secret != null && jukeboxDialog.data.sp_user != null && tokenFetched"
color="green-7" @click="authAccess">Authorise access</q-btn>
<q-btn v-else color="green-7" disable color="green-7">Authorise access</q-btn>
<q-btn
v-if="jukeboxDialog.data.sp_secret != null && jukeboxDialog.data.sp_user != null && tokenFetched"
color="primary"
@click="authAccess"
>Authorise access</q-btn
>
<q-btn v-else color="primary" disable color="primary"
>Authorise access</q-btn
>
</div>
<div class="col-8">
<q-btn color="green-7" class="float-right" @click="closeFormDialog">Cancel</q-btn>
<q-btn
color="primary"
class="float-right"
@click="closeFormDialog"
>Cancel</q-btn
>
</div>
</div>
<br />
</q-step>
<q-step :name="4" title="Select playlists" icon="queue_music" active-color="green-8" :done="step > 4">
<q-select class="q-pb-md q-pt-md" filled dense emit-value v-model="jukeboxDialog.data.sp_device"
:options="devices" label="Device jukebox will play to"></q-select>
<q-select class="q-pb-md" filled dense multiple emit-value v-model="jukeboxDialog.data.sp_playlists"
:options="playlists" label="Playlists available to the jukebox"></q-select>
<q-step
:name="4"
title="Select playlists"
icon="queue_music"
active-color="primary"
:done="step > 4"
>
<q-select
class="q-pb-md q-pt-md"
filled
dense
emit-value
v-model="jukeboxDialog.data.sp_device"
:options="devices"
label="Device jukebox will play to"
></q-select>
<q-select
class="q-pb-md"
filled
dense
multiple
emit-value
v-model="jukeboxDialog.data.sp_playlists"
:options="playlists"
label="Playlists available to the jukebox"
></q-select>
<div class="row q-mt-md">
<div class="col-5">
<q-btn v-if="jukeboxDialog.data.sp_device != null && jukeboxDialog.data.sp_playlists != null"
color="green-7" @click="createJukebox">Create Jukebox</q-btn>
<q-btn v-else color="green-7" disable>Create Jukebox</q-btn>
<q-btn
v-if="jukeboxDialog.data.sp_device != null && jukeboxDialog.data.sp_playlists != null"
color="primary"
@click="createJukebox"
>Create Jukebox</q-btn
>
<q-btn v-else color="primary" disable>Create Jukebox</q-btn>
</div>
<div class="col-7">
<q-btn color="green-7" class="float-right" @click="closeFormDialog">Cancel</q-btn>
<q-btn
color="primary"
class="float-right"
@click="closeFormDialog"
>Cancel</q-btn
>
</div>
</div>
</q-step>
@@ -169,15 +333,28 @@
<h5 class="q-my-none">Shareable Jukebox QR</h5>
</center>
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
<qrcode :value="qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id" :options="{width: 800}"
class="rounded-borders"></qrcode>
<qrcode
:value="qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id"
:options="{width: 800}"
class="rounded-borders"
></qrcode>
</q-responsive>
<div class="row q-mt-lg q-gutter-sm">
<q-btn outline color="grey"
@click="copyText(qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id, 'Link copied to clipboard!')">
Copy jukebox link</q-btn>
<q-btn outline color="grey" type="a" :href="qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id"
target="_blank">Open jukebox</q-btn>
<q-btn
outline
color="grey"
@click="copyText(qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id, 'Link copied to clipboard!')"
>
Copy jukebox link</q-btn
>
<q-btn
outline
color="grey"
type="a"
:href="qrCodeDialog.data.url + '/jukebox/' + qrCodeDialog.data.id"
target="_blank"
>Open jukebox</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
</div>
</q-card>
@@ -186,4 +363,4 @@
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script src="https://cdn.jsdelivr.net/npm/pica@6.1.1/dist/pica.min.js"></script>
<script src="/jukebox/static/js/index.js"></script>
{% endblock %}
{% endblock %}
@@ -199,6 +199,7 @@
self.receive.paymentReq = response.data[0][1]
self.receive.paymentHash = response.data[0][0]
self.receive.dialogues.second = true
self.$q.notify({
message: 'Processing'
})