shadok-ai 0.2.8 → 0.2.10
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 +26 -22
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -258,10 +258,8 @@
|
|
|
258
258
|
.tab {
|
|
259
259
|
position: relative;
|
|
260
260
|
display: flex;
|
|
261
|
-
/*
|
|
262
|
-
|
|
263
|
-
align-items: flex-start;
|
|
264
|
-
gap: 8px;
|
|
261
|
+
flex-direction: column; /* ligne 1 (led+nom+icônes) puis ligne 2 (infos) */
|
|
262
|
+
gap: 1px;
|
|
265
263
|
font-family: var(--mono);
|
|
266
264
|
font-size: 12px;
|
|
267
265
|
color: var(--text-dim);
|
|
@@ -271,8 +269,7 @@
|
|
|
271
269
|
cursor: pointer;
|
|
272
270
|
user-select: none;
|
|
273
271
|
}
|
|
274
|
-
|
|
275
|
-
.tab .led { margin-top: 4px; }
|
|
272
|
+
.tab-row1 { display: flex; align-items: center; gap: 8px; }
|
|
276
273
|
/* Context-window usage: tiny number + thin bar at the bottom of the tab. */
|
|
277
274
|
.tab .ctxnum { font-size: 9px; color: var(--text-dim); flex: none; }
|
|
278
275
|
/* Heure du dernier message, discrète (le nom en flex:1 la pousse à droite). */
|
|
@@ -310,14 +307,12 @@
|
|
|
310
307
|
border-radius: 0 4px 4px 0;
|
|
311
308
|
box-shadow: inset 3px 0 0 var(--phosphor);
|
|
312
309
|
}
|
|
313
|
-
/*
|
|
314
|
-
|
|
315
|
-
.tab-
|
|
316
|
-
/* Ligne 2 : « xxx ago » + % de contexte, ensemble sous le nom. */
|
|
317
|
-
.tab-info { display: flex; align-items: baseline; gap: 6px; }
|
|
318
|
-
/* Le % de contexte poussé à droite de la ligne (« xxx ago » reste à gauche). */
|
|
319
|
-
.tab-info .ctxnum { margin-left: auto; }
|
|
310
|
+
/* Ligne 2 pleine largeur : « xxx ago » à gauche, % de contexte tout à droite. */
|
|
311
|
+
.tab-row2 { display: flex; align-items: baseline; gap: 6px; }
|
|
312
|
+
.tab-row2 .ctxnum { margin-left: auto; }
|
|
320
313
|
.tab .name {
|
|
314
|
+
flex: 1;
|
|
315
|
+
min-width: 0;
|
|
321
316
|
overflow: hidden;
|
|
322
317
|
text-overflow: ellipsis;
|
|
323
318
|
white-space: nowrap;
|
|
@@ -1533,14 +1528,15 @@
|
|
|
1533
1528
|
tg.innerHTML = '<svg viewBox="0 0 24 24" width="12" height="12" style="vertical-align:-1px" aria-hidden="true"><path fill="#26A5E4" d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/></svg>';
|
|
1534
1529
|
tg.title = "Mirrored to Telegram";
|
|
1535
1530
|
// Nom + heure empilés (l'heure SOUS le titre, pour ne pas le tronquer).
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1531
|
+
// Deux lignes : ligne 1 = led + nom + icônes ; ligne 2 PLEINE LARGEUR =
|
|
1532
|
+
// « xxx ago » à gauche, % de contexte tout à droite (plus caché par les icônes).
|
|
1533
|
+
const row1 = document.createElement("div");
|
|
1534
|
+
row1.className = "tab-row1";
|
|
1535
|
+
row1.append(led, name, timer, mute, cron, tg, close);
|
|
1536
|
+
const row2 = document.createElement("div");
|
|
1537
|
+
row2.className = "tab-row2";
|
|
1538
|
+
row2.append(lastAt, ctxNum);
|
|
1539
|
+
btn.append(row1, row2);
|
|
1544
1540
|
// Context-window usage: a thin progress bar at the bottom of the tab.
|
|
1545
1541
|
const ctxBar = document.createElement("div");
|
|
1546
1542
|
ctxBar.className = "ctxbar";
|
|
@@ -3644,6 +3640,14 @@
|
|
|
3644
3640
|
for (let i = 0; i < bin.length; i++) a[i] = bin.charCodeAt(i);
|
|
3645
3641
|
return a;
|
|
3646
3642
|
}
|
|
3643
|
+
// Keystroke → base64, UTF-8 first. btoa() alone treats the string as Latin1,
|
|
3644
|
+
// so "é" (U+00E9) went out as the single byte 0xE9 instead of its UTF-8 pair
|
|
3645
|
+
// 0xC3 0xA9 → mojibake in the pane; anything above U+00FF (emoji…) threw.
|
|
3646
|
+
function strToB64Utf8(s) {
|
|
3647
|
+
let bin = "";
|
|
3648
|
+
for (const b of new TextEncoder().encode(s)) bin += String.fromCharCode(b);
|
|
3649
|
+
return btoa(bin);
|
|
3650
|
+
}
|
|
3647
3651
|
function updateTermBtn() {
|
|
3648
3652
|
const on = !!(active && active.termOn);
|
|
3649
3653
|
const b = $("chanTerm");
|
|
@@ -3669,7 +3673,7 @@
|
|
|
3669
3673
|
term.open($("xtermHost"));
|
|
3670
3674
|
term.onData((d) => {
|
|
3671
3675
|
if (term && termSession && termSession.ws)
|
|
3672
|
-
termSession.ws.send(JSON.stringify({ type: "term-input", data:
|
|
3676
|
+
termSession.ws.send(JSON.stringify({ type: "term-input", data: strToB64Utf8(d) }));
|
|
3673
3677
|
});
|
|
3674
3678
|
}
|
|
3675
3679
|
if (termSession !== active) {
|