@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.cjs
CHANGED
|
@@ -38,7 +38,8 @@ function isInside(target, selector) {
|
|
|
38
38
|
return !!target.closest(selector);
|
|
39
39
|
}
|
|
40
40
|
function escapeHtml(s) {
|
|
41
|
-
|
|
41
|
+
if (s == null) return "";
|
|
42
|
+
return String(s).replace(/[&<>"']/g, (ch) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[ch]);
|
|
42
43
|
}
|
|
43
44
|
function formatTime(ts) {
|
|
44
45
|
const d = new Date(ts);
|
|
@@ -50,14 +51,16 @@ function formatTime(ts) {
|
|
|
50
51
|
return d.toLocaleDateString() + " " + d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
51
52
|
}
|
|
52
53
|
function initials(name) {
|
|
53
|
-
|
|
54
|
+
if (!name) return "";
|
|
55
|
+
return String(name).split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0].toUpperCase()).join("");
|
|
54
56
|
}
|
|
55
57
|
function avatarHtml(user, className = "vz-comment-author-avatar") {
|
|
56
58
|
if (!user) return `<span class="${className}">\xB7</span>`;
|
|
59
|
+
const displayName = user.name || user.id || "User";
|
|
57
60
|
if (user.avatarUrl) {
|
|
58
|
-
return `<span class="${className}"><img src="${escapeHtml(user.avatarUrl)}" alt="${escapeHtml(
|
|
61
|
+
return `<span class="${className}"><img src="${escapeHtml(user.avatarUrl)}" alt="${escapeHtml(displayName)}" /></span>`;
|
|
59
62
|
}
|
|
60
|
-
return `<span class="${className}">${escapeHtml(initials(
|
|
63
|
+
return `<span class="${className}">${escapeHtml(initials(displayName) || "?")}</span>`;
|
|
61
64
|
}
|
|
62
65
|
function refId() {
|
|
63
66
|
return Math.random().toString(36).slice(2, 10);
|
|
@@ -460,6 +463,26 @@ var CloudStorageAdapter = class {
|
|
|
460
463
|
accessDenialReason() {
|
|
461
464
|
return this.accessDeniedReason;
|
|
462
465
|
}
|
|
466
|
+
/**
|
|
467
|
+
* Fetch the list of users who can be @-mentioned on this workspace.
|
|
468
|
+
* Used by the popover's mention dropdown — returns owner + joined
|
|
469
|
+
* editors/viewers, sorted owner-first. Silent on no auth (returns [])
|
|
470
|
+
* so popover doesn't open a popup just to render an empty dropdown.
|
|
471
|
+
*/
|
|
472
|
+
async searchMentionable() {
|
|
473
|
+
if (!this.cachedToken || this.isExpired(this.cachedToken)) return [];
|
|
474
|
+
try {
|
|
475
|
+
const res = await this.fetchAuthed(
|
|
476
|
+
this.apiUrl + "/api/workspaces/" + encodeURIComponent(this.workspace) + "/mentionable",
|
|
477
|
+
{ method: "GET" }
|
|
478
|
+
);
|
|
479
|
+
if (!res.ok) return [];
|
|
480
|
+
const json = await this.parseJson(res);
|
|
481
|
+
return Array.isArray(json?.users) ? json.users : [];
|
|
482
|
+
} catch {
|
|
483
|
+
return [];
|
|
484
|
+
}
|
|
485
|
+
}
|
|
463
486
|
/* ─── StorageAdapter v2 ───────────────────────────────────────────── */
|
|
464
487
|
async load(_namespace) {
|
|
465
488
|
if (!this.cachedToken || this.isExpired(this.cachedToken)) {
|
|
@@ -1209,7 +1232,7 @@ function renderRepliesHtml(c) {
|
|
|
1209
1232
|
const items = replies.map(
|
|
1210
1233
|
(r) => `
|
|
1211
1234
|
<div class="vz-reply" data-reply-id="${escapeHtml(r.id)}">
|
|
1212
|
-
${r.author ? `<div class="vz-comment-author">${avatarHtml(r.author)} <span class="vz-comment-author-name">${escapeHtml(r.author.name)}</span></div>` : ""}
|
|
1235
|
+
${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>` : ""}
|
|
1213
1236
|
<div class="vz-reply-text">${escapeHtml(r.text)}</div>
|
|
1214
1237
|
<div class="vz-comment-meta">
|
|
1215
1238
|
<span>${escapeHtml(formatTime(typeof r.createdAt === "number" ? r.createdAt : new Date(r.createdAt).getTime()))}</span>
|
|
@@ -1486,7 +1509,7 @@ var Popover = class {
|
|
|
1486
1509
|
${comments.length === 0 ? '<div class="vz-empty">No comments yet.</div>' : comments.map(
|
|
1487
1510
|
(c) => `
|
|
1488
1511
|
<div class="vz-comment" data-comment-id="${escapeHtml(c.id)}">
|
|
1489
|
-
${c.author ? `<div class="vz-comment-author">${avatarHtml(c.author)} <span class="vz-comment-author-name">${escapeHtml(c.author.name)}</span></div>` : ""}
|
|
1512
|
+
${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>` : ""}
|
|
1490
1513
|
<div>${renderCommentText(c.text, c.id)}</div>
|
|
1491
1514
|
${renderAttachmentsHtml(c.attachments)}
|
|
1492
1515
|
<div class="vz-comment-meta">
|
|
@@ -3297,22 +3320,23 @@ var Vizu = class {
|
|
|
3297
3320
|
this.user = user;
|
|
3298
3321
|
this.popover?.setUser(user);
|
|
3299
3322
|
this.pill?.setUser(user);
|
|
3300
|
-
if (this.pill) {
|
|
3301
|
-
if (this.shouldShowPill()) this.pill.show();
|
|
3302
|
-
else this.pill.hide();
|
|
3303
|
-
}
|
|
3304
3323
|
this.bus.emit("user:changed", { user });
|
|
3324
|
+
if (this.enabled && !this.root && this.shouldMount()) {
|
|
3325
|
+
this.deferred(() => this.mount());
|
|
3326
|
+
}
|
|
3305
3327
|
}
|
|
3306
3328
|
getUser() {
|
|
3307
3329
|
return this.user;
|
|
3308
3330
|
}
|
|
3309
3331
|
/**
|
|
3310
|
-
* Whether the
|
|
3311
|
-
*
|
|
3312
|
-
*
|
|
3313
|
-
*
|
|
3332
|
+
* Whether the full Vizu UI (pill, highlighter, markers, popover) can
|
|
3333
|
+
* be mounted right now. Cloud-mode workspaces hold off until the
|
|
3334
|
+
* user is signed in; non-cloud usage (local / memory storage) has no
|
|
3335
|
+
* auth concept and mounts immediately. Re-checked from `enable()`
|
|
3336
|
+
* and from `setUser()` so that the moment auth resolves, the UI
|
|
3337
|
+
* appears without the user needing to press the shortcut again.
|
|
3314
3338
|
*/
|
|
3315
|
-
|
|
3339
|
+
shouldMount() {
|
|
3316
3340
|
if (!(this.storage instanceof CloudStorageAdapter)) return true;
|
|
3317
3341
|
return this.user !== null;
|
|
3318
3342
|
}
|
|
@@ -3339,7 +3363,9 @@ var Vizu = class {
|
|
|
3339
3363
|
if (this.enabled) return;
|
|
3340
3364
|
this.enabled = true;
|
|
3341
3365
|
this.bus.emit("enabled", {});
|
|
3342
|
-
|
|
3366
|
+
if (this.shouldMount()) {
|
|
3367
|
+
this.deferred(() => this.mount());
|
|
3368
|
+
}
|
|
3343
3369
|
}
|
|
3344
3370
|
disable() {
|
|
3345
3371
|
if (!this.enabled) return;
|
|
@@ -3679,7 +3705,7 @@ var Vizu = class {
|
|
|
3679
3705
|
this.pill.setUser(this.user);
|
|
3680
3706
|
this.pill.setComments(this.comments);
|
|
3681
3707
|
this.pill.setMultiSelectState(this.multiSelectMode, this.pendingFingerprints.length);
|
|
3682
|
-
|
|
3708
|
+
this.pill.show();
|
|
3683
3709
|
this.highlighter = new Highlighter(
|
|
3684
3710
|
this.root,
|
|
3685
3711
|
this.opts.ignoreSelectors ?? [],
|