@devchitchat/chat 4.1.2 → 4.2.1
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
|
@@ -165,6 +165,9 @@ export default function CallIsland(root) {
|
|
|
165
165
|
if (!article.querySelector('.message-hover-actions')) {
|
|
166
166
|
const toolbar = document.createElement('div')
|
|
167
167
|
toolbar.className = 'message-hover-actions'
|
|
168
|
+
const quickPicks = document.createElement('span')
|
|
169
|
+
quickPicks.className = 'quick-picks'
|
|
170
|
+
toolbar.appendChild(quickPicks)
|
|
168
171
|
const reactBtn = document.createElement('button')
|
|
169
172
|
reactBtn.className = 'btn-react btn-icon'
|
|
170
173
|
reactBtn.type = 'button'
|
|
@@ -181,6 +184,7 @@ export default function CallIsland(root) {
|
|
|
181
184
|
toolbar.appendChild(actionsBtn)
|
|
182
185
|
}
|
|
183
186
|
article.appendChild(toolbar)
|
|
187
|
+
renderQuickPicks(toolbar)
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
// Apply inline rendering (URLs, @mentions) to server-rendered message text.
|
|
@@ -695,6 +699,8 @@ export default function CallIsland(root) {
|
|
|
695
699
|
}
|
|
696
700
|
|
|
697
701
|
enableTaskCheckboxes(article)
|
|
702
|
+
const toolbar = article.querySelector('.message-hover-actions')
|
|
703
|
+
if (toolbar) renderQuickPicks(toolbar)
|
|
698
704
|
messages.appendChild(article)
|
|
699
705
|
renderReactionBar(article, reactions ?? [], msg_id)
|
|
700
706
|
messages.scrollTop = messages.scrollHeight
|
|
@@ -736,6 +742,22 @@ export default function CallIsland(root) {
|
|
|
736
742
|
recents.unshift(emoji)
|
|
737
743
|
if (recents.length > RECENT_MAX) recents = recents.slice(0, RECENT_MAX)
|
|
738
744
|
localStorage.setItem(RECENT_KEY, JSON.stringify(recents))
|
|
745
|
+
refreshAllQuickPicks()
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function renderQuickPicks(toolbar) {
|
|
749
|
+
const slot = toolbar.querySelector('.quick-picks')
|
|
750
|
+
if (!slot) return
|
|
751
|
+
const recents = loadRecentEmoji().slice(0, 4)
|
|
752
|
+
slot.innerHTML = recents.map(emoji =>
|
|
753
|
+
`<button class="btn-quick-react btn-icon" data-emoji="${escHtml(emoji)}" type="button" title="${escHtml(emoji)}">${emoji}</button>`
|
|
754
|
+
).join('')
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
function refreshAllQuickPicks() {
|
|
758
|
+
for (const toolbar of messages.querySelectorAll('.message-hover-actions')) {
|
|
759
|
+
renderQuickPicks(toolbar)
|
|
760
|
+
}
|
|
739
761
|
}
|
|
740
762
|
|
|
741
763
|
let emojiPickerEl = null
|
|
@@ -913,6 +935,18 @@ export default function CallIsland(root) {
|
|
|
913
935
|
ws.send({ t: 'msg.edit', body: { msg_id: article.dataset.msgId, channel_id: channelId, text: newText } })
|
|
914
936
|
})
|
|
915
937
|
|
|
938
|
+
// Delegated click on .btn-quick-react — send reaction without opening picker
|
|
939
|
+
messages.addEventListener('click', e => {
|
|
940
|
+
const btn = e.target.closest('.btn-quick-react')
|
|
941
|
+
if (!btn) return
|
|
942
|
+
e.stopPropagation()
|
|
943
|
+
const emoji = btn.dataset.emoji
|
|
944
|
+
const msgId = btn.closest('article.message')?.dataset.msgId
|
|
945
|
+
if (!emoji || !msgId) return
|
|
946
|
+
saveRecentEmoji(emoji)
|
|
947
|
+
ws.send({ t: 'reaction.add', body: { msg_id: msgId, channel_id: channelId, emoji } })
|
|
948
|
+
})
|
|
949
|
+
|
|
916
950
|
// Delegated click on .reaction-pill — toggle reaction
|
|
917
951
|
messages.addEventListener('click', e => {
|
|
918
952
|
const pill = e.target.closest('.reaction-pill')
|
|
@@ -134,7 +134,7 @@ export function makeMessageEl({ msg_id, seq, user_id, user_display_name, ts, tex
|
|
|
134
134
|
const isSelf = userId != null && user_id === userId
|
|
135
135
|
const attachmentHtml = (attachments ?? []).map(a => renderAttachment(a)).join('')
|
|
136
136
|
const editedHtml = edited_at ? '<span class="message-edited">(edited)</span>' : ''
|
|
137
|
-
const actionsHtml = `<div class="message-hover-actions"><button class="btn-react btn-icon" type="button" title="Add reaction" aria-label="Add reaction">🙂</button>${isSelf ? '<button class="btn-msg-actions btn-icon" type="button" title="Message actions">…</button>' : ''}</div>`
|
|
137
|
+
const actionsHtml = `<div class="message-hover-actions"><span class="quick-picks"></span><button class="btn-react btn-icon" type="button" title="Add reaction" aria-label="Add reaction">🙂</button>${isSelf ? '<button class="btn-msg-actions btn-icon" type="button" title="Message actions">…</button>' : ''}</div>`
|
|
138
138
|
const textHtml = rendered_text ?? (text ? renderText(text, { userHandle }) : '')
|
|
139
139
|
article.innerHTML = `
|
|
140
140
|
<span class="message-handle${isSelf ? '' : ' dm-trigger'}" data-user-id="${escHtml(user_id)}" title="${isSelf ? '' : 'Send a direct message'}">${escHtml(user_display_name ?? user_id)}</span>
|
|
@@ -499,7 +499,10 @@ details summary {
|
|
|
499
499
|
font-size: 1rem;
|
|
500
500
|
margin-bottom: 7px;
|
|
501
501
|
}
|
|
502
|
-
.chat-topic {
|
|
502
|
+
.chat-topic {
|
|
503
|
+
color: var(--text-secondary);
|
|
504
|
+
display: none; /* don't show this for now.*/
|
|
505
|
+
}
|
|
503
506
|
.chat-header-actions { margin-left: auto; display: flex; gap: 6px; }
|
|
504
507
|
|
|
505
508
|
.search-bar { padding: 8px 20px; background: var(--bg-topbar); border-bottom: 1px solid var(--border); }
|
|
@@ -848,8 +851,11 @@ details summary {
|
|
|
848
851
|
}
|
|
849
852
|
.btn-primary:hover { opacity: 0.85; }
|
|
850
853
|
.btn-ghost {
|
|
851
|
-
|
|
852
|
-
|
|
854
|
+
border: none;
|
|
855
|
+
padding: 6px 12px;
|
|
856
|
+
border-radius: var(--radius-sm);
|
|
857
|
+
color: var(--text-muted);
|
|
858
|
+
cursor: pointer;
|
|
853
859
|
}
|
|
854
860
|
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }
|
|
855
861
|
.btn-icon {
|
|
@@ -1508,7 +1514,6 @@ body:has(.admin-topbar) main {
|
|
|
1508
1514
|
border: 1px solid var(--border);
|
|
1509
1515
|
border-radius: 6px;
|
|
1510
1516
|
margin-bottom: 8px;
|
|
1511
|
-
overflow: hidden;
|
|
1512
1517
|
}
|
|
1513
1518
|
|
|
1514
1519
|
.hub-group__summary {
|
|
@@ -1803,6 +1808,9 @@ article.message { position: relative; }
|
|
|
1803
1808
|
z-index: 10;
|
|
1804
1809
|
}
|
|
1805
1810
|
article.message:hover .message-hover-actions { opacity: 1; pointer-events: auto; }
|
|
1811
|
+
.quick-picks { display: contents; }
|
|
1812
|
+
.quick-picks:not(:empty) + .btn-react { border-left: 1px solid var(--border); margin-left: 1px; padding-left: 6px; }
|
|
1813
|
+
.btn-quick-react,
|
|
1806
1814
|
.btn-react,
|
|
1807
1815
|
.btn-msg-actions {
|
|
1808
1816
|
background: none;
|
|
@@ -1815,6 +1823,7 @@ article.message:hover .message-hover-actions { opacity: 1; pointer-events: auto;
|
|
|
1815
1823
|
color: var(--text-secondary);
|
|
1816
1824
|
transition: background var(--transition), color var(--transition);
|
|
1817
1825
|
}
|
|
1826
|
+
.btn-quick-react:hover,
|
|
1818
1827
|
.btn-react:hover,
|
|
1819
1828
|
.btn-msg-actions:hover {
|
|
1820
1829
|
background: color-mix(in srgb, var(--accent) 15%, transparent);
|