bloby-bot 0.22.19 → 0.23.1
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/cli.js
CHANGED
|
@@ -538,6 +538,15 @@ class Stepper {
|
|
|
538
538
|
lineCount += 1 + this.infoLines.length;
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
+
// Clear leftover lines when content shrinks (e.g. info lines removed)
|
|
542
|
+
if (lineCount < this._totalLines) {
|
|
543
|
+
const extra = this._totalLines - lineCount;
|
|
544
|
+
for (let i = 0; i < extra; i++) {
|
|
545
|
+
process.stdout.write('\x1b[2K\n');
|
|
546
|
+
}
|
|
547
|
+
process.stdout.write(`\x1b[${extra}A`);
|
|
548
|
+
}
|
|
549
|
+
|
|
541
550
|
this._totalLines = lineCount;
|
|
542
551
|
}
|
|
543
552
|
|
|
@@ -710,6 +719,17 @@ function finalMessage(tunnelUrl, relayUrl) {
|
|
|
710
719
|
}
|
|
711
720
|
}
|
|
712
721
|
|
|
722
|
+
function readyMessage(tunnelUrl, relayUrl) {
|
|
723
|
+
if (relayUrl) {
|
|
724
|
+
console.log(`\n ${c.pink}${c.bold}${link(relayUrl)}${c.reset}`);
|
|
725
|
+
console.log(` ${c.dim}(cmd+click or ctrl+click to open)${c.reset}`);
|
|
726
|
+
}
|
|
727
|
+
if (tunnelUrl && tunnelUrl !== relayUrl) {
|
|
728
|
+
console.log(` ${c.dim}Tunnel:${c.reset} ${c.dim}${link(tunnelUrl)}${c.reset}`);
|
|
729
|
+
}
|
|
730
|
+
console.log('');
|
|
731
|
+
}
|
|
732
|
+
|
|
713
733
|
function writeVersionFile(version) {
|
|
714
734
|
try { fs.writeFileSync(path.join(DATA_DIR, 'VERSION'), version); } catch {}
|
|
715
735
|
}
|
|
@@ -1552,13 +1572,7 @@ async function update() {
|
|
|
1552
1572
|
if (daemonWasRunning) {
|
|
1553
1573
|
if (updateResult && updateResult.healthOk) {
|
|
1554
1574
|
console.log(` ${c.blue}✔${c.reset} Daemon restarted with new version.`);
|
|
1555
|
-
|
|
1556
|
-
console.log(` ${c.dim}Tunnel:${c.reset} ${c.blue}${link(updateResult.tunnelUrl)}${c.reset}`);
|
|
1557
|
-
}
|
|
1558
|
-
if (updateResult.relayUrl) {
|
|
1559
|
-
console.log(` ${c.dim}URL:${c.reset} ${c.pink}${link(updateResult.relayUrl)}${c.reset}`);
|
|
1560
|
-
}
|
|
1561
|
-
console.log('');
|
|
1575
|
+
readyMessage(updateResult.tunnelUrl, updateResult.relayUrl);
|
|
1562
1576
|
} else {
|
|
1563
1577
|
console.log(` ${c.yellow}⚠${c.reset} Daemon may still be starting. Check ${c.pink}bloby daemon status${c.reset}\n`);
|
|
1564
1578
|
}
|
|
@@ -1690,14 +1704,8 @@ async function daemon(sub) {
|
|
|
1690
1704
|
const restartResult = await waitForDaemonHealth(restartStepper, restartConfig, restartHasTunnel, restartLogOffset);
|
|
1691
1705
|
restartStepper.finish();
|
|
1692
1706
|
|
|
1693
|
-
console.log(`\n ${c.blue}✔${c.reset} Bloby daemon restarted
|
|
1694
|
-
|
|
1695
|
-
console.log(` ${c.dim}Tunnel:${c.reset} ${c.blue}${link(restartResult.tunnelUrl)}${c.reset}`);
|
|
1696
|
-
}
|
|
1697
|
-
if (restartResult.relayUrl) {
|
|
1698
|
-
console.log(` ${c.dim}URL:${c.reset} ${c.pink}${link(restartResult.relayUrl)}${c.reset}`);
|
|
1699
|
-
}
|
|
1700
|
-
if (restartResult.tunnelUrl || restartResult.relayUrl) console.log('');
|
|
1707
|
+
console.log(`\n ${c.blue}✔${c.reset} Bloby daemon restarted.`);
|
|
1708
|
+
readyMessage(restartResult.tunnelUrl, restartResult.relayUrl);
|
|
1701
1709
|
break;
|
|
1702
1710
|
}
|
|
1703
1711
|
|
|
@@ -1830,14 +1838,8 @@ async function daemon(sub) {
|
|
|
1830
1838
|
const sysRestartResult = await waitForDaemonHealth(sysRestartStepper, sysRestartConfig, sysRestartHasTunnel, 0);
|
|
1831
1839
|
sysRestartStepper.finish();
|
|
1832
1840
|
|
|
1833
|
-
console.log(`\n ${c.blue}✔${c.reset} Bloby daemon restarted
|
|
1834
|
-
|
|
1835
|
-
console.log(` ${c.dim}Tunnel:${c.reset} ${c.blue}${link(sysRestartResult.tunnelUrl)}${c.reset}`);
|
|
1836
|
-
}
|
|
1837
|
-
if (sysRestartResult.relayUrl) {
|
|
1838
|
-
console.log(` ${c.dim}URL:${c.reset} ${c.pink}${link(sysRestartResult.relayUrl)}${c.reset}`);
|
|
1839
|
-
}
|
|
1840
|
-
if (sysRestartResult.tunnelUrl || sysRestartResult.relayUrl) console.log('');
|
|
1841
|
+
console.log(`\n ${c.blue}✔${c.reset} Bloby daemon restarted.`);
|
|
1842
|
+
readyMessage(sysRestartResult.tunnelUrl, sysRestartResult.relayUrl);
|
|
1841
1843
|
break;
|
|
1842
1844
|
}
|
|
1843
1845
|
|
package/package.json
CHANGED
|
@@ -320,6 +320,7 @@ export default function InputBar({ onSend, onStop, streaming, whisperEnabled, on
|
|
|
320
320
|
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
|
321
321
|
|
|
322
322
|
holdTimerRef.current = setTimeout(() => {
|
|
323
|
+
try { navigator.vibrate?.(50); } catch {}
|
|
323
324
|
beginRecording();
|
|
324
325
|
}, 200);
|
|
325
326
|
}, [isMobile, isRecording, voiceEnabled, beginRecording, stopRecording]);
|
|
@@ -528,14 +529,17 @@ export default function InputBar({ onSend, onStop, streaming, whisperEnabled, on
|
|
|
528
529
|
{/* Draggable mic (DOM transform for 60fps) */}
|
|
529
530
|
<div
|
|
530
531
|
ref={micRef}
|
|
531
|
-
className="shrink-0 touch-none select-none will-change-transform"
|
|
532
|
+
className="shrink-0 touch-none select-none will-change-transform relative z-10"
|
|
532
533
|
style={{ transition: 'none' }}
|
|
533
534
|
onPointerDown={handleMicDown}
|
|
534
535
|
onPointerMove={handleMicMove}
|
|
535
536
|
onPointerUp={handleMicUp}
|
|
536
537
|
onPointerCancel={handleMicCancel}
|
|
537
538
|
>
|
|
538
|
-
<div
|
|
539
|
+
<div
|
|
540
|
+
className="flex items-center justify-center h-11 w-11 rounded-full bg-destructive text-destructive-foreground"
|
|
541
|
+
style={{ animation: 'mic-pulse-scale 2s ease-in-out infinite' }}
|
|
542
|
+
>
|
|
539
543
|
<Mic className="h-5 w-5" />
|
|
540
544
|
</div>
|
|
541
545
|
</div>
|
package/supervisor/widget.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
'#bloby-widget-panel.open{transform:translateX(0)}',
|
|
14
14
|
'#bloby-widget-panel iframe{width:100%;height:100%;border:none;background:#212121}',
|
|
15
15
|
'@media(max-width:480px){#bloby-widget-panel{width:100vw}}',
|
|
16
|
+
'@keyframes bloby-bubble-record{0%,100%{transform:scale(1.2) translateY(-12px)}50%{transform:scale(1.25) translateY(-14px)}}',
|
|
16
17
|
].join('\n');
|
|
17
18
|
document.head.appendChild(style);
|
|
18
19
|
|
|
@@ -475,7 +476,17 @@
|
|
|
475
476
|
loadHpSprite(function() { if (hpPointerDown) beginHpAnimation(); });
|
|
476
477
|
return;
|
|
477
478
|
}
|
|
479
|
+
try { navigator.vibrate(50); } catch(e) {}
|
|
478
480
|
badgeEl.style.display = 'none';
|
|
481
|
+
// Grow + shift up, then start pulsating after the transition
|
|
482
|
+
canvas.style.transition = 'transform 0.2s ease';
|
|
483
|
+
canvas.style.transform = 'scale(1.2) translateY(-12px)';
|
|
484
|
+
setTimeout(function() {
|
|
485
|
+
if (hpState === 'activating' || hpState === 'recording') {
|
|
486
|
+
canvas.style.transition = 'none';
|
|
487
|
+
canvas.style.animation = 'bloby-bubble-record 2s ease-in-out infinite';
|
|
488
|
+
}
|
|
489
|
+
}, 220);
|
|
479
490
|
hpState = 'activating';
|
|
480
491
|
hpFrame = HP_ACTIVATE_START;
|
|
481
492
|
hpPingPong = 1;
|
|
@@ -524,6 +535,11 @@
|
|
|
524
535
|
}
|
|
525
536
|
}
|
|
526
537
|
|
|
538
|
+
// Shrink back smoothly
|
|
539
|
+
canvas.style.animation = '';
|
|
540
|
+
canvas.style.transition = 'transform 0.2s ease';
|
|
541
|
+
canvas.style.transform = '';
|
|
542
|
+
|
|
527
543
|
// v2 deactivation: reverse 40→11 (activate played backwards)
|
|
528
544
|
if (hpState === 'activating') {
|
|
529
545
|
hpState = 'activating_then_deactivate';
|
|
@@ -593,6 +609,7 @@
|
|
|
593
609
|
// ══════════════════════════════════════════════════════════════════
|
|
594
610
|
|
|
595
611
|
var isOpen = false;
|
|
612
|
+
var toggleCooldown = false;
|
|
596
613
|
|
|
597
614
|
function toggle() {
|
|
598
615
|
console.log('[widget] toggle called', { canvasPhase: canvasPhase, isOpen: isOpen });
|
|
@@ -643,8 +660,11 @@
|
|
|
643
660
|
stopHpRecording(false);
|
|
644
661
|
}
|
|
645
662
|
// Tap detection: preventDefault on pointerdown suppresses click on mobile,
|
|
646
|
-
// so we handle taps here instead.
|
|
663
|
+
// so we handle taps here instead. Set cooldown to prevent the synthesized
|
|
664
|
+
// click from hitting the backdrop (bubble is hidden by then).
|
|
647
665
|
if (!hpWasHold) {
|
|
666
|
+
toggleCooldown = true;
|
|
667
|
+
setTimeout(function() { toggleCooldown = false; }, 400);
|
|
648
668
|
toggle();
|
|
649
669
|
}
|
|
650
670
|
hpWasHold = false;
|
|
@@ -674,7 +694,7 @@
|
|
|
674
694
|
});
|
|
675
695
|
|
|
676
696
|
bubble.addEventListener('contextmenu', function(e) { e.preventDefault(); });
|
|
677
|
-
backdrop.addEventListener('click', toggle);
|
|
697
|
+
backdrop.addEventListener('click', function() { if (!toggleCooldown) toggle(); });
|
|
678
698
|
document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && isOpen) toggle(); });
|
|
679
699
|
|
|
680
700
|
// ── PWA Install ──
|