nio-cat 0.4.3 → 0.5.0
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/bin/nio.js +29 -2
- package/package.json +1 -1
- package/src/agents/claude.js +13 -3
- package/src/hub.js +41 -6
- package/src/server.js +9 -0
- package/src/tunnel.js +22 -1
- package/web/app/app.js +248 -75
- package/web/app/index.html +3 -5
- package/web/app/style.css +92 -9
- package/web/board.css +24 -3
- package/web/board.js +10 -0
- package/web/sw.js +1 -1
package/web/app/index.html
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<body>
|
|
40
40
|
<header class="mbar">
|
|
41
41
|
<button class="icon-btn burger" id="burger" type="button" aria-label="Obre el menú" aria-expanded="false" aria-controls="side"><span></span><span></span><span></span></button>
|
|
42
|
-
<a href="/" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a>
|
|
42
|
+
<a href="/app" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a>
|
|
43
43
|
<span class="here" id="here"></span>
|
|
44
44
|
<span class="grow"></span>
|
|
45
45
|
<span id="mRight"></span>
|
|
@@ -47,12 +47,10 @@
|
|
|
47
47
|
<div class="scrim" id="scrim"></div>
|
|
48
48
|
<div class="shell">
|
|
49
49
|
<aside class="side" id="side">
|
|
50
|
-
<div class="brand"><a href="/" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a><button class="icon-btn collapse" id="collapse" type="button" aria-label="Plega el menú" aria-expanded="true"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="15" rx="2.5"/><path d="M9.5 4.5v15M15.5 10l-2 2 2 2"/></svg></button></div>
|
|
50
|
+
<div class="brand"><a href="/app" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a><button class="icon-btn collapse" id="collapse" type="button" aria-label="Plega el menú" aria-expanded="true"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="15" rx="2.5"/><path d="M9.5 4.5v15M15.5 10l-2 2 2 2"/></svg></button></div>
|
|
51
51
|
<nav id="nav" aria-label="Seccions"></nav>
|
|
52
52
|
<div class="foot">
|
|
53
53
|
<div class="conn" id="sideConn"></div>
|
|
54
|
-
<a class="kbd" href="#/ordinadors" data-act="help" title="Com es fa"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v5M12 16v.1"/></svg><span class="l">Com es fa</span></a>
|
|
55
|
-
<button class="kbd" data-act="tour" type="button" title="Tutorial"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M9.6 9.3a2.5 2.5 0 0 1 4.8.9c0 1.7-2.4 2.2-2.4 3.6M12 17.2v.1"/></svg><span class="l">Tutorial</span></button>
|
|
56
54
|
<button class="kbd" data-act="palette" type="button" title="Cerca o fes una acció (⌘K)"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg><span class="l">Cerca o fes una acció</span><kbd>⌘K</kbd></button>
|
|
57
55
|
</div>
|
|
58
56
|
</aside>
|
|
@@ -69,7 +67,7 @@
|
|
|
69
67
|
<div class="tour-card" id="tourCard" role="dialog" aria-modal="false" aria-labelledby="tourT"></div>
|
|
70
68
|
</div>
|
|
71
69
|
<nav class="tabbar" id="tabbar" aria-label="Navegació"></nav>
|
|
72
|
-
<div class="toasts" id="toasts" aria-live="polite"></div>
|
|
70
|
+
<div class="toasts" id="toasts" popover="manual" aria-live="polite"></div>
|
|
73
71
|
|
|
74
72
|
<script src="/bot.js"></script>
|
|
75
73
|
<script src="/board.js"></script>
|
package/web/app/style.css
CHANGED
|
@@ -82,7 +82,12 @@ kbd { font: 600 11px var(--font); padding: 1px 6px; border: 1px solid var(--bord
|
|
|
82
82
|
body.side-collapsed .shell { grid-template-columns: 72px minmax(0, 1fr); }
|
|
83
83
|
body.side-collapsed .brand .collapse { transform: translateX(4px); }
|
|
84
84
|
body.side-collapsed .brand .collapse svg { transform: scaleX(-1); }
|
|
85
|
-
body.side-collapsed .brand .word
|
|
85
|
+
body.side-collapsed .brand .word { visibility: hidden; }
|
|
86
|
+
body.side-collapsed .side nav a .l, body.side-collapsed .kbd .l, body.side-collapsed .kbd kbd, body.side-collapsed .conn span, body.side-collapsed .conn svg { display: none; }
|
|
87
|
+
body.side-collapsed .conn { padding-left: 0; justify-content: center; }
|
|
88
|
+
body.side-collapsed .side nav .grp { font-size: 0; padding: 9px 13px 5px; }
|
|
89
|
+
body.side-collapsed .side nav .grp::before { content: ''; display: block; height: 1px; background: var(--border); }
|
|
90
|
+
body.side-collapsed .side nav .grp:first-child { display: none; }
|
|
86
91
|
body.side-collapsed .side nav a .badge { position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; font-size: 9px; padding: 0 4px; }
|
|
87
92
|
}
|
|
88
93
|
|
|
@@ -104,7 +109,7 @@ kbd { font: 600 11px var(--font); padding: 1px 6px; border: 1px solid var(--bord
|
|
|
104
109
|
.icon-btn { position: relative; display: grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: 12px; background: none; color: var(--fg); }
|
|
105
110
|
.icon-btn:hover { background: color-mix(in srgb, var(--bg-2) 80%, transparent); }
|
|
106
111
|
.icon-btn .badge { position: absolute; top: 3px; right: 1px; min-width: 18px; height: 18px; font-size: 10px; }
|
|
107
|
-
input[type="text"], input[type="url"], input[type="search"], select, textarea.field { width: 100%; min-width: 0; height: 42px; padding: 0 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); outline: none; }
|
|
112
|
+
input[type="text"], input[type="password"], input[type="url"], input[type="search"], select, textarea.field { width: 100%; min-width: 0; height: 42px; padding: 0 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); outline: none; }
|
|
108
113
|
textarea.field { height: auto; padding: 10px 12px; resize: vertical; line-height: 1.45; }
|
|
109
114
|
input:focus, select:focus, textarea:focus { border-color: var(--fg); }
|
|
110
115
|
select { appearance: none; -webkit-appearance: none; padding-right: 40px; cursor: pointer; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2369615c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px 16px; }
|
|
@@ -134,8 +139,13 @@ button.chip:hover { border-color: var(--fg); }
|
|
|
134
139
|
@keyframes pulse { 50% { opacity: .3; } }
|
|
135
140
|
.agent-tag { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; }
|
|
136
141
|
.agent-tag::before { content: ""; width: 8px; height: 8px; border-radius: 3px; background: var(--c, var(--fg-muted)); }
|
|
137
|
-
[data-agent="claude"] { --c:
|
|
138
|
-
[data-agent="antigravity"] { --c:
|
|
142
|
+
[data-agent="claude"] { --c: #e8602c; } [data-agent="codex"] { --c: #2b5bd8; } [data-agent="grok"] { --c: var(--fg); }
|
|
143
|
+
[data-agent="antigravity"] { --c: #0f9d8a; } [data-agent="ollama"] { --c: #b08a5a; } [data-agent="demo"] { --c: var(--lemon); } [data-agent="browser"] { --c: #8a5cf6; }
|
|
144
|
+
.agent-tag.nosq::before { display: none; }
|
|
145
|
+
.abot { display: inline-flex; color: var(--c, var(--fg)); }
|
|
146
|
+
.abot .bot { --s: 20px; --bw: .15; }
|
|
147
|
+
.chat-head .abot .bot { --s: 30px; --bw: .14; }
|
|
148
|
+
.typing .abot .bot { --s: 22px; --bw: .15; }
|
|
139
149
|
.empty { padding: 48px 20px; text-align: center; color: var(--fg-muted); display: grid; justify-items: center; gap: 8px; }
|
|
140
150
|
.empty .bot { --s: 56px; --bw: .13; color: var(--fg); margin-bottom: 8px; }
|
|
141
151
|
.empty h2 { font-size: 20px; font-weight: 500; letter-spacing: -.04em; color: var(--fg); }
|
|
@@ -175,6 +185,7 @@ button.chip:hover { border-color: var(--fg); }
|
|
|
175
185
|
|
|
176
186
|
/* ---------- Sessions ---------- */
|
|
177
187
|
.session-card .title { font-size: 16px; font-weight: 500; letter-spacing: -.02em; margin-top: 8px; }
|
|
188
|
+
.session-card .last.err { color: var(--red); }
|
|
178
189
|
.session-card .last { color: var(--fg-muted); font-size: 14px; margin-top: 4px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
179
190
|
.session-card .meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; font-size: 12px; color: var(--fg-muted); }
|
|
180
191
|
.fab { position: fixed; right: 24px; bottom: calc(24px + var(--safe-b)); z-index: 15; display: inline-flex; align-items: center; gap: 8px; height: 50px; padding: 0 20px 0 16px; border: 0; border-radius: 16px; background: var(--fg); color: var(--bg); font-weight: 600; box-shadow: 0 14px 30px -14px color-mix(in srgb, var(--fg) 70%, transparent); transition: transform .15s; }
|
|
@@ -183,7 +194,6 @@ button.chip:hover { border-color: var(--fg); }
|
|
|
183
194
|
/* ---------- Xat de sessió ---------- */
|
|
184
195
|
.chat { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
|
|
185
196
|
.chat-head { display: flex; align-items: center; gap: 12px; padding: 14px 24px; border-bottom: 1px solid var(--border); }
|
|
186
|
-
.chat-head .bot { --s: 30px; --bw: .14; }
|
|
187
197
|
.chat-head h1 { font-size: 17px; font-weight: 600; letter-spacing: -.03em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
188
198
|
.chat-head .sub { font-size: 12px; color: var(--fg-muted); }
|
|
189
199
|
.mode-bar { display: flex; gap: 6px; padding: 10px 24px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); }
|
|
@@ -210,12 +220,11 @@ button.chip:hover { border-color: var(--fg); }
|
|
|
210
220
|
.tool pre { margin: 0 12px 12px; padding: 10px 12px; max-height: 320px; overflow: auto; border-radius: 8px; background: var(--code); font: 12px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
211
221
|
.ev-info, .ev-result { text-align: center; font-size: 12px; color: var(--fg-muted); }
|
|
212
222
|
.ev-result { display: flex; justify-content: center; gap: 6px; }
|
|
213
|
-
.ev-error { padding: 10px 14px; border-radius: 10px; border: 1px solid color-mix(in srgb, var(--red) 35%, transparent); background: color-mix(in srgb, var(--red) 6%, var(--white)); color: var(--red); font-size: 14px; white-space: pre-wrap; }
|
|
223
|
+
.ev-error { display: grid; gap: 2px; padding: 10px 14px; border-radius: 10px; border: 1px solid color-mix(in srgb, var(--red) 35%, transparent); background: color-mix(in srgb, var(--red) 6%, var(--white)); color: var(--red); font-size: 14px; white-space: pre-wrap; }
|
|
214
224
|
.ev-logs { font-size: 12px; color: var(--fg-muted); }
|
|
215
225
|
.ev-logs summary { cursor: pointer; }
|
|
216
226
|
.ev-logs pre { margin-top: 6px; padding: 10px; border-radius: 8px; background: var(--code); font: 11px/1.5 var(--mono); max-height: 220px; overflow: auto; white-space: pre-wrap; }
|
|
217
227
|
.typing { display: flex; align-items: center; gap: 10px; color: var(--fg-muted); font-size: 13px; }
|
|
218
|
-
.typing .bot { --s: 22px; --bw: .15; color: var(--fg); }
|
|
219
228
|
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
|
|
220
229
|
|
|
221
230
|
.approval { padding: 16px; border-radius: var(--radius); border: 1.5px solid var(--accent); background: var(--white); display: grid; gap: 10px; animation: rise .25s var(--ease); }
|
|
@@ -345,7 +354,7 @@ body.board-mode .view-enter { animation: none; }
|
|
|
345
354
|
body.chat-mode .mbar { position: fixed; left: 0; right: 0; transform: translateY(var(--vvt, 0px)); }
|
|
346
355
|
body.chat-mode .chat { position: fixed; left: 0; right: 0; top: calc(56px + var(--safe-t) + var(--vvt, 0px)); height: calc(var(--vvh, 100dvh) - 56px - var(--safe-t)); }
|
|
347
356
|
body.chat-mode.kb .composer { padding-bottom: 10px; }
|
|
348
|
-
.composer textarea, input[type="text"], input[type="url"], input[type="search"], select, textarea.field { font-size: 16px; }
|
|
357
|
+
.composer textarea, input[type="text"], input[type="password"], input[type="url"], input[type="search"], select, textarea.field { font-size: 16px; }
|
|
349
358
|
.chat-head { display: none; }
|
|
350
359
|
.mode-bar { padding: 10px 16px; }
|
|
351
360
|
.feed { padding: 18px 16px 24px; }
|
|
@@ -449,7 +458,7 @@ video.scan { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 14p
|
|
|
449
458
|
.burger { display: none; }
|
|
450
459
|
.tabbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; padding: 6px 8px calc(6px + var(--safe-b)); background: color-mix(in srgb, var(--bg) 94%, transparent); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border-top: 1px solid var(--border); }
|
|
451
460
|
.tabbar > * { flex: 1; position: relative; display: grid; justify-items: center; gap: 2px; padding: 6px 0; border: 0; background: none; border-radius: 10px; font-size: 11px; font-weight: 600; color: var(--fg-muted); text-decoration: none; }
|
|
452
|
-
.tabbar [aria-current="page"] { color: var(--
|
|
461
|
+
.tabbar [aria-current="page"] { color: var(--accent); }
|
|
453
462
|
.tabbar .badge { position: absolute; top: 2px; left: calc(50% + 6px); min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--accent); color: #fff; font-size: 10px; line-height: 16px; text-align: center; }
|
|
454
463
|
body:not(.no-tabs):not(.kb) .main { padding-bottom: calc(64px + var(--safe-b)); }
|
|
455
464
|
body.no-tabs .tabbar, body.kb .tabbar { display: none; }
|
|
@@ -480,3 +489,77 @@ a.kbd { text-decoration: none; color: inherit; }
|
|
|
480
489
|
.slash .t { font-size: 11px; padding: 1px 7px; border-radius: 6px; background: var(--bg-2); color: var(--fg-muted); }
|
|
481
490
|
.slash .t.ag { background: color-mix(in srgb, var(--lemon) 60%, var(--bg)); color: var(--fg); }
|
|
482
491
|
@media (max-width: 820px) { .slash { left: 12px; right: 12px; } .slash .h { grid-column: 1 / -1; grid-row: 2; } }
|
|
492
|
+
/* ---------- Veu ---------- */
|
|
493
|
+
.ev-error b { font-size: 12px; letter-spacing: .02em; text-transform: uppercase; }
|
|
494
|
+
.speak { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; height: 28px; padding: 0 10px; border: 1px solid var(--border); border-radius: 999px; background: none; color: var(--fg-muted); font-size: 12px; font-weight: 600; }
|
|
495
|
+
.speak:hover { color: var(--fg); border-color: var(--fg); }
|
|
496
|
+
.speak .ico { width: 15px; height: 15px; }
|
|
497
|
+
.speak.wait { opacity: .6; } .speak.on { color: var(--accent); border-color: var(--accent); }
|
|
498
|
+
.composer .mic { flex: none; display: grid; place-items: center; width: 46px; height: 46px; border: 1px solid var(--border); border-radius: 14px; background: var(--white); color: var(--fg-muted); }
|
|
499
|
+
.composer .mic:hover { color: var(--fg); border-color: var(--fg); }
|
|
500
|
+
.composer .mic.rec { background: var(--red); border-color: var(--red); color: #fff; animation: pulse 1.1s ease-in-out infinite; }
|
|
501
|
+
.composer .mic.wait { opacity: .5; }
|
|
502
|
+
|
|
503
|
+
/* ---------- Ordre i text net ---------- */
|
|
504
|
+
.grid2.one { grid-template-columns: minmax(0, 1fr); max-width: 640px; }
|
|
505
|
+
.top h1, .top p, .panel.empty h2, .panel.empty p, .stepper p, .stepper b, .help-body p, .card p, .sheet h2, .sheet p, .tour-card h3, .tour-card p, .muted.small { text-wrap: balance; }
|
|
506
|
+
@media (max-width: 820px) {
|
|
507
|
+
.side nav a[href="#/models"] { display: none; }
|
|
508
|
+
.top p, .panel.empty p, .stepper p, .help-body p, .sheet p, .tour-card p, .computer .muted { text-wrap: balance; }
|
|
509
|
+
.panel.empty { text-align: center; }
|
|
510
|
+
.panel.empty .stepper { text-align: left; }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/* ---------- Afegeix un ordinador ---------- */
|
|
514
|
+
dialog.sheet.wiz.compact { height: fit-content; max-height: min(86dvh, 720px); }
|
|
515
|
+
dialog.sheet.wiz.compact[open] { display: flex; flex-direction: column; }
|
|
516
|
+
.compact .wiz-body { min-height: 330px; padding-top: 12px; gap: 18px; }
|
|
517
|
+
.compact .wiz-head { gap: 14px; }
|
|
518
|
+
.compact .wiz-head .icon-btn { margin-right: -8px; }
|
|
519
|
+
.compact .wiz-head h2 { font-size: 22px; font-weight: 500; letter-spacing: -.045em; }
|
|
520
|
+
.compact .seg button svg { width: 16px; height: 16px; }
|
|
521
|
+
.compact .seg button[aria-pressed="true"] { box-shadow: 0 1px 2px color-mix(in srgb, var(--fg) 12%, transparent); }
|
|
522
|
+
.add-intro { display: grid; gap: 4px; }
|
|
523
|
+
.add-intro h3 { font-size: 18px; font-weight: 500; letter-spacing: -.03em; line-height: 1.25; }
|
|
524
|
+
.add-intro p, .hint { font-size: 14px; color: var(--fg-muted); text-wrap: pretty; }
|
|
525
|
+
.hint { font-size: 13px; }
|
|
526
|
+
.field-row { display: flex; gap: 8px; }
|
|
527
|
+
.field-row input { flex: 1; min-width: 0; height: 46px; }
|
|
528
|
+
.field-row .btn { height: 46px; padding: 0 18px; flex: none; }
|
|
529
|
+
.hosts { display: grid; gap: 8px; font-size: 12px; font-weight: 600; letter-spacing: .02em; color: var(--fg-muted); }
|
|
530
|
+
.hosts .row { gap: 6px; }
|
|
531
|
+
.todo { list-style: none; display: grid; gap: 14px; counter-reset: t; }
|
|
532
|
+
.todo li { display: grid; grid-template-columns: 24px 1fr; gap: 12px; align-items: start; font-size: 14px; }
|
|
533
|
+
.todo .n { width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; background: var(--bg-2); font-size: 12px; font-weight: 600; margin-top: -1px; }
|
|
534
|
+
.todo li > div { display: grid; gap: 8px; min-width: 0; }
|
|
535
|
+
.todo .cmd { margin-top: 2px; }
|
|
536
|
+
.live { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: 10px; background: var(--panel); border: 1px solid var(--border); font-size: 13px; color: var(--fg-muted); }
|
|
537
|
+
.live .pulse { width: 8px; height: 8px; flex: none; border-radius: 50%; background: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
|
|
538
|
+
.checks { list-style: none; display: grid; gap: 8px; padding-top: 16px; border-top: 1px solid var(--border); font-size: 13px; color: var(--fg-muted); }
|
|
539
|
+
.checks li { display: flex; gap: 10px; align-items: baseline; }
|
|
540
|
+
.checks li::before { content: '✓'; color: var(--moss); font-weight: 700; }
|
|
541
|
+
.or { display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--fg-muted); }
|
|
542
|
+
.or::before, .or::after { content: ''; flex: 1; height: 1px; background: var(--border); }
|
|
543
|
+
.scan { width: 100%; border-radius: 12px; background: #000; aspect-ratio: 4 / 3; object-fit: cover; }
|
|
544
|
+
.sheet p { text-wrap: pretty; }
|
|
545
|
+
@media (max-width: 820px) {
|
|
546
|
+
.compact .wiz-body { min-height: 300px; }
|
|
547
|
+
.compact .seg button span { white-space: nowrap; }
|
|
548
|
+
}
|
|
549
|
+
dialog.sheet.wiz.compact .sheet-in, .compact .wiz-body { flex: 0 1 auto; }
|
|
550
|
+
.compact .wiz-body { overflow-y: auto; }
|
|
551
|
+
|
|
552
|
+
/* Alertes: capa superior (popover) i gest de lliscar */
|
|
553
|
+
.toasts[popover] { inset: auto 20px calc(20px + var(--safe-b)) auto; margin: 0; padding: 0; border: 0; background: none; color: inherit; overflow: visible; width: auto; height: auto; max-width: calc(100vw - 24px); display: none; }
|
|
554
|
+
.toasts[popover]:popover-open { display: grid; }
|
|
555
|
+
@media (max-width: 820px) { .toasts[popover] { inset: auto 12px calc(12px + var(--safe-b)) 12px; max-width: none; } body.chat-mode .toasts[popover] { bottom: calc(84px + var(--safe-b)); } }
|
|
556
|
+
.toast { touch-action: pan-y; user-select: none; -webkit-user-select: none; cursor: grab; box-shadow: 0 8px 24px color-mix(in srgb, var(--fg) 22%, transparent); }
|
|
557
|
+
.toast.out { opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; }
|
|
558
|
+
|
|
559
|
+
/* Bot de l'agent dins la pastilla: enganxat a l'esquerra, centrat en vertical */
|
|
560
|
+
.chip:has(.abot) { padding: 0 11px 0 3px; }
|
|
561
|
+
.chip .abot { line-height: 0; align-items: center; }
|
|
562
|
+
.chip .abot .bot { --s: 20px; --bw: .15; }
|
|
563
|
+
.chip .agent-tag { gap: 7px; }
|
|
564
|
+
.sheet .list + .or { margin-top: 18px; }
|
|
565
|
+
.sheet #modelForm { margin-top: 4px; }
|
package/web/board.css
CHANGED
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
@keyframes bd-msg { from { opacity: 0; transform: translateY(6px); } }
|
|
107
107
|
.bd-chat .chips { display: flex; gap: 6px; overflow-x: auto; padding: 0 16px 10px; scrollbar-width: none; }
|
|
108
108
|
.bd-chat .chips::-webkit-scrollbar { display: none; }
|
|
109
|
-
.bd-chat .chip-s { flex: none; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding:
|
|
109
|
+
.bd-chat .chip-s { flex: none; max-width: 260px; box-sizing: border-box; height: 32px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 12px; line-height: 30px; text-align: center; border: 1px solid var(--border); border-radius: 999px; background: var(--white); font-size: 12px; font-weight: 500; cursor: pointer; }
|
|
110
110
|
.bd-chat .chip-s:hover { border-color: var(--fg); }
|
|
111
111
|
.bd-chat .cin { display: flex; gap: 8px; align-items: flex-end; padding: 12px 14px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }
|
|
112
112
|
.bd-chat .cin textarea { flex: 1; min-height: 42px; max-height: 140px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--white); resize: none; font: inherit; font-size: 14px; line-height: 1.4; outline: none; }
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
.bd-style { display: none; }
|
|
133
133
|
.style-open .bd-style:not([hidden]) { display: grid; left: 10px; right: 10px; top: auto; bottom: calc(70px + env(safe-area-inset-bottom)); width: auto; grid-template-columns: 1fr 1fr; }
|
|
134
134
|
.bd-help .cols { grid-template-columns: 1fr; }
|
|
135
|
-
.bd-chat { position: absolute; left: 0; right: 0; bottom: 0; z-index: 9; width: auto; height: min(
|
|
135
|
+
.bd-chat { position: absolute; top: auto; left: 0; right: 0; bottom: 0; z-index: 9; width: auto; height: min(78%, 600px); border: 0; border-top: 1px solid var(--border); border-radius: 20px 20px 0 0; transform: translateY(105%); transition: transform .34s var(--bd-ease), visibility 0s linear .34s; box-shadow: 0 -20px 50px -30px color-mix(in srgb, var(--fg) 55%, transparent); }
|
|
136
136
|
.chat-open .bd-chat { transform: none; transition: transform .34s var(--bd-ease), visibility 0s; }
|
|
137
137
|
.bd-chat header::before { content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 4px; background: var(--border); }
|
|
138
138
|
.bd-empty { top: 42%; }
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
|
|
141
141
|
/* El llenç s'adapta a la seva amplada real (tauleta, xat obert, mòbil) */
|
|
142
142
|
@container stage (max-width: 720px) {
|
|
143
|
-
.bd-chat { position: absolute; left: 0; right: 0; bottom: 0; z-index: 9; width: auto; height: min(
|
|
143
|
+
.bd-chat { position: absolute; top: auto; left: 0; right: 0; bottom: 0; z-index: 9; width: auto; height: min(78%, 600px); border: 0; border-top: 1px solid var(--border); border-radius: 20px 20px 0 0; transform: translateY(105%); transition: transform .34s var(--bd-ease), visibility 0s linear .34s; box-shadow: 0 -20px 50px -30px color-mix(in srgb, var(--fg) 55%, transparent); }
|
|
144
144
|
.chat-open .bd-chat { transform: none; transition: transform .34s var(--bd-ease), visibility 0s; }
|
|
145
145
|
.bd-chat header::before { content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 4px; background: var(--border); }
|
|
146
146
|
.chat-open .bd-tools, .chat-open .bd-right { transform: none; }
|
|
@@ -168,3 +168,24 @@
|
|
|
168
168
|
.bd-tools .sep { display: none; }
|
|
169
169
|
.bd-tools .tb { flex: 1 1 0; min-width: 30px; width: auto; height: 38px; }
|
|
170
170
|
}
|
|
171
|
+
|
|
172
|
+
/* Xat com a drawer inferior (mòbil, tauleta i llenç estret) */
|
|
173
|
+
.bd-scrim { display: none; }
|
|
174
|
+
.bd-chat header { position: relative; touch-action: none; cursor: grab; }
|
|
175
|
+
.bd-chat.dragging { transition: none !important; }
|
|
176
|
+
@media (max-width: 820px) {
|
|
177
|
+
.bd-scrim { display: block; position: absolute; inset: 0; z-index: 8; border: 0; background: color-mix(in srgb, var(--fg) 30%, transparent); opacity: 0; visibility: hidden; transition: opacity .3s, visibility 0s linear .3s; }
|
|
178
|
+
.chat-open .bd-scrim { opacity: 1; visibility: visible; transition: opacity .3s, visibility 0s; }
|
|
179
|
+
.bd-chat { max-width: 640px; margin: 0 auto; }
|
|
180
|
+
.bd-chat header { padding-top: 22px; }
|
|
181
|
+
.bd-chat .msgs { overscroll-behavior: contain; }
|
|
182
|
+
.bd-chat .cin textarea { font-size: 16px; }
|
|
183
|
+
.bd-chat .cin { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
|
|
184
|
+
}
|
|
185
|
+
@container stage (max-width: 720px) {
|
|
186
|
+
.bd-scrim { display: block; position: absolute; inset: 0; z-index: 8; border: 0; background: color-mix(in srgb, var(--fg) 30%, transparent); opacity: 0; visibility: hidden; transition: opacity .3s, visibility 0s linear .3s; }
|
|
187
|
+
.chat-open .bd-scrim { opacity: 1; visibility: visible; transition: opacity .3s, visibility 0s; }
|
|
188
|
+
.bd-chat { max-width: 640px; margin: 0 auto; }
|
|
189
|
+
.bd-chat header { padding-top: 22px; }
|
|
190
|
+
.bd-chat .cin textarea { font-size: 16px; }
|
|
191
|
+
}
|
package/web/board.js
CHANGED
|
@@ -1019,6 +1019,14 @@ function onKey(e) {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
function onKeyUp(e) { if (e.key === ' ') { spaceDown = false; R && R.stage.classList.remove('space'); } }
|
|
1021
1021
|
|
|
1022
|
+
function chatSwipe(chat) {
|
|
1023
|
+
const head = chat.querySelector('header'); let y0 = null, dy = 0;
|
|
1024
|
+
const drawer = () => getComputedStyle(chat).bottom === '0px' && getComputedStyle(chat).left === '0px' && getComputedStyle(chat).top !== '0px';
|
|
1025
|
+
head.addEventListener('pointerdown', (e) => { if (e.target.closest('button') || !drawer()) return; y0 = e.clientY; dy = 0; head.setPointerCapture(e.pointerId); chat.classList.add('dragging'); });
|
|
1026
|
+
head.addEventListener('pointermove', (e) => { if (y0 === null) return; dy = Math.max(0, e.clientY - y0); chat.style.transform = `translateY(${dy}px)`; });
|
|
1027
|
+
const end = () => { if (y0 === null) return; y0 = null; chat.classList.remove('dragging'); chat.style.transform = ''; if (dy > 70) openChat(false); };
|
|
1028
|
+
head.addEventListener('pointerup', end); head.addEventListener('pointercancel', end);
|
|
1029
|
+
}
|
|
1022
1030
|
function openChat(open, focus = true, persist = true) {
|
|
1023
1031
|
if (persist) { B.opts.chat = open; save(); }
|
|
1024
1032
|
if (!R) return;
|
|
@@ -1107,6 +1115,7 @@ function template() {
|
|
|
1107
1115
|
</div>
|
|
1108
1116
|
</div>
|
|
1109
1117
|
|
|
1118
|
+
<button type="button" class="bd-scrim" data-bd="chat" aria-label="Tanca el xat" tabindex="-1"></button>
|
|
1110
1119
|
<aside class="bd-chat" id="bdChat" aria-label="Xat amb en Nio">
|
|
1111
1120
|
<header><span class="who">${window.NioBot ? NioBot.html('idle', 'hbot') : ''}<span><b>Nio</b><small>Et dibuixa el que li demanis</small></span></span><button type="button" class="ib" data-bd="chat" aria-label="Tanca el xat">${svgI(ICON.close)}</button></header>
|
|
1112
1121
|
<label class="brain"><span>Amb</span><select id="bdBrain" aria-label="Què fa servir el xat"></select></label>
|
|
@@ -1171,6 +1180,7 @@ function mount(root) {
|
|
|
1171
1180
|
on(document, 'click', e => { if (R && !e.target.closest('.bd-menuwrap')) { const m = R.root.querySelector('#bdMenu'); if (m) m.hidden = true; } });
|
|
1172
1181
|
on(window, 'resize', () => { applyView(); drawSel(); });
|
|
1173
1182
|
if (document.fonts) document.fonts.load(`500 24px Caveat`).then(() => { if (R) { B.els.forEach(el => { if (el.type === 'text' && el.text) fitText(el); }); full(); } }).catch(() => {});
|
|
1183
|
+
chatSwipe(R.chat);
|
|
1174
1184
|
full(); drawChat(); drawBrains(); setTool(tool); openChat(B.opts.chat && !matchMedia('(max-width: 820px)').matches, false, false);
|
|
1175
1185
|
window.NioBot?.refresh();
|
|
1176
1186
|
}
|
package/web/sw.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// nio · service worker: obre l'app encara que no hi hagi connexió i mostra els avisos.
|
|
2
|
-
const SHELL = 'nio-shell-
|
|
2
|
+
const SHELL = 'nio-shell-v14';
|
|
3
3
|
const FILES = ['/app', '/app/style.css', '/app/app.js', '/bot.css', '/bot.js', '/board.css', '/board.js', '/favicon.svg', '/manifest.webmanifest'];
|
|
4
4
|
|
|
5
5
|
self.addEventListener('install', (e) => {
|