clay-server 3.8.0-beta.1 → 3.8.0-beta.2
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/lib/builtin-mates.js +14 -14
- package/lib/mates.js +2 -6
- package/lib/project-mate-interaction.js +7 -7
- package/lib/project-sessions.js +1 -1
- package/lib/project-user-mention.js +4 -4
- package/lib/project.js +4 -3
- package/lib/public/css/avatar-imprints.css +46 -0
- package/lib/public/css/icon-strip.css +3 -3
- package/lib/public/css/profile.css +123 -95
- package/lib/public/css/session-actions.css +40 -9
- package/lib/public/css/user-settings.css +1 -1
- package/lib/public/index.html +2 -2
- package/lib/public/modules/app-cursors.js +2 -2
- package/lib/public/modules/app-dm.js +1 -8
- package/lib/public/modules/app-messages.js +2 -2
- package/lib/public/modules/app-projects.js +7 -6
- package/lib/public/modules/app-rate-limit.js +0 -1
- package/lib/public/modules/app-rendering.js +0 -3
- package/lib/public/modules/avatar-imprint.js +134 -0
- package/lib/public/modules/avatar.js +25 -19
- package/lib/public/modules/debate.js +10 -5
- package/lib/public/modules/mate-sidebar.js +2 -2
- package/lib/public/modules/mention.js +26 -16
- package/lib/public/modules/profile.js +73 -190
- package/lib/public/modules/session-actions.js +5 -3
- package/lib/public/modules/sidebar-mates.js +5 -4
- package/lib/public/modules/sidebar-sessions.js +1 -1
- package/lib/public/style.css +1 -0
- package/lib/server-auth.js +2 -2
- package/lib/server-dm.js +8 -8
- package/lib/server-mates.js +3 -3
- package/lib/server-settings.js +2 -2
- package/lib/server.js +5 -4
- package/lib/users.js +4 -4
- package/package.json +1 -1
|
@@ -72,8 +72,8 @@ function createCursorElement(userId, displayName, color, avatarStyle, avatarSeed
|
|
|
72
72
|
// Avatar
|
|
73
73
|
var avatarImg = document.createElement("img");
|
|
74
74
|
avatarImg.className = "remote-cursor-avatar";
|
|
75
|
-
avatarImg.src = avatarCustom ? avatarCustom : avatarUrl(avatarStyle || "
|
|
76
|
-
avatarImg.style.cssText = "width:14px;height:14px;border-radius:
|
|
75
|
+
avatarImg.src = avatarCustom ? avatarCustom : avatarUrl(avatarStyle || "imprint", avatarSeed || userId, 16);
|
|
76
|
+
avatarImg.style.cssText = "width:14px;height:14px;border-radius:4px;background:#fff;flex-shrink:0;";
|
|
77
77
|
tag.appendChild(avatarImg);
|
|
78
78
|
|
|
79
79
|
// Name label
|
|
@@ -215,7 +215,7 @@ export function enterDmMode(key, targetUser, messages) {
|
|
|
215
215
|
var termBtn = document.getElementById("terminal-toggle-btn");
|
|
216
216
|
if (termBtn) termBtn.style.display = "none";
|
|
217
217
|
// Apply mate color to chat title bar and panels
|
|
218
|
-
var mateColor = (targetUser.profile && targetUser.profile.avatarColor) || targetUser.avatarColor || "#
|
|
218
|
+
var mateColor = (targetUser.profile && targetUser.profile.avatarColor) || targetUser.avatarColor || "#5857fc";
|
|
219
219
|
document.body.style.setProperty("--mate-color", mateColor);
|
|
220
220
|
document.body.style.setProperty("--mate-color-tint", mateColor + "0a");
|
|
221
221
|
document.body.classList.add("mate-dm-active");
|
|
@@ -223,19 +223,12 @@ export function enterDmMode(key, targetUser, messages) {
|
|
|
223
223
|
var mp = targetUser.profile || {};
|
|
224
224
|
var mateAvUrlDm = mateAvatarUrl(targetUser, 36);
|
|
225
225
|
var myUser = store.get('cachedAllUsers').find(function (u) { return u.id === store.get('myUserId'); });
|
|
226
|
-
if (!myUser) {
|
|
227
|
-
try { var cached = JSON.parse(localStorage.getItem("clay_my_user") || "null"); if (cached) myUser = cached; } catch(e) {}
|
|
228
|
-
}
|
|
229
226
|
var myAvatarUrl = userAvatarUrl(myUser || { id: store.get('myUserId') }, 36);
|
|
230
227
|
var myDisplayName = (myUser && myUser.displayName) || "";
|
|
231
228
|
document.body.dataset.mateAvatarUrl = mateAvUrlDm;
|
|
232
229
|
document.body.dataset.mateName = mp.displayName || targetUser.displayName || targetUser.name || "";
|
|
233
230
|
document.body.dataset.myAvatarUrl = myAvatarUrl;
|
|
234
231
|
document.body.dataset.myDisplayName = myDisplayName;
|
|
235
|
-
// Cache my info for restore after hard refresh
|
|
236
|
-
if (myUser) {
|
|
237
|
-
try { localStorage.setItem("clay_my_user", JSON.stringify({ displayName: myUser.displayName, avatarStyle: myUser.avatarStyle, avatarSeed: myUser.avatarSeed, avatarCustom: myUser.avatarCustom, username: myUser.username })); } catch(e) {}
|
|
238
|
-
}
|
|
239
232
|
var titleBarContent = document.querySelector(".title-bar-content");
|
|
240
233
|
if (titleBarContent) {
|
|
241
234
|
titleBarContent.style.background = mateColor;
|
|
@@ -95,7 +95,7 @@ export function processMessage(msg) {
|
|
|
95
95
|
if (headerTitleEl) headerTitleEl.textContent = _mdn;
|
|
96
96
|
var _tbpn = document.getElementById("title-bar-project-name");
|
|
97
97
|
if (_tbpn) _tbpn.textContent = _mdn;
|
|
98
|
-
var _mc2 = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#
|
|
98
|
+
var _mc2 = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#5857fc";
|
|
99
99
|
var _tbc2 = document.querySelector(".title-bar-content");
|
|
100
100
|
if (_tbc2) { _tbc2.style.background = _mc2; _tbc2.classList.add("mate-dm-active"); }
|
|
101
101
|
document.body.classList.add("mate-dm-active");
|
|
@@ -299,7 +299,7 @@ export function processMessage(msg) {
|
|
|
299
299
|
var tbProjectName = document.getElementById("title-bar-project-name");
|
|
300
300
|
if (tbProjectName) tbProjectName.textContent = _mateDN;
|
|
301
301
|
// Re-apply mate title bar styling (may be lost during project switch)
|
|
302
|
-
var _mc = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#
|
|
302
|
+
var _mc = (store.get('dmTargetUser').profile && store.get('dmTargetUser').profile.avatarColor) || store.get('dmTargetUser').avatarColor || "#5857fc";
|
|
303
303
|
var _tbc = document.querySelector(".title-bar-content");
|
|
304
304
|
if (_tbc) { _tbc.style.background = _mc; _tbc.classList.add("mate-dm-active"); }
|
|
305
305
|
document.body.classList.add("mate-dm-active");
|
|
@@ -257,12 +257,13 @@ export function updateProjectList(msg) {
|
|
|
257
257
|
if (msg.dmConversations) store.set({ cachedDmConversations: msg.dmConversations });
|
|
258
258
|
// renderUserStrip is handled by the store subscriber
|
|
259
259
|
var st2 = store.snap();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
var refreshedMyUser = st2.cachedAllUsers.find(function (u) { return u.id === st2.myUserId; });
|
|
261
|
+
if (refreshedMyUser) {
|
|
262
|
+
document.body.dataset.myDisplayName = refreshedMyUser.displayName || refreshedMyUser.username || "";
|
|
263
|
+
document.body.dataset.myAvatarUrl = userAvatarUrl(refreshedMyUser, 36);
|
|
264
|
+
var myMessageAvatars = document.querySelectorAll('.dm-bubble-avatar-me');
|
|
265
|
+
for (var avatarIndex = 0; avatarIndex < myMessageAvatars.length; avatarIndex++) {
|
|
266
|
+
myMessageAvatars[avatarIndex].src = document.body.dataset.myAvatarUrl;
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
// Render my avatar (always present, hidden behind user-island)
|
|
@@ -311,7 +311,6 @@ export function addScheduledMessageBubble(text, resetsAt) {
|
|
|
311
311
|
if (isChannel) {
|
|
312
312
|
// Channel mode: avatar + header with scheduled badge + message
|
|
313
313
|
var _me = store.get('cachedAllUsers').find(function (u) { return u.id === store.get('myUserId'); });
|
|
314
|
-
if (!_me) { try { _me = JSON.parse(localStorage.getItem("clay_my_user") || "null"); } catch(e) {} }
|
|
315
314
|
var _myName = document.body.dataset.myDisplayName || (_me && (_me.displayName || _me.username)) || "Me";
|
|
316
315
|
|
|
317
316
|
var avi = document.createElement("img");
|
|
@@ -552,9 +552,6 @@ export function addUserMessage(text, images, pastes, fromUserId, fromUserName, d
|
|
|
552
552
|
_displayName = fromUserName || (_targetUser && (_targetUser.displayName || _targetUser.username)) || "User";
|
|
553
553
|
} else {
|
|
554
554
|
_targetUser = cachedAllUsers.find(function (u) { return u.id === myUserId; });
|
|
555
|
-
if (!_targetUser) {
|
|
556
|
-
try { _targetUser = JSON.parse(localStorage.getItem("clay_my_user") || "null"); } catch(e) {}
|
|
557
|
-
}
|
|
558
555
|
_displayName = document.body.dataset.myDisplayName || "";
|
|
559
556
|
if (!_displayName) {
|
|
560
557
|
_displayName = (_targetUser && (_targetUser.displayName || _targetUser.username)) || "Me";
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Clay Imprints: deterministic SVG identities derived from a stable seed.
|
|
2
|
+
|
|
3
|
+
var PAPER = "#f1efe8";
|
|
4
|
+
var INK = "#1b1b1a";
|
|
5
|
+
var LIGHT_BASE = "#e7e5de";
|
|
6
|
+
var LIGHT_FIELD = "#333330";
|
|
7
|
+
var REGISTRATION_INDIGO = "#5857fc";
|
|
8
|
+
var BRAND_GREEN = "#07e5a3";
|
|
9
|
+
|
|
10
|
+
function hashString(value) {
|
|
11
|
+
var text = String(value || "anonymous");
|
|
12
|
+
var hash = 2166136261;
|
|
13
|
+
for (var index = 0; index < text.length; index++) {
|
|
14
|
+
hash ^= text.charCodeAt(index);
|
|
15
|
+
hash = Math.imul(hash, 16777619);
|
|
16
|
+
}
|
|
17
|
+
return hash >>> 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function makeRandom(seed) {
|
|
21
|
+
var state = seed >>> 0;
|
|
22
|
+
return function nextRandom() {
|
|
23
|
+
state += 0x6d2b79f5;
|
|
24
|
+
var value = state;
|
|
25
|
+
value = Math.imul(value ^ (value >>> 15), value | 1);
|
|
26
|
+
value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
|
|
27
|
+
return ((value ^ (value >>> 14)) >>> 0) / 4294967296;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function between(random, min, max) {
|
|
32
|
+
return min + random() * (max - min);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function number(value) {
|
|
36
|
+
return Math.round(value * 100) / 100;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function xmlText(value) {
|
|
40
|
+
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function legacyIdentity(style, seed) {
|
|
44
|
+
var sourceStyle = String(style || "imprint").toLowerCase();
|
|
45
|
+
var sourceSeed = String(seed || "anonymous");
|
|
46
|
+
if (sourceStyle === "imprint") return sourceSeed;
|
|
47
|
+
return "legacy:" + sourceStyle + ":" + sourceSeed;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function curvePath(y, bow, endOffset) {
|
|
51
|
+
return "M -28 " + number(y) +
|
|
52
|
+
" C 17 " + number(y + bow) +
|
|
53
|
+
", 71 " + number(y - bow) +
|
|
54
|
+
", 124 " + number(y + endOffset);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function cutPath(random) {
|
|
58
|
+
var start = between(random, 37, 52);
|
|
59
|
+
var first = between(random, 14, 84);
|
|
60
|
+
var second = between(random, 12, 86);
|
|
61
|
+
var end = between(random, 40, 64);
|
|
62
|
+
return "M -22 " + number(start) + " C 21 " + number(first) + ", 73 " + number(second) + ", 118 " + number(end);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function imprintSvg(options) {
|
|
66
|
+
var settings = options || {};
|
|
67
|
+
var size = Math.max(12, Math.min(256, Number(settings.size) || 64));
|
|
68
|
+
var identity = legacyIdentity(settings.style, settings.seed);
|
|
69
|
+
var hash = hashString(identity);
|
|
70
|
+
var random = makeRandom(hash);
|
|
71
|
+
var darkBase = random() > 0.52;
|
|
72
|
+
var base = darkBase ? INK : LIGHT_BASE;
|
|
73
|
+
var field = darkBase ? PAPER : LIGHT_FIELD;
|
|
74
|
+
var accent = REGISTRATION_INDIGO;
|
|
75
|
+
var rotation = Math.floor(random() * 4) * 90;
|
|
76
|
+
var bandWidth = between(random, 37, 56);
|
|
77
|
+
var secondaryWidth = between(random, 14, 24);
|
|
78
|
+
var cutWidth = between(random, 15, 25);
|
|
79
|
+
var firstY = between(random, 24, 42);
|
|
80
|
+
var secondY = between(random, 58, 78);
|
|
81
|
+
var firstBow = between(random, -34, 34);
|
|
82
|
+
var secondBow = between(random, -32, 32);
|
|
83
|
+
var firstPath = curvePath(firstY, firstBow, 6);
|
|
84
|
+
var secondPath = curvePath(secondY, -secondBow, -5);
|
|
85
|
+
var contours = "";
|
|
86
|
+
|
|
87
|
+
if (size >= 40) {
|
|
88
|
+
for (var contour = -1; contour <= 1; contour++) {
|
|
89
|
+
var offset = contour * 5.2;
|
|
90
|
+
contours += '<path d="' + curvePath(firstY + offset, firstBow, 0) + '" fill="none" stroke="' +
|
|
91
|
+
(darkBase ? PAPER : INK) + '" stroke-opacity="0.2" stroke-width="0.8"/>';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var clipId = "imprint-" + hash.toString(16);
|
|
96
|
+
return '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size +
|
|
97
|
+
'" viewBox="0 0 96 96"><defs><clipPath id="' + clipId +
|
|
98
|
+
'"><rect width="96" height="96" rx="24"/></clipPath></defs><g clip-path="url(#' + clipId +
|
|
99
|
+
')"><rect width="96" height="96" fill="' + base + '"/><g transform="rotate(' + rotation +
|
|
100
|
+
' 48 48)"><path d="' + firstPath + '" fill="none" stroke="' + field + '" stroke-width="' +
|
|
101
|
+
number(bandWidth) + '" stroke-linecap="square"/><path d="' + secondPath + '" fill="none" stroke="' +
|
|
102
|
+
accent + '" stroke-width="' + number(secondaryWidth) + '" stroke-linecap="square"/><path d="' +
|
|
103
|
+
cutPath(random) + '" fill="none" stroke="' + base + '" stroke-width="' + number(cutWidth) +
|
|
104
|
+
'" stroke-linecap="square"/>' + contours + '</g></g><rect x="0.5" y="0.5" width="95" height="95" rx="23.5" fill="none" stroke="' +
|
|
105
|
+
(darkBase ? "#000000" : INK) + '" stroke-opacity="0.16"/></svg>';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function imprintDataUrl(options) {
|
|
109
|
+
return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(imprintSvg(options));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function mateMarkSvg(options) {
|
|
113
|
+
var settings = options || {};
|
|
114
|
+
var size = Math.max(12, Math.min(256, Number(settings.size) || 64));
|
|
115
|
+
var identity = String(settings.seed || "M").trim();
|
|
116
|
+
var initial = Array.from(identity || "M")[0].toUpperCase();
|
|
117
|
+
var palette = [
|
|
118
|
+
{ background: REGISTRATION_INDIGO, foreground: PAPER },
|
|
119
|
+
{ background: BRAND_GREEN, foreground: INK },
|
|
120
|
+
{ background: PAPER, foreground: REGISTRATION_INDIGO },
|
|
121
|
+
][initial.codePointAt(0) % 3];
|
|
122
|
+
var clipId = "mate-mark";
|
|
123
|
+
|
|
124
|
+
return '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size +
|
|
125
|
+
'" viewBox="0 0 96 96"><defs><clipPath id="' + clipId +
|
|
126
|
+
'"><rect width="96" height="96" rx="24"/></clipPath></defs><g clip-path="url(#' + clipId +
|
|
127
|
+
')"><rect width="96" height="96" fill="' + palette.background + '"/><text x="48" y="50" fill="' + palette.foreground +
|
|
128
|
+
'" font-family="Arial, Helvetica, sans-serif" font-size="43" font-weight="600" text-anchor="middle" dominant-baseline="middle">' +
|
|
129
|
+
xmlText(initial) + '</text></g><rect x="0.5" y="0.5" width="95" height="95" rx="23.5" fill="none" stroke="#000000" stroke-opacity="0.18"/></svg>';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function mateMarkDataUrl(options) {
|
|
133
|
+
return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(mateMarkSvg(options));
|
|
134
|
+
}
|
|
@@ -1,36 +1,42 @@
|
|
|
1
|
-
// Centralized
|
|
2
|
-
|
|
1
|
+
// Centralized Clay Imprint URL builder for people and Mates.
|
|
2
|
+
import { imprintDataUrl, mateMarkDataUrl } from './avatar-imprint.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
{ id: 'bottts', name: 'Bots' },
|
|
7
|
-
{ id: 'pixel-art', name: 'Pixel' },
|
|
8
|
-
{ id: 'adventurer', name: 'Adventurer' },
|
|
9
|
-
{ id: 'micah', name: 'Micah' },
|
|
10
|
-
{ id: 'fun-emoji', name: 'Emoji' },
|
|
11
|
-
{ id: 'icons', name: 'Icons' },
|
|
12
|
-
];
|
|
4
|
+
var imprintCache = new Map();
|
|
5
|
+
var mateMarkCache = new Map();
|
|
13
6
|
|
|
14
|
-
//
|
|
7
|
+
// Legacy style remains part of the identity hash so existing selections map
|
|
8
|
+
// deterministically into the new Clay Imprint system.
|
|
15
9
|
export function avatarUrl(style, seed, size) {
|
|
16
|
-
var
|
|
17
|
-
|
|
10
|
+
var cacheKey = [style || 'imprint', seed || 'anonymous', size || 64].join('|');
|
|
11
|
+
if (imprintCache.has(cacheKey)) return imprintCache.get(cacheKey);
|
|
12
|
+
var url = imprintDataUrl({ style: style || 'imprint', seed: seed || 'anonymous', size: size || 64 });
|
|
13
|
+
if (imprintCache.size >= 512) imprintCache.delete(imprintCache.keys().next().value);
|
|
14
|
+
imprintCache.set(cacheKey, url);
|
|
15
|
+
return url;
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
// Build avatar URL for a user object, preferring custom avatar if set.
|
|
21
19
|
export function userAvatarUrl(user, size) {
|
|
22
20
|
if (user && user.avatarCustom) return user.avatarCustom;
|
|
23
|
-
var style = (user && user.avatarStyle) || '
|
|
21
|
+
var style = (user && user.avatarStyle) || 'imprint';
|
|
24
22
|
var seed = (user && (user.avatarSeed || user.username || user.id)) || 'anonymous';
|
|
25
23
|
return avatarUrl(style, seed, size);
|
|
26
24
|
}
|
|
27
25
|
|
|
26
|
+
export function mateMarkUrl(seed, size) {
|
|
27
|
+
var cacheKey = [seed || 'mate', size || 64].join('|');
|
|
28
|
+
if (mateMarkCache.has(cacheKey)) return mateMarkCache.get(cacheKey);
|
|
29
|
+
var url = mateMarkDataUrl({ seed: seed || 'mate', size: size || 64 });
|
|
30
|
+
if (mateMarkCache.size >= 256) mateMarkCache.delete(mateMarkCache.keys().next().value);
|
|
31
|
+
mateMarkCache.set(cacheKey, url);
|
|
32
|
+
return url;
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
// Build avatar URL for a mate object, preferring custom avatar if set.
|
|
29
36
|
export function mateAvatarUrl(mate, size) {
|
|
30
|
-
if (!mate) return
|
|
37
|
+
if (!mate) return mateMarkUrl('mate', size);
|
|
31
38
|
var p = mate.profile || mate;
|
|
32
39
|
if (p.avatarCustom || mate.avatarCustom) return p.avatarCustom || mate.avatarCustom;
|
|
33
|
-
var
|
|
34
|
-
|
|
35
|
-
return avatarUrl(style, seed, size);
|
|
40
|
+
var identity = p.displayName || mate.name || mate.displayName || 'Mate';
|
|
41
|
+
return mateMarkUrl(identity, size);
|
|
36
42
|
}
|
|
@@ -53,7 +53,15 @@ export function resetDebateState() {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function buildAvatarUrl(meta) {
|
|
56
|
-
return
|
|
56
|
+
return mateAvatarUrl({
|
|
57
|
+
id: meta.mateId,
|
|
58
|
+
profile: {
|
|
59
|
+
avatarStyle: meta.avatarStyle || "imprint",
|
|
60
|
+
avatarSeed: meta.avatarSeed || meta.mateId || "mate",
|
|
61
|
+
avatarColor: meta.avatarColor || "#5857fc",
|
|
62
|
+
avatarCustom: meta.avatarCustom || "",
|
|
63
|
+
},
|
|
64
|
+
}, 32);
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
// --- Float info panel ---
|
|
@@ -943,12 +951,9 @@ function createPanelItem(mate) {
|
|
|
943
951
|
cb.type = "checkbox";
|
|
944
952
|
item.appendChild(cb);
|
|
945
953
|
|
|
946
|
-
var avatarSrc = "https://api.dicebear.com/7.x/" +
|
|
947
|
-
((mate.profile && mate.profile.avatarStyle) || "bottts") +
|
|
948
|
-
"/svg?seed=" + encodeURIComponent((mate.profile && mate.profile.avatarSeed) || mate.id);
|
|
949
954
|
var avi = document.createElement("img");
|
|
950
955
|
avi.className = "debate-panel-item-avatar";
|
|
951
|
-
avi.src =
|
|
956
|
+
avi.src = mateAvatarUrl(mate, 32);
|
|
952
957
|
item.appendChild(avi);
|
|
953
958
|
|
|
954
959
|
var info = document.createElement("div");
|
|
@@ -139,7 +139,7 @@ export function showMateSidebar(mateId, mateData) {
|
|
|
139
139
|
var profile = mateData.profile || mateData || {};
|
|
140
140
|
var displayName = profile.displayName || mateData.displayName || mateData.name || "Mate";
|
|
141
141
|
|
|
142
|
-
var mateColor = profile.avatarColor || mateData.avatarColor || "#
|
|
142
|
+
var mateColor = profile.avatarColor || mateData.avatarColor || "#5857fc";
|
|
143
143
|
|
|
144
144
|
var mateAvUrl = mateAvatarUrl(mateData, 32);
|
|
145
145
|
if (avatarEl) avatarEl.src = mateAvUrl;
|
|
@@ -267,7 +267,7 @@ export function updateMateSidebarProfile(mateData) {
|
|
|
267
267
|
if (!columnEl || !mateData) return;
|
|
268
268
|
var profile = mateData.profile || mateData || {};
|
|
269
269
|
var displayName = profile.displayName || mateData.displayName || mateData.name || "Mate";
|
|
270
|
-
var mateColor = profile.avatarColor || mateData.avatarColor || "#
|
|
270
|
+
var mateColor = profile.avatarColor || mateData.avatarColor || "#5857fc";
|
|
271
271
|
|
|
272
272
|
if (avatarEl) {
|
|
273
273
|
avatarEl.src = mateAvatarUrl(mateData, 32);
|
|
@@ -112,7 +112,7 @@ function buildMentionCandidates() {
|
|
|
112
112
|
kind: "mate",
|
|
113
113
|
id: m.id,
|
|
114
114
|
name: (m.profile && m.profile.displayName) || m.name || "Mate",
|
|
115
|
-
color: (m.profile && m.profile.avatarColor) || "#
|
|
115
|
+
color: (m.profile && m.profile.avatarColor) || "#5857fc",
|
|
116
116
|
avatarSrc: mateAvatarUrl(m, 24),
|
|
117
117
|
vendor: m.vendor || "claude",
|
|
118
118
|
bio: m.bio || (m.profile && m.profile.bio) || "",
|
|
@@ -134,9 +134,8 @@ function buildMentionCandidates() {
|
|
|
134
134
|
kind: "user",
|
|
135
135
|
id: u.id,
|
|
136
136
|
name: u.displayName || u.username || "User",
|
|
137
|
-
color: u.avatarColor || "#
|
|
138
|
-
|
|
139
|
-
avatarSrc: "https://api.dicebear.com/7.x/" + (u.avatarStyle || "thumbs") + "/svg?seed=" + encodeURIComponent(u.avatarSeed || u.username || u.id),
|
|
137
|
+
color: u.avatarColor || "#5857fc",
|
|
138
|
+
avatarSrc: userAvatarUrl(u, 24),
|
|
140
139
|
vendor: null,
|
|
141
140
|
bio: u.username ? "@" + u.username : "",
|
|
142
141
|
primary: false,
|
|
@@ -424,7 +423,7 @@ export function stickyReapplyMention() {
|
|
|
424
423
|
var kind = selectedMateKind;
|
|
425
424
|
var id = selectedMateId;
|
|
426
425
|
var name = selectedMateName;
|
|
427
|
-
var color = selectedMateColor || "#
|
|
426
|
+
var color = selectedMateColor || "#5857fc";
|
|
428
427
|
var avatarSrc = selectedMateAvatar || "";
|
|
429
428
|
// Reset index but keep selection
|
|
430
429
|
mentionAtIdx = -1;
|
|
@@ -516,7 +515,7 @@ export function handleMentionStart(msg) {
|
|
|
516
515
|
header.className = "dm-bubble-header";
|
|
517
516
|
var nameSpan = document.createElement("span");
|
|
518
517
|
nameSpan.className = "dm-bubble-name";
|
|
519
|
-
nameSpan.style.color = msg.avatarColor || "#
|
|
518
|
+
nameSpan.style.color = msg.avatarColor || "#5857fc";
|
|
520
519
|
nameSpan.textContent = msg.mateName || "Mate";
|
|
521
520
|
header.appendChild(nameSpan);
|
|
522
521
|
|
|
@@ -556,7 +555,7 @@ export function handleMentionStart(msg) {
|
|
|
556
555
|
// Project chat: mention block style
|
|
557
556
|
currentMentionEl = document.createElement("div");
|
|
558
557
|
currentMentionEl.className = "msg-mention";
|
|
559
|
-
currentMentionEl.style.setProperty("--mention-color", msg.avatarColor || "#
|
|
558
|
+
currentMentionEl.style.setProperty("--mention-color", msg.avatarColor || "#5857fc");
|
|
560
559
|
|
|
561
560
|
var header = document.createElement("div");
|
|
562
561
|
header.className = "mention-header";
|
|
@@ -754,15 +753,13 @@ function isDmLayout() {
|
|
|
754
753
|
|
|
755
754
|
function getMyAvatarSrc() {
|
|
756
755
|
if (document.body.dataset.myAvatarUrl) return document.body.dataset.myAvatarUrl;
|
|
757
|
-
var myUser =
|
|
758
|
-
try { myUser = JSON.parse(localStorage.getItem("clay_my_user") || "null"); } catch (e) {}
|
|
756
|
+
var myUser = (store.get('cachedAllUsers') || []).find(function (u) { return u.id === store.get('myUserId'); });
|
|
759
757
|
return userAvatarUrl(myUser || {}, 36);
|
|
760
758
|
}
|
|
761
759
|
|
|
762
760
|
function getMyDisplayName() {
|
|
763
761
|
if (document.body.dataset.myDisplayName) return document.body.dataset.myDisplayName;
|
|
764
|
-
var myUser =
|
|
765
|
-
try { myUser = JSON.parse(localStorage.getItem("clay_my_user") || "null"); } catch (e) {}
|
|
762
|
+
var myUser = (store.get('cachedAllUsers') || []).find(function (u) { return u.id === store.get('myUserId'); });
|
|
766
763
|
return (myUser && (myUser.displayName || myUser.username)) || "Me";
|
|
767
764
|
}
|
|
768
765
|
|
|
@@ -772,14 +769,27 @@ function timeStr() {
|
|
|
772
769
|
}
|
|
773
770
|
|
|
774
771
|
function buildMentionAvatarUrl(meta) {
|
|
775
|
-
return
|
|
772
|
+
return mateAvatarUrl({
|
|
773
|
+
id: meta.mateId,
|
|
774
|
+
profile: {
|
|
775
|
+
avatarStyle: meta.avatarStyle || "imprint",
|
|
776
|
+
avatarSeed: meta.avatarSeed || meta.mateId,
|
|
777
|
+
avatarColor: meta.avatarColor || "#5857fc",
|
|
778
|
+
avatarCustom: meta.avatarCustom || "",
|
|
779
|
+
},
|
|
780
|
+
}, 36);
|
|
776
781
|
}
|
|
777
782
|
|
|
778
783
|
function buildUserAvatarUrlFromEntry(entry, who) {
|
|
779
784
|
// who = "from" | "target"
|
|
780
|
-
var style = entry[who + "AvatarStyle"] || "thumbs";
|
|
781
785
|
var seed = entry[who + "AvatarSeed"] || entry[who === "from" ? "fromName" : "targetName"] || entry[who === "from" ? "from" : "targetUserId"];
|
|
782
|
-
return
|
|
786
|
+
return userAvatarUrl({
|
|
787
|
+
id: entry[who === "from" ? "from" : "targetUserId"],
|
|
788
|
+
avatarStyle: entry[who + "AvatarStyle"] || "imprint",
|
|
789
|
+
avatarSeed: seed || "user",
|
|
790
|
+
avatarColor: entry[who + "AvatarColor"] || "#5857fc",
|
|
791
|
+
avatarCustom: entry[who + "AvatarCustom"] || "",
|
|
792
|
+
}, 36);
|
|
783
793
|
}
|
|
784
794
|
|
|
785
795
|
// Render a user-to-user @mention bubble (live receive AND history replay).
|
|
@@ -1021,7 +1031,7 @@ export function renderMentionResponse(entry) {
|
|
|
1021
1031
|
header.className = "dm-bubble-header";
|
|
1022
1032
|
var nameSpan = document.createElement("span");
|
|
1023
1033
|
nameSpan.className = "dm-bubble-name";
|
|
1024
|
-
nameSpan.style.color = entry.avatarColor || "#
|
|
1034
|
+
nameSpan.style.color = entry.avatarColor || "#5857fc";
|
|
1025
1035
|
nameSpan.textContent = entry.mateName || "Mate";
|
|
1026
1036
|
header.appendChild(nameSpan);
|
|
1027
1037
|
|
|
@@ -1050,7 +1060,7 @@ export function renderMentionResponse(entry) {
|
|
|
1050
1060
|
// Project chat: use mention block style
|
|
1051
1061
|
var el = document.createElement("div");
|
|
1052
1062
|
el.className = "msg-mention";
|
|
1053
|
-
el.style.setProperty("--mention-color", entry.avatarColor || "#
|
|
1063
|
+
el.style.setProperty("--mention-color", entry.avatarColor || "#5857fc");
|
|
1054
1064
|
|
|
1055
1065
|
var mheader = document.createElement("div");
|
|
1056
1066
|
mheader.className = "mention-header";
|