@product7/product7-js 0.5.1 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +4 -4
  2. package/dist/README.md +4 -4
  3. package/dist/product7-js.js +7124 -7130
  4. package/dist/product7-js.js.map +1 -1
  5. package/dist/product7-js.min.js +1 -1
  6. package/dist/product7-js.min.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/api/APIService.js +1 -0
  9. package/src/api/services/{MessengerService.js → WebChatService.js} +15 -15
  10. package/src/core/APIService.js +16 -16
  11. package/src/core/Product7.js +4 -4
  12. package/src/core/WebSocketService.js +3 -3
  13. package/src/docs/api.md +9 -9
  14. package/src/docs/example.md +12 -12
  15. package/src/docs/framework-integrations.md +5 -5
  16. package/src/index.js +41 -42
  17. package/src/styles/base.js +9 -9
  18. package/src/styles/design-tokens.js +2 -2
  19. package/src/styles/feedback.js +2 -2
  20. package/src/styles/styles.js +4 -4
  21. package/src/styles/survey.js +3 -2
  22. package/src/styles/{messenger-components.js → web-chat-components.js} +114 -114
  23. package/src/styles/{messenger-core.js → web-chat-core.js} +32 -32
  24. package/src/styles/{messenger-features.js → web-chat-features.js} +20 -20
  25. package/src/styles/{messenger-views.js → web-chat-views.js} +137 -137
  26. package/src/styles/web-chat.js +17 -0
  27. package/src/styles/{messengerCustomStyles.js → webChatCustomStyles.js} +17 -19
  28. package/src/widgets/SurveyWidget.js +6 -1
  29. package/src/widgets/{MessengerWidget.js → WebChatWidget.js} +169 -172
  30. package/src/widgets/WidgetFactory.js +3 -3
  31. package/src/widgets/{messenger/MessengerState.js → web-chat/WebChatState.js} +1 -1
  32. package/src/widgets/{messenger → web-chat}/components/NavigationTabs.js +13 -13
  33. package/src/widgets/{messenger/components/MessengerLauncher.js → web-chat/components/WebChatLauncher.js} +15 -17
  34. package/src/widgets/{messenger/components/MessengerPanel.js → web-chat/components/WebChatPanel.js} +11 -11
  35. package/src/widgets/{messenger → web-chat}/views/ChangelogView.js +17 -17
  36. package/src/widgets/{messenger → web-chat}/views/ChatView.js +97 -99
  37. package/src/widgets/{messenger → web-chat}/views/ConversationsView.js +24 -24
  38. package/src/widgets/{messenger → web-chat}/views/HelpView.js +29 -29
  39. package/src/widgets/{messenger → web-chat}/views/HomeView.js +53 -55
  40. package/src/widgets/{messenger → web-chat}/views/PreChatFormView.js +17 -17
  41. package/src/styles/messenger.js +0 -17
@@ -1,4 +1,4 @@
1
- export class ChatView {
1
+ export class ChatView {
2
2
  constructor(state, options = {}) {
3
3
  this.state = state;
4
4
  this.options = options;
@@ -15,14 +15,14 @@ export class ChatView {
15
15
 
16
16
  render() {
17
17
  this.element = document.createElement('div');
18
- this.element.className = 'messenger-view messenger-chat-view';
18
+ this.element.className = 'web-chat-view web-chat-chat-view';
19
19
 
20
20
  this._updateContent();
21
21
 
22
22
  this._unsubscribe = this.state.subscribe((type, data) => {
23
23
  if (type === 'connectionChange') {
24
24
  const banner = this.element?.querySelector(
25
- '.messenger-connection-banner'
25
+ '.web-chat-connection-banner'
26
26
  );
27
27
  if (banner) {
28
28
  banner.style.display = data.connected ? 'none' : 'flex';
@@ -88,50 +88,50 @@ export class ChatView {
88
88
  : `<iconify-icon icon="ph:chats-circle-duotone" width="20" height="20"></iconify-icon>`;
89
89
 
90
90
  this.element.innerHTML = `
91
- <div class="messenger-chat-header">
92
- <button class="sdk-btn-icon messenger-back-btn" aria-label="Back">
91
+ <div class="web-chat-chat-header">
92
+ <button class="sdk-btn-icon web-chat-back-btn" aria-label="Back">
93
93
  <iconify-icon icon="ph:arrow-left" width="20" height="20"></iconify-icon>
94
94
  </button>
95
- <div class="messenger-chat-header-avatar">
95
+ <div class="web-chat-chat-header-avatar">
96
96
  ${headerAvatarHtml}
97
97
  </div>
98
- <div class="messenger-chat-header-info">
99
- <span class="messenger-chat-title">${this._escapeHtml(teamName)}</span>
100
- <span class="messenger-chat-subtitle">${isClosed ? 'Conversation resolved' : this.state.responseTime || 'Typically replies within minutes'}</span>
98
+ <div class="web-chat-chat-header-info">
99
+ <span class="web-chat-chat-title">${this._escapeHtml(teamName)}</span>
100
+ <span class="web-chat-chat-subtitle">${isClosed ? 'Conversation resolved' : this.state.responseTime || 'Typically replies within minutes'}</span>
101
101
  </div>
102
- <div class="messenger-chat-header-actions">
103
- <button class="sdk-btn-icon sdk-close-btn messenger-mobile-close-btn" aria-label="Close">
102
+ <div class="web-chat-chat-header-actions">
103
+ <button class="sdk-btn-icon sdk-close-btn web-chat-mobile-close-btn" aria-label="Close">
104
104
  <iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
105
105
  </button>
106
106
  </div>
107
107
  </div>
108
108
 
109
- <div class="messenger-connection-banner" style="display:none;">
109
+ <div class="web-chat-connection-banner" style="display:none;">
110
110
  <iconify-icon icon="ph:wifi-slash" width="14" height="14"></iconify-icon>
111
111
  <span>Reconnecting…</span>
112
112
  </div>
113
113
 
114
- <div class="messenger-chat-messages">
114
+ <div class="web-chat-chat-messages">
115
115
  ${messagesHtml}
116
116
  ${
117
117
  isClosed
118
118
  ? `
119
- <div class="messenger-closed-banner">
119
+ <div class="web-chat-closed-banner">
120
120
  <iconify-icon icon="ph:check-circle-duotone" width="18" height="18"></iconify-icon>
121
121
  <span>This conversation has been resolved</span>
122
122
  </div>
123
123
  `
124
124
  : ''
125
125
  }
126
- <div class="messenger-typing-indicator">
127
- <div class="messenger-typing-dots">
126
+ <div class="web-chat-typing-indicator">
127
+ <div class="web-chat-typing-dots">
128
128
  <span></span><span></span><span></span>
129
129
  </div>
130
- <span class="messenger-typing-text"></span>
130
+ <span class="web-chat-typing-text"></span>
131
131
  </div>
132
132
  </div>
133
133
 
134
- <div class="messenger-scroll-pill" style="display:none;">
134
+ <div class="web-chat-scroll-pill" style="display:none;">
135
135
  <iconify-icon icon="ph:arrow-down" width="14" height="14"></iconify-icon>
136
136
  <span>New message</span>
137
137
  </div>
@@ -140,33 +140,33 @@ export class ChatView {
140
140
  isClosed
141
141
  ? ''
142
142
  : `
143
- <div class="messenger-compose-attachments-preview"></div>
143
+ <div class="web-chat-compose-attachments-preview"></div>
144
144
 
145
- <div class="messenger-chat-compose">
146
- <div class="messenger-compose-input-wrapper">
147
- <textarea class="messenger-compose-input" placeholder="${placeholder}" rows="1"></textarea>
145
+ <div class="web-chat-chat-compose">
146
+ <div class="web-chat-compose-input-wrapper">
147
+ <textarea class="web-chat-compose-input" placeholder="${placeholder}" rows="1"></textarea>
148
148
  </div>
149
- <div class="messenger-compose-bottom">
150
- <div class="messenger-compose-actions">
151
- <button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
149
+ <div class="web-chat-compose-bottom">
150
+ <div class="web-chat-compose-actions">
151
+ <button class="sdk-btn-icon web-chat-compose-attach" aria-label="Attach file">
152
152
  <iconify-icon icon="ph:paperclip-duotone" width="20" height="20"></iconify-icon>
153
153
  </button>
154
- <button class="sdk-btn-icon messenger-emoji-btn" aria-label="Emoji">
154
+ <button class="sdk-btn-icon web-chat-emoji-btn" aria-label="Emoji">
155
155
  <iconify-icon icon="ph:smiley-duotone" width="20" height="20"></iconify-icon>
156
156
  </button>
157
157
  </div>
158
- <button class="messenger-compose-send" aria-label="Send" disabled>
158
+ <button class="web-chat-compose-send" aria-label="Send" disabled>
159
159
  <iconify-icon icon="ph:paper-plane-right" width="20" height="20"></iconify-icon>
160
160
  </button>
161
161
  </div>
162
- <input type="file" class="messenger-compose-file-input" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip" />
162
+ <input type="file" class="web-chat-compose-file-input" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip" />
163
163
  </div>
164
164
  `
165
165
  }
166
166
  `;
167
167
 
168
168
  this._typingIndicator = this.element.querySelector(
169
- '.messenger-typing-indicator'
169
+ '.web-chat-typing-indicator'
170
170
  );
171
171
  this._attachEvents();
172
172
  this._scrollToBottom();
@@ -178,11 +178,11 @@ export class ChatView {
178
178
  const logoUrl = this.options.logoUrl;
179
179
 
180
180
  const logoHtml = logoUrl
181
- ? `<div class="messenger-chat-empty-logo"><img src="${this._escapeHtml(logoUrl)}" alt="${this._escapeHtml(this.state.teamName)}" /></div>`
181
+ ? `<div class="web-chat-chat-empty-logo"><img src="${this._escapeHtml(logoUrl)}" alt="${this._escapeHtml(this.state.teamName)}" /></div>`
182
182
  : '';
183
183
 
184
184
  return `
185
- <div class="messenger-chat-empty">
185
+ <div class="web-chat-chat-empty">
186
186
  ${logoHtml}
187
187
  <h3>${isNewConversation ? 'Start a new conversation' : 'Start the conversation'}</h3>
188
188
  </div>
@@ -194,12 +194,12 @@ export class ChatView {
194
194
  return attachments
195
195
  .map((att) => {
196
196
  if (att.type === 'image') {
197
- return `<img class="messenger-message-image" src="${this._escapeHtml(att.url)}" alt="${this._escapeHtml(att.name || 'image')}" data-url="${this._escapeHtml(att.url)}" />`;
197
+ return `<img class="web-chat-message-image" src="${this._escapeHtml(att.url)}" alt="${this._escapeHtml(att.name || 'image')}" data-url="${this._escapeHtml(att.url)}" />`;
198
198
  }
199
- return `<a class="messenger-message-file" href="${this._escapeHtml(att.url)}" data-url="${this._escapeHtml(att.url)}" data-name="${this._escapeHtml(att.name || 'file')}">
199
+ return `<a class="web-chat-message-file" href="${this._escapeHtml(att.url)}" data-url="${this._escapeHtml(att.url)}" data-name="${this._escapeHtml(att.name || 'file')}">
200
200
  <iconify-icon icon="ph:file-duotone" width="18" height="18"></iconify-icon>
201
201
  <span>${this._escapeHtml(att.name || 'file')}</span>
202
- <iconify-icon icon="ph:download-simple" width="16" height="16" class="messenger-file-download-icon"></iconify-icon>
202
+ <iconify-icon icon="ph:download-simple" width="16" height="16" class="web-chat-file-download-icon"></iconify-icon>
203
203
  </a>`;
204
204
  })
205
205
  .join('');
@@ -212,8 +212,8 @@ export class ChatView {
212
212
 
213
213
  const isOwn = message.isOwn;
214
214
  const messageClass = isOwn
215
- ? 'messenger-message-own'
216
- : 'messenger-message-received';
215
+ ? 'web-chat-message-own'
216
+ : 'web-chat-message-received';
217
217
  const timeStr = isLastInGroup
218
218
  ? this._formatMessageTime(message.timestamp)
219
219
  : '';
@@ -221,25 +221,25 @@ export class ChatView {
221
221
  const isOptimistic = message.isOptimistic;
222
222
 
223
223
  const contentHtml = message.content
224
- ? `<div class="messenger-message-content">${this._formatMessageContent(message.content)}</div>`
224
+ ? `<div class="web-chat-message-content">${this._formatMessageContent(message.content)}</div>`
225
225
  : '';
226
226
  const bubbleHtml = contentHtml
227
- ? `<div class="messenger-message-bubble">${contentHtml}</div>`
227
+ ? `<div class="web-chat-message-bubble">${contentHtml}</div>`
228
228
  : '';
229
229
 
230
230
  if (isOwn) {
231
231
  const sentIndicator = isLastInGroup
232
- ? `<div class="messenger-message-meta messenger-message-meta-own">
232
+ ? `<div class="web-chat-message-meta web-chat-message-meta-own">
233
233
  ${
234
234
  isOptimistic
235
- ? `<span class="messenger-message-sent-status">Sending…</span>`
236
- : `<span class="messenger-message-sent-status">Sent</span>`
235
+ ? `<span class="web-chat-message-sent-status">Sending…</span>`
236
+ : `<span class="web-chat-message-sent-status">Sent</span>`
237
237
  }
238
238
  ${timeStr ? `<span>·</span><span>${timeStr}</span>` : ''}
239
239
  </div>`
240
240
  : '';
241
241
  return `
242
- <div class="messenger-message ${messageClass}${isOptimistic ? ' messenger-message-optimistic' : ''}">
242
+ <div class="web-chat-message ${messageClass}${isOptimistic ? ' web-chat-message-optimistic' : ''}">
243
243
  ${bubbleHtml}
244
244
  ${attachmentsHtml}
245
245
  ${sentIndicator}
@@ -249,15 +249,15 @@ export class ChatView {
249
249
 
250
250
  const avatarHtml = this._renderSenderAvatar(message.sender);
251
251
  return `
252
- <div class="messenger-message ${messageClass}">
253
- <div class="messenger-message-row">
254
- <div class="messenger-message-avatar">${avatarHtml}</div>
255
- <div class="messenger-message-wrapper">
252
+ <div class="web-chat-message ${messageClass}">
253
+ <div class="web-chat-message-row">
254
+ <div class="web-chat-message-avatar">${avatarHtml}</div>
255
+ <div class="web-chat-message-wrapper">
256
256
  ${bubbleHtml}
257
257
  ${attachmentsHtml}
258
258
  </div>
259
259
  </div>
260
- ${timeStr ? `<div class="messenger-message-meta"><span>${timeStr}</span></div>` : ''}
260
+ ${timeStr ? `<div class="web-chat-message-meta"><span>${timeStr}</span></div>` : ''}
261
261
  </div>
262
262
  `;
263
263
  }
@@ -286,11 +286,11 @@ export class ChatView {
286
286
  const action = rawAction.charAt(0).toUpperCase() + rawAction.slice(1);
287
287
 
288
288
  return `
289
- <div class="messenger-message-system-event">
290
- <div class="messenger-message-system-event-avatar">${logoHtml}</div>
291
- <span class="messenger-message-system-event-name">${this._escapeHtml(name)}</span>
292
- <span class="messenger-message-system-event-action">${this._escapeHtml(action)}</span>
293
- ${timeStr ? `<span class="messenger-message-system-event-time">${timeStr}</span>` : ''}
289
+ <div class="web-chat-message-system-event">
290
+ <div class="web-chat-message-system-event-avatar">${logoHtml}</div>
291
+ <span class="web-chat-message-system-event-name">${this._escapeHtml(name)}</span>
292
+ <span class="web-chat-message-system-event-action">${this._escapeHtml(action)}</span>
293
+ ${timeStr ? `<span class="web-chat-message-system-event-time">${timeStr}</span>` : ''}
294
294
  </div>
295
295
  `;
296
296
  }
@@ -304,16 +304,16 @@ export class ChatView {
304
304
  const timeStr = this._formatMessageTime(message.timestamp);
305
305
 
306
306
  return `
307
- <div class="messenger-message messenger-message-received">
308
- <div class="messenger-message-row">
309
- <div class="messenger-message-avatar">${avatarHtml}</div>
310
- <div class="messenger-message-wrapper">
311
- <div class="messenger-message-bubble">
312
- <div class="messenger-message-content">${this._formatMessageContent(content)}</div>
307
+ <div class="web-chat-message web-chat-message-received">
308
+ <div class="web-chat-message-row">
309
+ <div class="web-chat-message-avatar">${avatarHtml}</div>
310
+ <div class="web-chat-message-wrapper">
311
+ <div class="web-chat-message-bubble">
312
+ <div class="web-chat-message-content">${this._formatMessageContent(content)}</div>
313
313
  </div>
314
314
  </div>
315
315
  </div>
316
- ${timeStr ? `<div class="messenger-message-meta"><span>${timeStr}</span></div>` : ''}
316
+ ${timeStr ? `<div class="web-chat-message-meta"><span>${timeStr}</span></div>` : ''}
317
317
  </div>
318
318
  `;
319
319
  }
@@ -342,7 +342,7 @@ export class ChatView {
342
342
  })
343
343
  .join('');
344
344
 
345
- return `<div class="messenger-avatar-stack">${avatarItems}</div>`;
345
+ return `<div class="web-chat-avatar-stack">${avatarItems}</div>`;
346
346
  }
347
347
 
348
348
  _formatMessageTime(timestamp) {
@@ -372,9 +372,9 @@ export class ChatView {
372
372
 
373
373
  _appendMessage(message) {
374
374
  const messagesContainer = this.element.querySelector(
375
- '.messenger-chat-messages'
375
+ '.web-chat-chat-messages'
376
376
  );
377
- const emptyState = messagesContainer.querySelector('.messenger-chat-empty');
377
+ const emptyState = messagesContainer.querySelector('.web-chat-chat-empty');
378
378
  if (emptyState) {
379
379
  emptyState.remove();
380
380
  }
@@ -394,14 +394,14 @@ export class ChatView {
394
394
  if (isNearBottom) {
395
395
  this._scrollToBottom();
396
396
  } else if (!message.isOwn) {
397
- const pill = this.element.querySelector('.messenger-scroll-pill');
397
+ const pill = this.element.querySelector('.web-chat-scroll-pill');
398
398
  if (pill) pill.style.display = 'flex';
399
399
  }
400
400
  }
401
401
 
402
402
  _scrollToBottom() {
403
403
  const messagesContainer = this.element.querySelector(
404
- '.messenger-chat-messages'
404
+ '.web-chat-chat-messages'
405
405
  );
406
406
  if (messagesContainer) {
407
407
  setTimeout(() => {
@@ -412,9 +412,9 @@ export class ChatView {
412
412
 
413
413
  _setupScrollPill() {
414
414
  const messagesContainer = this.element.querySelector(
415
- '.messenger-chat-messages'
415
+ '.web-chat-chat-messages'
416
416
  );
417
- const pill = this.element.querySelector('.messenger-scroll-pill');
417
+ const pill = this.element.querySelector('.web-chat-scroll-pill');
418
418
  if (!messagesContainer || !pill) return;
419
419
 
420
420
  pill.addEventListener('click', () => {
@@ -469,8 +469,8 @@ export class ChatView {
469
469
  }
470
470
 
471
471
  _updateSendButtonState() {
472
- const input = this.element.querySelector('.messenger-compose-input');
473
- const sendBtn = this.element.querySelector('.messenger-compose-send');
472
+ const input = this.element.querySelector('.web-chat-compose-input');
473
+ const sendBtn = this.element.querySelector('.web-chat-compose-send');
474
474
  if (input && sendBtn) {
475
475
  sendBtn.disabled =
476
476
  !input.value.trim() && this._pendingAttachments.length === 0;
@@ -479,7 +479,7 @@ export class ChatView {
479
479
 
480
480
  _renderAttachmentPreviews() {
481
481
  const container = this.element.querySelector(
482
- '.messenger-compose-attachments-preview'
482
+ '.web-chat-compose-attachments-preview'
483
483
  );
484
484
  if (!container) return;
485
485
 
@@ -494,38 +494,36 @@ export class ChatView {
494
494
  .map((att, i) => {
495
495
  const isImage = att.type.startsWith('image');
496
496
  const thumb = isImage
497
- ? `<img class="messenger-attachment-thumb" src="${att.preview}" alt="${this._escapeHtml(att.file.name)}" />`
498
- : `<div class="messenger-attachment-thumb messenger-attachment-file-icon"><iconify-icon icon="ph:file-duotone" width="24" height="24"></iconify-icon></div>`;
497
+ ? `<img class="web-chat-attachment-thumb" src="${att.preview}" alt="${this._escapeHtml(att.file.name)}" />`
498
+ : `<div class="web-chat-attachment-thumb web-chat-attachment-file-icon"><iconify-icon icon="ph:file-duotone" width="24" height="24"></iconify-icon></div>`;
499
499
  return `
500
- <div class="messenger-attachment-preview" data-index="${i}">
500
+ <div class="web-chat-attachment-preview" data-index="${i}">
501
501
  ${thumb}
502
- <button class="messenger-attachment-remove" data-index="${i}" aria-label="Remove">&times;</button>
502
+ <button class="web-chat-attachment-remove" data-index="${i}" aria-label="Remove">&times;</button>
503
503
  </div>
504
504
  `;
505
505
  })
506
506
  .join('');
507
507
 
508
- container
509
- .querySelectorAll('.messenger-attachment-remove')
510
- .forEach((btn) => {
511
- btn.addEventListener('click', (e) => {
512
- const idx = parseInt(e.currentTarget.dataset.index, 10);
513
- this._pendingAttachments.splice(idx, 1);
514
- this._renderAttachmentPreviews();
515
- this._updateSendButtonState();
516
- });
508
+ container.querySelectorAll('.web-chat-attachment-remove').forEach((btn) => {
509
+ btn.addEventListener('click', (e) => {
510
+ const idx = parseInt(e.currentTarget.dataset.index, 10);
511
+ this._pendingAttachments.splice(idx, 1);
512
+ this._renderAttachmentPreviews();
513
+ this._updateSendButtonState();
517
514
  });
515
+ });
518
516
  }
519
517
 
520
518
  _attachEvents() {
521
519
  this.element
522
- .querySelector('.messenger-back-btn')
520
+ .querySelector('.web-chat-back-btn')
523
521
  .addEventListener('click', () => {
524
522
  this.state.setView('messages');
525
523
  });
526
524
 
527
525
  const mobileCloseBtn = this.element.querySelector(
528
- '.messenger-mobile-close-btn'
526
+ '.web-chat-mobile-close-btn'
529
527
  );
530
528
  if (mobileCloseBtn) {
531
529
  mobileCloseBtn.addEventListener('click', () => {
@@ -533,8 +531,8 @@ export class ChatView {
533
531
  });
534
532
  }
535
533
 
536
- const input = this.element.querySelector('.messenger-compose-input');
537
- const sendBtn = this.element.querySelector('.messenger-compose-send');
534
+ const input = this.element.querySelector('.web-chat-compose-input');
535
+ const sendBtn = this.element.querySelector('.web-chat-compose-send');
538
536
 
539
537
  if (input && sendBtn) {
540
538
  input.addEventListener('input', () => {
@@ -559,7 +557,7 @@ export class ChatView {
559
557
  });
560
558
  }
561
559
 
562
- const emojiBtn = this.element.querySelector('.messenger-emoji-btn');
560
+ const emojiBtn = this.element.querySelector('.web-chat-emoji-btn');
563
561
  if (emojiBtn) {
564
562
  emojiBtn.addEventListener('click', (e) => {
565
563
  e.stopPropagation();
@@ -567,9 +565,9 @@ export class ChatView {
567
565
  });
568
566
  }
569
567
 
570
- const attachBtn = this.element.querySelector('.messenger-compose-attach');
568
+ const attachBtn = this.element.querySelector('.web-chat-compose-attach');
571
569
  const fileInput = this.element.querySelector(
572
- '.messenger-compose-file-input'
570
+ '.web-chat-compose-file-input'
573
571
  );
574
572
 
575
573
  if (attachBtn && fileInput) {
@@ -598,11 +596,11 @@ export class ChatView {
598
596
  }
599
597
 
600
598
  const messagesContainer = this.element.querySelector(
601
- '.messenger-chat-messages'
599
+ '.web-chat-chat-messages'
602
600
  );
603
601
  if (messagesContainer) {
604
602
  messagesContainer.addEventListener('click', (e) => {
605
- const fileLink = e.target.closest('.messenger-message-file');
603
+ const fileLink = e.target.closest('.web-chat-message-file');
606
604
  if (fileLink) {
607
605
  e.preventDefault();
608
606
  const url = fileLink.dataset.url;
@@ -611,7 +609,7 @@ export class ChatView {
611
609
  return;
612
610
  }
613
611
 
614
- const img = e.target.closest('.messenger-message-image');
612
+ const img = e.target.closest('.web-chat-message-image');
615
613
  if (img) {
616
614
  const url = img.dataset.url || img.src;
617
615
  window.open(url, '_blank');
@@ -650,7 +648,7 @@ export class ChatView {
650
648
  async _sendMessage() {
651
649
  if (this._isConversationClosed) return;
652
650
 
653
- const input = this.element.querySelector('.messenger-compose-input');
651
+ const input = this.element.querySelector('.web-chat-compose-input');
654
652
  const content = input.value.trim();
655
653
  const hasAttachments = this._pendingAttachments.length > 0;
656
654
 
@@ -715,7 +713,7 @@ export class ChatView {
715
713
 
716
714
  async _toggleEmojiPicker() {
717
715
  const existing = this.element.querySelector(
718
- '.messenger-emoji-picker-container'
716
+ '.web-chat-emoji-picker-container'
719
717
  );
720
718
  if (existing) {
721
719
  existing.remove();
@@ -734,12 +732,12 @@ export class ChatView {
734
732
  }
735
733
 
736
734
  const container = document.createElement('div');
737
- container.className = 'messenger-emoji-picker-container';
735
+ container.className = 'web-chat-emoji-picker-container';
738
736
 
739
737
  const picker = document.createElement('emoji-picker');
740
738
  container.appendChild(picker);
741
739
 
742
- const compose = this.element.querySelector('.messenger-chat-compose');
740
+ const compose = this.element.querySelector('.web-chat-chat-compose');
743
741
  compose.parentNode.insertBefore(container, compose);
744
742
  this._emojiPickerOpen = true;
745
743
 
@@ -756,7 +754,7 @@ export class ChatView {
756
754
  this._emojiOutsideHandler = (e) => {
757
755
  if (
758
756
  !container.contains(e.target) &&
759
- !e.target.closest('.messenger-emoji-btn')
757
+ !e.target.closest('.web-chat-emoji-btn')
760
758
  ) {
761
759
  container.remove();
762
760
  this._emojiPickerOpen = false;
@@ -771,7 +769,7 @@ export class ChatView {
771
769
  }
772
770
 
773
771
  _insertEmoji(emoji) {
774
- const input = this.element.querySelector('.messenger-compose-input');
772
+ const input = this.element.querySelector('.web-chat-compose-input');
775
773
  if (!input) return;
776
774
  const start = input.selectionStart;
777
775
  const end = input.selectionEnd;
@@ -815,7 +813,7 @@ export class ChatView {
815
813
  if (this._typingIndicator) {
816
814
  this._typingIndicator.style.display = 'flex';
817
815
  const textEl = this._typingIndicator.querySelector(
818
- '.messenger-typing-text'
816
+ '.web-chat-typing-text'
819
817
  );
820
818
  if (textEl) {
821
819
  textEl.textContent = `${userName || 'Support'} is typing...`;
@@ -1,4 +1,4 @@
1
- export class ConversationsView {
1
+ export class ConversationsView {
2
2
  constructor(state, options = {}) {
3
3
  this.state = state;
4
4
  this.options = options;
@@ -17,7 +17,7 @@ export class ConversationsView {
17
17
 
18
18
  render() {
19
19
  this.element = document.createElement('div');
20
- this.element.className = 'messenger-view messenger-conversations-view';
20
+ this.element.className = 'web-chat-view web-chat-conversations-view';
21
21
 
22
22
  this._updateContent();
23
23
  this._attachEvents();
@@ -48,8 +48,8 @@ export class ConversationsView {
48
48
  let conversationsHtml;
49
49
  if (conversations.length === 0) {
50
50
  conversationsHtml = `
51
- <div class="messenger-empty-state">
52
- <div class="messenger-empty-state-icon">
51
+ <div class="web-chat-empty-state">
52
+ <div class="web-chat-empty-state-icon">
53
53
  <iconify-icon icon="ph:chat-circle-duotone" width="48" height="48"></iconify-icon>
54
54
  </div>
55
55
  <h3>No conversations yet</h3>
@@ -58,26 +58,26 @@ export class ConversationsView {
58
58
  `;
59
59
  } else {
60
60
  conversationsHtml = `
61
- <div class="messenger-conversations-list">
61
+ <div class="web-chat-conversations-list">
62
62
  ${conversations.map((conv) => this._renderConversationItem(conv)).join('')}
63
63
  </div>
64
64
  `;
65
65
  }
66
66
 
67
67
  this.element.innerHTML = `
68
- <div class="messenger-conversations-header">
68
+ <div class="web-chat-conversations-header">
69
69
  <h2>Messages</h2>
70
- <button class="sdk-close-btn messenger-mobile-close-btn" aria-label="Close">
70
+ <button class="sdk-close-btn web-chat-mobile-close-btn" aria-label="Close">
71
71
  <iconify-icon icon="ph:x" width="18" height="18"></iconify-icon>
72
72
  </button>
73
73
  </div>
74
74
 
75
- <div class="messenger-conversations-body">
75
+ <div class="web-chat-conversations-body">
76
76
  ${conversationsHtml}
77
77
  </div>
78
78
 
79
- <div class="messenger-conversations-footer">
80
- <button class="messenger-new-message-btn">
79
+ <div class="web-chat-conversations-footer">
80
+ <button class="web-chat-new-message-btn">
81
81
  <iconify-icon icon="ph:pencil-simple" width="16" height="16" style="flex-shrink: 0; color: var(--msg-text-secondary);"></iconify-icon>
82
82
  <span style="flex: 1;">New conversation</span>
83
83
  <iconify-icon icon="ph:caret-right" width="16" height="16" style="flex-shrink: 0; color: var(--msg-text-tertiary);"></iconify-icon>
@@ -98,19 +98,19 @@ export class ConversationsView {
98
98
  );
99
99
 
100
100
  return `
101
- <div class="messenger-conversation-item ${unreadClass} ${closedClass}" data-conversation-id="${conversation.id}">
102
- <div class="messenger-conversation-avatars">
101
+ <div class="web-chat-conversation-item ${unreadClass} ${closedClass}" data-conversation-id="${conversation.id}">
102
+ <div class="web-chat-conversation-avatars">
103
103
  ${avatarsHtml}
104
104
  </div>
105
- <div class="messenger-conversation-content">
106
- <div class="messenger-conversation-header">
107
- <span class="messenger-conversation-title">${conversation.title || 'Chat with team'}</span>
108
- <span class="messenger-conversation-time">${timeAgo}</span>
105
+ <div class="web-chat-conversation-content">
106
+ <div class="web-chat-conversation-header">
107
+ <span class="web-chat-conversation-title">${conversation.title || 'Chat with team'}</span>
108
+ <span class="web-chat-conversation-time">${timeAgo}</span>
109
109
  </div>
110
- <div class="messenger-conversation-preview">
111
- ${conversation.unread > 0 ? '<span class="messenger-unread-dot"></span>' : ''}
112
- ${isClosed ? '<span class="messenger-conversation-resolved-badge">Resolved</span>' : ''}
113
- <span class="messenger-conversation-message">${this._truncateMessage(conversation.lastMessage)}</span>
110
+ <div class="web-chat-conversation-preview">
111
+ ${conversation.unread > 0 ? '<span class="web-chat-unread-dot"></span>' : ''}
112
+ ${isClosed ? '<span class="web-chat-conversation-resolved-badge">Resolved</span>' : ''}
113
+ <span class="web-chat-conversation-message">${this._truncateMessage(conversation.lastMessage)}</span>
114
114
  </div>
115
115
  </div>
116
116
  </div>
@@ -138,7 +138,7 @@ export class ConversationsView {
138
138
  const color1 = this._getAvatarColor('S');
139
139
  const color2 = this._getAvatarColor('T');
140
140
  return `
141
- <div class="messenger-avatar-stack">
141
+ <div class="web-chat-avatar-stack">
142
142
  <div class="sdk-avatar sdk-avatar-sm" style="background-color: ${color1};">S</div>
143
143
  <div class="sdk-avatar sdk-avatar-sm" style="background-color: ${color2};">T</div>
144
144
  </div>
@@ -157,7 +157,7 @@ export class ConversationsView {
157
157
  })
158
158
  .join('');
159
159
 
160
- return `<div class="messenger-avatar-stack">${avatarItems}</div>`;
160
+ return `<div class="web-chat-avatar-stack">${avatarItems}</div>`;
161
161
  }
162
162
 
163
163
  _formatTimeAgo(timestamp) {
@@ -192,7 +192,7 @@ export class ConversationsView {
192
192
  }
193
193
 
194
194
  this.element
195
- .querySelectorAll('.messenger-conversation-item')
195
+ .querySelectorAll('.web-chat-conversation-item')
196
196
  .forEach((item) => {
197
197
  item.addEventListener('click', () => {
198
198
  const convId = item.dataset.conversationId;
@@ -206,7 +206,7 @@ export class ConversationsView {
206
206
  });
207
207
  });
208
208
 
209
- const newMsgBtn = this.element.querySelector('.messenger-new-message-btn');
209
+ const newMsgBtn = this.element.querySelector('.web-chat-new-message-btn');
210
210
  if (newMsgBtn) {
211
211
  newMsgBtn.addEventListener('click', () => {
212
212
  this._startNewConversation();