shadok-ai 0.9.13 → 0.9.14
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/package.json +1 -1
- package/public/index.html +56 -5
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -1475,6 +1475,26 @@
|
|
|
1475
1475
|
#secretsList li:nth-child(odd) { background: rgba(255,255,255,.04); }
|
|
1476
1476
|
#secretsList code { font-size: 13px; }
|
|
1477
1477
|
#secretsList button { background: none; border: none; color: #e26; cursor: pointer; font-size: 14px; }
|
|
1478
|
+
/* Le panneau Users n'avait AUCUN style : d'où les puces brutes et le nom, le
|
|
1479
|
+
rôle et les boutons empilés les uns sous les autres. Même traitement que
|
|
1480
|
+
#profilesList, dont il est le frère. */
|
|
1481
|
+
#usersList { list-style: none; padding: 0; margin: 0 0 10px; }
|
|
1482
|
+
#usersList li { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; }
|
|
1483
|
+
#usersList li:nth-child(odd) { background: rgba(255,255,255,.04); }
|
|
1484
|
+
#usersList .pmeta { font-size: 12px; opacity: .7; }
|
|
1485
|
+
#usersList button { background: none; border: 1px solid rgba(255,255,255,.15); border-radius: 5px; color: inherit; cursor: pointer; font-size: 12px; padding: 2px 8px; }
|
|
1486
|
+
#usersList .u-actions { display: flex; gap: 6px; flex: none; }
|
|
1487
|
+
#usersAdd { display: flex; gap: 8px; }
|
|
1488
|
+
#usersAdd input { flex: 1; min-width: 0; padding: 6px 8px; border-radius: 6px; border: 1px solid rgba(255,255,255,.15); background: rgba(0,0,0,.25); color: inherit; }
|
|
1489
|
+
#usersAdd select, #usersAdd button { padding: 6px 12px; border-radius: 6px; border: 1px solid rgba(255,255,255,.15); background: rgba(255,255,255,.08); color: inherit; cursor: pointer; }
|
|
1490
|
+
/* L'invitation est un OBJET à transmettre, pas une phrase : un encadré, une
|
|
1491
|
+
URL en monospace qui se coupe n'importe où plutôt que de laisser une
|
|
1492
|
+
traîne, et de quoi la copier sans la sélectionner à la souris. */
|
|
1493
|
+
#inviteBox { margin-top: 12px; border: 1px solid var(--amber); border-radius: 8px; padding: 10px 12px; background: rgba(224,164,74,.06); }
|
|
1494
|
+
#inviteBox .ib-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text-dim); }
|
|
1495
|
+
#inviteBox .ib-url { margin-top: 6px; font-family: var(--mono); font-size: 12px; line-height: 1.45; word-break: break-all; user-select: all; }
|
|
1496
|
+
#inviteBox button { background: none; border: 1px solid rgba(255,255,255,.15); border-radius: 5px; color: inherit; cursor: pointer; font-size: 12px; padding: 2px 8px; flex: none; }
|
|
1497
|
+
#inviteBox button:hover { border-color: var(--amber); color: var(--amber); }
|
|
1478
1498
|
#secretsAdd { display: flex; gap: 8px; }
|
|
1479
1499
|
#secretsAdd input { flex: 1; min-width: 0; padding: 6px 8px; border-radius: 6px; border: 1px solid rgba(255,255,255,.15); background: rgba(0,0,0,.25); color: inherit; }
|
|
1480
1500
|
#secretsAdd button { padding: 6px 12px; border-radius: 6px; border: 1px solid rgba(255,255,255,.15); background: rgba(255,255,255,.08); color: inherit; cursor: pointer; }
|
|
@@ -1767,7 +1787,10 @@
|
|
|
1767
1787
|
<select id="userRole"><option value="member">member</option><option value="admin">admin</option></select>
|
|
1768
1788
|
<button type="submit">Invite</button>
|
|
1769
1789
|
</form>
|
|
1770
|
-
<
|
|
1790
|
+
<div id="inviteBox" hidden>
|
|
1791
|
+
<div class="ib-head"><span id="inviteWho"></span><button type="button" id="inviteCopy">Copy</button></div>
|
|
1792
|
+
<div class="ib-url" id="inviteUrl"></div>
|
|
1793
|
+
</div>
|
|
1771
1794
|
</div>
|
|
1772
1795
|
</div>
|
|
1773
1796
|
|
|
@@ -6290,13 +6313,43 @@
|
|
|
6290
6313
|
await fetch("/users?name=" + encodeURIComponent(u.name), { method: "DELETE" });
|
|
6291
6314
|
renderUsers();
|
|
6292
6315
|
});
|
|
6316
|
+
btns.className = "u-actions";
|
|
6293
6317
|
btns.append(flip, del);
|
|
6294
6318
|
li.append(meta, btns);
|
|
6295
6319
|
ul.appendChild(li);
|
|
6296
6320
|
}
|
|
6297
6321
|
}
|
|
6322
|
+
/** The link is the only way in and it is shown once, so it gets a block of
|
|
6323
|
+
* its own: readable, selectable, and copyable without aiming at wrapped text. */
|
|
6324
|
+
function showInvite(name, url) {
|
|
6325
|
+
$("inviteWho").textContent = "Invitation for " + name + " — valid 7 days";
|
|
6326
|
+
$("inviteUrl").textContent = url;
|
|
6327
|
+
$("inviteCopy").textContent = "Copy";
|
|
6328
|
+
$("inviteBox").hidden = false;
|
|
6329
|
+
}
|
|
6330
|
+
|
|
6331
|
+
$("inviteCopy").addEventListener("click", async () => {
|
|
6332
|
+
const url = $("inviteUrl").textContent;
|
|
6333
|
+
// navigator.clipboard only exists in a SECURE context. An instance reached
|
|
6334
|
+
// over plain http on a LAN has none, and the button would fail silently —
|
|
6335
|
+
// so select the text and say what to press instead of pretending it worked.
|
|
6336
|
+
try {
|
|
6337
|
+
if (!navigator.clipboard) throw new Error("no clipboard");
|
|
6338
|
+
await navigator.clipboard.writeText(url);
|
|
6339
|
+
$("inviteCopy").textContent = "Copied";
|
|
6340
|
+
setTimeout(() => { $("inviteCopy").textContent = "Copy"; }, 1500);
|
|
6341
|
+
} catch {
|
|
6342
|
+
const r = document.createRange();
|
|
6343
|
+
r.selectNodeContents($("inviteUrl"));
|
|
6344
|
+
const sel = getSelection();
|
|
6345
|
+
sel.removeAllRanges();
|
|
6346
|
+
sel.addRange(r);
|
|
6347
|
+
$("inviteCopy").textContent = navigator.platform.includes("Mac") ? "Press ⌘C" : "Press Ctrl+C";
|
|
6348
|
+
}
|
|
6349
|
+
});
|
|
6350
|
+
|
|
6298
6351
|
$("usersBtn").addEventListener("click", async () => {
|
|
6299
|
-
$("
|
|
6352
|
+
$("inviteBox").hidden = true;
|
|
6300
6353
|
await renderUsers();
|
|
6301
6354
|
$("usersOverlay").hidden = false;
|
|
6302
6355
|
});
|
|
@@ -6314,9 +6367,7 @@
|
|
|
6314
6367
|
if (!r.ok) { alert(out.error || "failed"); return; }
|
|
6315
6368
|
// The link is the ONLY way in, and it is shown once. It stays on screen
|
|
6316
6369
|
// until the panel is reopened rather than flashing past in a toast.
|
|
6317
|
-
|
|
6318
|
-
$("inviteOut").textContent =
|
|
6319
|
-
"Invitation link for " + name + ", valid 7 days — send it to them: " + location.origin + out.inviteUrl;
|
|
6370
|
+
showInvite(name, location.origin + out.inviteUrl);
|
|
6320
6371
|
$("userName").value = "";
|
|
6321
6372
|
renderUsers();
|
|
6322
6373
|
});
|