@product7/product7-js 0.1.6 → 0.1.7
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.
package/package.json
CHANGED
|
@@ -253,6 +253,49 @@ export const messengerComponentsStyles = `
|
|
|
253
253
|
COMPOSE AREA
|
|
254
254
|
======================================== */
|
|
255
255
|
|
|
256
|
+
/* ========================================
|
|
257
|
+
EMOJI PICKER
|
|
258
|
+
======================================== */
|
|
259
|
+
|
|
260
|
+
.messenger-emoji-picker-container {
|
|
261
|
+
padding: 0 var(--spacing-3) var(--spacing-2);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.messenger-emoji-picker-container emoji-picker {
|
|
265
|
+
width: 100%;
|
|
266
|
+
height: 320px;
|
|
267
|
+
border-radius: var(--radius-xl);
|
|
268
|
+
border: 1px solid var(--msg-border);
|
|
269
|
+
box-shadow: var(--shadow-lg);
|
|
270
|
+
|
|
271
|
+
--background: var(--msg-bg);
|
|
272
|
+
--border-color: var(--msg-border);
|
|
273
|
+
--border-radius: 12px;
|
|
274
|
+
--category-font-color: var(--msg-text-secondary);
|
|
275
|
+
--category-font-size: 0.7rem;
|
|
276
|
+
--emoji-size: 1.35rem;
|
|
277
|
+
--emoji-padding: 0.3rem;
|
|
278
|
+
--input-border-color: var(--msg-border);
|
|
279
|
+
--input-border-radius: 8px;
|
|
280
|
+
--input-font-color: var(--msg-text);
|
|
281
|
+
--input-font-size: 0.8rem;
|
|
282
|
+
--input-placeholder-color: var(--msg-text-tertiary);
|
|
283
|
+
--input-padding: 0.375rem 0.625rem;
|
|
284
|
+
--outline-color: var(--color-primary);
|
|
285
|
+
--num-columns: 8;
|
|
286
|
+
--indicator-color: var(--color-primary);
|
|
287
|
+
--hover-background: var(--msg-bg-hover);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.messenger-widget.theme-dark .messenger-emoji-picker-container emoji-picker {
|
|
291
|
+
--background: var(--msg-bg);
|
|
292
|
+
--border-color: var(--msg-border);
|
|
293
|
+
--category-font-color: var(--msg-text-secondary);
|
|
294
|
+
--input-font-color: var(--msg-text);
|
|
295
|
+
--input-placeholder-color: var(--msg-text-tertiary);
|
|
296
|
+
--hover-background: var(--msg-bg-hover);
|
|
297
|
+
}
|
|
298
|
+
|
|
256
299
|
.messenger-chat-compose {
|
|
257
300
|
display: flex;
|
|
258
301
|
flex-direction: column;
|
|
@@ -9,6 +9,8 @@ export class ChatView {
|
|
|
9
9
|
this._typingIndicator = null;
|
|
10
10
|
this._isConversationClosed = false;
|
|
11
11
|
this._pendingAttachments = [];
|
|
12
|
+
this._emojiPickerOpen = false;
|
|
13
|
+
this._emojiOutsideHandler = null;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
render() {
|
|
@@ -129,7 +131,7 @@ export class ChatView {
|
|
|
129
131
|
<button class="sdk-btn-icon messenger-compose-attach" aria-label="Attach file">
|
|
130
132
|
<iconify-icon icon="ph:paperclip-duotone" width="20" height="20"></iconify-icon>
|
|
131
133
|
</button>
|
|
132
|
-
<button class="sdk-btn-icon" aria-label="Emoji">
|
|
134
|
+
<button class="sdk-btn-icon messenger-emoji-btn" aria-label="Emoji">
|
|
133
135
|
<iconify-icon icon="ph:smiley-duotone" width="20" height="20"></iconify-icon>
|
|
134
136
|
</button>
|
|
135
137
|
</div>
|
|
@@ -398,6 +400,14 @@ export class ChatView {
|
|
|
398
400
|
});
|
|
399
401
|
}
|
|
400
402
|
|
|
403
|
+
const emojiBtn = this.element.querySelector('.messenger-emoji-btn');
|
|
404
|
+
if (emojiBtn) {
|
|
405
|
+
emojiBtn.addEventListener('click', (e) => {
|
|
406
|
+
e.stopPropagation();
|
|
407
|
+
this._toggleEmojiPicker();
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
401
411
|
const attachBtn = this.element.querySelector('.messenger-compose-attach');
|
|
402
412
|
const fileInput = this.element.querySelector(
|
|
403
413
|
'.messenger-compose-file-input'
|
|
@@ -528,6 +538,85 @@ export class ChatView {
|
|
|
528
538
|
this._updateSendButtonState();
|
|
529
539
|
}
|
|
530
540
|
|
|
541
|
+
_loadEmojiPicker() {
|
|
542
|
+
if (document.querySelector('#product7-emoji-picker-script')) {
|
|
543
|
+
return Promise.resolve();
|
|
544
|
+
}
|
|
545
|
+
return new Promise((resolve, reject) => {
|
|
546
|
+
const script = document.createElement('script');
|
|
547
|
+
script.id = 'product7-emoji-picker-script';
|
|
548
|
+
script.type = 'module';
|
|
549
|
+
script.src =
|
|
550
|
+
'https://cdn.jsdelivr.net/npm/emoji-picker-element@1/index.js';
|
|
551
|
+
script.onload = resolve;
|
|
552
|
+
script.onerror = reject;
|
|
553
|
+
document.head.appendChild(script);
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
async _toggleEmojiPicker() {
|
|
558
|
+
const existing = this.element.querySelector(
|
|
559
|
+
'.messenger-emoji-picker-container'
|
|
560
|
+
);
|
|
561
|
+
if (existing) {
|
|
562
|
+
existing.remove();
|
|
563
|
+
this._emojiPickerOpen = false;
|
|
564
|
+
if (this._emojiOutsideHandler) {
|
|
565
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
566
|
+
this._emojiOutsideHandler = null;
|
|
567
|
+
}
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
try {
|
|
572
|
+
await this._loadEmojiPicker();
|
|
573
|
+
} catch {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const container = document.createElement('div');
|
|
578
|
+
container.className = 'messenger-emoji-picker-container';
|
|
579
|
+
|
|
580
|
+
const picker = document.createElement('emoji-picker');
|
|
581
|
+
container.appendChild(picker);
|
|
582
|
+
|
|
583
|
+
const compose = this.element.querySelector('.messenger-chat-compose');
|
|
584
|
+
compose.parentNode.insertBefore(container, compose);
|
|
585
|
+
this._emojiPickerOpen = true;
|
|
586
|
+
|
|
587
|
+
picker.addEventListener('emoji-click', (e) => {
|
|
588
|
+
this._insertEmoji(e.detail.unicode);
|
|
589
|
+
container.remove();
|
|
590
|
+
this._emojiPickerOpen = false;
|
|
591
|
+
if (this._emojiOutsideHandler) {
|
|
592
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
593
|
+
this._emojiOutsideHandler = null;
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
this._emojiOutsideHandler = (e) => {
|
|
598
|
+
if (!container.contains(e.target) && !e.target.closest('.messenger-emoji-btn')) {
|
|
599
|
+
container.remove();
|
|
600
|
+
this._emojiPickerOpen = false;
|
|
601
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
602
|
+
this._emojiOutsideHandler = null;
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
setTimeout(() => document.addEventListener('click', this._emojiOutsideHandler), 0);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
_insertEmoji(emoji) {
|
|
609
|
+
const input = this.element.querySelector('.messenger-compose-input');
|
|
610
|
+
if (!input) return;
|
|
611
|
+
const start = input.selectionStart;
|
|
612
|
+
const end = input.selectionEnd;
|
|
613
|
+
input.value =
|
|
614
|
+
input.value.slice(0, start) + emoji + input.value.slice(end);
|
|
615
|
+
input.selectionStart = input.selectionEnd = start + emoji.length;
|
|
616
|
+
input.focus();
|
|
617
|
+
input.dispatchEvent(new Event('input'));
|
|
618
|
+
}
|
|
619
|
+
|
|
531
620
|
_startTyping() {
|
|
532
621
|
if (this._isConversationClosed) return;
|
|
533
622
|
if (!this._isTyping && this.state.activeConversationId) {
|
|
@@ -585,6 +674,9 @@ export class ChatView {
|
|
|
585
674
|
clearTimeout(this._typingTimeout);
|
|
586
675
|
}
|
|
587
676
|
this._stopTyping();
|
|
677
|
+
if (this._emojiOutsideHandler) {
|
|
678
|
+
document.removeEventListener('click', this._emojiOutsideHandler);
|
|
679
|
+
}
|
|
588
680
|
if (this.element && this.element.parentNode) {
|
|
589
681
|
this.element.parentNode.removeChild(this.element);
|
|
590
682
|
}
|