clay-server 2.29.4-beta.2 → 2.29.4-beta.3
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.
|
@@ -1135,13 +1135,8 @@ export function processMessage(msg) {
|
|
|
1135
1135
|
var _s1 = store.getState();
|
|
1136
1136
|
if (fromId && fromId !== _s1.myUserId) {
|
|
1137
1137
|
_s1.dmUnread[fromId] = (_s1.dmUnread[fromId] || 0) + 1;
|
|
1138
|
-
//
|
|
1139
|
-
|
|
1140
|
-
// just update the badge in-place to avoid a full DOM rebuild flicker.
|
|
1141
|
-
var existingEl = document.querySelector('.icon-strip-user[data-user-id="' + fromId + '"]');
|
|
1142
|
-
if (!existingEl) {
|
|
1143
|
-
renderUserStrip(_s1.cachedAllUsers, _s1.cachedOnlineIds, _s1.myUserId, _s1.cachedDmFavorites, _s1.cachedDmConversations, _s1.dmUnread, _s1.dmRemovedUsers, _s1.cachedMatesList);
|
|
1144
|
-
}
|
|
1138
|
+
// Re-render strip so non-favorited sender appears
|
|
1139
|
+
renderUserStrip(_s1.cachedAllUsers, _s1.cachedOnlineIds, _s1.myUserId, _s1.cachedDmFavorites, _s1.cachedDmConversations, _s1.dmUnread, _s1.dmRemovedUsers, _s1.cachedMatesList);
|
|
1145
1140
|
updateDmBadge(fromId, _s1.dmUnread[fromId]);
|
|
1146
1141
|
}
|
|
1147
1142
|
}
|
|
@@ -181,23 +181,40 @@ export function setCachedRemovedProjects(v) { cachedRemovedProjects = v; }
|
|
|
181
181
|
|
|
182
182
|
export function updateProjectList(msg) {
|
|
183
183
|
if (typeof msg.projectCount === "number") cachedProjectCount = msg.projectCount;
|
|
184
|
-
|
|
184
|
+
|
|
185
|
+
// Compare projects before caching to detect actual changes
|
|
186
|
+
var projectsChanged = false;
|
|
187
|
+
if (msg.projects) {
|
|
188
|
+
var projectsJson = JSON.stringify(msg.projects);
|
|
189
|
+
if (projectsJson !== _lastProjectsJson) {
|
|
190
|
+
projectsChanged = true;
|
|
191
|
+
_lastProjectsJson = projectsJson;
|
|
192
|
+
}
|
|
193
|
+
cachedProjects = msg.projects;
|
|
194
|
+
}
|
|
185
195
|
if (msg.removedProjects) cachedRemovedProjects = msg.removedProjects;
|
|
186
196
|
else if (msg.removedProjects === undefined) { /* keep cached */ }
|
|
187
197
|
else cachedRemovedProjects = [];
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
var
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
|
|
199
|
+
// Only re-render project strip + title bar if data or active slug changed
|
|
200
|
+
var slugChanged = _ctx.currentSlug !== _lastRenderedSlug;
|
|
201
|
+
if (projectsChanged || slugChanged) {
|
|
202
|
+
_lastRenderedSlug = _ctx.currentSlug;
|
|
203
|
+
var count = cachedProjectCount || 0;
|
|
204
|
+
renderProjectList();
|
|
205
|
+
var projectHint = _ctx.$("project-hint");
|
|
206
|
+
if (count === 1 && projectHint) {
|
|
207
|
+
try {
|
|
208
|
+
if (!localStorage.getItem("clay-project-hint-dismissed")) {
|
|
209
|
+
projectHint.classList.remove("hidden");
|
|
210
|
+
}
|
|
211
|
+
} catch (e) {}
|
|
212
|
+
} else if (projectHint) {
|
|
213
|
+
projectHint.classList.add("hidden");
|
|
214
|
+
}
|
|
199
215
|
}
|
|
200
|
-
|
|
216
|
+
|
|
217
|
+
// Update topbar with server-wide presence (renderTopbarPresence has its own guard)
|
|
201
218
|
if (msg.serverUsers) {
|
|
202
219
|
var newOnlineIds = msg.serverUsers.map(function (u) { return u.id; });
|
|
203
220
|
var prevOnlineIds = _ctx.cachedOnlineIds || [];
|
|
@@ -211,12 +228,24 @@ export function updateProjectList(msg) {
|
|
|
211
228
|
}
|
|
212
229
|
}
|
|
213
230
|
}
|
|
214
|
-
|
|
231
|
+
|
|
232
|
+
// Update user strip (DM targets) - only if user data actually changed
|
|
215
233
|
if (msg.allUsers) {
|
|
234
|
+
var allUsersJson = JSON.stringify(msg.allUsers);
|
|
235
|
+
var dmFavJson = msg.dmFavorites ? JSON.stringify(msg.dmFavorites) : _lastDmFavJson;
|
|
236
|
+
var dmConvJson = msg.dmConversations ? JSON.stringify(msg.dmConversations) : _lastDmConvJson;
|
|
237
|
+
var userDataChanged = allUsersJson !== _lastAllUsersJson || dmFavJson !== _lastDmFavJson || dmConvJson !== _lastDmConvJson;
|
|
238
|
+
|
|
216
239
|
_ctx.setCachedAllUsers(msg.allUsers);
|
|
217
240
|
if (msg.dmFavorites) _ctx.setCachedDmFavorites(msg.dmFavorites);
|
|
218
241
|
if (msg.dmConversations) _ctx.setCachedDmConversations(msg.dmConversations);
|
|
219
|
-
|
|
242
|
+
|
|
243
|
+
if (userDataChanged) {
|
|
244
|
+
_lastAllUsersJson = allUsersJson;
|
|
245
|
+
_lastDmFavJson = dmFavJson;
|
|
246
|
+
_lastDmConvJson = dmConvJson;
|
|
247
|
+
_ctx.renderUserStrip(msg.allUsers, _ctx.cachedOnlineIds, _ctx.myUserId, _ctx.cachedDmFavorites, _ctx.cachedDmConversations, _ctx.dmUnread, _ctx.dmRemovedUsers, _ctx.cachedMatesList);
|
|
248
|
+
}
|
|
220
249
|
if (document.body.classList.contains("mate-dm-active") || document.body.classList.contains("wide-view")) {
|
|
221
250
|
var refreshedMyUser = _ctx.cachedAllUsers.find(function (u) { return u.id === _ctx.myUserId; });
|
|
222
251
|
if (refreshedMyUser) {
|
|
@@ -240,6 +269,11 @@ export function updateProjectList(msg) {
|
|
|
240
269
|
}
|
|
241
270
|
|
|
242
271
|
var _lastTopbarUserIds = [];
|
|
272
|
+
var _lastProjectsJson = "";
|
|
273
|
+
var _lastRenderedSlug = null;
|
|
274
|
+
var _lastAllUsersJson = "";
|
|
275
|
+
var _lastDmFavJson = "";
|
|
276
|
+
var _lastDmConvJson = "";
|
|
243
277
|
export function renderTopbarPresence(serverUsers) {
|
|
244
278
|
var countEl = document.getElementById("client-count");
|
|
245
279
|
if (!countEl) return;
|
|
@@ -311,11 +345,7 @@ export function renderProjectList() {
|
|
|
311
345
|
}
|
|
312
346
|
}
|
|
313
347
|
}
|
|
314
|
-
//
|
|
315
|
-
var allDots = document.querySelectorAll("#icon-strip-projects .icon-strip-status");
|
|
316
|
-
for (var di = 0; di < allDots.length; di++) {
|
|
317
|
-
allDots[di].classList.remove("connected", "processing");
|
|
318
|
-
}
|
|
348
|
+
// Re-apply current socket status to the active icon's dot
|
|
319
349
|
var dot = _ctx.getStatusDot();
|
|
320
350
|
if (dot) {
|
|
321
351
|
if (_ctx.connected && _ctx.processing) { dot.classList.add("connected"); dot.classList.add("processing"); }
|
|
@@ -1170,62 +1170,12 @@ function showWorktreeModal(parentSlug, parentName) {
|
|
|
1170
1170
|
|
|
1171
1171
|
// --- Render icon strip ---
|
|
1172
1172
|
|
|
1173
|
-
// Build a fingerprint string for the project list so we can detect when only
|
|
1174
|
-
// the active slug changed (no structural DOM rebuild needed).
|
|
1175
|
-
function projectListFingerprint(projects) {
|
|
1176
|
-
var parts = [];
|
|
1177
|
-
for (var i = 0; i < projects.length; i++) {
|
|
1178
|
-
var p = projects[i];
|
|
1179
|
-
parts.push(p.slug + ":" + (p.icon || "") + ":" + (p.isProcessing ? 1 : 0) + ":" + (p.unread || 0) + ":" + (p.pendingPermissions || 0) + ":" + (p.isWorktree ? 1 : 0) + ":" + (p.parentSlug || "") + ":" + (p.worktreeAccessible !== false ? 1 : 0));
|
|
1180
|
-
}
|
|
1181
|
-
return parts.join("|");
|
|
1182
|
-
}
|
|
1183
|
-
var _lastStripFingerprint = "";
|
|
1184
|
-
|
|
1185
1173
|
export function renderIconStrip(projects, currentSlug) {
|
|
1186
1174
|
cachedProjectList = projects;
|
|
1187
1175
|
cachedCurrentSlug = currentSlug;
|
|
1188
1176
|
|
|
1189
1177
|
var container = document.getElementById("icon-strip-projects");
|
|
1190
1178
|
if (!container) return;
|
|
1191
|
-
|
|
1192
|
-
// Fast path: if only the active slug changed (project list unchanged),
|
|
1193
|
-
// just toggle active classes instead of a full DOM rebuild.
|
|
1194
|
-
var fp = projectListFingerprint(projects);
|
|
1195
|
-
if (fp === _lastStripFingerprint && container.children.length > 0) {
|
|
1196
|
-
var currentDmUserId2 = _ctx.getCurrentDmUserId ? _ctx.getCurrentDmUserId() : null;
|
|
1197
|
-
var items = container.querySelectorAll(".icon-strip-item");
|
|
1198
|
-
for (var fi = 0; fi < items.length; fi++) {
|
|
1199
|
-
var isNowActive = items[fi].dataset.slug === currentSlug && !currentDmUserId2;
|
|
1200
|
-
items[fi].classList.toggle("active", isNowActive);
|
|
1201
|
-
// Clear stale socket status dot from inactive items
|
|
1202
|
-
if (!isNowActive) {
|
|
1203
|
-
var statusDot = items[fi].querySelector(".icon-strip-status");
|
|
1204
|
-
if (statusDot) statusDot.classList.remove("connected", "processing");
|
|
1205
|
-
}
|
|
1206
|
-
// Update unread badge visibility (active items hide their badge)
|
|
1207
|
-
var badge = items[fi].querySelector(".icon-strip-project-badge");
|
|
1208
|
-
if (badge && badge.classList.contains("has-unread") && isNowActive) {
|
|
1209
|
-
badge.textContent = "";
|
|
1210
|
-
badge.classList.remove("has-unread");
|
|
1211
|
-
}
|
|
1212
|
-
// Update pending permission glow
|
|
1213
|
-
if (isNowActive) items[fi].classList.remove("has-pending-perm");
|
|
1214
|
-
}
|
|
1215
|
-
// Update home icon
|
|
1216
|
-
var homeIcon2 = document.querySelector(".icon-strip-home");
|
|
1217
|
-
if (homeIcon2) {
|
|
1218
|
-
if ((!currentSlug || projects.length === 0) && !currentDmUserId2) {
|
|
1219
|
-
homeIcon2.classList.add("active");
|
|
1220
|
-
} else {
|
|
1221
|
-
homeIcon2.classList.remove("active");
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
renderProjectList(projects, currentSlug);
|
|
1225
|
-
return;
|
|
1226
|
-
}
|
|
1227
|
-
_lastStripFingerprint = fp;
|
|
1228
|
-
|
|
1229
1179
|
container.innerHTML = "";
|
|
1230
1180
|
|
|
1231
1181
|
var currentDmUserId = _ctx.getCurrentDmUserId ? _ctx.getCurrentDmUserId() : null;
|