nostrmarket/static/components/direct-messages.js
PatMulligan 33c62ba1ea CHORE: Improve UI (#112)
* Refactor merchant details layout for improved responsiveness and styling in index.html

* Revamp key pair component layout with improved styling and functionality. Added a header with a toggle for showing the private key, enhanced QR code display for both public and private keys, and included copy buttons for better user interaction.

Update key pair component styling and functionality: adjust QR code dimensions, improve key display format with truncation, and refine button margins for enhanced user experience.

Add 'show-buttons' prop to QR code components in key pair template for improved functionality

Update key pair component layout to use 'col-sm-6' for responsive design of QR code sections, enhancing display on smaller screens.

* Enhance direct messages component layout with improved styling and responsiveness. Updated class names for better alignment, added ellipsis for long customer labels, and modified button styles for consistency. Improved select options display with custom templates for better user experience.

* Refactor customer label generation in direct messages component for improved readability. Added checks for undefined customer data, enhanced label formatting with truncation for long descriptions, and adjusted unread message display format.

* make format
2025-09-15 09:48:13 +03:00

173 lines
4.7 KiB
JavaScript

window.app.component('direct-messages', {
name: 'direct-messages',
props: ['active-chat-customer', 'merchant-id', 'adminkey', 'inkey'],
template: '#direct-messages',
delimiters: ['${', '}'],
watch: {
activeChatCustomer: async function (n) {
this.activePublicKey = n
},
activePublicKey: async function (n) {
await this.getDirectMessages(n)
}
},
computed: {
messagesAsJson: function () {
return this.messages.map(m => {
const dateFrom = moment(m.event_created_at * 1000).fromNow()
try {
const message = JSON.parse(m.message)
return {
isJson: message.type >= 0,
dateFrom,
...m,
message
}
} catch (error) {
return {
isJson: false,
dateFrom,
...m,
message: m.message
}
}
})
}
},
data: function () {
return {
customers: [],
unreadMessages: 0,
activePublicKey: null,
messages: [],
newMessage: '',
showAddPublicKey: false,
newPublicKey: null,
showRawMessage: false,
rawMessage: null
}
},
methods: {
sendMessage: async function () {},
buildCustomerLabel: function (c) {
if (!c) return ''
let label = c.profile.name || 'unknown'
if (c.profile.about) {
label += ` - ${c.profile.about.substring(0, 30)}`
if (c.profile.about.length > 30) label += '...'
}
if (c.unread_messages) {
label = `[${c.unread_messages} new] ${label}`
}
label += ` (${c.public_key.slice(0, 8)}...${c.public_key.slice(-8)})`
return label
},
getDirectMessages: async function (pubkey) {
if (!pubkey) {
this.messages = []
return
}
try {
const {data} = await LNbits.api.request(
'GET',
'/nostrmarket/api/v1/message/' + pubkey,
this.inkey
)
this.messages = data
this.focusOnChatBox(this.messages.length - 1)
} catch (error) {
LNbits.utils.notifyApiError(error)
}
},
getCustomers: async function () {
try {
const {data} = await LNbits.api.request(
'GET',
'/nostrmarket/api/v1/customer',
this.inkey
)
this.customers = data
this.unreadMessages = data.filter(c => c.unread_messages).length
} catch (error) {
LNbits.utils.notifyApiError(error)
}
},
sendDirectMesage: async function () {
try {
const {data} = await LNbits.api.request(
'POST',
'/nostrmarket/api/v1/message',
this.adminkey,
{
message: this.newMessage,
public_key: this.activePublicKey
}
)
this.messages = this.messages.concat([data])
this.newMessage = ''
this.focusOnChatBox(this.messages.length - 1)
} catch (error) {
LNbits.utils.notifyApiError(error)
}
},
addPublicKey: async function () {
try {
const {data} = await LNbits.api.request(
'POST',
'/nostrmarket/api/v1/customer',
this.adminkey,
{
public_key: this.newPublicKey,
merchant_id: this.merchantId,
unread_messages: 0
}
)
this.newPublicKey = null
this.activePublicKey = data.public_key
await this.selectActiveCustomer()
} catch (error) {
LNbits.utils.notifyApiError(error)
} finally {
this.showAddPublicKey = false
}
},
handleNewMessage: async function (data) {
if (data.customerPubkey === this.activePublicKey) {
this.messages.push(data.dm)
this.focusOnChatBox(this.messages.length - 1)
// focus back on input box
}
this.getCustomersDebounced()
},
showOrderDetails: function (orderId, eventId) {
this.$emit('order-selected', {orderId, eventId})
},
showClientOrders: function () {
this.$emit('customer-selected', this.activePublicKey)
},
selectActiveCustomer: async function () {
await this.getDirectMessages(this.activePublicKey)
await this.getCustomers()
},
showMessageRawData: function (index) {
this.rawMessage = this.messages[index]?.message
this.showRawMessage = true
},
focusOnChatBox: function (index) {
setTimeout(() => {
const lastChatBox = document.getElementsByClassName(
`chat-mesage-index-${index}`
)
if (lastChatBox && lastChatBox[0]) {
lastChatBox[0].scrollIntoView()
}
}, 100)
}
},
created: async function () {
await this.getCustomers()
this.getCustomersDebounced = _.debounce(this.getCustomers, 2000, false)
}
})