fix splitting layout bug - was not splitting visually original shell
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user