Update for jukebox extension readme
removed the profit column showing 0
This commit is contained in:
parent
1e0367a451
commit
2da68bf974
2 changed files with 88 additions and 59 deletions
|
|
@ -1,5 +1,36 @@
|
||||||
# Jukebox
|
# 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"\
|
||||||
|

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

|
||||||
|
- follow the steps to get your Spotify App and get the client ID and secret key\
|
||||||
|

|
||||||
|
- paste the codes in the form\
|
||||||
|

|
||||||
|
- copy the _Redirect URL_ presented on the form\
|
||||||
|

|
||||||
|
- on Spotify click the "EDIT SETTINGS" button and paste the copied link in the _Redirect URI's_ prompt
|
||||||
|

|
||||||
|
- 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)\
|
||||||
|

|
||||||
|
|
||||||
|
3. After Jukebox is created, click the icon to open the dialog with the shareable QR, open the Jukebox page, etc...\
|
||||||
|

|
||||||
|
4. The users will see the Jukebox page and choose a song from the selected playlist\
|
||||||
|

|
||||||
|
5. After selecting a song they'd like to hear next a dialog will show presenting the music\
|
||||||
|

|
||||||
|
6. After payment, the song will automatically start playing on the device selected or enter the queue if some other music is already playing
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,6 @@ new Vue({
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: 'Price',
|
label: 'Price',
|
||||||
field: 'price'
|
field: 'price'
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'profit',
|
|
||||||
align: 'left',
|
|
||||||
label: 'Profit',
|
|
||||||
field: 'profit'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
pagination: {
|
pagination: {
|
||||||
|
|
@ -81,7 +75,7 @@ new Vue({
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {
|
methods: {
|
||||||
openQrCodeDialog: function (linkId) {
|
openQrCodeDialog: function(linkId) {
|
||||||
var link = _.findWhere(this.JukeboxLinks, {id: linkId})
|
var link = _.findWhere(this.JukeboxLinks, {id: linkId})
|
||||||
|
|
||||||
this.qrCodeDialog.data = _.clone(link)
|
this.qrCodeDialog.data = _.clone(link)
|
||||||
|
|
@ -93,8 +87,12 @@ new Vue({
|
||||||
getJukeboxes() {
|
getJukeboxes() {
|
||||||
self = this
|
self = this
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request('GET', '/jukebox/api/v1/jukebox', self.g.user.wallets[0].adminkey)
|
.request(
|
||||||
.then(function (response) {
|
'GET',
|
||||||
|
'/jukebox/api/v1/jukebox',
|
||||||
|
self.g.user.wallets[0].adminkey
|
||||||
|
)
|
||||||
|
.then(function(response) {
|
||||||
self.JukeboxLinks = response.data.map(mapJukebox)
|
self.JukeboxLinks = response.data.map(mapJukebox)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
@ -105,15 +103,15 @@ new Vue({
|
||||||
self = this
|
self = this
|
||||||
LNbits.utils
|
LNbits.utils
|
||||||
.confirmDialog('Are you sure you want to delete this Jukebox?')
|
.confirmDialog('Are you sure you want to delete this Jukebox?')
|
||||||
.onOk(function () {
|
.onOk(function() {
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request(
|
.request(
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/jukebox/api/v1/jukebox/' + juke_id,
|
'/jukebox/api/v1/jukebox/' + juke_id,
|
||||||
self.g.user.wallets[0].adminkey
|
self.g.user.wallets[0].adminkey
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function(response) {
|
||||||
self.JukeboxLinks = _.reject(self.JukeboxLinks, function (obj) {
|
self.JukeboxLinks = _.reject(self.JukeboxLinks, function(obj) {
|
||||||
return obj.id === juke_id
|
return obj.id === juke_id
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -123,7 +121,7 @@ new Vue({
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateJukebox: function (linkId) {
|
updateJukebox: function(linkId) {
|
||||||
self = this
|
self = this
|
||||||
var link = _.findWhere(self.JukeboxLinks, {id: linkId})
|
var link = _.findWhere(self.JukeboxLinks, {id: linkId})
|
||||||
self.jukeboxDialog.data = _.clone(link._data)
|
self.jukeboxDialog.data = _.clone(link._data)
|
||||||
|
|
@ -165,10 +163,10 @@ new Vue({
|
||||||
LNbits.utils.notifyApiError(err)
|
LNbits.utils.notifyApiError(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
authAccess() {
|
authAccess() {
|
||||||
self = this
|
self = this
|
||||||
self.requestAuthorization()
|
self.requestAuthorization()
|
||||||
self.getSpotifyTokens()
|
self.getSpotifyTokens()
|
||||||
self.$q.notify({
|
self.$q.notify({
|
||||||
spinner: true,
|
spinner: true,
|
||||||
message: 'Processing',
|
message: 'Processing',
|
||||||
|
|
@ -178,7 +176,7 @@ new Vue({
|
||||||
getSpotifyTokens() {
|
getSpotifyTokens() {
|
||||||
self = this
|
self = this
|
||||||
var counter = 0
|
var counter = 0
|
||||||
var timerId = setInterval(function () {
|
var timerId = setInterval(function() {
|
||||||
counter++
|
counter++
|
||||||
if (!self.jukeboxDialog.data.sp_user) {
|
if (!self.jukeboxDialog.data.sp_user) {
|
||||||
clearInterval(timerId)
|
clearInterval(timerId)
|
||||||
|
|
@ -195,37 +193,37 @@ new Vue({
|
||||||
if (self.jukeboxDialog.data.sp_access_token) {
|
if (self.jukeboxDialog.data.sp_access_token) {
|
||||||
self.refreshPlaylists()
|
self.refreshPlaylists()
|
||||||
self.refreshDevices()
|
self.refreshDevices()
|
||||||
console.log("this.devices")
|
console.log('this.devices')
|
||||||
console.log(self.devices)
|
console.log(self.devices)
|
||||||
console.log("this.devices")
|
console.log('this.devices')
|
||||||
setTimeout(function () {
|
setTimeout(function() {
|
||||||
if (self.devices.length < 1 || self.playlists.length < 1) {
|
if (self.devices.length < 1 || self.playlists.length < 1) {
|
||||||
self.$q.notify({
|
self.$q.notify({
|
||||||
spinner: true,
|
spinner: true,
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message:
|
message:
|
||||||
'Error! Make sure Spotify is open on the device you wish to use, has playlists, and is playing something',
|
'Error! Make sure Spotify is open on the device you wish to use, has playlists, and is playing something',
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
|
||||||
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.api
|
||||||
LNbits.utils.notifyApiError(err)
|
.request(
|
||||||
})
|
'DELETE',
|
||||||
clearInterval(timerId)
|
'/jukebox/api/v1/jukebox/' + response.data.id,
|
||||||
self.closeFormDialog()
|
self.g.user.wallets[0].adminkey
|
||||||
} else {
|
)
|
||||||
self.step = 4
|
.then(function(response) {
|
||||||
clearInterval(timerId)
|
self.getJukeboxes()
|
||||||
}
|
})
|
||||||
}, 2000)
|
.catch(err => {
|
||||||
|
LNbits.utils.notifyApiError(err)
|
||||||
|
})
|
||||||
|
clearInterval(timerId)
|
||||||
|
self.closeFormDialog()
|
||||||
|
} else {
|
||||||
|
self.step = 4
|
||||||
|
clearInterval(timerId)
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -269,7 +267,7 @@ new Vue({
|
||||||
self.g.user.wallets[0].adminkey,
|
self.g.user.wallets[0].adminkey,
|
||||||
self.jukeboxDialog.data
|
self.jukeboxDialog.data
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function(response) {
|
||||||
console.log(response.data)
|
console.log(response.data)
|
||||||
if (
|
if (
|
||||||
self.jukeboxDialog.data.sp_playlists &&
|
self.jukeboxDialog.data.sp_playlists &&
|
||||||
|
|
@ -290,7 +288,7 @@ new Vue({
|
||||||
'Bearer ' + this.jukeboxDialog.data.sp_access_token
|
'Bearer ' + this.jukeboxDialog.data.sp_access_token
|
||||||
)
|
)
|
||||||
xhr.send(body)
|
xhr.send(body)
|
||||||
xhr.onload = function () {
|
xhr.onload = function() {
|
||||||
if (xhr.status == 401) {
|
if (xhr.status == 401) {
|
||||||
self.refreshAccessToken()
|
self.refreshAccessToken()
|
||||||
self.playlistApi(
|
self.playlistApi(
|
||||||
|
|
@ -326,7 +324,7 @@ new Vue({
|
||||||
'Bearer ' + this.jukeboxDialog.data.sp_access_token
|
'Bearer ' + this.jukeboxDialog.data.sp_access_token
|
||||||
)
|
)
|
||||||
xhr.send(body)
|
xhr.send(body)
|
||||||
xhr.onload = function () {
|
xhr.onload = function() {
|
||||||
if (xhr.status == 401) {
|
if (xhr.status == 401) {
|
||||||
self.refreshAccessToken()
|
self.refreshAccessToken()
|
||||||
self.deviceApi(
|
self.deviceApi(
|
||||||
|
|
@ -347,15 +345,15 @@ new Vue({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
refreshDevices() {
|
refreshDevices() {
|
||||||
self = this
|
self = this
|
||||||
self.deviceApi(
|
self.deviceApi(
|
||||||
'GET',
|
'GET',
|
||||||
'https://api.spotify.com/v1/me/player/devices',
|
'https://api.spotify.com/v1/me/player/devices',
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
fetchAccessToken(code) {
|
fetchAccessToken(code) {
|
||||||
self = this
|
self = this
|
||||||
let body = 'grant_type=authorization_code'
|
let body = 'grant_type=authorization_code'
|
||||||
body += '&code=' + code
|
body += '&code=' + code
|
||||||
|
|
@ -363,16 +361,16 @@ new Vue({
|
||||||
'&redirect_uri=' +
|
'&redirect_uri=' +
|
||||||
encodeURI(self.locationcbPath + self.jukeboxDialog.data.sp_id)
|
encodeURI(self.locationcbPath + self.jukeboxDialog.data.sp_id)
|
||||||
|
|
||||||
self.callAuthorizationApi(body)
|
self.callAuthorizationApi(body)
|
||||||
},
|
},
|
||||||
refreshAccessToken() {
|
refreshAccessToken() {
|
||||||
self = this
|
self = this
|
||||||
let body = 'grant_type=refresh_token'
|
let body = 'grant_type=refresh_token'
|
||||||
body += '&refresh_token=' + self.jukeboxDialog.data.sp_refresh_token
|
body += '&refresh_token=' + self.jukeboxDialog.data.sp_refresh_token
|
||||||
body += '&client_id=' + self.jukeboxDialog.data.sp_user
|
body += '&client_id=' + self.jukeboxDialog.data.sp_user
|
||||||
self.callAuthorizationApi(body)
|
self.callAuthorizationApi(body)
|
||||||
},
|
},
|
||||||
callAuthorizationApi(body) {
|
callAuthorizationApi(body) {
|
||||||
self = this
|
self = this
|
||||||
console.log(
|
console.log(
|
||||||
btoa(
|
btoa(
|
||||||
|
|
@ -394,7 +392,7 @@ new Vue({
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
xhr.send(body)
|
xhr.send(body)
|
||||||
xhr.onload = function () {
|
xhr.onload = function() {
|
||||||
let responseObj = JSON.parse(xhr.response)
|
let responseObj = JSON.parse(xhr.response)
|
||||||
if (responseObj.access_token) {
|
if (responseObj.access_token) {
|
||||||
self.jukeboxDialog.data.sp_access_token = responseObj.access_token
|
self.jukeboxDialog.data.sp_access_token = responseObj.access_token
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue