Fix sidebar sections, terminal resize, and improve .gitignore

Sidebar:
- Add -webkit-user-select: none to section headers (WebKit prefix)
- Fix class mismatches: sidebar-section-chevron → section-chevron,
  sidebar-section-count → section-count, sidebar-section-list → sidebar-list

Terminal resize:
- Poll container dimensions after creation — retry fit every 50ms
  until container has non-zero width/height (up to 20 attempts)
- Add flex: 1 and min-height: 0 to .xterm inside session-panel
  so it participates in flex layout correctly

.gitignore:
- Comprehensive rewrite covering build output, Wails bindings,
  frontend libs, IDE files, OS metadata, and application data
This commit is contained in:
2026-04-15 00:00:00 +01:00
parent 59b26918d7
commit b31573f8a0
6 changed files with 67 additions and 31 deletions
+44 -20
View File
@@ -1,36 +1,60 @@
# Build output # ==========================================================================
build/ # Nexus Terminal — .gitignore
# ==========================================================================
# ── Build output ──────────────────────────────────────────────────────────
build/bin/
build/darwin/
build/windows/
build/linux/
dist/ dist/
# Dependencies # ── Go ────────────────────────────────────────────────────────────────────
vendor/ vendor/
frontend/node_modules/ *.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
__debug_bin*
coverage.out
coverage.html
# IDE # ── Frontend ──────────────────────────────────────────────────────────────
frontend/node_modules/
frontend/src/js/lib/
# ── Wails auto-generated bindings (recreated on every build) ──────────────
frontend/wailsjs/
# ── IDE / editor ──────────────────────────────────────────────────────────
.idea/ .idea/
.vscode/ .vscode/
*.swp *.swp
*.swo *.swo
*~ *~
*.sublime-project
*.sublime-workspace
.project
.classpath
.settings/
# OS # ── OS metadata ───────────────────────────────────────────────────────────
.DS_Store .DS_Store
.DS_Store?
._*
Thumbs.db Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
# Test # ── Application data (never commit user data or secrets) ──────────────────
coverage.out
coverage.html
# Binaries
*.exe
*.dll
*.so
*.dylib
# Debug
__debug_bin*
# Application data (never commit)
*.db *.db
*.sqlite *.sqlite
*.sqlite3
vault.json vault.json
*.pem
*.key
!build/appicon.png
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

+1
View File
@@ -77,6 +77,7 @@
letter-spacing: 0.06em; letter-spacing: 0.06em;
cursor: pointer; cursor: pointer;
transition: color var(--transition-fast), background var(--transition-fast); transition: color var(--transition-fast), background var(--transition-fast);
-webkit-user-select: none;
user-select: none; user-select: none;
text-align: left; text-align: left;
background: none; background: none;
+2
View File
@@ -69,7 +69,9 @@
/* xterm.js overrides for consistent look */ /* xterm.js overrides for consistent look */
.terminal-container .xterm, .terminal-container .xterm,
.session-panel .xterm { .session-panel .xterm {
flex: 1;
height: 100%; height: 100%;
min-height: 0;
padding: var(--space-1); padding: var(--space-1);
} }
+4 -4
View File
@@ -113,16 +113,16 @@ class Sidebar {
// Section header // Section header
const header = createElement('div', 'sidebar-section-header'); const header = createElement('div', 'sidebar-section-header');
header.innerHTML = ` header.innerHTML = `
<span class="sidebar-section-chevron ${isCollapsed ? 'collapsed' : ''}">${isCollapsed ? '▸' : '▾'}</span> <span class="section-chevron ${isCollapsed ? 'collapsed' : ''}">${isCollapsed ? '▸' : '▾'}</span>
<span class="sidebar-section-title">${escapeHtml(title)}</span> <span>${escapeHtml(title)}</span>
<span class="sidebar-section-count">${profiles.length}</span> <span class="section-count">${profiles.length}</span>
`; `;
header.addEventListener('click', () => this.toggleSection(key)); header.addEventListener('click', () => this.toggleSection(key));
section.appendChild(header); section.appendChild(header);
// Items // Items
if (!isCollapsed) { if (!isCollapsed) {
const list = createElement('div', 'sidebar-section-list'); const list = createElement('div', 'sidebar-list');
for (const profile of profiles) { for (const profile of profiles) {
list.appendChild(this.renderProfileItem(profile)); list.appendChild(this.renderProfileItem(profile));
} }
+16 -7
View File
@@ -67,14 +67,23 @@ class TerminalManager {
const container = document.getElementById(containerId); const container = document.getElementById(containerId);
term.open(container); term.open(container);
// Fit the terminal once the container has had time to lay out. // Fit the terminal once the container has real dimensions.
// A single requestAnimationFrame is not enough — the panel may // The panel may have just transitioned from display:none, so we
// still be transitioning from display:none, so we retry briefly. // poll until the container reports a non-trivial size.
const doFit = () => { try { fitAddon.fit(); } catch (_) { /* noop */ } }; const doFit = () => { try { fitAddon.fit(); } catch (_) { /* noop */ } };
requestAnimationFrame(doFit); let fitAttempts = 0;
setTimeout(doFit, 50); const tryFit = () => {
setTimeout(doFit, 150); fitAttempts++;
setTimeout(doFit, 400); const rect = container.getBoundingClientRect();
if (rect.width > 10 && rect.height > 10) {
doFit();
} else if (fitAttempts < 20) {
// Container still has no size — retry
setTimeout(tryFit, 50);
return;
}
};
requestAnimationFrame(tryFit);
// Forward user keystrokes to the backend // Forward user keystrokes to the backend
term.onData((data) => { term.onData((data) => {