Livestream Fix (#198)

Co-authored-by: Tiago Vasconcelos <tvasconcelos@gmail.com>
This commit is contained in:
Tiago Vasconcelos
2021-06-04 20:27:25 +01:00
committed by GitHub
parent f4c3ac18b6
commit 7412373f11
5 changed files with 70 additions and 37 deletions

View File

@@ -15,8 +15,12 @@ The revenue will be sent to a wallet created specifically for that producer, wit
## Usage ## Usage
1. Start by adding a track\ 1. Start by adding a track\
![add new track](https://i.imgur.com/Cu0eGrW.jpg) - set the producer, or choose an existing one - set the track name - define a minimum price where a user can download the track - set the download URL, where user will be redirected if he tips the livestream and the tip is equal or above the set price\ ![add new track](https://i.imgur.com/Cu0eGrW.jpg)
![track settings](https://i.imgur.com/HTJYwcW.jpg) - set the producer, or choose an existing one
- set the track name
- define a minimum price where a user can download the track
- set the download URL, where user will be redirected if he tips the livestream and the tip is equal or above the set price\
![track settings](https://i.imgur.com/HTJYwcW.jpg)
2. Adjust the percentage of the pay you want to take from the user's tips. 10%, the default, means that the DJ will keep 10% of all the tips sent by users. The other 90% will go to an auto generated producer wallet\ 2. Adjust the percentage of the pay you want to take from the user's tips. 10%, the default, means that the DJ will keep 10% of all the tips sent by users. The other 90% will go to an auto generated producer wallet\
![adjust percentage](https://i.imgur.com/9weHKAB.jpg) ![adjust percentage](https://i.imgur.com/9weHKAB.jpg)
3. For every different producer added, when adding tracks, a wallet is generated for them\ 3. For every different producer added, when adding tracks, a wallet is generated for them\

View File

@@ -37,6 +37,7 @@ new Vue({
}, },
methods: { methods: {
getTrackLabel(trackId) { getTrackLabel(trackId) {
if (!trackId) return
let track = this.tracksMap[trackId] let track = this.tracksMap[trackId]
return `${track.name}, ${this.producersMap[track.producer].name}` return `${track.name}, ${this.producersMap[track.producer].name}`
}, },
@@ -162,6 +163,7 @@ new Vue({
}) })
}, },
updateCurrentTrack(track) { updateCurrentTrack(track) {
console.log(this.nextCurrentTrack, this.livestream)
if (this.livestream.current_track === track) { if (this.livestream.current_track === track) {
// if clicking the same, stop it // if clicking the same, stop it
track = 0 track = 0
@@ -175,6 +177,7 @@ new Vue({
) )
.then(() => { .then(() => {
this.livestream.current_track = track this.livestream.current_track = track
this.nextCurrentTrack = track
this.$q.notify({ this.$q.notify({
message: `Current track updated.`, message: `Current track updated.`,
timeout: 700 timeout: 700

View File

@@ -27,8 +27,8 @@
<div class="col"> <div class="col">
{% raw %} {% raw %}
<q-btn unelevated color="deep-purple" type="submit"> <q-btn unelevated color="deep-purple" type="submit">
{{ nextCurrentTrack === livestream.current_track ? 'Stop' : 'Set' {{ nextCurrentTrack && nextCurrentTrack ===
}} current track livestream.current_track ? 'Stop' : 'Set' }} current track
</q-btn> </q-btn>
{% endraw %} {% endraw %}
</div> </div>

View File

@@ -1,3 +1,29 @@
<h1>Support Tickets</h1> # Support Tickets
<h2>Get paid sats to answer questions</h2>
Charge people per word for contacting you. Possible applications include, paid support ticketing, PAYG language services, contact spam protection. ## Get paid sats to answer questions
Charge a per word amount for people to contact you.
Possible applications include, paid support ticketing, PAYG language services, contact spam protection.
1. Click "NEW FORM" to create a new contact form\
![new contact form](https://i.imgur.com/kZqWGPe.png)
2. Fill out the contact form
- set the wallet to use
- give your form a name
- set an optional webhook that will get called when the form receives a payment
- give it a small description
- set the amount you want to charge, per **word**, for people to contact you\
![form settings](https://i.imgur.com/AsXeVet.png)
3. Your new contact form will appear on the _Forms_ section. Note that you can create various forms with different rates per word, for different purposes\
![forms section](https://i.imgur.com/gg71HhM.png)
4. When a user wants to reach out to you, they will get to the contact form. They can fill out some information:
- a name
- an optional email if they want you to reply
- and the actual message
- at the bottom, a value in satoshis, will display how much it will cost them to send this message\
![user view of form](https://i.imgur.com/DWGJWQz.png)
- after submiting the Lightning Network invoice will pop up and after payment the message will be sent to you\
![contact form payment](https://i.imgur.com/7heGsiO.png)
5. Back in "Support ticket" extension you'll get the messages your fans, users, haters, etc, sent you on the _Tickets_ section\
![tickets](https://i.imgur.com/dGhJ6Ok.png)

View File

@@ -230,7 +230,7 @@
</div> </div>
{% endblock %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block scripts %} {{ window_vars(user) }}
<script> <script>
var mapLNTicket = function (obj) { var mapLNTicket = function(obj) {
obj.date = Quasar.utils.date.formatDate( obj.date = Quasar.utils.date.formatDate(
new Date(obj.time * 1000), new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm' 'YYYY-MM-DD HH:mm'
@@ -243,7 +243,7 @@
new Vue({ new Vue({
el: '#vue', el: '#vue',
mixins: [windowMixin], mixins: [windowMixin],
data: function () { data: function() {
return { return {
forms: [], forms: [],
tickets: [], tickets: [],
@@ -294,7 +294,7 @@
} }
}, },
methods: { methods: {
getTickets: function () { getTickets: function() {
var self = this var self = this
LNbits.api LNbits.api
@@ -303,40 +303,40 @@
'/lnticket/api/v1/tickets?all_wallets', '/lnticket/api/v1/tickets?all_wallets',
this.g.user.wallets[0].inkey this.g.user.wallets[0].inkey
) )
.then(function (response) { .then(function(response) {
self.tickets = response.data.map(function (obj) { self.tickets = response.data.map(function(obj) {
return mapLNTicket(obj) return mapLNTicket(obj)
}) })
}) })
}, },
deleteTicket: function (ticketId) { deleteTicket: function(ticketId) {
var self = this var self = this
var tickets = _.findWhere(this.tickets, {id: ticketId}) var tickets = _.findWhere(this.tickets, {id: ticketId})
LNbits.utils LNbits.utils
.confirmDialog('Are you sure you want to delete this ticket') .confirmDialog('Are you sure you want to delete this ticket')
.onOk(function () { .onOk(function() {
LNbits.api LNbits.api
.request( .request(
'DELETE', 'DELETE',
'/lnticket/api/v1/tickets/' + ticketId, '/lnticket/api/v1/tickets/' + ticketId,
_.findWhere(self.g.user.wallets, {id: tickets.wallet}).inkey _.findWhere(self.g.user.wallets, {id: tickets.wallet}).inkey
) )
.then(function (response) { .then(function(response) {
self.tickets = _.reject(self.tickets, function (obj) { self.tickets = _.reject(self.tickets, function(obj) {
return obj.id == ticketId return obj.id == ticketId
}) })
}) })
.catch(function (error) { .catch(function(error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}) })
}, },
exportticketsCSV: function () { exportticketsCSV: function() {
LNbits.utils.exportCSV(this.ticketsTable.columns, this.tickets) LNbits.utils.exportCSV(this.ticketsTable.columns, this.tickets)
}, },
getForms: function () { getForms: function() {
var self = this var self = this
LNbits.api LNbits.api
@@ -345,13 +345,13 @@
'/lnticket/api/v1/forms?all_wallets', '/lnticket/api/v1/forms?all_wallets',
this.g.user.wallets[0].inkey this.g.user.wallets[0].inkey
) )
.then(function (response) { .then(function(response) {
self.forms = response.data.map(function (obj) { self.forms = response.data.map(function(obj) {
return mapLNTicket(obj) return mapLNTicket(obj)
}) })
}) })
}, },
sendFormData: function () { sendFormData: function() {
var wallet = _.findWhere(this.g.user.wallets, { var wallet = _.findWhere(this.g.user.wallets, {
id: this.formDialog.data.wallet id: this.formDialog.data.wallet
}) })
@@ -364,20 +364,20 @@
} }
}, },
createForm: function (wallet, data) { createForm: function(wallet, data) {
var self = this var self = this
LNbits.api LNbits.api
.request('POST', '/lnticket/api/v1/forms', wallet.inkey, data) .request('POST', '/lnticket/api/v1/forms', wallet.inkey, data)
.then(function (response) { .then(function(response) {
self.forms.push(mapLNTicket(response.data)) self.forms.push(mapLNTicket(response.data))
self.formDialog.show = false self.formDialog.show = false
self.formDialog.data = {} self.formDialog.data = {}
}) })
.catch(function (error) { .catch(function(error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}, },
updateformDialog: function (formId) { updateformDialog: function(formId) {
var link = _.findWhere(this.forms, {id: formId}) var link = _.findWhere(this.forms, {id: formId})
console.log(link.id) console.log(link.id)
this.formDialog.data.id = link.id this.formDialog.data.id = link.id
@@ -387,7 +387,7 @@
this.formDialog.data.costpword = link.costpword this.formDialog.data.costpword = link.costpword
this.formDialog.show = true this.formDialog.show = true
}, },
updateForm: function (wallet, data) { updateForm: function(wallet, data) {
var self = this var self = this
console.log(data) console.log(data)
@@ -398,47 +398,47 @@
wallet.inkey, wallet.inkey,
data data
) )
.then(function (response) { .then(function(response) {
self.forms = _.reject(self.forms, function (obj) { self.forms = _.reject(self.forms, function(obj) {
return obj.id == data.id return obj.id == data.id
}) })
self.forms.push(mapLNTicket(response.data)) self.forms.push(mapLNTicket(response.data))
self.formDialog.show = false self.formDialog.show = false
self.formDialog.data = {} self.formDialog.data = {}
}) })
.catch(function (error) { .catch(function(error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}, },
deleteForm: function (formsId) { deleteForm: function(formsId) {
var self = this var self = this
var forms = _.findWhere(this.forms, {id: formsId}) var forms = _.findWhere(this.forms, {id: formsId})
LNbits.utils LNbits.utils
.confirmDialog('Are you sure you want to delete this form link?') .confirmDialog('Are you sure you want to delete this form link?')
.onOk(function () { .onOk(function() {
LNbits.api LNbits.api
.request( .request(
'DELETE', 'DELETE',
'/lnticket/api/v1/forms/' + formsId, '/lnticket/api/v1/forms/' + formsId,
_.findWhere(self.g.user.wallets, {id: forms.wallet}).inkey _.findWhere(self.g.user.wallets, {id: forms.wallet}).inkey
) )
.then(function (response) { .then(function(response) {
self.forms = _.reject(self.forms, function (obj) { self.forms = _.reject(self.forms, function(obj) {
return obj.id == formsId return obj.id == formsId
}) })
}) })
.catch(function (error) { .catch(function(error) {
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}) })
}, },
exportformsCSV: function () { exportformsCSV: function() {
LNbits.utils.exportCSV(this.formsTable.columns, this.forms) LNbits.utils.exportCSV(this.formsTable.columns, this.forms)
} }
}, },
created: function () { created: function() {
if (this.g.user.wallets.length) { if (this.g.user.wallets.length) {
this.getTickets() this.getTickets()
this.getForms() this.getForms()