@unhingged/vizu-core 0.1.10 → 0.1.12
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/dist/auto.cjs +43 -17
- package/dist/auto.cjs.map +1 -1
- package/dist/auto.js +43 -17
- package/dist/auto.js.map +1 -1
- package/dist/index.cjs +43 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -5
- package/dist/index.d.ts +26 -5
- package/dist/index.js +43 -17
- package/dist/index.js.map +1 -1
- package/dist/vizu.min.js +11 -11
- package/dist/vizu.min.js.map +1 -1
- package/package.json +1 -1
package/dist/auto.js
CHANGED
|
@@ -12,7 +12,8 @@ function isInside(target, selector) {
|
|
|
12
12
|
return !!target.closest(selector);
|
|
13
13
|
}
|
|
14
14
|
function escapeHtml(s) {
|
|
15
|
-
|
|
15
|
+
if (s == null) return "";
|
|
16
|
+
return String(s).replace(/[&<>"']/g, (ch) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[ch]);
|
|
16
17
|
}
|
|
17
18
|
function formatTime(ts) {
|
|
18
19
|
const d = new Date(ts);
|
|
@@ -24,14 +25,16 @@ function formatTime(ts) {
|
|
|
24
25
|
return d.toLocaleDateString() + " " + d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
25
26
|
}
|
|
26
27
|
function initials(name) {
|
|
27
|
-
|
|
28
|
+
if (!name) return "";
|
|
29
|
+
return String(name).split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0].toUpperCase()).join("");
|
|
28
30
|
}
|
|
29
31
|
function avatarHtml(user, className = "vz-comment-author-avatar") {
|
|
30
32
|
if (!user) return `<span class="${className}">\xB7</span>`;
|
|
33
|
+
const displayName = user.name || user.id || "User";
|
|
31
34
|
if (user.avatarUrl) {
|
|
32
|
-
return `<span class="${className}"><img src="${escapeHtml(user.avatarUrl)}" alt="${escapeHtml(
|
|
35
|
+
return `<span class="${className}"><img src="${escapeHtml(user.avatarUrl)}" alt="${escapeHtml(displayName)}" /></span>`;
|
|
33
36
|
}
|
|
34
|
-
return `<span class="${className}">${escapeHtml(initials(
|
|
37
|
+
return `<span class="${className}">${escapeHtml(initials(displayName) || "?")}</span>`;
|
|
35
38
|
}
|
|
36
39
|
function refId() {
|
|
37
40
|
return Math.random().toString(36).slice(2, 10);
|
|
@@ -434,6 +437,26 @@ var CloudStorageAdapter = class {
|
|
|
434
437
|
accessDenialReason() {
|
|
435
438
|
return this.accessDeniedReason;
|
|
436
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* Fetch the list of users who can be @-mentioned on this workspace.
|
|
442
|
+
* Used by the popover's mention dropdown — returns owner + joined
|
|
443
|
+
* editors/viewers, sorted owner-first. Silent on no auth (returns [])
|
|
444
|
+
* so popover doesn't open a popup just to render an empty dropdown.
|
|
445
|
+
*/
|
|
446
|
+
async searchMentionable() {
|
|
447
|
+
if (!this.cachedToken || this.isExpired(this.cachedToken)) return [];
|
|
448
|
+
try {
|
|
449
|
+
const res = await this.fetchAuthed(
|
|
450
|
+
this.apiUrl + "/api/workspaces/" + encodeURIComponent(this.workspace) + "/mentionable",
|
|
451
|
+
{ method: "GET" }
|
|
452
|
+
);
|
|
453
|
+
if (!res.ok) return [];
|
|
454
|
+
const json = await this.parseJson(res);
|
|
455
|
+
return Array.isArray(json?.users) ? json.users : [];
|
|
456
|
+
} catch {
|
|
457
|
+
return [];
|
|
458
|
+
}
|
|
459
|
+
}
|
|
437
460
|
/* ─── StorageAdapter v2 ───────────────────────────────────────────── */
|
|
438
461
|
async load(_namespace) {
|
|
439
462
|
if (!this.cachedToken || this.isExpired(this.cachedToken)) {
|
|
@@ -1183,7 +1206,7 @@ function renderRepliesHtml(c) {
|
|
|
1183
1206
|
const items = replies.map(
|
|
1184
1207
|
(r) => `
|
|
1185
1208
|
<div class="vz-reply" data-reply-id="${escapeHtml(r.id)}">
|
|
1186
|
-
${r.author ? `<div class="vz-comment-author">${avatarHtml(r.author)} <span class="vz-comment-author-name">${escapeHtml(r.author.name)}</span></div>` : ""}
|
|
1209
|
+
${r.author ? `<div class="vz-comment-author">${avatarHtml(r.author)} <span class="vz-comment-author-name">${escapeHtml(r.author.name || r.author.id || "User")}</span></div>` : ""}
|
|
1187
1210
|
<div class="vz-reply-text">${escapeHtml(r.text)}</div>
|
|
1188
1211
|
<div class="vz-comment-meta">
|
|
1189
1212
|
<span>${escapeHtml(formatTime(typeof r.createdAt === "number" ? r.createdAt : new Date(r.createdAt).getTime()))}</span>
|
|
@@ -1460,7 +1483,7 @@ var Popover = class {
|
|
|
1460
1483
|
${comments.length === 0 ? '<div class="vz-empty">No comments yet.</div>' : comments.map(
|
|
1461
1484
|
(c) => `
|
|
1462
1485
|
<div class="vz-comment" data-comment-id="${escapeHtml(c.id)}">
|
|
1463
|
-
${c.author ? `<div class="vz-comment-author">${avatarHtml(c.author)} <span class="vz-comment-author-name">${escapeHtml(c.author.name)}</span></div>` : ""}
|
|
1486
|
+
${c.author ? `<div class="vz-comment-author">${avatarHtml(c.author)} <span class="vz-comment-author-name">${escapeHtml(c.author.name || c.author.id || "User")}</span></div>` : ""}
|
|
1464
1487
|
<div>${renderCommentText(c.text, c.id)}</div>
|
|
1465
1488
|
${renderAttachmentsHtml(c.attachments)}
|
|
1466
1489
|
<div class="vz-comment-meta">
|
|
@@ -3271,22 +3294,23 @@ var Vizu = class {
|
|
|
3271
3294
|
this.user = user;
|
|
3272
3295
|
this.popover?.setUser(user);
|
|
3273
3296
|
this.pill?.setUser(user);
|
|
3274
|
-
if (this.pill) {
|
|
3275
|
-
if (this.shouldShowPill()) this.pill.show();
|
|
3276
|
-
else this.pill.hide();
|
|
3277
|
-
}
|
|
3278
3297
|
this.bus.emit("user:changed", { user });
|
|
3298
|
+
if (this.enabled && !this.root && this.shouldMount()) {
|
|
3299
|
+
this.deferred(() => this.mount());
|
|
3300
|
+
}
|
|
3279
3301
|
}
|
|
3280
3302
|
getUser() {
|
|
3281
3303
|
return this.user;
|
|
3282
3304
|
}
|
|
3283
3305
|
/**
|
|
3284
|
-
* Whether the
|
|
3285
|
-
*
|
|
3286
|
-
*
|
|
3287
|
-
*
|
|
3306
|
+
* Whether the full Vizu UI (pill, highlighter, markers, popover) can
|
|
3307
|
+
* be mounted right now. Cloud-mode workspaces hold off until the
|
|
3308
|
+
* user is signed in; non-cloud usage (local / memory storage) has no
|
|
3309
|
+
* auth concept and mounts immediately. Re-checked from `enable()`
|
|
3310
|
+
* and from `setUser()` so that the moment auth resolves, the UI
|
|
3311
|
+
* appears without the user needing to press the shortcut again.
|
|
3288
3312
|
*/
|
|
3289
|
-
|
|
3313
|
+
shouldMount() {
|
|
3290
3314
|
if (!(this.storage instanceof CloudStorageAdapter)) return true;
|
|
3291
3315
|
return this.user !== null;
|
|
3292
3316
|
}
|
|
@@ -3313,7 +3337,9 @@ var Vizu = class {
|
|
|
3313
3337
|
if (this.enabled) return;
|
|
3314
3338
|
this.enabled = true;
|
|
3315
3339
|
this.bus.emit("enabled", {});
|
|
3316
|
-
|
|
3340
|
+
if (this.shouldMount()) {
|
|
3341
|
+
this.deferred(() => this.mount());
|
|
3342
|
+
}
|
|
3317
3343
|
}
|
|
3318
3344
|
disable() {
|
|
3319
3345
|
if (!this.enabled) return;
|
|
@@ -3653,7 +3679,7 @@ var Vizu = class {
|
|
|
3653
3679
|
this.pill.setUser(this.user);
|
|
3654
3680
|
this.pill.setComments(this.comments);
|
|
3655
3681
|
this.pill.setMultiSelectState(this.multiSelectMode, this.pendingFingerprints.length);
|
|
3656
|
-
|
|
3682
|
+
this.pill.show();
|
|
3657
3683
|
this.highlighter = new Highlighter(
|
|
3658
3684
|
this.root,
|
|
3659
3685
|
this.opts.ignoreSelectors ?? [],
|