fix: breadcrumbs

This commit is contained in:
Vlad Stan 2023-07-05 15:54:13 +03:00
parent 6c02e58f84
commit ff9891302a
4 changed files with 67 additions and 55 deletions

View file

@ -24,11 +24,7 @@
<q-banner v-if="styles?.ui?.banner" class="row q-pa-none q-mb-md"> <q-banner v-if="styles?.ui?.banner" class="row q-pa-none q-mb-md">
<q-img :src="styles.ui.banner" style="width: 100%; height: 250px" cover></q-img> <q-img :src="styles.ui.banner" style="width: 100%; height: 250px" cover></q-img>
</q-banner> </q-banner>
<q-toolbar>
<q-breadcrumbs>
<q-breadcrumbs-el :label="styles.name ?? 'Market'" icon="home"></q-breadcrumbs-el>
</q-breadcrumbs>
</q-toolbar>
<div class="row q-col-gutter-md"> <div class="row q-col-gutter-md">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3" v-for="(item, idx) in products" :key="idx"> <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3" v-for="(item, idx) in products" :key="idx">
<product-card :product="item" @change-page="changePageM"></product-card> <product-card :product="item" @change-page="changePageM"></product-card>

View file

@ -1,10 +1,6 @@
<div> <div>
<q-toolbar> <q-toolbar>
<q-breadcrumbs class="cursor">
<q-breadcrumbs-el :label="styles.name ?? 'Market'" icon="home" @click="$emit('change-page', 'market')"
style="cursor: pointer"></q-breadcrumbs-el>
<q-breadcrumbs-el :label="stall?.name || 'Stall'" icon="widgets"></q-breadcrumbs-el>
</q-breadcrumbs>
<q-toolbar-title></q-toolbar-title> <q-toolbar-title></q-toolbar-title>
<chat-dialog v-if="this.customerPrivkey || this.customerUseExtension" :account="account ? account : dropIn" <chat-dialog v-if="this.customerPrivkey || this.customerUseExtension" :account="account ? account : dropIn"
:merchant="stall.pubkey" :relays="relays" :pool="pool" /> :merchant="stall.pubkey" :relays="relays" :pool="pool" />

View file

@ -17,9 +17,9 @@ const market = async () => {
...Object.values(event.tags).reduce((acc, tag) => { ...Object.values(event.tags).reduce((acc, tag) => {
let [key, value] = tag let [key, value] = tag
if (key == 't') { if (key == 't') {
return {...acc, [key]: [...(acc[key] || []), value]} return { ...acc, [key]: [...(acc[key] || []), value] }
} else { } else {
return {...acc, [key]: value} return { ...acc, [key]: value }
} }
}, {}) }, {})
} }
@ -115,12 +115,12 @@ const market = async () => {
isValidKey() { isValidKey() {
let key = this.accountDialog.data.key let key = this.accountDialog.data.key
if (key && key.startsWith('n')) { if (key && key.startsWith('n')) {
let {type, data} = NostrTools.nip19.decode(key) let { type, data } = NostrTools.nip19.decode(key)
key = data key = data
} }
return key?.toLowerCase()?.match(/^[0-9a-f]{64}$/) return key?.toLowerCase()?.match(/^[0-9a-f]{64}$/)
}, },
canEditConfig(){ canEditConfig() {
return this.account && this.account.pubkey == this.config?.pubkey return this.account && this.account.pubkey == this.config?.pubkey
} }
}, },
@ -154,10 +154,10 @@ const market = async () => {
let product_id = params.get('product_id') let product_id = params.get('product_id')
let naddr = params.get('naddr') let naddr = params.get('naddr')
if(naddr) { if (naddr) {
try { try {
let {type, data} = NostrTools.nip19.decode(naddr) let { type, data } = NostrTools.nip19.decode(naddr)
if(type == 'naddr' && data.kind == '30019') { // just double check if (type == 'naddr' && data.kind == '30019') { // just double check
this.config = { this.config = {
d: data.identifier, d: data.identifier,
pubkey: data.pubkey, pubkey: data.pubkey,
@ -165,7 +165,7 @@ const market = async () => {
} }
} }
this.naddr = naddr this.naddr = naddr
}catch (err){ } catch (err) {
console.error(err) console.error(err)
} }
} }
@ -211,9 +211,9 @@ const market = async () => {
nip07 = true nip07 = true
} }
if (this.isValidKey) { if (this.isValidKey) {
let {key, watchOnly} = this.accountDialog.data let { key, watchOnly } = this.accountDialog.data
if (key.startsWith('n')) { if (key.startsWith('n')) {
let {type, data} = NostrTools.nip19.decode(key) let { type, data } = NostrTools.nip19.decode(key)
key = data key = data
} }
this.$q.localStorage.set('diagonAlley.account', { this.$q.localStorage.set('diagonAlley.account', {
@ -241,42 +241,42 @@ const market = async () => {
openAccountDialog() { openAccountDialog() {
this.accountDialog.show = true this.accountDialog.show = true
}, },
editConfigDialog(){ editConfigDialog() {
if(this.canEditConfig && this.config?.opts){ if (this.canEditConfig && this.config?.opts) {
let {name, about, ui} = this.config.opts let { name, about, ui } = this.config.opts
this.configDialog.data = {name, about, ui} this.configDialog.data = { name, about, ui }
this.configDialog.data.identifier = this.config?.d this.configDialog.data.identifier = this.config?.d
} }
this.openConfigDialog() this.openConfigDialog()
}, },
openConfigDialog() { openConfigDialog() {
if(!this.account){ if (!this.account) {
this.$q.notify({ this.$q.notify({
message: `You need to be logged in first.`, message: `You need to be logged in first.`,
color: 'negative', color: 'negative',
icon: 'warning' icon: 'warning'
}) })
return return
} }
this.configDialog.show = true this.configDialog.show = true
}, },
async sendConfig() { async sendConfig() {
let {name, about, ui} = this.configDialog.data let { name, about, ui } = this.configDialog.data
let merchants = Array.from(this.pubkeys) let merchants = Array.from(this.pubkeys)
let identifier = this.configDialog.data.identifier ?? crypto.randomUUID() let identifier = this.configDialog.data.identifier ?? crypto.randomUUID()
let event = { let event = {
...(await NostrTools.getBlankEvent()), ...(await NostrTools.getBlankEvent()),
kind: 30019, kind: 30019,
content: JSON.stringify({name, about, ui, merchants}), content: JSON.stringify({ name, about, ui, merchants }),
created_at: Math.floor(Date.now() / 1000), created_at: Math.floor(Date.now() / 1000),
tags: [['d', identifier]], tags: [['d', identifier]],
pubkey: this.account.pubkey pubkey: this.account.pubkey
} }
event.id = NostrTools.getEventHash(event) event.id = NostrTools.getEventHash(event)
try { try {
if(this.account.useExtension){ if (this.account.useExtension) {
event = await window.nostr.signEvent(event) event = await window.nostr.signEvent(event)
}else if (this.account.privkey) { } else if (this.account.privkey) {
event.sig = await NostrTools.signEvent(event, this.account.privkey) event.sig = await NostrTools.signEvent(event, this.account.privkey)
} }
let pub = this.pool.publish(Array.from(this.relays), event) let pub = this.pool.publish(Array.from(this.relays), event)
@ -299,20 +299,22 @@ const market = async () => {
}) })
this.config = this.configDialog.data this.config = this.configDialog.data
this.resetConfig() this.resetConfig()
return return
}, },
resetConfig() { resetConfig() {
this.configDialog = {show: false, this.configDialog = {
show: false,
identifier: null, identifier: null,
data: { data: {
name: null, name: null,
about: null, about: null,
ui: { ui: {
picture: null, picture: null,
banner: null, banner: null,
theme: null theme: null
}
} }
}} }
}, },
async updateData(events) { async updateData(events) {
if (events.length < 1) { if (events.length < 1) {
@ -336,10 +338,10 @@ const market = async () => {
return return
} else if (e.kind == 30018) { } else if (e.kind == 30018) {
//it's a product `d` is the prod. id //it's a product `d` is the prod. id
products.set(e.d, {...e.content, id: e.d, categories: e.t}) products.set(e.d, { ...e.content, id: e.d, categories: e.t })
} else if (e.kind == 30017) { } else if (e.kind == 30017) {
// it's a stall `d` is the stall id // it's a stall `d` is the stall id
stalls.set(e.d, {...e.content, id: e.d, pubkey: e.pubkey}) stalls.set(e.d, { ...e.content, id: e.d, pubkey: e.pubkey })
} }
}) })
@ -364,9 +366,9 @@ const market = async () => {
async initNostr() { async initNostr() {
this.$q.loading.show() this.$q.loading.show()
const pool = new NostrTools.SimplePool() const pool = new NostrTools.SimplePool()
// If there is an naddr in the URL, get it and parse content // If there is an naddr in the URL, get it and parse content
if (this.config) { if (this.config) {
// add relays to the set // add relays to the set
this.config.relays.forEach(r => this.relays.add(r)) this.config.relays.forEach(r => this.relays.add(r))
await pool.get(this.config.relays, { await pool.get(this.config.relays, {
@ -375,17 +377,17 @@ const market = async () => {
authors: [this.config.pubkey], authors: [this.config.pubkey],
'#d': [this.config.d] '#d': [this.config.d]
}).then(event => { }).then(event => {
if(!event) return if (!event) return
let content = JSON.parse(event.content) let content = JSON.parse(event.content)
this.config = {... this.config, opts: content} this.config = { ... this.config, opts: content }
// add merchants // add merchants
this.config.opts?.merchants.forEach(m => this.pubkeys.add(m)) this.config.opts?.merchants.forEach(m => this.pubkeys.add(m))
// change theme // change theme
let {theme} = this.config.opts?.ui let { theme } = this.config.opts?.ui
theme && document.body.setAttribute('data-theme', theme) theme && document.body.setAttribute('data-theme', theme)
}).catch(err => console.error(err)) }).catch(err => console.error(err))
} }
let relays = Array.from(this.relays) let relays = Array.from(this.relays)
// Get metadata and market data from the pubkeys // Get metadata and market data from the pubkeys
@ -419,11 +421,12 @@ const market = async () => {
event => { event => {
this.updateData([event]) this.updateData([event])
}, },
{id: 'masterSub'} //pass ID to cancel previous sub { id: 'masterSub' } //pass ID to cancel previous sub
) )
}, },
navigateTo(page, opts = {stall: null, product: null, pubkey: null}) { navigateTo(page, opts = { stall: null, product: null, pubkey: null }) {
let {stall, product, pubkey} = opts console.log("### navigateTo", page, opts)
let { stall, product, pubkey } = opts
let url = new URL(window.location) let url = new URL(window.location)
if (pubkey) url.searchParams.set('merchant_pubkey', pubkey) if (pubkey) url.searchParams.set('merchant_pubkey', pubkey)
@ -437,8 +440,9 @@ const market = async () => {
if (stall) { if (stall) {
this.activeStall = stall this.activeStall = stall
url.searchParams.set('stall_id', stall) url.searchParams.set('stall_id', stall)
this.activeProduct = product
if (product) { if (product) {
this.activeProduct = product
url.searchParams.set('product_id', product) url.searchParams.set('product_id', product)
} }
} }
@ -474,7 +478,7 @@ const market = async () => {
let regExp = /^#([0-9a-f]{3}){1,2}$/i let regExp = /^#([0-9a-f]{3}){1,2}$/i
if (pubkey.startsWith('n')) { if (pubkey.startsWith('n')) {
try { try {
let {type, data} = NostrTools.nip19.decode(pubkey) let { type, data } = NostrTools.nip19.decode(pubkey)
if (type === 'npub') pubkey = data if (type === 'npub') pubkey = data
else if (type === 'nprofile') { else if (type === 'nprofile') {
pubkey = data.pubkey pubkey = data.pubkey

View file

@ -184,6 +184,20 @@
</q-toolbar> </q-toolbar>
</div> </div>
<div class="q-mt-xl">
<q-breadcrumbs class="cursor">
<q-breadcrumbs-el :label="'Market'" icon="home" @click="navigateTo('market')"
class="cursor-pointer"></q-breadcrumbs-el>
<q-breadcrumbs-el v-if="activeStall" :label="stallName" @click="navigateTo('stall', {stall: activeStall})"
icon="widgets" class="cursor-pointer"></q-breadcrumbs-el>
<q-breadcrumbs-el v-if="activeProduct" :label="productName"
@click="navigateTo('product', {product: activeStall})" class="cursor-pointer"
icon="widgets"></q-breadcrumbs-el>
</q-breadcrumbs>
</div>
<q-separator class="q-mt-md q-mb-md"></q-separator>
<market-config v-if="showMarketConfig"></market-config> <market-config v-if="showMarketConfig"></market-config>
<customer-stall v-else-if="!isLoading && activeStall" :stall="stalls.find(stall => stall.id == activeStall)" <customer-stall v-else-if="!isLoading && activeStall" :stall="stalls.find(stall => stall.id == activeStall)"
:products="filterProducts" :stall-products="products.filter(p => p.stall_id == activeStall)" :products="filterProducts" :stall-products="products.filter(p => p.stall_id == activeStall)"
@ -191,7 +205,9 @@
@login-dialog="openAccountDialog" @change-page="navigateTo"></customer-stall> @login-dialog="openAccountDialog" @change-page="navigateTo"></customer-stall>
<customer-market v-else :search-nostr="searchNostr" :relays="relays" :products="filterProducts" <customer-market v-else :search-nostr="searchNostr" :relays="relays" :products="filterProducts"
:styles="config?.opts ?? {}" @change-page="navigateTo" @update-data="updateData"></customer-market> :styles="config?.opts ?? {}" @change-page="navigateTo" @update-data="updateData"></customer-market>
</q-page-container> </q-page-container>
<!-- ACCOUNT DIALOG --> <!-- ACCOUNT DIALOG -->
<q-dialog v-model="accountDialog.show" persistent> <q-dialog v-model="accountDialog.show" persistent>
<q-card style="min-width: 350px"> <q-card style="min-width: 350px">