@luckydraw/cumulus 1.0.23 → 1.0.24
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/CHANGELOG.md +8 -0
- package/dist/gateway/static/widget.js +340 -318
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.0.24
|
|
4
|
+
|
|
5
|
+
Patch release. The `/select` panel is now a compact overlay, matching `/revert`.
|
|
6
|
+
|
|
7
|
+
- **`/select` used to bolt checkboxes onto the full live message bubbles** in the actual conversation view — scrolling through complete rendered content (including blex blocks and code) just to pick messages to delete.
|
|
8
|
+
- **It now opens a dedicated overlay**, styled like the existing `/revert` list: one compact row per message (role badge, one-line preview, timestamp, checkbox), with the same header/close chrome and a footer bar for selection count / Select All / Delete. The live thread underneath stays undisturbed while selecting.
|
|
9
|
+
- Implemented once and shared between the standalone `/chat` panel and the embedded widget, since both already shared the row-rendering and delete-confirm code.
|
|
10
|
+
|
|
3
11
|
## v1.0.23
|
|
4
12
|
|
|
5
13
|
Patch release. Search result snippets now show why a match was found, and the model is told to search before claiming something isn't on record.
|
|
@@ -1760,18 +1760,7 @@
|
|
|
1760
1760
|
' 50% { box-shadow: 0 0 6px #3b82f6, 0 0 14px rgba(59,130,246,0.6); }',
|
|
1761
1761
|
'}',
|
|
1762
1762
|
|
|
1763
|
-
/* ──
|
|
1764
|
-
'.cumulus-msg-checkbox {',
|
|
1765
|
-
' display: none; flex-shrink: 0; align-self: flex-start; margin-top: 0.4em;',
|
|
1766
|
-
' width: 16px; height: 16px; cursor: pointer; accent-color: #0066cc;',
|
|
1767
|
-
'}',
|
|
1768
|
-
'.cumulus-selection-mode .cumulus-msg-checkbox { display: block; }',
|
|
1769
|
-
'.cumulus-selection-mode .cumulus-msg-row {',
|
|
1770
|
-
' flex-direction: row; align-items: flex-start; gap: 8px;',
|
|
1771
|
-
'}',
|
|
1772
|
-
'.cumulus-selection-mode .cumulus-msg-row > *:not(.cumulus-msg-checkbox) { flex: 1; min-width: 0; }',
|
|
1773
|
-
|
|
1774
|
-
/* ── Selection action bar (floats at bottom of messages area) ── */
|
|
1763
|
+
/* ── Selection action bar (footer of the select-messages overlay) ── */
|
|
1775
1764
|
'.cumulus-selection-bar {',
|
|
1776
1765
|
' display: flex; align-items: center; gap: 8px;',
|
|
1777
1766
|
' padding: 8px 12px;',
|
|
@@ -1922,6 +1911,30 @@
|
|
|
1922
1911
|
' padding: 0 5px; flex-shrink: 0;',
|
|
1923
1912
|
'}',
|
|
1924
1913
|
|
|
1914
|
+
/* ── Select-messages overlay rows ── */
|
|
1915
|
+
'.cumulus-select-item {',
|
|
1916
|
+
' display: flex; align-items: center; gap: 0.6em;',
|
|
1917
|
+
' padding: 0.5em 0.6em; border-radius: 4px;',
|
|
1918
|
+
' border: 1px solid #333; margin-bottom: 0.3em; cursor: pointer;',
|
|
1919
|
+
'}',
|
|
1920
|
+
'.cumulus-select-item:hover { border-color: #555; background: #252525; }',
|
|
1921
|
+
'.cumulus-select-checkbox {',
|
|
1922
|
+
' flex-shrink: 0; width: 16px; height: 16px; cursor: pointer; accent-color: #0066cc;',
|
|
1923
|
+
'}',
|
|
1924
|
+
'.cumulus-select-role {',
|
|
1925
|
+
' font-size: 0.75em; color: #888; background: #2a2a2a;',
|
|
1926
|
+
' border: 1px solid #3a3a3a; border-radius: 3px;',
|
|
1927
|
+
' padding: 1px 6px; flex-shrink: 0; min-width: 4.5em; text-align: center;',
|
|
1928
|
+
' text-transform: uppercase;',
|
|
1929
|
+
'}',
|
|
1930
|
+
'.cumulus-select-preview {',
|
|
1931
|
+
' flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;',
|
|
1932
|
+
' color: #ccc; font-size: 0.9em;',
|
|
1933
|
+
'}',
|
|
1934
|
+
'.cumulus-select-time {',
|
|
1935
|
+
' font-size: 0.75em; color: #666; flex-shrink: 0;',
|
|
1936
|
+
'}',
|
|
1937
|
+
|
|
1925
1938
|
/* ── Revert confirm panel ── */
|
|
1926
1939
|
'.cumulus-revert-confirm {',
|
|
1927
1940
|
' padding: 1.5em; display: flex; flex-direction: column;',
|
|
@@ -3781,7 +3794,6 @@
|
|
|
3781
3794
|
var EMBEDDED_STREAM_TIMEOUT = 120000;
|
|
3782
3795
|
var authenticated = false;
|
|
3783
3796
|
var pendingAttachments = [];
|
|
3784
|
-
var selectionMode = false;
|
|
3785
3797
|
var selectedIds = {};
|
|
3786
3798
|
|
|
3787
3799
|
// ── Panel ──
|
|
@@ -4000,40 +4012,16 @@
|
|
|
4000
4012
|
destroyBlexBlocks(m);
|
|
4001
4013
|
});
|
|
4002
4014
|
messagesEl.innerHTML = '';
|
|
4003
|
-
// Apply selection mode class
|
|
4004
|
-
if (selectionMode) {
|
|
4005
|
-
messagesEl.classList.add('cumulus-selection-mode');
|
|
4006
|
-
} else {
|
|
4007
|
-
messagesEl.classList.remove('cumulus-selection-mode');
|
|
4008
|
-
}
|
|
4009
4015
|
if (messages.length === 0 && !streaming) {
|
|
4010
4016
|
messagesEl.innerHTML =
|
|
4011
4017
|
'<div class="cumulus-empty">Send a message to start chatting</div>';
|
|
4012
|
-
|
|
4018
|
+
refreshSelectOverlay(panel);
|
|
4013
4019
|
return;
|
|
4014
4020
|
}
|
|
4015
4021
|
for (var i = 0; i < messages.length; i++) {
|
|
4016
4022
|
var msg = messages[i];
|
|
4017
4023
|
var row = document.createElement('div');
|
|
4018
4024
|
row.className = 'cumulus-msg-row';
|
|
4019
|
-
// Add checkbox in selection mode
|
|
4020
|
-
if (selectionMode && msg.id) {
|
|
4021
|
-
var cb = document.createElement('input');
|
|
4022
|
-
cb.type = 'checkbox';
|
|
4023
|
-
cb.className = 'cumulus-msg-checkbox';
|
|
4024
|
-
cb.checked = !!selectedIds[msg.id];
|
|
4025
|
-
(function (msgId) {
|
|
4026
|
-
cb.addEventListener('change', function () {
|
|
4027
|
-
if (cb.checked) {
|
|
4028
|
-
selectedIds[msgId] = true;
|
|
4029
|
-
} else {
|
|
4030
|
-
delete selectedIds[msgId];
|
|
4031
|
-
}
|
|
4032
|
-
updateEmbeddedSelectionBar();
|
|
4033
|
-
});
|
|
4034
|
-
})(msg.id);
|
|
4035
|
-
row.appendChild(cb);
|
|
4036
|
-
}
|
|
4037
4025
|
// Suppress thinking-role entries
|
|
4038
4026
|
if (msg.role === 'thinking') continue;
|
|
4039
4027
|
|
|
@@ -4059,115 +4047,95 @@
|
|
|
4059
4047
|
messagesEl.appendChild(row);
|
|
4060
4048
|
}
|
|
4061
4049
|
scrollToBottom();
|
|
4062
|
-
|
|
4050
|
+
refreshSelectOverlay(panel);
|
|
4063
4051
|
}
|
|
4064
4052
|
|
|
4065
|
-
function
|
|
4066
|
-
var
|
|
4067
|
-
if (
|
|
4068
|
-
|
|
4053
|
+
function openEmbeddedSelectOverlay() {
|
|
4054
|
+
var existing = panel.querySelector('.cumulus-overlay');
|
|
4055
|
+
if (existing) {
|
|
4056
|
+
existing.remove();
|
|
4057
|
+
return;
|
|
4058
|
+
}
|
|
4069
4059
|
|
|
4070
|
-
|
|
4071
|
-
var selectableCount = messages.filter(function (m) {
|
|
4072
|
-
return !!m.id;
|
|
4073
|
-
}).length;
|
|
4060
|
+
selectedIds = {};
|
|
4074
4061
|
|
|
4075
|
-
var
|
|
4076
|
-
|
|
4062
|
+
var overlay = document.createElement('div');
|
|
4063
|
+
overlay.className = 'cumulus-overlay';
|
|
4064
|
+
overlay.setAttribute('data-overlay-kind', 'select');
|
|
4077
4065
|
|
|
4078
|
-
var
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
selectedIds = {};
|
|
4090
|
-
} else {
|
|
4091
|
-
messages.forEach(function (m) {
|
|
4092
|
-
if (m.id) selectedIds[m.id] = true;
|
|
4093
|
-
});
|
|
4094
|
-
}
|
|
4095
|
-
renderMessages();
|
|
4096
|
-
});
|
|
4097
|
-
bar.appendChild(selectAllBtn);
|
|
4098
|
-
|
|
4099
|
-
var deleteBtn = document.createElement('button');
|
|
4100
|
-
deleteBtn.className = 'cumulus-selection-delete-btn';
|
|
4101
|
-
deleteBtn.textContent = 'Delete';
|
|
4102
|
-
deleteBtn.disabled = selectedCount === 0;
|
|
4103
|
-
deleteBtn.addEventListener('click', function () {
|
|
4104
|
-
if (selectedCount === 0) return;
|
|
4105
|
-
showEmbeddedDeleteMessagesConfirm(Object.keys(selectedIds));
|
|
4066
|
+
var header = document.createElement('div');
|
|
4067
|
+
header.className = 'cumulus-overlay-header';
|
|
4068
|
+
var title = document.createElement('span');
|
|
4069
|
+
title.className = 'cumulus-overlay-title';
|
|
4070
|
+
title.textContent = 'Select Messages';
|
|
4071
|
+
header.appendChild(title);
|
|
4072
|
+
var closeBtn = document.createElement('button');
|
|
4073
|
+
closeBtn.className = 'cumulus-overlay-close';
|
|
4074
|
+
closeBtn.textContent = '\xD7';
|
|
4075
|
+
closeBtn.addEventListener('click', function () {
|
|
4076
|
+
overlay.remove();
|
|
4106
4077
|
});
|
|
4107
|
-
|
|
4078
|
+
header.appendChild(closeBtn);
|
|
4079
|
+
overlay.appendChild(header);
|
|
4108
4080
|
|
|
4109
|
-
var
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4081
|
+
var body = document.createElement('div');
|
|
4082
|
+
body.className = 'cumulus-overlay-body';
|
|
4083
|
+
overlay.appendChild(body);
|
|
4084
|
+
|
|
4085
|
+
var footer = document.createElement('div');
|
|
4086
|
+
footer.className = 'cumulus-selection-bar';
|
|
4087
|
+
overlay.appendChild(footer);
|
|
4088
|
+
|
|
4089
|
+
function refresh() {
|
|
4090
|
+
renderSelectRows(body, messages, selectedIds, updateFooter);
|
|
4091
|
+
updateFooter();
|
|
4092
|
+
}
|
|
4093
|
+
|
|
4094
|
+
function updateFooter() {
|
|
4095
|
+
footer.innerHTML = '';
|
|
4096
|
+
var selectedCount = Object.keys(selectedIds).length;
|
|
4097
|
+
var selectableCount = messages.filter(function (m) {
|
|
4098
|
+
return !!m.id;
|
|
4099
|
+
}).length;
|
|
4100
|
+
|
|
4101
|
+
var countEl = document.createElement('span');
|
|
4102
|
+
countEl.className = 'cumulus-selection-count';
|
|
4103
|
+
countEl.textContent = selectedCount + ' selected';
|
|
4104
|
+
footer.appendChild(countEl);
|
|
4105
|
+
|
|
4106
|
+
var selectAllBtn = document.createElement('button');
|
|
4107
|
+
selectAllBtn.className = 'cumulus-selection-select-all-btn';
|
|
4108
|
+
selectAllBtn.textContent =
|
|
4109
|
+
selectedCount === selectableCount && selectableCount > 0
|
|
4110
|
+
? 'Deselect All'
|
|
4111
|
+
: 'Select All';
|
|
4112
|
+
selectAllBtn.addEventListener('click', function () {
|
|
4113
|
+
if (selectedCount === selectableCount && selectableCount > 0) {
|
|
4114
|
+
selectedIds = {};
|
|
4115
|
+
} else {
|
|
4116
|
+
messages.forEach(function (m) {
|
|
4117
|
+
if (m.id) selectedIds[m.id] = true;
|
|
4118
|
+
});
|
|
4119
|
+
}
|
|
4120
|
+
refresh();
|
|
4121
|
+
});
|
|
4122
|
+
footer.appendChild(selectAllBtn);
|
|
4123
|
+
|
|
4124
|
+
var deleteBtn = document.createElement('button');
|
|
4125
|
+
deleteBtn.className = 'cumulus-selection-delete-btn';
|
|
4126
|
+
deleteBtn.textContent = 'Delete';
|
|
4127
|
+
deleteBtn.disabled = selectedCount === 0;
|
|
4128
|
+
deleteBtn.setAttribute('data-testid', 'webchat-select-delete-btn');
|
|
4129
|
+
deleteBtn.addEventListener('click', function () {
|
|
4130
|
+
if (selectedCount === 0) return;
|
|
4131
|
+
showDeleteMessagesConfirm(sessionId, panel, Object.keys(selectedIds));
|
|
4132
|
+
});
|
|
4133
|
+
footer.appendChild(deleteBtn);
|
|
4114
4134
|
}
|
|
4115
|
-
}
|
|
4116
|
-
|
|
4117
|
-
function showEmbeddedDeleteMessagesConfirm(ids) {
|
|
4118
|
-
var existing = panel.querySelector('.cumulus-confirm-dialog');
|
|
4119
|
-
if (existing) existing.remove();
|
|
4120
|
-
|
|
4121
|
-
var dialog = document.createElement('div');
|
|
4122
|
-
dialog.className = 'cumulus-confirm-dialog';
|
|
4123
|
-
|
|
4124
|
-
var box = document.createElement('div');
|
|
4125
|
-
box.className = 'cumulus-confirm-dialog-box';
|
|
4126
|
-
|
|
4127
|
-
var title = document.createElement('div');
|
|
4128
|
-
title.className = 'cumulus-confirm-dialog-title';
|
|
4129
|
-
title.textContent = 'Delete Messages';
|
|
4130
|
-
box.appendChild(title);
|
|
4131
|
-
|
|
4132
|
-
var text = document.createElement('div');
|
|
4133
|
-
text.className = 'cumulus-confirm-dialog-text';
|
|
4134
|
-
text.textContent =
|
|
4135
|
-
ids.length + ' message' + (ids.length === 1 ? '' : 's') + ' will be permanently deleted.';
|
|
4136
|
-
box.appendChild(text);
|
|
4137
|
-
|
|
4138
|
-
var warn = document.createElement('div');
|
|
4139
|
-
warn.className = 'cumulus-confirm-dialog-warn';
|
|
4140
|
-
warn.textContent = 'This cannot be undone.';
|
|
4141
|
-
box.appendChild(warn);
|
|
4142
|
-
|
|
4143
|
-
var actions = document.createElement('div');
|
|
4144
|
-
actions.className = 'cumulus-confirm-dialog-actions';
|
|
4145
|
-
|
|
4146
|
-
var cancelBtn = document.createElement('button');
|
|
4147
|
-
cancelBtn.className = 'cumulus-confirm-dialog-cancel';
|
|
4148
|
-
cancelBtn.textContent = 'Cancel';
|
|
4149
|
-
cancelBtn.addEventListener('click', function () {
|
|
4150
|
-
dialog.remove();
|
|
4151
|
-
});
|
|
4152
|
-
actions.appendChild(cancelBtn);
|
|
4153
|
-
|
|
4154
|
-
var confirmBtn = document.createElement('button');
|
|
4155
|
-
confirmBtn.className = 'cumulus-confirm-dialog-confirm';
|
|
4156
|
-
confirmBtn.setAttribute('data-testid', 'webchat-delete-messages-confirm');
|
|
4157
|
-
confirmBtn.textContent = 'Delete';
|
|
4158
|
-
confirmBtn.addEventListener('click', function () {
|
|
4159
|
-
confirmBtn.disabled = true;
|
|
4160
|
-
confirmBtn.textContent = 'Deleting\u2026';
|
|
4161
|
-
if (connection) {
|
|
4162
|
-
connection.send({ type: 'delete_messages', threadName: sessionId, messageIds: ids });
|
|
4163
|
-
}
|
|
4164
|
-
dialog.remove();
|
|
4165
|
-
});
|
|
4166
|
-
actions.appendChild(confirmBtn);
|
|
4167
4135
|
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
panel.appendChild(
|
|
4136
|
+
overlay._refresh = refresh;
|
|
4137
|
+
refresh();
|
|
4138
|
+
panel.appendChild(overlay);
|
|
4171
4139
|
}
|
|
4172
4140
|
|
|
4173
4141
|
function hasUploadingAttachments() {
|
|
@@ -4464,14 +4432,10 @@
|
|
|
4464
4432
|
}
|
|
4465
4433
|
break;
|
|
4466
4434
|
case 'messages_deleted':
|
|
4467
|
-
// Server confirmed deletion — reload history and
|
|
4468
|
-
selectionMode = false;
|
|
4435
|
+
// Server confirmed deletion — reload history and close the overlay
|
|
4469
4436
|
selectedIds = {};
|
|
4470
|
-
var
|
|
4471
|
-
if (
|
|
4472
|
-
embSelectBtn.textContent = 'Select';
|
|
4473
|
-
embSelectBtn.classList.remove('active');
|
|
4474
|
-
}
|
|
4437
|
+
var selOverlay = panel.querySelector('.cumulus-overlay[data-overlay-kind="select"]');
|
|
4438
|
+
if (selOverlay) selOverlay.remove();
|
|
4475
4439
|
messages = [];
|
|
4476
4440
|
// Re-request history
|
|
4477
4441
|
if (connection) {
|
|
@@ -4617,15 +4581,7 @@
|
|
|
4617
4581
|
var embSelectBtn = panel.querySelector('[data-testid="webchat-select-btn"]');
|
|
4618
4582
|
if (embSelectBtn) {
|
|
4619
4583
|
embSelectBtn.addEventListener('click', function () {
|
|
4620
|
-
|
|
4621
|
-
selectedIds = {};
|
|
4622
|
-
embSelectBtn.textContent = selectionMode ? 'Done' : 'Select';
|
|
4623
|
-
if (selectionMode) {
|
|
4624
|
-
embSelectBtn.classList.add('active');
|
|
4625
|
-
} else {
|
|
4626
|
-
embSelectBtn.classList.remove('active');
|
|
4627
|
-
}
|
|
4628
|
-
renderMessages();
|
|
4584
|
+
openEmbeddedSelectOverlay();
|
|
4629
4585
|
});
|
|
4630
4586
|
}
|
|
4631
4587
|
|
|
@@ -4738,7 +4694,6 @@
|
|
|
4738
4694
|
interjecting: false,
|
|
4739
4695
|
pendingAttachments: [],
|
|
4740
4696
|
historyLoaded: false,
|
|
4741
|
-
selectionMode: false,
|
|
4742
4697
|
selectedIds: {},
|
|
4743
4698
|
draft: '', // persists unsent textarea text across thread switches
|
|
4744
4699
|
// Pagination state
|
|
@@ -7776,7 +7731,7 @@
|
|
|
7776
7731
|
selectBtn.setAttribute('title', 'Select messages to delete');
|
|
7777
7732
|
selectBtn.textContent = 'Select';
|
|
7778
7733
|
selectBtn.addEventListener('click', function () {
|
|
7779
|
-
|
|
7734
|
+
openSelectOverlay(panel, threadName);
|
|
7780
7735
|
});
|
|
7781
7736
|
actions.appendChild(selectBtn);
|
|
7782
7737
|
|
|
@@ -8522,16 +8477,10 @@
|
|
|
8522
8477
|
destroyBlexBlocks(m);
|
|
8523
8478
|
});
|
|
8524
8479
|
messagesEl.innerHTML = '';
|
|
8525
|
-
// Apply selection mode class to messages container
|
|
8526
|
-
if (state.selectionMode) {
|
|
8527
|
-
messagesEl.classList.add('cumulus-selection-mode');
|
|
8528
|
-
} else {
|
|
8529
|
-
messagesEl.classList.remove('cumulus-selection-mode');
|
|
8530
|
-
}
|
|
8531
8480
|
if (state.messages.length === 0 && !state.streaming) {
|
|
8532
8481
|
messagesEl.innerHTML =
|
|
8533
8482
|
'<div class="cumulus-empty">Send a message to start chatting</div>';
|
|
8534
|
-
|
|
8483
|
+
refreshSelectOverlay(panel);
|
|
8535
8484
|
return;
|
|
8536
8485
|
}
|
|
8537
8486
|
// Show "load older" indicator if more messages are available
|
|
@@ -8548,24 +8497,6 @@
|
|
|
8548
8497
|
var msg = state.messages[i];
|
|
8549
8498
|
var row = document.createElement('div');
|
|
8550
8499
|
row.className = 'cumulus-msg-row';
|
|
8551
|
-
// Add checkbox if in selection mode and message has an id
|
|
8552
|
-
if (state.selectionMode && msg.id) {
|
|
8553
|
-
var cb = document.createElement('input');
|
|
8554
|
-
cb.type = 'checkbox';
|
|
8555
|
-
cb.className = 'cumulus-msg-checkbox';
|
|
8556
|
-
cb.checked = !!state.selectedIds[msg.id];
|
|
8557
|
-
(function (msgId) {
|
|
8558
|
-
cb.addEventListener('change', function () {
|
|
8559
|
-
if (cb.checked) {
|
|
8560
|
-
state.selectedIds[msgId] = true;
|
|
8561
|
-
} else {
|
|
8562
|
-
delete state.selectedIds[msgId];
|
|
8563
|
-
}
|
|
8564
|
-
updateSelectionBar();
|
|
8565
|
-
});
|
|
8566
|
-
})(msg.id);
|
|
8567
|
-
row.appendChild(cb);
|
|
8568
|
-
}
|
|
8569
8500
|
// Suppress thinking-role entries
|
|
8570
8501
|
if (msg.role === 'thinking') continue;
|
|
8571
8502
|
|
|
@@ -8612,132 +8543,7 @@
|
|
|
8612
8543
|
}
|
|
8613
8544
|
renderActivityBar();
|
|
8614
8545
|
scrollToBottom();
|
|
8615
|
-
|
|
8616
|
-
}
|
|
8617
|
-
|
|
8618
|
-
function updateSelectionBar() {
|
|
8619
|
-
// Remove existing bar
|
|
8620
|
-
var existingBar = panel.querySelector('.cumulus-selection-bar');
|
|
8621
|
-
if (existingBar) existingBar.remove();
|
|
8622
|
-
if (!state.selectionMode) return;
|
|
8623
|
-
|
|
8624
|
-
var selectedCount = Object.keys(state.selectedIds).length;
|
|
8625
|
-
var selectableCount = state.messages.filter(function (m) {
|
|
8626
|
-
return !!m.id;
|
|
8627
|
-
}).length;
|
|
8628
|
-
|
|
8629
|
-
var bar = document.createElement('div');
|
|
8630
|
-
bar.className = 'cumulus-selection-bar';
|
|
8631
|
-
|
|
8632
|
-
var countEl = document.createElement('span');
|
|
8633
|
-
countEl.className = 'cumulus-selection-count';
|
|
8634
|
-
countEl.textContent = selectedCount + ' selected';
|
|
8635
|
-
bar.appendChild(countEl);
|
|
8636
|
-
|
|
8637
|
-
var selectAllBtn = document.createElement('button');
|
|
8638
|
-
selectAllBtn.className = 'cumulus-selection-select-all-btn';
|
|
8639
|
-
selectAllBtn.textContent =
|
|
8640
|
-
selectedCount === selectableCount && selectableCount > 0 ? 'Deselect All' : 'Select All';
|
|
8641
|
-
selectAllBtn.addEventListener('click', function () {
|
|
8642
|
-
if (selectedCount === selectableCount && selectableCount > 0) {
|
|
8643
|
-
// Deselect all
|
|
8644
|
-
state.selectedIds = {};
|
|
8645
|
-
} else {
|
|
8646
|
-
// Select all with IDs
|
|
8647
|
-
state.messages.forEach(function (m) {
|
|
8648
|
-
if (m.id) state.selectedIds[m.id] = true;
|
|
8649
|
-
});
|
|
8650
|
-
}
|
|
8651
|
-
renderPanelMessages();
|
|
8652
|
-
});
|
|
8653
|
-
bar.appendChild(selectAllBtn);
|
|
8654
|
-
|
|
8655
|
-
var deleteBtn = document.createElement('button');
|
|
8656
|
-
deleteBtn.className = 'cumulus-selection-delete-btn';
|
|
8657
|
-
deleteBtn.textContent = 'Delete';
|
|
8658
|
-
deleteBtn.disabled = selectedCount === 0;
|
|
8659
|
-
deleteBtn.addEventListener('click', function () {
|
|
8660
|
-
if (selectedCount === 0) return;
|
|
8661
|
-
showDeleteMessagesConfirm(threadName, panel, Object.keys(state.selectedIds));
|
|
8662
|
-
});
|
|
8663
|
-
bar.appendChild(deleteBtn);
|
|
8664
|
-
|
|
8665
|
-
// Insert before input area
|
|
8666
|
-
var inputAreaEl = panel.querySelector('.cumulus-input-area');
|
|
8667
|
-
if (inputAreaEl) {
|
|
8668
|
-
panel.insertBefore(bar, inputAreaEl);
|
|
8669
|
-
} else {
|
|
8670
|
-
panel.appendChild(bar);
|
|
8671
|
-
}
|
|
8672
|
-
}
|
|
8673
|
-
|
|
8674
|
-
function toggleSelectionMode() {
|
|
8675
|
-
state.selectionMode = !state.selectionMode;
|
|
8676
|
-
state.selectedIds = {};
|
|
8677
|
-
selectBtn.textContent = state.selectionMode ? 'Done' : 'Select';
|
|
8678
|
-
if (state.selectionMode) {
|
|
8679
|
-
selectBtn.classList.add('active');
|
|
8680
|
-
} else {
|
|
8681
|
-
selectBtn.classList.remove('active');
|
|
8682
|
-
}
|
|
8683
|
-
renderPanelMessages();
|
|
8684
|
-
}
|
|
8685
|
-
|
|
8686
|
-
function showDeleteMessagesConfirm(tName, panelEl, ids) {
|
|
8687
|
-
// Remove any existing confirm dialog
|
|
8688
|
-
var existing = panelEl.querySelector('.cumulus-confirm-dialog');
|
|
8689
|
-
if (existing) existing.remove();
|
|
8690
|
-
|
|
8691
|
-
var dialog = document.createElement('div');
|
|
8692
|
-
dialog.className = 'cumulus-confirm-dialog';
|
|
8693
|
-
|
|
8694
|
-
var box = document.createElement('div');
|
|
8695
|
-
box.className = 'cumulus-confirm-dialog-box';
|
|
8696
|
-
|
|
8697
|
-
var title = document.createElement('div');
|
|
8698
|
-
title.className = 'cumulus-confirm-dialog-title';
|
|
8699
|
-
title.textContent = 'Delete Messages';
|
|
8700
|
-
box.appendChild(title);
|
|
8701
|
-
|
|
8702
|
-
var text = document.createElement('div');
|
|
8703
|
-
text.className = 'cumulus-confirm-dialog-text';
|
|
8704
|
-
text.textContent =
|
|
8705
|
-
ids.length + ' message' + (ids.length === 1 ? '' : 's') + ' will be permanently deleted.';
|
|
8706
|
-
box.appendChild(text);
|
|
8707
|
-
|
|
8708
|
-
var warn = document.createElement('div');
|
|
8709
|
-
warn.className = 'cumulus-confirm-dialog-warn';
|
|
8710
|
-
warn.textContent = 'This cannot be undone.';
|
|
8711
|
-
box.appendChild(warn);
|
|
8712
|
-
|
|
8713
|
-
var actions = document.createElement('div');
|
|
8714
|
-
actions.className = 'cumulus-confirm-dialog-actions';
|
|
8715
|
-
|
|
8716
|
-
var cancelBtn = document.createElement('button');
|
|
8717
|
-
cancelBtn.className = 'cumulus-confirm-dialog-cancel';
|
|
8718
|
-
cancelBtn.textContent = 'Cancel';
|
|
8719
|
-
cancelBtn.addEventListener('click', function () {
|
|
8720
|
-
dialog.remove();
|
|
8721
|
-
});
|
|
8722
|
-
actions.appendChild(cancelBtn);
|
|
8723
|
-
|
|
8724
|
-
var confirmBtn = document.createElement('button');
|
|
8725
|
-
confirmBtn.className = 'cumulus-confirm-dialog-confirm';
|
|
8726
|
-
confirmBtn.setAttribute('data-testid', 'webchat-delete-messages-confirm');
|
|
8727
|
-
confirmBtn.textContent = 'Delete';
|
|
8728
|
-
confirmBtn.addEventListener('click', function () {
|
|
8729
|
-
confirmBtn.disabled = true;
|
|
8730
|
-
confirmBtn.textContent = 'Deleting\u2026';
|
|
8731
|
-
if (connection) {
|
|
8732
|
-
connection.send({ type: 'delete_messages', threadName: tName, messageIds: ids });
|
|
8733
|
-
}
|
|
8734
|
-
dialog.remove();
|
|
8735
|
-
});
|
|
8736
|
-
actions.appendChild(confirmBtn);
|
|
8737
|
-
|
|
8738
|
-
box.appendChild(actions);
|
|
8739
|
-
dialog.appendChild(box);
|
|
8740
|
-
panelEl.appendChild(dialog);
|
|
8546
|
+
refreshSelectOverlay(panel);
|
|
8741
8547
|
}
|
|
8742
8548
|
|
|
8743
8549
|
function hasPanelUploading() {
|
|
@@ -9277,6 +9083,230 @@
|
|
|
9277
9083
|
});
|
|
9278
9084
|
}
|
|
9279
9085
|
|
|
9086
|
+
// ── Select-messages overlay ──
|
|
9087
|
+
// Compact one-line rows with checkboxes, modeled on the revert overlay's
|
|
9088
|
+
// list shape (task 163) — replaces the old inline checkboxes bolted onto
|
|
9089
|
+
// full message bubbles in the live thread view.
|
|
9090
|
+
function messagePreviewText(content) {
|
|
9091
|
+
if (typeof content !== 'string') return '';
|
|
9092
|
+
var text = content
|
|
9093
|
+
.replace(/```[\s\S]*?```/g, ' ')
|
|
9094
|
+
.replace(/[#*_`~>]/g, '')
|
|
9095
|
+
.replace(/\s+/g, ' ')
|
|
9096
|
+
.trim();
|
|
9097
|
+
if (text.length > 90) text = text.slice(0, 90) + '…';
|
|
9098
|
+
return text || '(empty)';
|
|
9099
|
+
}
|
|
9100
|
+
|
|
9101
|
+
function renderSelectRows(body, messages, selectedIds, onToggle) {
|
|
9102
|
+
body.innerHTML = '';
|
|
9103
|
+
var any = false;
|
|
9104
|
+
messages.forEach(function (msg) {
|
|
9105
|
+
if (msg.role === 'thinking') return;
|
|
9106
|
+
any = true;
|
|
9107
|
+
|
|
9108
|
+
var item = document.createElement('div');
|
|
9109
|
+
item.className = 'cumulus-select-item';
|
|
9110
|
+
item.setAttribute('data-testid', 'webchat-select-item');
|
|
9111
|
+
|
|
9112
|
+
var cb = document.createElement('input');
|
|
9113
|
+
cb.type = 'checkbox';
|
|
9114
|
+
cb.className = 'cumulus-select-checkbox';
|
|
9115
|
+
cb.disabled = !msg.id;
|
|
9116
|
+
cb.checked = !!(msg.id && selectedIds[msg.id]);
|
|
9117
|
+
item.appendChild(cb);
|
|
9118
|
+
|
|
9119
|
+
var roleEl = document.createElement('span');
|
|
9120
|
+
roleEl.className = 'cumulus-select-role';
|
|
9121
|
+
roleEl.textContent = msg.role || 'message';
|
|
9122
|
+
item.appendChild(roleEl);
|
|
9123
|
+
|
|
9124
|
+
var previewEl = document.createElement('span');
|
|
9125
|
+
previewEl.className = 'cumulus-select-preview';
|
|
9126
|
+
previewEl.textContent = messagePreviewText(msg.content);
|
|
9127
|
+
item.appendChild(previewEl);
|
|
9128
|
+
|
|
9129
|
+
var timeEl = document.createElement('span');
|
|
9130
|
+
timeEl.className = 'cumulus-select-time';
|
|
9131
|
+
timeEl.textContent = formatTime(msg.timestamp);
|
|
9132
|
+
item.appendChild(timeEl);
|
|
9133
|
+
|
|
9134
|
+
function applyToggle(checked) {
|
|
9135
|
+
if (!msg.id) return;
|
|
9136
|
+
cb.checked = checked;
|
|
9137
|
+
if (checked) {
|
|
9138
|
+
selectedIds[msg.id] = true;
|
|
9139
|
+
} else {
|
|
9140
|
+
delete selectedIds[msg.id];
|
|
9141
|
+
}
|
|
9142
|
+
onToggle();
|
|
9143
|
+
}
|
|
9144
|
+
|
|
9145
|
+
cb.addEventListener('change', function () {
|
|
9146
|
+
applyToggle(cb.checked);
|
|
9147
|
+
});
|
|
9148
|
+
item.addEventListener('click', function (e) {
|
|
9149
|
+
if (e.target === cb) return;
|
|
9150
|
+
applyToggle(!cb.checked);
|
|
9151
|
+
});
|
|
9152
|
+
|
|
9153
|
+
body.appendChild(item);
|
|
9154
|
+
});
|
|
9155
|
+
if (!any) {
|
|
9156
|
+
body.innerHTML = '<div class="cumulus-overlay-empty">No messages to select.</div>';
|
|
9157
|
+
}
|
|
9158
|
+
}
|
|
9159
|
+
|
|
9160
|
+
function showDeleteMessagesConfirm(tName, panelEl, ids) {
|
|
9161
|
+
// Remove any existing confirm dialog
|
|
9162
|
+
var existing = panelEl.querySelector('.cumulus-confirm-dialog');
|
|
9163
|
+
if (existing) existing.remove();
|
|
9164
|
+
|
|
9165
|
+
var dialog = document.createElement('div');
|
|
9166
|
+
dialog.className = 'cumulus-confirm-dialog';
|
|
9167
|
+
|
|
9168
|
+
var box = document.createElement('div');
|
|
9169
|
+
box.className = 'cumulus-confirm-dialog-box';
|
|
9170
|
+
|
|
9171
|
+
var title = document.createElement('div');
|
|
9172
|
+
title.className = 'cumulus-confirm-dialog-title';
|
|
9173
|
+
title.textContent = 'Delete Messages';
|
|
9174
|
+
box.appendChild(title);
|
|
9175
|
+
|
|
9176
|
+
var text = document.createElement('div');
|
|
9177
|
+
text.className = 'cumulus-confirm-dialog-text';
|
|
9178
|
+
text.textContent =
|
|
9179
|
+
ids.length + ' message' + (ids.length === 1 ? '' : 's') + ' will be permanently deleted.';
|
|
9180
|
+
box.appendChild(text);
|
|
9181
|
+
|
|
9182
|
+
var warn = document.createElement('div');
|
|
9183
|
+
warn.className = 'cumulus-confirm-dialog-warn';
|
|
9184
|
+
warn.textContent = 'This cannot be undone.';
|
|
9185
|
+
box.appendChild(warn);
|
|
9186
|
+
|
|
9187
|
+
var actions = document.createElement('div');
|
|
9188
|
+
actions.className = 'cumulus-confirm-dialog-actions';
|
|
9189
|
+
|
|
9190
|
+
var cancelBtn = document.createElement('button');
|
|
9191
|
+
cancelBtn.className = 'cumulus-confirm-dialog-cancel';
|
|
9192
|
+
cancelBtn.textContent = 'Cancel';
|
|
9193
|
+
cancelBtn.addEventListener('click', function () {
|
|
9194
|
+
dialog.remove();
|
|
9195
|
+
});
|
|
9196
|
+
actions.appendChild(cancelBtn);
|
|
9197
|
+
|
|
9198
|
+
var confirmBtn = document.createElement('button');
|
|
9199
|
+
confirmBtn.className = 'cumulus-confirm-dialog-confirm';
|
|
9200
|
+
confirmBtn.setAttribute('data-testid', 'webchat-delete-messages-confirm');
|
|
9201
|
+
confirmBtn.textContent = 'Delete';
|
|
9202
|
+
confirmBtn.addEventListener('click', function () {
|
|
9203
|
+
confirmBtn.disabled = true;
|
|
9204
|
+
confirmBtn.textContent = 'Deleting…';
|
|
9205
|
+
if (connection) {
|
|
9206
|
+
connection.send({ type: 'delete_messages', threadName: tName, messageIds: ids });
|
|
9207
|
+
}
|
|
9208
|
+
dialog.remove();
|
|
9209
|
+
});
|
|
9210
|
+
actions.appendChild(confirmBtn);
|
|
9211
|
+
|
|
9212
|
+
box.appendChild(actions);
|
|
9213
|
+
dialog.appendChild(box);
|
|
9214
|
+
panelEl.appendChild(dialog);
|
|
9215
|
+
}
|
|
9216
|
+
|
|
9217
|
+
function openSelectOverlay(panel, threadName) {
|
|
9218
|
+
var existing = panel.querySelector('.cumulus-overlay');
|
|
9219
|
+
if (existing) {
|
|
9220
|
+
existing.remove();
|
|
9221
|
+
return;
|
|
9222
|
+
}
|
|
9223
|
+
|
|
9224
|
+
getThreadState(threadName).selectedIds = {};
|
|
9225
|
+
|
|
9226
|
+
var overlay = document.createElement('div');
|
|
9227
|
+
overlay.className = 'cumulus-overlay';
|
|
9228
|
+
overlay.setAttribute('data-overlay-kind', 'select');
|
|
9229
|
+
|
|
9230
|
+
var header = document.createElement('div');
|
|
9231
|
+
header.className = 'cumulus-overlay-header';
|
|
9232
|
+
var title = document.createElement('span');
|
|
9233
|
+
title.className = 'cumulus-overlay-title';
|
|
9234
|
+
title.textContent = 'Select Messages';
|
|
9235
|
+
header.appendChild(title);
|
|
9236
|
+
var closeBtn = document.createElement('button');
|
|
9237
|
+
closeBtn.className = 'cumulus-overlay-close';
|
|
9238
|
+
closeBtn.textContent = '\xD7';
|
|
9239
|
+
closeBtn.addEventListener('click', function () {
|
|
9240
|
+
overlay.remove();
|
|
9241
|
+
});
|
|
9242
|
+
header.appendChild(closeBtn);
|
|
9243
|
+
overlay.appendChild(header);
|
|
9244
|
+
|
|
9245
|
+
var body = document.createElement('div');
|
|
9246
|
+
body.className = 'cumulus-overlay-body';
|
|
9247
|
+
overlay.appendChild(body);
|
|
9248
|
+
|
|
9249
|
+
var footer = document.createElement('div');
|
|
9250
|
+
footer.className = 'cumulus-selection-bar';
|
|
9251
|
+
overlay.appendChild(footer);
|
|
9252
|
+
|
|
9253
|
+
function refresh() {
|
|
9254
|
+
var st = getThreadState(threadName);
|
|
9255
|
+
renderSelectRows(body, st.messages, st.selectedIds, updateFooter);
|
|
9256
|
+
updateFooter();
|
|
9257
|
+
}
|
|
9258
|
+
|
|
9259
|
+
function updateFooter() {
|
|
9260
|
+
var st = getThreadState(threadName);
|
|
9261
|
+
footer.innerHTML = '';
|
|
9262
|
+
var selectedCount = Object.keys(st.selectedIds).length;
|
|
9263
|
+
var selectableCount = st.messages.filter(function (m) {
|
|
9264
|
+
return !!m.id;
|
|
9265
|
+
}).length;
|
|
9266
|
+
|
|
9267
|
+
var countEl = document.createElement('span');
|
|
9268
|
+
countEl.className = 'cumulus-selection-count';
|
|
9269
|
+
countEl.textContent = selectedCount + ' selected';
|
|
9270
|
+
footer.appendChild(countEl);
|
|
9271
|
+
|
|
9272
|
+
var selectAllBtn = document.createElement('button');
|
|
9273
|
+
selectAllBtn.className = 'cumulus-selection-select-all-btn';
|
|
9274
|
+
selectAllBtn.textContent =
|
|
9275
|
+
selectedCount === selectableCount && selectableCount > 0 ? 'Deselect All' : 'Select All';
|
|
9276
|
+
selectAllBtn.addEventListener('click', function () {
|
|
9277
|
+
if (selectedCount === selectableCount && selectableCount > 0) {
|
|
9278
|
+
st.selectedIds = {};
|
|
9279
|
+
} else {
|
|
9280
|
+
st.messages.forEach(function (m) {
|
|
9281
|
+
if (m.id) st.selectedIds[m.id] = true;
|
|
9282
|
+
});
|
|
9283
|
+
}
|
|
9284
|
+
refresh();
|
|
9285
|
+
});
|
|
9286
|
+
footer.appendChild(selectAllBtn);
|
|
9287
|
+
|
|
9288
|
+
var deleteBtn = document.createElement('button');
|
|
9289
|
+
deleteBtn.className = 'cumulus-selection-delete-btn';
|
|
9290
|
+
deleteBtn.textContent = 'Delete';
|
|
9291
|
+
deleteBtn.disabled = selectedCount === 0;
|
|
9292
|
+
deleteBtn.setAttribute('data-testid', 'webchat-select-delete-btn');
|
|
9293
|
+
deleteBtn.addEventListener('click', function () {
|
|
9294
|
+
if (selectedCount === 0) return;
|
|
9295
|
+
showDeleteMessagesConfirm(threadName, panel, Object.keys(st.selectedIds));
|
|
9296
|
+
});
|
|
9297
|
+
footer.appendChild(deleteBtn);
|
|
9298
|
+
}
|
|
9299
|
+
|
|
9300
|
+
overlay._refresh = refresh;
|
|
9301
|
+
refresh();
|
|
9302
|
+
panel.appendChild(overlay);
|
|
9303
|
+
}
|
|
9304
|
+
|
|
9305
|
+
function refreshSelectOverlay(panel) {
|
|
9306
|
+
var overlay = panel.querySelector('.cumulus-overlay[data-overlay-kind="select"]');
|
|
9307
|
+
if (overlay && overlay._refresh) overlay._refresh();
|
|
9308
|
+
}
|
|
9309
|
+
|
|
9280
9310
|
// ── Revert overlay ──
|
|
9281
9311
|
function openRevertOverlay(panel, threadName) {
|
|
9282
9312
|
var existing = panel.querySelector('.cumulus-overlay');
|
|
@@ -9648,20 +9678,12 @@
|
|
|
9648
9678
|
var dState = getThreadState(data.threadName);
|
|
9649
9679
|
dState.messages = [];
|
|
9650
9680
|
dState.historyLoaded = false;
|
|
9651
|
-
dState.selectionMode = false;
|
|
9652
9681
|
dState.selectedIds = {};
|
|
9653
|
-
//
|
|
9682
|
+
// Close the select overlay on the visible panel, if open
|
|
9654
9683
|
var dPanel = document.querySelector('[data-thread-panel="' + data.threadName + '"]');
|
|
9655
9684
|
if (dPanel) {
|
|
9656
|
-
var
|
|
9657
|
-
if (
|
|
9658
|
-
var dBar = dPanel.querySelector('.cumulus-selection-bar');
|
|
9659
|
-
if (dBar) dBar.remove();
|
|
9660
|
-
var dSelectBtn = dPanel.querySelector('[data-testid="webchat-select-btn"]');
|
|
9661
|
-
if (dSelectBtn) {
|
|
9662
|
-
dSelectBtn.textContent = 'Select';
|
|
9663
|
-
dSelectBtn.classList.remove('active');
|
|
9664
|
-
}
|
|
9685
|
+
var dOverlay = dPanel.querySelector('.cumulus-overlay[data-overlay-kind="select"]');
|
|
9686
|
+
if (dOverlay) dOverlay.remove();
|
|
9665
9687
|
}
|
|
9666
9688
|
connection &&
|
|
9667
9689
|
connection.send({ type: 'history', threadName: data.threadName, limit: 200 });
|