Merge pull request #22 from lnbits/allow_multiple_images

Multiple fixes
This commit is contained in:
Vlad Stan 2023-03-17 18:00:55 +02:00 committed by GitHub
commit efa5741445
6 changed files with 103 additions and 70 deletions

View file

@ -5,13 +5,12 @@ async function chatDialog(path) {
name: 'chat-dialog',
template,
props: ['account', 'merchant', 'relays'],
props: ['account', 'merchant', 'relays', 'pool'],
data: function () {
return {
dialog: false,
isChat: true,
loading: false,
pool: null,
nostrMessages: [],
newMessage: '',
ordersTable: {
@ -82,11 +81,10 @@ async function chatDialog(path) {
},
async closeDialog() {
this.dialog = false
await this.pool.close(Array.from(this.relays))
await this.sub.unsub()
},
async startPool() {
this.loading = true
this.pool = new NostrTools.SimplePool()
let messagesMap = new Map()
let sub = this.pool.sub(Array.from(this.relays), [
{
@ -98,6 +96,7 @@ async function chatDialog(path) {
'#p': [this.account.pubkey]
}
])
sub.on('eose', () => {
this.loading = false
this.nostrMessages = Array.from(messagesMap.values())
@ -133,6 +132,7 @@ async function chatDialog(path) {
console.error('Unable to decrypt message!')
}
})
this.sub = sub
},
async sendMessage() {
if (this.newMessage && this.newMessage.length < 1) return
@ -146,6 +146,10 @@ async function chatDialog(path) {
}
event.id = NostrTools.getEventHash(event)
event.sig = this.signEvent(event)
// This doesn't work yet
// this.pool.publish(Array.from(this.relays), event)
// this.newMessage = ''
// We need this hack
for (const url of Array.from(this.relays)) {
try {
let relay = NostrTools.relayInit(url)

View file

@ -18,6 +18,7 @@
:account="account ? account : dropIn"
:merchant="stall.pubkey"
:relays="relays"
:pool="pool"
/>
<shopping-cart
:cart="cart"
@ -235,12 +236,7 @@
@click="copyText(qrCodeDialog.data.payment_request)"
>Copy invoice</q-btn
>
<q-btn
@click="closeQrCodeDialog"
v-close-popup
flat
color="grey"
class="q-ml-auto"
<q-btn @click="closeQrCodeDialog" flat color="grey" class="q-ml-auto"
>Close</q-btn
>
</div>

View file

@ -11,7 +11,8 @@ async function customerStall(path) {
'products',
'product-detail',
'change-page',
'relays'
'relays',
'pool'
],
data: function () {
return {
@ -38,6 +39,7 @@ async function customerStall(path) {
data: {
payment_request: null
},
dismissMsg: null,
show: false
},
downloadOrderDialog: {
@ -85,10 +87,17 @@ async function customerStall(path) {
return LNbits.utils.formatCurrency(amount, unit)
},
addToCart(item) {
console.log('add to cart', item)
let prod = this.cart.products
if (prod.has(item.id)) {
let qty = prod.get(item.id).quantity
if (qty == item.quantity) {
this.$q.notify({
type: 'warning',
message: `${item.name} only has ${item.quantity} units!`,
icon: 'production_quantity_limits'
})
return
}
prod.set(item.id, {
...prod.get(item.id),
quantity: qty + 1
@ -114,7 +123,6 @@ async function customerStall(path) {
this.updateCart(+item.price, true)
},
updateCart(price, del = false) {
console.log(this.cart, this.cartMenu)
if (del) {
this.cart.total -= price
this.cart.size--
@ -125,7 +133,10 @@ async function customerStall(path) {
this.cartMenu = Array.from(this.cart.products, item => {
return {id: item[0], ...item[1]}
})
console.log(this.cart, this.cartMenu)
this.$q.localStorage.set(`diagonAlley.carts.${this.stall.id}`, {
...this.cart,
products: Object.fromEntries(this.cart.products)
})
},
resetCart() {
this.cart = {
@ -133,6 +144,7 @@ async function customerStall(path) {
size: 0,
products: new Map()
}
this.$q.localStorage.remove(`diagonAlley.carts.${this.stall.id}`)
},
async downloadOrder() {
let created_at = Math.floor(Date.now() / 1000)
@ -181,6 +193,7 @@ async function customerStall(path) {
this.checkoutDialog.show = true
},
resetCheckout() {
this.loading = false
this.checkoutDialog = {
show: false,
data: {
@ -188,8 +201,22 @@ async function customerStall(path) {
}
}
},
openQrCodeDialog() {
this.qrCodeDialog = {
data: {
payment_request: null
},
dismissMsg: this.$q.notify({
message: 'Waiting for invoice from merchant...'
}),
show: true
}
},
closeQrCodeDialog() {
this.qrCodeDialog.show = false
setTimeout(() => {
this.qrCodeDialog.dismissMsg()
}, 1000)
},
async placeOrder() {
this.loading = true
@ -247,9 +274,6 @@ async function customerStall(path) {
await this.sendOrder(event)
},
async sendOrder(order) {
this.$q.notify({
message: 'Waiting for invoice from merchant...'
})
for (const url of Array.from(this.relays)) {
try {
let relay = NostrTools.relayInit(url)
@ -278,7 +302,7 @@ async function customerStall(path) {
}
this.loading = false
this.resetCart()
this.qrCodeDialog.show = true
this.openQrCodeDialog()
this.listenMessages()
},
async listenMessages() {
@ -319,7 +343,7 @@ async function customerStall(path) {
this.messageFilter(plaintext, cb => Promise.resolve(pool.close))
} catch {
console.error('Unable to decrypt message!')
console.debug('Unable to decrypt message! Probably not for us!')
}
})
} catch (err) {
@ -331,9 +355,8 @@ async function customerStall(path) {
let json = JSON.parse(text)
if (json.id != this.activeOrder) return
if (json.payment_options) {
let payment_request = json.payment_options.find(
o => o.type == 'ln'
).link
let payment_request = json.payment_options.find(o => o.type == 'ln')
.link
if (!payment_request) return
this.loading = false
this.qrCodeDialog.data.payment_request = payment_request
@ -359,6 +382,18 @@ async function customerStall(path) {
this.customerPubkey = this.account?.pubkey
this.customerPrivkey = this.account?.privkey
this.customerUseExtension = this.account?.useExtension
let storedCart = this.$q.localStorage.getItem(
`diagonAlley.carts.${this.stall.id}`
)
if (storedCart) {
this.cart.total = storedCart.total
this.cart.size = storedCart.size
this.cart.products = new Map(Object.entries(storedCart.products))
this.cartMenu = Array.from(this.cart.products, item => {
return {id: item[0], ...item[1]}
})
}
setTimeout(() => {
if (window.nostr) {
this.hasNip07 = true

View file

@ -77,6 +77,7 @@
View details
</q-btn>
<q-btn
v-if="!isStall"
flat
class="text-weight-bold text-capitalize q-ml-auto"
dense

View file

@ -11,11 +11,16 @@ const market = async () => {
]
const eventToObj = event => {
event.content = JSON.parse(event.content) || null
return {
...event,
...Object.values(event.tags).reduce((acc, tag) => {
let [key, value] = tag
return {...acc, [key]: [...(acc[key] || []), value]}
if (key == 't') {
return {...acc, [key]: [...(acc[key] || []), value]}
} else {
return {...acc, [key]: value}
}
}, {})
}
}
@ -55,7 +60,8 @@ const market = async () => {
inputRelay: null,
activePage: 'market',
activeStall: null,
activeProduct: null
activeProduct: null,
pool: null
}
},
computed: {
@ -209,13 +215,18 @@ const market = async () => {
this.products.forEach(p => products.set(p.id, p))
events.map(eventToObj).map(e => {
if (e.kind == 30018) {
if (e.kind == 0) {
this.profiles.set(e.pubkey, e.content)
if (e.pubkey == this.account?.pubkey) {
this.accountMetadata = this.profiles.get(this.account.pubkey)
}
return
} else if (e.kind == 30018) {
//it's a product `d` is the prod. id
products.set(e.d, {...e.content, id: e.d[0], categories: e.t})
products.set(e.d, {...e.content, id: e.d, categories: e.t})
} else if (e.kind == 30017) {
// it's a stall `d` is the stall id
stalls.set(e.d, {...e.content, id: e.d[0], pubkey: e.pubkey})
return
stalls.set(e.d, {...e.content, id: e.d, pubkey: e.pubkey})
}
})
@ -226,7 +237,7 @@ const market = async () => {
let stall = this.stalls.find(s => s.id == obj.stall_id)
if (!stall) return
obj.stallName = stall.name
obj.images = [obj.image]
obj.images = obj.images || [obj.image]
if (obj.currency != 'sat') {
obj.formatedPrice = this.getAmountFormated(
obj.price,
@ -241,10 +252,9 @@ const market = async () => {
this.$q.loading.show()
const pool = new NostrTools.SimplePool()
let relays = Array.from(this.relays)
let products = new Map()
let stalls = new Map()
// Get metadata and market data from the pubkeys
let sub = await pool
await pool
.list(relays, [
{
kinds: [0, 30017, 30018], // for production kind is 30017
@ -252,46 +262,31 @@ const market = async () => {
}
])
.then(async events => {
this.events = events || []
this.events.map(eventToObj).map(e => {
if (e.kind == 0) {
this.profiles.set(e.pubkey, e.content)
if (e.pubkey == this.account?.pubkey) {
this.accountMetadata = this.profiles.get(this.account.pubkey)
}
return
} else if (e.kind == 30018) {
//it's a product `d` is the prod. id
products.set(e.d, {...e.content, id: e.d[0], categories: e.t})
} else if (e.kind == 30017) {
// it's a stall `d` is the stall id
stalls.set(e.d, {...e.content, id: e.d[0], pubkey: e.pubkey})
return
}
})
if (!events || events.length == 0) return
await this.updateData(events)
})
await Promise.resolve(sub)
this.stalls = await Array.from(stalls.values())
this.products = Array.from(products.values())
.map(obj => {
let stall = this.stalls.find(s => s.id == obj.stall_id)
if (!stall) return
obj.stallName = stall.name
obj.images = [obj.image]
if (obj.currency != 'sat') {
obj.formatedPrice = this.getAmountFormated(
obj.price,
obj.currency
)
}
return obj
})
.filter(f => f)
this.$q.loading.hide()
pool.close(relays)
this.pool = pool
this.poolSubscribe()
return
},
async poolSubscribe() {
this.poolSub = this.pool.sub(Array.from(this.relays), [
{
kinds: [0, 30017, 30018],
authors: Array.from(this.pubkeys),
since: Date.now() / 1000
}
])
this.poolSub.on(
'event',
event => {
this.updateData([event])
},
{id: 'masterSub'} //pass ID to cancel previous sub
)
},
navigateTo(page, opts = {stall: null, product: null, pubkey: null}) {
let {stall, product, pubkey} = opts
let url = new URL(window.location)
@ -356,7 +351,7 @@ const market = async () => {
`diagonAlley.merchants`,
Array.from(this.pubkeys)
)
await this.initNostr()
this.initNostr()
},
removePubkey(pubkey) {
// Needs a hack for Vue reactivity
@ -368,7 +363,7 @@ const market = async () => {
`diagonAlley.merchants`,
Array.from(this.pubkeys)
)
Promise.resolve(this.initNostr())
this.initNostr()
},
async addRelay() {
let relay = String(this.inputRelay).trim()
@ -379,7 +374,7 @@ const market = async () => {
this.relays.add(relay)
this.$q.localStorage.set(`diagonAlley.relays`, Array.from(this.relays))
this.inputRelay = null
await this.initNostr()
this.initNostr()
},
removeRelay(relay) {
// Needs a hack for Vue reactivity
@ -387,6 +382,7 @@ const market = async () => {
relays.delete(relay)
this.relays = new Set(Array.from(relays))
this.$q.localStorage.set(`diagonAlley.relays`, Array.from(this.relays))
this.initNostr()
}
}
})

View file

@ -189,6 +189,7 @@
:product-detail="activeProduct"
:relays="relays"
:account="account"
:pool="pool"
@change-page="navigateTo"
></customer-stall>
<customer-market