fix splitting layout bug - was not splitting visually original shell

This commit is contained in:
2026-05-24 09:09:03 +00:00
parent 3ab54f812a
commit ade413bac7
10 changed files with 151 additions and 1 deletions
+3
View File
@@ -152,6 +152,9 @@ html, body { height: 100%; background: #0d0f14; color: #e2e8f0;
.tb-btn.tb-info { background: rgba(59,130,246,0.1); color: #93c5fd;
border: 1px solid rgba(59,130,246,0.2); }
.tb-btn.tb-info:hover { background: rgba(59,130,246,0.18); color: #bfdbfe; }
.tb-btn.tb-logout { background: rgba(245,158,11,0.08); color: #fbbf24;
border: 1px solid rgba(245,158,11,0.15); }
.tb-btn.tb-logout:hover { background: rgba(245,158,11,0.15); color: #fcd34d; }
.tb-sep { width: 1px; height: 20px; background: rgba(255,255,255,0.07); flex-shrink: 0; margin: 0 2px; }
/* ── Toast ── */
+56
View File
@@ -379,6 +379,9 @@ function splitPane(dir) {
// replaceNode uses leaf.parent (old parent) — set new parents AFTER
replaceNode(tab, leaf, splitNode);
// Re-apply grandparent's flex so the new splitNode.el inherits correct sizing.
// Without this, the new container has no flex rule and collapses visually.
if (splitNode.parent) applyFlex(splitNode.parent);
leaf.parent = splitNode;
newLeaf.parent = splitNode;
@@ -439,6 +442,8 @@ function closePane() {
replaceNode(tab, splitNode, sibling);
sibling.el.removeAttribute('style');
// Re-apply grandparent's flex so sibling gets correct sizing in its new position.
if (sibling.parent) applyFlex(sibling.parent);
const next = findFirstLeaf(sibling);
setActiveLeaf(tab, next);
@@ -708,6 +713,57 @@ function modalFb(id, msg, type) {
el.className = 'm-fb' + (type ? ' ' + type : '');
}
// ── Logout & inactivity ────────────────────────────────────────────────
const INACTIVITY_MS = 30 * 60 * 1000; // 30 min inactivity → auto-logout
const HEARTBEAT_MS = 5 * 60 * 1000; // 5 min heartbeat → extend server cookie
let _inactTimer = null;
let _hbTimer = null;
function _resetInactivity() {
clearTimeout(_inactTimer);
_inactTimer = setTimeout(doLogout, INACTIVITY_MS);
}
function _startHeartbeat() {
clearInterval(_hbTimer);
_hbTimer = setInterval(_sendHeartbeat, HEARTBEAT_MS);
}
async function _sendHeartbeat() {
try {
const res = await fetch('/api/refresh', { method: 'POST' });
if (res.status === 401) {
// Cookie already expired server-side — stop timers, go to login
clearInterval(_hbTimer);
clearTimeout(_inactTimer);
window.location.href = '/login?next=/s/' + WORKSPACE_ID;
}
} catch (_) {}
}
async function doLogout() {
clearTimeout(_inactTimer);
clearInterval(_hbTimer);
try {
const form = new URLSearchParams();
form.append('next', '/s/' + WORKSPACE_ID);
await fetch('/logout', {
method: 'POST',
body: form,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
} catch (_) {}
window.location.href = '/login?next=/s/' + WORKSPACE_ID;
}
// Reset inactivity timer on any user interaction.
['mousemove', 'keydown', 'touchstart', 'click'].forEach(ev =>
document.addEventListener(ev, _resetInactivity, { passive: true })
);
_resetInactivity();
_startHeartbeat();
// ── Bootstrap ──────────────────────────────────────────────────────────
// Terminal page is only served to authenticated users (server redirects
// unauthenticated requests to /login). Load saved workspace or start fresh.
+15
View File
@@ -148,6 +148,14 @@
</svg>
End
</button>
<!-- Logout (sign out, workspace preserved) -->
<button class="tb-btn tb-logout" onclick="doLogout()" title="Sign out — workspace is preserved, sign in again to resume">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
Logout
</button>
<!-- Upload -->
<button class="tb-btn" onclick="openModal('upOverlay')" title="Upload file">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -216,10 +224,17 @@
<table class="info-table">
<tr><td>Link button</td><td>Copy shareable workspace URL — open on any device to resume all tabs &amp; splits</td></tr>
<tr><td>End button</td><td>Clear saved layout; next visit starts fresh</td></tr>
<tr><td>Logout button</td><td>Sign out — workspace and all terminals are preserved; sign in again at the same URL to resume</td></tr>
<tr><td>Upload button</td><td>Upload file to server (lands in active shell's cwd by default)</td></tr>
<tr><td>Down button</td><td>Download file from server by path</td></tr>
</table>
<div class="info-section-label">Session timeout</div>
<table class="info-table">
<tr><td>Auto-logout</td><td>30 minutes of inactivity signs you out automatically (workspace preserved)</td></tr>
<tr><td>Active sessions</td><td>Session extends automatically while you are active</td></tr>
</table>
</div>
</div>
</div>