@hmduc16031996/claude-mb-bridge 2.5.2 → 2.5.4
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/app.js +32 -36
- package/public/index.html +13 -10
- package/public/styles.css +14 -27
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -1688,7 +1688,6 @@ class ClaudeRemote {
|
|
|
1688
1688
|
}
|
|
1689
1689
|
}
|
|
1690
1690
|
|
|
1691
|
-
// Mobile keys methods
|
|
1692
1691
|
initMobileKeys() {
|
|
1693
1692
|
// Only init on touch devices
|
|
1694
1693
|
if (window.matchMedia('(pointer: fine)').matches) return;
|
|
@@ -1723,54 +1722,45 @@ class ClaudeRemote {
|
|
|
1723
1722
|
});
|
|
1724
1723
|
}, { passive: true });
|
|
1725
1724
|
|
|
1726
|
-
//
|
|
1725
|
+
// Always show in mobile flex flow
|
|
1726
|
+
this.elements.mainScreen.classList.add('mobile-keys-visible');
|
|
1727
|
+
|
|
1728
|
+
// Handle initial sizing
|
|
1727
1729
|
if (window.visualViewport) {
|
|
1728
1730
|
window.visualViewport.addEventListener('resize', () => this.onViewportChange());
|
|
1729
1731
|
window.visualViewport.addEventListener('scroll', () => this.onViewportChange());
|
|
1732
|
+
this.onViewportChange();
|
|
1730
1733
|
}
|
|
1731
1734
|
}
|
|
1732
1735
|
|
|
1733
1736
|
onViewportChange() {
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
this.elements.mobileKeys.style.bottom = `${Math.max(0, keyboardHeight)}px`;
|
|
1746
|
-
this.showMobileKeys();
|
|
1747
|
-
} else {
|
|
1748
|
-
this.hideMobileKeys();
|
|
1737
|
+
if (!window.visualViewport) return;
|
|
1738
|
+
|
|
1739
|
+
// Adjust app height to match visual viewport (the actual visible area above the keyboard)
|
|
1740
|
+
const viewportHeight = window.visualViewport.height;
|
|
1741
|
+
const bodyHeight = window.innerHeight;
|
|
1742
|
+
|
|
1743
|
+
// On some mobile browsers, setting 100% isn't enough when keyboard is open
|
|
1744
|
+
// We explicitly set the app height to the visual viewport height
|
|
1745
|
+
const app = document.getElementById('app');
|
|
1746
|
+
if (app) {
|
|
1747
|
+
app.style.height = `${viewportHeight}px`;
|
|
1749
1748
|
}
|
|
1750
|
-
}
|
|
1751
1749
|
|
|
1752
|
-
|
|
1753
|
-
this.elements.mobileKeys.classList.remove('hidden');
|
|
1754
|
-
this.elements.mobileKeys.classList.add('visible');
|
|
1755
|
-
this.elements.mainScreen.classList.add('mobile-keys-visible');
|
|
1750
|
+
// Recalculate terminal size for the new container height
|
|
1756
1751
|
this.fitTerminal();
|
|
1757
|
-
}
|
|
1758
1752
|
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
this.
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
//
|
|
1767
|
-
setTimeout(() => {
|
|
1768
|
-
if (!this.elements.mobileKeys.classList.contains('visible')) {
|
|
1769
|
-
this.elements.mobileKeys.classList.add('hidden');
|
|
1770
|
-
}
|
|
1771
|
-
}, 300);
|
|
1753
|
+
// Ensure terminal scrolled to bottom so cursor is visible above keyboard
|
|
1754
|
+
// Only if the current session is terminal-based
|
|
1755
|
+
if (this.currentSessionId && this.terminal) {
|
|
1756
|
+
this.terminal.scrollToBottom();
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
// Log for debugging visibility if needed
|
|
1760
|
+
// console.log(`Viewport height: ${viewportHeight}, Body height: ${bodyHeight}`);
|
|
1772
1761
|
}
|
|
1773
1762
|
|
|
1763
|
+
|
|
1774
1764
|
handleMobileKey(key) {
|
|
1775
1765
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.currentSessionId) return;
|
|
1776
1766
|
|
|
@@ -1790,12 +1780,18 @@ class ClaudeRemote {
|
|
|
1790
1780
|
case 'slash':
|
|
1791
1781
|
this.ws.send('/');
|
|
1792
1782
|
break;
|
|
1783
|
+
case 'left':
|
|
1784
|
+
this.ws.send('\x1b[D'); // Arrow left
|
|
1785
|
+
break;
|
|
1793
1786
|
case 'up':
|
|
1794
1787
|
this.ws.send('\x1b[A'); // Arrow up
|
|
1795
1788
|
break;
|
|
1796
1789
|
case 'down':
|
|
1797
1790
|
this.ws.send('\x1b[B'); // Arrow down
|
|
1798
1791
|
break;
|
|
1792
|
+
case 'right':
|
|
1793
|
+
this.ws.send('\x1b[C'); // Arrow right
|
|
1794
|
+
break;
|
|
1799
1795
|
}
|
|
1800
1796
|
|
|
1801
1797
|
// Clear modifiers after sending a key (except when toggling modifiers)
|
package/public/index.html
CHANGED
|
@@ -130,6 +130,19 @@
|
|
|
130
130
|
</div>
|
|
131
131
|
</header>
|
|
132
132
|
|
|
133
|
+
<!-- Mobile Control Keys Toolbar (visible on mobile only) -->
|
|
134
|
+
<div id="mobile-keys" class="mobile-keys" role="toolbar" aria-label="Control keys">
|
|
135
|
+
<button type="button" class="mobile-key" data-key="escape" aria-label="Escape">Esc</button>
|
|
136
|
+
<button type="button" class="mobile-key mobile-key-modifier" data-key="ctrl" aria-label="Control modifier" aria-pressed="false">Ctrl</button>
|
|
137
|
+
<button type="button" class="mobile-key mobile-key-modifier" data-key="shift" aria-label="Shift modifier" aria-pressed="false">Shift</button>
|
|
138
|
+
<button type="button" class="mobile-key" data-key="tab" aria-label="Tab">Tab</button>
|
|
139
|
+
<button type="button" class="mobile-key" data-key="slash" aria-label="Slash">/</button>
|
|
140
|
+
<button type="button" class="mobile-key" data-key="left" aria-label="Arrow left">←</button>
|
|
141
|
+
<button type="button" class="mobile-key" data-key="up" aria-label="Arrow up">↑</button>
|
|
142
|
+
<button type="button" class="mobile-key" data-key="down" aria-label="Arrow down">↓</button>
|
|
143
|
+
<button type="button" class="mobile-key" data-key="right" aria-label="Arrow right">→</button>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
133
146
|
<!-- Terminal Container -->
|
|
134
147
|
<div id="terminal-container" role="application" aria-label="Terminal"></div>
|
|
135
148
|
|
|
@@ -140,16 +153,6 @@
|
|
|
140
153
|
</svg>
|
|
141
154
|
</button>
|
|
142
155
|
|
|
143
|
-
<!-- Mobile Control Keys Toolbar (visible when keyboard is open on mobile) -->
|
|
144
|
-
<div id="mobile-keys" class="mobile-keys hidden" role="toolbar" aria-label="Control keys">
|
|
145
|
-
<button type="button" class="mobile-key" data-key="escape" aria-label="Escape">Esc</button>
|
|
146
|
-
<button type="button" class="mobile-key mobile-key-modifier" data-key="ctrl" aria-label="Control modifier" aria-pressed="false">Ctrl</button>
|
|
147
|
-
<button type="button" class="mobile-key mobile-key-modifier" data-key="shift" aria-label="Shift modifier" aria-pressed="false">Shift</button>
|
|
148
|
-
<button type="button" class="mobile-key" data-key="tab" aria-label="Tab">Tab</button>
|
|
149
|
-
<button type="button" class="mobile-key" data-key="slash" aria-label="Slash">/</button>
|
|
150
|
-
<button type="button" class="mobile-key" data-key="up" aria-label="Arrow up">↑</button>
|
|
151
|
-
<button type="button" class="mobile-key" data-key="down" aria-label="Arrow down">↓</button>
|
|
152
|
-
</div>
|
|
153
156
|
|
|
154
157
|
<!-- Floating expand button (visible when header collapsed) -->
|
|
155
158
|
<button id="expand-header-btn" class="btn-icon floating-btn hidden" title="Show header" aria-label="Show header">
|
package/public/styles.css
CHANGED
|
@@ -63,11 +63,12 @@ body {
|
|
|
63
63
|
|
|
64
64
|
#app {
|
|
65
65
|
width: 100%;
|
|
66
|
-
height:
|
|
66
|
+
height: 100vh; /* Primary height */
|
|
67
67
|
display: flex;
|
|
68
68
|
flex-direction: column;
|
|
69
69
|
position: relative;
|
|
70
70
|
z-index: 1;
|
|
71
|
+
overflow: hidden;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
/* ===== SCREENS ===== */
|
|
@@ -1443,36 +1444,28 @@ kbd {
|
|
|
1443
1444
|
/* CRITICAL: z-index must be higher than touch-scroll-overlay (9999) to receive taps.
|
|
1444
1445
|
The overlay doesn't create a stacking context, so its 9999 z-index competes directly. */
|
|
1445
1446
|
.mobile-keys {
|
|
1446
|
-
position: fixed;
|
|
1447
|
-
left: 0;
|
|
1448
|
-
right: 0;
|
|
1449
1447
|
display: flex;
|
|
1450
1448
|
justify-content: center;
|
|
1451
|
-
gap: 0.
|
|
1452
|
-
padding: 0.5rem;
|
|
1449
|
+
gap: 0.25rem;
|
|
1450
|
+
padding: 0.375rem 0.5rem;
|
|
1453
1451
|
background: var(--bg-primary);
|
|
1454
|
-
border-
|
|
1455
|
-
z-index:
|
|
1456
|
-
opacity: 0;
|
|
1457
|
-
pointer-events: none;
|
|
1452
|
+
border-bottom: 1px solid var(--border);
|
|
1453
|
+
z-index: 5;
|
|
1458
1454
|
transition: opacity var(--transition);
|
|
1459
|
-
|
|
1455
|
+
flex-shrink: 0;
|
|
1460
1456
|
}
|
|
1461
1457
|
|
|
1462
|
-
.mobile-keys.visible {
|
|
1463
|
-
opacity: 1;
|
|
1464
|
-
pointer-events: auto;
|
|
1465
|
-
}
|
|
1466
1458
|
|
|
1467
1459
|
.mobile-key {
|
|
1460
|
+
flex: 1;
|
|
1461
|
+
min-width: 0;
|
|
1468
1462
|
display: inline-flex;
|
|
1469
1463
|
align-items: center;
|
|
1470
1464
|
justify-content: center;
|
|
1471
|
-
min-width: 48px;
|
|
1472
1465
|
height: 40px;
|
|
1473
|
-
padding: 0 0.
|
|
1466
|
+
padding: 0 0.25rem;
|
|
1474
1467
|
font-family: var(--font-mono);
|
|
1475
|
-
font-size: 0.
|
|
1468
|
+
font-size: 0.75rem;
|
|
1476
1469
|
background: var(--bg-surface);
|
|
1477
1470
|
color: var(--text-secondary);
|
|
1478
1471
|
border: 1px solid var(--border);
|
|
@@ -1502,15 +1495,9 @@ kbd {
|
|
|
1502
1495
|
}
|
|
1503
1496
|
}
|
|
1504
1497
|
|
|
1505
|
-
/*
|
|
1506
|
-
.mobile-keys
|
|
1507
|
-
|
|
1508
|
-
bottom: calc(56px + max(0.5rem, env(safe-area-inset-bottom)));
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
/* When mobile keys are visible, add padding to terminal */
|
|
1512
|
-
#main-screen.mobile-keys-visible #terminal-container {
|
|
1513
|
-
padding-bottom: calc(56px + env(safe-area-inset-bottom));
|
|
1498
|
+
/* Layout adjustments when toolbar is visible (now part of flex flow) */
|
|
1499
|
+
.mobile-keys + #terminal-container {
|
|
1500
|
+
border-top: none; /* Already have border-bottom on keys */
|
|
1514
1501
|
}
|
|
1515
1502
|
|
|
1516
1503
|
/* ===== SCROLL TO BOTTOM BUTTON ===== */
|