feat: implement seller-join flow for E2E chat with pending conversation discovery
This commit is contained in:
@@ -10,7 +10,7 @@ import { escapeHTML } from '../utils/helpers.js'
|
||||
|
||||
class ChatWidget extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['listing-id', 'seller-public-key', 'recipient-name']
|
||||
return ['listing-id', 'recipient-name']
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -20,27 +20,13 @@ class ChatWidget extends HTMLElement {
|
||||
this.unsubscribe = null
|
||||
this.loading = true
|
||||
this.error = null
|
||||
this._initialized = false
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
await cryptoService.ready
|
||||
|
||||
connectedCallback() {
|
||||
this.listingId = this.getAttribute('listing-id')
|
||||
this.sellerPublicKey = this.getAttribute('seller-public-key')
|
||||
this.recipientName = this.getAttribute('recipient-name') || 'Seller'
|
||||
|
||||
this.render()
|
||||
|
||||
if (this.listingId && this.sellerPublicKey) {
|
||||
await this.initConversation()
|
||||
} else {
|
||||
this.loading = false
|
||||
this.error = 'missing-data'
|
||||
this.render()
|
||||
}
|
||||
|
||||
this.unsubscribe = conversationsService.subscribe(() => this.refreshMessages())
|
||||
this.i18nUnsubscribe = i18n.subscribe(() => this.render())
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
@@ -48,12 +34,34 @@ class ChatWidget extends HTMLElement {
|
||||
if (this.i18nUnsubscribe) this.i18nUnsubscribe()
|
||||
}
|
||||
|
||||
async activate() {
|
||||
if (this._initialized) return
|
||||
this._initialized = true
|
||||
|
||||
await cryptoService.ready
|
||||
|
||||
if (!cryptoService.getPublicKey()) {
|
||||
this.loading = false
|
||||
this.error = 'no-keypair'
|
||||
this.render()
|
||||
return
|
||||
}
|
||||
|
||||
if (this.listingId) {
|
||||
await this.initConversation()
|
||||
} else {
|
||||
this.loading = false
|
||||
this.error = 'missing-data'
|
||||
this.render()
|
||||
}
|
||||
|
||||
this.unsubscribe = conversationsService.subscribe(() => this.refreshMessages())
|
||||
this.i18nUnsubscribe = i18n.subscribe(() => this.render())
|
||||
}
|
||||
|
||||
async initConversation() {
|
||||
try {
|
||||
this.conversation = await conversationsService.startOrGetConversation(
|
||||
this.listingId,
|
||||
this.sellerPublicKey
|
||||
)
|
||||
this.conversation = await conversationsService.startOrFindByListing(this.listingId)
|
||||
await this.loadMessages()
|
||||
} catch (e) {
|
||||
console.error('Failed to init conversation:', e)
|
||||
@@ -101,6 +109,8 @@ class ChatWidget extends HTMLElement {
|
||||
return
|
||||
}
|
||||
|
||||
const pending = this.conversation && !this.conversation.otherPublicKey
|
||||
|
||||
this.innerHTML = /* html */`
|
||||
<div class="chat-widget">
|
||||
<div class="chat-header">
|
||||
@@ -109,17 +119,20 @@ class ChatWidget extends HTMLElement {
|
||||
</div>
|
||||
|
||||
<div class="chat-messages" id="chat-messages">
|
||||
${this.renderMessagesHtml()}
|
||||
${pending
|
||||
? /* html */`<div class="chat-empty"><p>${t('chat.pending')}</p></div>`
|
||||
: this.renderMessagesHtml()}
|
||||
</div>
|
||||
|
||||
<form class="chat-input" id="chat-form">
|
||||
<input
|
||||
type="text"
|
||||
id="message-input"
|
||||
placeholder="${t('chat.placeholder')}"
|
||||
placeholder="${pending ? t('chat.pendingHint') : t('chat.placeholder')}"
|
||||
autocomplete="off"
|
||||
${pending ? 'disabled' : ''}
|
||||
>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<button type="submit" class="btn btn-primary" ${pending ? 'disabled' : ''}>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<line x1="22" y1="2" x2="11" y2="13"></line>
|
||||
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
||||
|
||||
Reference in New Issue
Block a user