shadok-ai 0.2.10 → 0.2.11
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 +45 -6
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -1605,15 +1605,37 @@
|
|
|
1605
1605
|
|
|
1606
1606
|
// Composer drafts, one per channel, remembered by session id.
|
|
1607
1607
|
const savedDrafts = JSON.parse(localStorage.getItem("cp.drafts") || "{}");
|
|
1608
|
+
/** Écrit MAINTENANT le brouillon de cet onglet, sans attendre le débounce. */
|
|
1609
|
+
function writeDraft(tab) {
|
|
1610
|
+
if (!tab.sessionId) return;
|
|
1611
|
+
clearTimeout(tab.draftTimer);
|
|
1612
|
+
if (tab.draft) savedDrafts[tab.sessionId] = tab.draft;
|
|
1613
|
+
else delete savedDrafts[tab.sessionId];
|
|
1614
|
+
localStorage.setItem("cp.drafts", JSON.stringify(savedDrafts));
|
|
1615
|
+
}
|
|
1608
1616
|
function persistDraft(tab) {
|
|
1609
1617
|
if (!tab.sessionId) return;
|
|
1610
1618
|
clearTimeout(tab.draftTimer);
|
|
1611
|
-
tab.draftTimer = setTimeout(() =>
|
|
1612
|
-
if (tab.draft) savedDrafts[tab.sessionId] = tab.draft;
|
|
1613
|
-
else delete savedDrafts[tab.sessionId];
|
|
1614
|
-
localStorage.setItem("cp.drafts", JSON.stringify(savedDrafts));
|
|
1615
|
-
}, 300);
|
|
1619
|
+
tab.draftTimer = setTimeout(() => writeDraft(tab), 300);
|
|
1616
1620
|
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Vide les écritures en attente de TOUS les onglets.
|
|
1623
|
+
*
|
|
1624
|
+
* Le débounce se réarme à chaque frappe : tant qu'on écrit sans marquer 300 ms
|
|
1625
|
+
* de pause, rien n'était jamais écrit — un rechargement en plein élan (typique
|
|
1626
|
+
* de l'auto-update, qui tombe quand il tombe) emportait tout le message. On
|
|
1627
|
+
* force donc l'écriture au moment où la page s'en va.
|
|
1628
|
+
*/
|
|
1629
|
+
function flushDrafts() {
|
|
1630
|
+
for (const t of tabs) writeDraft(t);
|
|
1631
|
+
}
|
|
1632
|
+
// `pagehide` couvre le rechargement, la navigation et la mise en bfcache ;
|
|
1633
|
+
// `visibilitychange` rattrape le mobile, où l'onglet peut être tué sans que
|
|
1634
|
+
// `pagehide` ne parte. localStorage étant synchrone, l'écriture aboutit.
|
|
1635
|
+
window.addEventListener("pagehide", flushDrafts);
|
|
1636
|
+
document.addEventListener("visibilitychange", () => {
|
|
1637
|
+
if (document.visibilityState === "hidden") flushDrafts();
|
|
1638
|
+
});
|
|
1617
1639
|
function dropDraft(tab) {
|
|
1618
1640
|
clearTimeout(tab.draftTimer);
|
|
1619
1641
|
tab.draft = "";
|
|
@@ -2156,6 +2178,7 @@
|
|
|
2156
2178
|
} else if (!dismissedChannels.has(c.sessionId)) {
|
|
2157
2179
|
const nt = createTab(c.group);
|
|
2158
2180
|
nt.sessionId = c.sessionId;
|
|
2181
|
+
nt.draft = savedDrafts[c.sessionId] || "";
|
|
2159
2182
|
if (c.branch) nt.branch = c.branch;
|
|
2160
2183
|
nt.profile = c.profile || null;
|
|
2161
2184
|
setCrons(nt, c.crons);
|
|
@@ -3115,7 +3138,14 @@
|
|
|
3115
3138
|
|
|
3116
3139
|
function handleVersion(msg) {
|
|
3117
3140
|
if (bootVersion === null) bootVersion = msg.current;
|
|
3118
|
-
else if (msg.current && msg.current !== bootVersion) {
|
|
3141
|
+
else if (msg.current && msg.current !== bootVersion) {
|
|
3142
|
+
// Mise à jour : la page part maintenant. On écrit d'abord — c'est LE cas
|
|
3143
|
+
// où l'on perdait un message en cours de frappe, puisque le rechargement
|
|
3144
|
+
// n'est pas déclenché par l'utilisateur.
|
|
3145
|
+
flushDrafts();
|
|
3146
|
+
location.reload();
|
|
3147
|
+
return;
|
|
3148
|
+
}
|
|
3119
3149
|
lastVersion = msg;
|
|
3120
3150
|
if (!verView) return;
|
|
3121
3151
|
const ahead = msg.latest && verIsNewer(msg.latest, msg.current);
|
|
@@ -3238,6 +3268,10 @@
|
|
|
3238
3268
|
promptInput.value = t.draft;
|
|
3239
3269
|
autosizePrompt();
|
|
3240
3270
|
}
|
|
3271
|
+
} else if (t.draft) {
|
|
3272
|
+
// Tapé AVANT que la session ne soit connue : `persistDraft` refuse
|
|
3273
|
+
// d'écrire sans id, ce texte n'était donc dans aucun stockage.
|
|
3274
|
+
writeDraft(t);
|
|
3241
3275
|
}
|
|
3242
3276
|
}
|
|
3243
3277
|
// launchTab reuses the tab object, so a bubble armed before the session
|
|
@@ -4394,6 +4428,11 @@
|
|
|
4394
4428
|
// Know the session id from the start, so a slow or failed reattach never
|
|
4395
4429
|
// drops the channel from a persist (which eroded the list to one).
|
|
4396
4430
|
t.sessionId = s.sessionId;
|
|
4431
|
+
// Le brouillon revient DÈS la création de l'onglet, sans attendre le
|
|
4432
|
+
// `ready` : après une mise à jour le serveur redémarre, la reconnexion
|
|
4433
|
+
// prend plusieurs secondes, et l'utilisateur retrouvait un champ vide —
|
|
4434
|
+
// de quoi croire que son message était perdu et le retaper.
|
|
4435
|
+
t.draft = savedDrafts[s.sessionId] || "";
|
|
4397
4436
|
if (s.branch) t.branch = s.branch;
|
|
4398
4437
|
t.profile = s.profile || null;
|
|
4399
4438
|
setCrons(t, s.crons);
|