Few UI cleanups
This commit is contained in:
@@ -84,11 +84,19 @@
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-section-header.sidebar-section-header-group .section-title {
|
||||||
|
color: var(--sidebar-group-title);
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-section-header:hover {
|
.sidebar-section-header:hover {
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
background: var(--bg-hover);
|
background: var(--bg-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-section-header.sidebar-section-header-group:hover .section-title {
|
||||||
|
color: var(--sidebar-group-title);
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-section-header .section-icon {
|
.sidebar-section-header .section-icon {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -174,18 +182,47 @@
|
|||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Protocol colour indicator dot */
|
/* Protocol indicator icon */
|
||||||
.sidebar-item .protocol-indicator {
|
.sidebar-item .protocol-indicator {
|
||||||
width: 8px;
|
width: 14px;
|
||||||
height: 8px;
|
height: 14px;
|
||||||
border-radius: 50%;
|
border-radius: var(--radius-sm);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: var(--text-tertiary);
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: var(--weight-semibold);
|
||||||
|
line-height: 1;
|
||||||
|
background: var(--bg-overlay);
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item .protocol-indicator::before {
|
||||||
|
content: '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-item .protocol-indicator.proto-ssh::before { content: '⌨'; }
|
||||||
|
.sidebar-item .protocol-indicator.proto-telnet::before { content: '⇄'; }
|
||||||
|
.sidebar-item .protocol-indicator.proto-raw::before { content: '≋'; }
|
||||||
|
.sidebar-item .protocol-indicator.proto-github::before { content: 'GH'; }
|
||||||
|
|
||||||
|
.sidebar-item .protocol-indicator.proto-ssh {
|
||||||
|
background: rgba(78, 205, 196, 0.18);
|
||||||
|
color: var(--protocol-ssh);
|
||||||
|
}
|
||||||
|
.sidebar-item .protocol-indicator.proto-telnet {
|
||||||
|
background: rgba(255, 167, 38, 0.18);
|
||||||
|
color: var(--protocol-telnet);
|
||||||
|
}
|
||||||
|
.sidebar-item .protocol-indicator.proto-raw {
|
||||||
|
background: rgba(171, 71, 188, 0.18);
|
||||||
|
color: var(--protocol-raw);
|
||||||
|
}
|
||||||
|
.sidebar-item .protocol-indicator.proto-github {
|
||||||
|
background: rgba(124, 138, 255, 0.18);
|
||||||
|
color: var(--protocol-github);
|
||||||
}
|
}
|
||||||
.sidebar-item .protocol-indicator.proto-ssh { background: var(--protocol-ssh); }
|
|
||||||
.sidebar-item .protocol-indicator.proto-telnet { background: var(--protocol-telnet); }
|
|
||||||
.sidebar-item .protocol-indicator.proto-raw { background: var(--protocol-raw); }
|
|
||||||
.sidebar-item .protocol-indicator.proto-github { background: var(--protocol-github); }
|
|
||||||
|
|
||||||
/* Text block (name + host) */
|
/* Text block (name + host) */
|
||||||
.sidebar-item-text {
|
.sidebar-item-text {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
--text-tertiary: #707070;
|
--text-tertiary: #707070;
|
||||||
--text-disabled: #4a4a4a;
|
--text-disabled: #4a4a4a;
|
||||||
--text-inverse: #1c1c1c;
|
--text-inverse: #1c1c1c;
|
||||||
|
--sidebar-group-title: #b89d5f;
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
Accent colours — teal / cyan
|
Accent colours — teal / cyan
|
||||||
|
|||||||
+18
-3
@@ -684,10 +684,19 @@ class App {
|
|||||||
_applyPreferences() {
|
_applyPreferences() {
|
||||||
const prefs = this.state.preferences;
|
const prefs = this.state.preferences;
|
||||||
|
|
||||||
// Sidebar width
|
// Sidebar width (drives the grid column width).
|
||||||
|
// Use the CSS variable so the workspace never sits underneath the sidebar.
|
||||||
|
const root = document.documentElement;
|
||||||
const sidebar = document.getElementById('sidebar');
|
const sidebar = document.getElementById('sidebar');
|
||||||
if (sidebar && prefs.sidebarWidth) {
|
const parsedSidebarWidth = Number(prefs.sidebarWidth);
|
||||||
sidebar.style.width = `${prefs.sidebarWidth}px`;
|
if (Number.isFinite(parsedSidebarWidth) && parsedSidebarWidth > 0) {
|
||||||
|
const clampedWidth = Math.max(180, Math.min(500, Math.round(parsedSidebarWidth)));
|
||||||
|
root.style.setProperty('--sidebar-width', `${clampedWidth}px`);
|
||||||
|
} else {
|
||||||
|
root.style.removeProperty('--sidebar-width');
|
||||||
|
}
|
||||||
|
if (sidebar) {
|
||||||
|
sidebar.style.width = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status bar visibility
|
// Status bar visibility
|
||||||
@@ -695,6 +704,12 @@ class App {
|
|||||||
if (statusBar) {
|
if (statusBar) {
|
||||||
statusBar.style.display = prefs.showStatusBar === false ? 'none' : 'flex';
|
statusBar.style.display = prefs.showStatusBar === false ? 'none' : 'flex';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refit any visible terminal after geometry changes.
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.terminals.fitActive();
|
||||||
|
this.splitPanes.refitAll();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ class Settings {
|
|||||||
if (this.app.terminals && this._prefs.terminalTheme) {
|
if (this.app.terminals && this._prefs.terminalTheme) {
|
||||||
this.app.terminals.applyTheme(this._prefs.terminalTheme);
|
this.app.terminals.applyTheme(this._prefs.terminalTheme);
|
||||||
}
|
}
|
||||||
|
if (this.app && typeof this.app._applyPreferences === 'function') {
|
||||||
|
this.app._applyPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
this.app.notifications.success('Settings saved');
|
this.app.notifications.success('Settings saved');
|
||||||
this.close();
|
this.close();
|
||||||
|
|||||||
@@ -138,12 +138,16 @@ class Sidebar {
|
|||||||
_renderSection(title, key, profiles) {
|
_renderSection(title, key, profiles) {
|
||||||
const section = createElement('div', 'sidebar-section');
|
const section = createElement('div', 'sidebar-section');
|
||||||
const isCollapsed = this.collapsedSections.has(key);
|
const isCollapsed = this.collapsedSections.has(key);
|
||||||
|
const isGroupSection = key.startsWith('group:');
|
||||||
|
|
||||||
// Section header
|
// Section header
|
||||||
const header = createElement('div', 'sidebar-section-header');
|
const header = createElement(
|
||||||
|
'div',
|
||||||
|
`sidebar-section-header ${isGroupSection ? 'sidebar-section-header-group' : ''}`.trim()
|
||||||
|
);
|
||||||
header.innerHTML = `
|
header.innerHTML = `
|
||||||
<span class="section-chevron ${isCollapsed ? 'collapsed' : ''}">${isCollapsed ? '▸' : '▾'}</span>
|
<span class="section-chevron ${isCollapsed ? 'collapsed' : ''}">${isCollapsed ? '▸' : '▾'}</span>
|
||||||
<span>${escapeHtml(title)}</span>
|
<span class="section-title">${escapeHtml(title)}</span>
|
||||||
<span class="section-count">${profiles.length}</span>
|
<span class="section-count">${profiles.length}</span>
|
||||||
`;
|
`;
|
||||||
// Prevent mousedown from starting a text selection gesture in WKWebView,
|
// Prevent mousedown from starting a text selection gesture in WKWebView,
|
||||||
@@ -182,20 +186,24 @@ class Sidebar {
|
|||||||
item.classList.add('sidebar-item-active');
|
item.classList.add('sidebar-item-active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol colour dot
|
// Protocol icon
|
||||||
const dot = createElement('span', `protocol-indicator ${protocolColour(profile.protocol)}`);
|
const protocolLabel = ""; // Seemed pretty naff to have this as well as the little icon badboy this._protocolLabel(profile.protocol);
|
||||||
item.appendChild(dot);
|
const indicator = createElement('span', `protocol-indicator ${protocolColour(profile.protocol)}`, {
|
||||||
|
title: protocolLabel,
|
||||||
|
'aria-label': protocolLabel,
|
||||||
|
});
|
||||||
|
item.appendChild(indicator);
|
||||||
|
|
||||||
// Text content
|
// Text content
|
||||||
const textWrapper = createElement('div', 'sidebar-item-text');
|
const textWrapper = createElement('div', 'sidebar-item-text');
|
||||||
|
const displayName = (profile.displayName || '').trim();
|
||||||
|
const primaryLabel = displayName || profile.host || 'Untitled';
|
||||||
const nameEl = createElement('span', 'sidebar-item-name', {
|
const nameEl = createElement('span', 'sidebar-item-name', {
|
||||||
textContent: profile.displayName || profile.host || 'Untitled',
|
textContent: primaryLabel,
|
||||||
});
|
});
|
||||||
textWrapper.appendChild(nameEl);
|
textWrapper.appendChild(nameEl);
|
||||||
|
|
||||||
const subtitle = profile.host
|
const subtitle = protocolLabel;
|
||||||
? `${profile.host}:${profile.port}`
|
|
||||||
: profile.protocol.toUpperCase();
|
|
||||||
const subEl = createElement('span', 'sidebar-item-host', {
|
const subEl = createElement('span', 'sidebar-item-host', {
|
||||||
textContent: truncate(subtitle, 30),
|
textContent: truncate(subtitle, 30),
|
||||||
});
|
});
|
||||||
@@ -424,6 +432,27 @@ class Sidebar {
|
|||||||
.sort((a, b) => b.score - a.score)
|
.sort((a, b) => b.score - a.score)
|
||||||
.map((r) => r.profile);
|
.map((r) => r.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a display label for a protocol.
|
||||||
|
* @param {string} protocol
|
||||||
|
* @returns {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_protocolLabel(protocol) {
|
||||||
|
switch (protocol) {
|
||||||
|
case 'github':
|
||||||
|
return 'GitHub';
|
||||||
|
case 'ssh':
|
||||||
|
return 'SSH';
|
||||||
|
case 'telnet':
|
||||||
|
return 'TELNET';
|
||||||
|
case 'raw':
|
||||||
|
return 'RAW';
|
||||||
|
default:
|
||||||
|
return (protocol || '').toUpperCase() || 'UNKNOWN';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.NexusTerminal = window.NexusTerminal || {};
|
window.NexusTerminal = window.NexusTerminal || {};
|
||||||
|
|||||||
Reference in New Issue
Block a user