diff --git a/crud.py b/crud.py index 3917270..a939f52 100644 --- a/crud.py +++ b/crud.py @@ -448,6 +448,14 @@ async def get_orders_for_stall(merchant_id: str, stall_id: str) -> List[Order]: return [Order.from_row(row) for row in rows] +async def get_public_keys_for_orders(merchant_id: str) -> List[str]: + rows = await db.fetchall( + "SELECT DISTINCT public_key FROM nostrmarket.orders WHERE merchant_id = ?", + (merchant_id,), + ) + return [row[0] for row in rows] + + async def get_last_order_time(public_key: str) -> int: row = await db.fetchone( """ @@ -572,3 +580,11 @@ async def delete_merchant_direct_messages(merchant_id: str) -> None: "DELETE FROM nostrmarket.direct_messages WHERE merchant_id = ?", (merchant_id,), ) + + +async def get_public_keys_for_direct_messages(merchant_id: str) -> List[str]: + rows = await db.fetchall( + "SELECT DISTINCT public_key FROM nostrmarket.direct_messages WHERE merchant_id = ?", + (merchant_id), + ) + return [row[0] for row in rows] diff --git a/helpers.py b/helpers.py index d06598d..390fd7f 100644 --- a/helpers.py +++ b/helpers.py @@ -61,7 +61,6 @@ def test_decrypt_encrypt(encoded_message: str, encryption_key): assert ( encoded_message == ecrypted_msg ), f"expected '{encoded_message}', but got '{ecrypted_msg}'" - print("### test_decrypt_encrypt", encoded_message == ecrypted_msg) ffi = FFI() diff --git a/nostr/nostr_client.py b/nostr/nostr_client.py index e47af98..6a29d2c 100644 --- a/nostr/nostr_client.py +++ b/nostr/nostr_client.py @@ -46,7 +46,6 @@ class NostrClient: logger.info("Connected to 'nostrclient' websocket") def on_message(_, message): - # print("### on_message", message) self.recieve_event_queue.put_nowait(message) while True: @@ -66,7 +65,6 @@ class NostrClient: await asyncio.sleep(5) async def publish_nostr_event(self, e: NostrEvent): - print("### publish_nostr_event", e.dict()) await self.send_req_queue.put(["EVENT", e.dict()]) async def subscribe_to_direct_messages(self, public_key: str, since: int): @@ -75,8 +73,6 @@ class NostrClient: if since != 0: in_messages_filter["since"] = since out_messages_filter["since"] = since - print("### in_messages_filter", in_messages_filter) - print("### out_messages_filter", out_messages_filter) await self.send_req_queue.put( ["REQ", f"direct-messages-in:{public_key}", in_messages_filter] diff --git a/services.py b/services.py index 13f5154..f3f5fc3 100644 --- a/services.py +++ b/services.py @@ -191,7 +191,6 @@ async def process_nostr_message(msg: str): await _handle_nip04_message(merchant_public_key, event) return except Exception as ex: - print("####### bad message", msg) logger.warning(ex) @@ -199,7 +198,6 @@ async def _handle_nip04_message(merchant_public_key: str, event: NostrEvent): merchant = await get_merchant_by_pubkey(merchant_public_key) assert merchant, f"Merchant not found for public key '{merchant_public_key}'" - # print("### clear_text_msg", subscription_name, clear_text_msg) if event.pubkey == merchant_public_key: assert len(event.tag_values("p")) != 0, "Outgong message has no 'p' tag" clear_text_msg = merchant.decrypt_message( @@ -260,7 +258,6 @@ async def _handle_dirrect_message( order["event_created_at"] = event_created_at return await _handle_new_order(PartialOrder(**order)) else: - # print("### text_msg", text_msg, event_created_at, event_id) dm = PartialDirectMessage( event_id=event_id, event_created_at=event_created_at, diff --git a/static/components/direct-messages/direct-messages.html b/static/components/direct-messages/direct-messages.html index 17cf401..43a81ac 100644 --- a/static/components/direct-messages/direct-messages.html +++ b/static/components/direct-messages/direct-messages.html @@ -7,13 +7,14 @@ - + @input="selectActiveCustomer()" + > +
diff --git a/static/components/direct-messages/direct-messages.js b/static/components/direct-messages/direct-messages.js index 9020cad..96112d9 100644 --- a/static/components/direct-messages/direct-messages.js +++ b/static/components/direct-messages/direct-messages.js @@ -2,27 +2,32 @@ async function directMessages(path) { const template = await loadTemplateAsync(path) Vue.component('direct-messages', { name: 'direct-messages', - props: ['adminkey', 'inkey'], + props: ['active-public-key', 'adminkey', 'inkey'], template, + watch: { + activePublicKey: async function (n) { + await this.getDirectMessages(n) + } + }, data: function () { return { - activePublicKey: - '186895a32209c3a92f0efaa7c65c3f8da690c75b952b815718c0d55d3eed821e', + customersPublicKeys: [], messages: [], newMessage: '' } }, methods: { sendMessage: async function () {}, - getDirectMessages: async function () { - if (!this.activePublicKey) { + getDirectMessages: async function (pubkey) { + if (!pubkey) { + this.messages = [] return } try { const {data} = await LNbits.api.request( 'GET', - '/nostrmarket/api/v1/message/' + this.activePublicKey, + '/nostrmarket/api/v1/message/' + pubkey, this.inkey ) this.messages = data @@ -35,6 +40,18 @@ async function directMessages(path) { LNbits.utils.notifyApiError(error) } }, + getCustomersPublicKeys: async function () { + try { + const {data} = await LNbits.api.request( + 'GET', + '/nostrmarket/api/v1/customers', + this.inkey + ) + this.customersPublicKeys = data + } catch (error) { + LNbits.utils.notifyApiError(error) + } + }, sendDirectMesage: async function () { try { const {data} = await LNbits.api.request( @@ -47,13 +64,15 @@ async function directMessages(path) { } ) this.messages = this.messages.concat([data]) - console.log('### this.messages', this.messages) this.newMessage = '' this.focusOnChatBox(this.messages.length - 1) } catch (error) { LNbits.utils.notifyApiError(error) } }, + selectActiveCustomer: async function () { + await this.getDirectMessages(this.activePublicKey) + }, focusOnChatBox: function (index) { setTimeout(() => { const lastChatBox = document.getElementsByClassName( @@ -66,7 +85,7 @@ async function directMessages(path) { } }, created: async function () { - await this.getDirectMessages() + await this.getCustomersPublicKeys() } }) } diff --git a/static/components/order-list/order-list.html b/static/components/order-list/order-list.html index cdac035..2f53051 100644 --- a/static/components/order-list/order-list.html +++ b/static/components/order-list/order-list.html @@ -44,7 +44,12 @@ - {{toShortId(props.row.public_key)}} + + {{toShortId(props.row.public_key)}} + {{formatDate(props.row.time)}} diff --git a/static/components/order-list/order-list.js b/static/components/order-list/order-list.js index 482cc8a..e325fa5 100644 --- a/static/components/order-list/order-list.js +++ b/static/components/order-list/order-list.js @@ -45,7 +45,7 @@ async function orderList(path) { field: 'shipped' }, { - name: 'pubkey', + name: 'public_key', align: 'left', label: 'Customer', field: 'pubkey' @@ -91,13 +91,11 @@ async function orderList(path) { this.inkey ) this.orders = data.map(s => ({...s, expanded: false})) - console.log('### this.orders', this.orders) } catch (error) { LNbits.utils.notifyApiError(error) } }, updateOrderShipped: async function () { - console.log('### order', this.selectedOrder) this.selectedOrder.shipped = !this.selectedOrder.shipped try { await LNbits.api.request( @@ -128,6 +126,9 @@ async function orderList(path) { // do not change the status yet this.selectedOrder.shipped = !order.shipped this.showShipDialog = true + }, + customerSelected: function (customerPubkey) { + this.$emit('customer-selected', customerPubkey) } }, created: async function () { diff --git a/static/components/shipping-zones/shipping-zones.js b/static/components/shipping-zones/shipping-zones.js index 71e3ae6..173d713 100644 --- a/static/components/shipping-zones/shipping-zones.js +++ b/static/components/shipping-zones/shipping-zones.js @@ -102,13 +102,11 @@ async function shippingZones(path) { this.inkey ) this.zones = data - console.log('### data', data) } catch (error) { LNbits.utils.notifyApiError(error) } }, sendZoneFormData: async function () { - console.log('### data', this.zoneDialog.data) this.zoneDialog.showDialog = false if (this.zoneDialog.data.id) { await this.updateShippingZone(this.zoneDialog.data) @@ -118,7 +116,6 @@ async function shippingZones(path) { await this.getZones() }, createShippingZone: async function (newZone) { - console.log('### newZone', newZone) try { await LNbits.api.request( 'POST', diff --git a/static/components/stall-details/stall-details.html b/static/components/stall-details/stall-details.html index 4239f68..9b5741d 100644 --- a/static/components/stall-details/stall-details.html +++ b/static/components/stall-details/stall-details.html @@ -190,6 +190,7 @@ :adminkey="adminkey" :inkey="inkey" :stall-id="stallId" + @customer-selected="customerSelectedForOrder" >
diff --git a/static/components/stall-details/stall-details.js b/static/components/stall-details/stall-details.js index e687a67..d488e98 100644 --- a/static/components/stall-details/stall-details.js +++ b/static/components/stall-details/stall-details.js @@ -119,8 +119,6 @@ async function stallDetails(path) { this.inkey ) this.stall = this.mapStall(data) - - console.log('### this.stall', this.stall) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -197,8 +195,6 @@ async function stallDetails(path) { this.inkey ) this.products = data - - console.log('### this.products', this.products) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -305,6 +301,9 @@ async function stallDetails(path) { } } this.productDialog.showDialog = true + }, + customerSelectedForOrder: function (customerPubkey) { + this.$emit('customer-selected-for-order', customerPubkey) } }, created: async function () { diff --git a/static/components/stall-list/stall-list.html b/static/components/stall-list/stall-list.html index ea738bf..bd63551 100644 --- a/static/components/stall-list/stall-list.html +++ b/static/components/stall-list/stall-list.html @@ -46,9 +46,7 @@ - - {{props.row.name}} + {{props.row.name}} {{props.row.currency}} @@ -74,6 +72,7 @@ :currencies="currencies" @stall-deleted="handleStallDeleted" @stall-updated="handleStallUpdated" + @customer-selected-for-order="customerSelectedForOrder" > diff --git a/static/components/stall-list/stall-list.js b/static/components/stall-list/stall-list.js index d41c062..dca7fb9 100644 --- a/static/components/stall-list/stall-list.js +++ b/static/components/stall-list/stall-list.js @@ -170,6 +170,9 @@ async function stallList(path) { shippingZones: [] } this.stallDialog.show = true + }, + customerSelectedForOrder: function (customerPubkey) { + this.$emit('customer-selected-for-order', customerPubkey) } }, created: async function () { diff --git a/static/js/index.js b/static/js/index.js index d530977..75e6f01 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -20,6 +20,7 @@ const merchant = async () => { return { merchant: {}, shippingZones: [], + activeChatCustomer: '', showKeys: false, importKeyDialog: { show: false, @@ -92,6 +93,9 @@ const merchant = async () => { } catch (error) { LNbits.utils.notifyApiError(error) } + }, + customerSelectedForOrder: function (customerPubkey) { + this.activeChatCustomer = customerPubkey } }, created: async function () { diff --git a/templates/nostrmarket/index.html b/templates/nostrmarket/index.html index 32d0ca0..8907395 100644 --- a/templates/nostrmarket/index.html +++ b/templates/nostrmarket/index.html @@ -37,6 +37,7 @@ :adminkey="g.user.wallets[0].adminkey" :inkey="g.user.wallets[0].inkey" :wallet-options="g.user.walletOptions" + @customer-selected-for-order="customerSelectedForOrder" >
@@ -114,6 +115,7 @@
diff --git a/views_api.py b/views_api.py index 1934b42..cefac0a 100644 --- a/views_api.py +++ b/views_api.py @@ -39,6 +39,8 @@ from .crud import ( get_orders_for_stall, get_product, get_products, + get_public_keys_for_direct_messages, + get_public_keys_for_orders, get_stall, get_stalls, get_zone, @@ -643,14 +645,11 @@ async def api_update_order_status( try: assert data.shipped != None, "Shipped value is required for order" merchant = await get_merchant_for_user(wallet.wallet.user) - assert merchant, "Merchant cannot be found" + assert merchant, "Merchant cannot be found for order {data.id}" order = await update_order_shipped_status(merchant.id, data.id, data.shipped) assert order, "Cannot find updated order" - merchant = await get_merchant_for_user(merchant.id) - assert merchant, f"Merchant cannot be found for order {data.id}" - data.paid = order.paid dm_content = json.dumps(data.dict(), separators=(",", ":"), ensure_ascii=False) @@ -727,6 +726,35 @@ async def api_create_message( ) +######################################## CUSTOMERS ######################################## + + +@nostrmarket_ext.get("/api/v1/customers") +async def api_create_message( + wallet: WalletTypeInfo = Depends(get_key_type), +) -> DirectMessage: + try: + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, f"Merchant cannot be found" + + dm_pubkeys = await get_public_keys_for_direct_messages(merchant.id) + orders_pubkeys = await get_public_keys_for_orders(merchant.id) + + return list(dict.fromkeys(dm_pubkeys + orders_pubkeys)) + + except AssertionError as ex: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, + detail=str(ex), + ) + except Exception as ex: + logger.warning(ex) + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="Cannot create message", + ) + + ######################################## OTHER ########################################