refactor: remove legacy chat service, migrate chat-widget to Directus conversations
This commit is contained in:
@@ -1,45 +1,44 @@
|
||||
/**
|
||||
* Chat Widget Component
|
||||
* Embedded chat for buyer-seller communication
|
||||
* Embedded chat for buyer-seller communication using Directus conversations
|
||||
*/
|
||||
|
||||
import { t, i18n } from '../i18n.js'
|
||||
import { chatService } from '../services/chat.js'
|
||||
import { conversationsService } from '../services/conversations.js'
|
||||
import { cryptoService } from '../services/crypto.js'
|
||||
|
||||
class ChatWidget extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['listing-id', 'recipient-id', 'recipient-key', 'recipient-name']
|
||||
return ['listing-id', 'seller-public-key', 'recipient-name']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.chat = null
|
||||
this.conversation = null
|
||||
this.messages = []
|
||||
this.unsubscribe = null
|
||||
this.loading = true
|
||||
this.error = null
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
await cryptoService.ready
|
||||
|
||||
this.listingId = this.getAttribute('listing-id')
|
||||
this.recipientId = this.getAttribute('recipient-id')
|
||||
this.recipientKey = this.getAttribute('recipient-key')
|
||||
this.sellerPublicKey = this.getAttribute('seller-public-key')
|
||||
this.recipientName = this.getAttribute('recipient-name') || 'Seller'
|
||||
|
||||
if (this.listingId && this.recipientId && this.recipientKey) {
|
||||
this.chat = chatService.getOrCreateChat(
|
||||
this.recipientId,
|
||||
this.recipientKey,
|
||||
this.listingId
|
||||
)
|
||||
await this.loadMessages()
|
||||
this.render()
|
||||
|
||||
if (this.listingId && this.sellerPublicKey) {
|
||||
await this.initConversation()
|
||||
} else {
|
||||
this.loading = false
|
||||
this.error = 'missing-data'
|
||||
this.render()
|
||||
}
|
||||
|
||||
this.render()
|
||||
this.setupEventListeners()
|
||||
|
||||
this.unsubscribe = chatService.subscribe(() => this.refreshMessages())
|
||||
this.unsubscribe = conversationsService.subscribe(() => this.refreshMessages())
|
||||
this.i18nUnsubscribe = i18n.subscribe(() => this.render())
|
||||
}
|
||||
|
||||
@@ -48,9 +47,28 @@ class ChatWidget extends HTMLElement {
|
||||
if (this.i18nUnsubscribe) this.i18nUnsubscribe()
|
||||
}
|
||||
|
||||
async initConversation() {
|
||||
try {
|
||||
this.conversation = await conversationsService.startOrGetConversation(
|
||||
this.listingId,
|
||||
this.sellerPublicKey
|
||||
)
|
||||
await this.loadMessages()
|
||||
} catch (e) {
|
||||
console.error('Failed to init conversation:', e)
|
||||
this.error = 'init-failed'
|
||||
}
|
||||
this.loading = false
|
||||
this.render()
|
||||
this.setupEventListeners()
|
||||
}
|
||||
|
||||
async loadMessages() {
|
||||
if (!this.chat) return
|
||||
this.messages = await chatService.getMessages(this.chat.id, this.recipientKey)
|
||||
if (!this.conversation) return
|
||||
this.messages = await conversationsService.getMessages(
|
||||
this.conversation.id,
|
||||
this.conversation.otherPublicKey
|
||||
)
|
||||
}
|
||||
|
||||
async refreshMessages() {
|
||||
@@ -60,6 +78,28 @@ class ChatWidget extends HTMLElement {
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.loading) {
|
||||
this.innerHTML = /* html */`
|
||||
<div class="chat-widget">
|
||||
<div class="chat-loading">
|
||||
<span>${t('common.loading')}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
return
|
||||
}
|
||||
|
||||
if (this.error) {
|
||||
this.innerHTML = /* html */`
|
||||
<div class="chat-widget">
|
||||
<div class="chat-error">
|
||||
<p>${t('chat.unavailable')}</p>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
return
|
||||
}
|
||||
|
||||
this.innerHTML = /* html */`
|
||||
<div class="chat-widget">
|
||||
<div class="chat-header">
|
||||
@@ -129,15 +169,17 @@ class ChatWidget extends HTMLElement {
|
||||
const input = this.querySelector('#message-input')
|
||||
const text = input?.value.trim()
|
||||
|
||||
if (!text || !this.chat) return
|
||||
if (!text || !this.conversation) return
|
||||
|
||||
input.value = ''
|
||||
|
||||
await chatService.sendMessage(
|
||||
this.chat.id,
|
||||
this.recipientKey,
|
||||
await conversationsService.sendMessage(
|
||||
this.conversation.id,
|
||||
this.conversation.otherPublicKey,
|
||||
text
|
||||
)
|
||||
|
||||
await this.refreshMessages()
|
||||
}
|
||||
|
||||
scrollToBottom() {
|
||||
@@ -177,6 +219,17 @@ style.textContent = /* css */`
|
||||
background: var(--color-bg);
|
||||
}
|
||||
|
||||
chat-widget .chat-loading,
|
||||
chat-widget .chat-error {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-text-muted);
|
||||
text-align: center;
|
||||
padding: var(--space-lg);
|
||||
}
|
||||
|
||||
chat-widget .chat-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user