a1e532cb3f
The multi-device enable checkbox is the gating control; device name only matters when multi-device is on. Place the checkbox first to reinforce the logical dependency between the two settings. No behavioral change — no tests enforce element ordering within a panel.
226 lines
13 KiB
HTML
226 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
<meta name="theme-color" content="#0D1117" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
<link rel="manifest" href="/manifest.json" />
|
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<title>muxplex</title>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ── Overview view ─────────────────────────────────────────────────────── -->
|
|
<div id="view-overview" class="view view--active">
|
|
<header class="app-header">
|
|
<h1 class="app-wordmark"><img src="/wordmark-on-dark.svg" alt="muxplex" height="24" /></h1>
|
|
<div class="header-actions">
|
|
<button id="new-session-btn" class="header-btn" aria-label="New session">+</button>
|
|
<button id="view-mode-btn" class="header-btn" aria-label="Toggle view mode" title="View: auto">▦</button>
|
|
<button id="settings-btn" class="header-btn" aria-label="Settings">⚙</button>
|
|
<span id="connection-status"></span>
|
|
</div>
|
|
</header>
|
|
<div id="filter-bar" class="filter-bar"></div>
|
|
<div id="session-grid" class="session-grid" role="list"></div>
|
|
<div id="empty-state" class="empty-state hidden">No active tmux sessions</div>
|
|
</div>
|
|
|
|
<!-- ── Expanded (terminal) view ──────────────────────────────────────────── -->
|
|
<div id="view-expanded" class="view hidden">
|
|
<header class="expanded-header">
|
|
<button id="back-btn" class="back-btn" aria-label="Back">←</button>
|
|
<button id="sidebar-toggle-btn" class="sidebar-toggle-btn" aria-label="Toggle session list">☰</button>
|
|
<span id="expanded-session-name" class="expanded-session-name"></span>
|
|
<button id="settings-btn-expanded" class="header-btn" aria-label="Settings">⚙</button>
|
|
</header>
|
|
<div class="view-body">
|
|
<div id="session-sidebar" class="session-sidebar">
|
|
<div class="sidebar-header">
|
|
<span class="sidebar-title">Sessions</span>
|
|
<button id="sidebar-collapse-btn" class="sidebar-collapse-btn" aria-label="Collapse session list">‹</button>
|
|
</div>
|
|
<div id="sidebar-list" class="sidebar-list"></div>
|
|
<div class="sidebar-footer">
|
|
<button id="sidebar-new-session-btn" class="sidebar-new-btn">+ New</button>
|
|
</div>
|
|
</div>
|
|
<div id="terminal-container" class="terminal-container"></div>
|
|
</div>
|
|
<div id="reconnect-overlay" class="reconnect-overlay hidden" aria-live="polite">Reconnecting…</div>
|
|
</div>
|
|
|
|
<!-- ── Bottom sheet (session switcher) ───────────────────────────────────── -->
|
|
<div id="bottom-sheet" class="bottom-sheet hidden" role="dialog" aria-modal="true" aria-label="Switch session">
|
|
<div class="bottom-sheet__backdrop" id="sheet-backdrop"></div>
|
|
<div class="bottom-sheet__panel">
|
|
<div class="bottom-sheet__handle" aria-hidden="true"></div>
|
|
<ul id="sheet-list" class="bottom-sheet__list" role="listbox" aria-label="Sessions"></ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── Session pill (persistent overlay button) ──────────────────────────── -->
|
|
<button id="session-pill" class="session-pill hidden" aria-label="Switch session">
|
|
<span id="session-pill-label" class="session-pill__label"></span>
|
|
<span id="session-pill-bell" class="session-pill__bell hidden" aria-hidden="true">🔔</span>
|
|
</button>
|
|
|
|
<!-- ── Mobile FAB (new session) ───────────────────────────────────────────── -->
|
|
<button id="new-session-fab" class="new-session-fab" aria-label="New session">+</button>
|
|
|
|
<!-- ── Toast notification ─────────────────────────────────────────────────── -->
|
|
<div id="toast" class="toast hidden" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
|
|
<!-- ── Settings ─────────────────────────────────────────────────────────────────────── -->
|
|
<div id="settings-backdrop" class="settings-backdrop hidden"></div>
|
|
<dialog id="settings-dialog" class="settings-dialog">
|
|
<div class="settings-dialog-header">
|
|
<h2 class="settings-dialog-title">Settings</h2>
|
|
<button id="settings-close-btn" class="settings-close-btn" aria-label="Close settings">×</button>
|
|
</div>
|
|
<div class="settings-layout">
|
|
<nav class="settings-tabs">
|
|
<button class="settings-tab settings-tab--active" data-tab="display">Display</button>
|
|
<button class="settings-tab" data-tab="sessions">Sessions</button>
|
|
<button class="settings-tab" data-tab="notifications">Notifications</button>
|
|
<button class="settings-tab" data-tab="new-session">Commands</button>
|
|
<button class="settings-tab" data-tab="devices">Multi-Device</button>
|
|
</nav>
|
|
<div class="settings-content">
|
|
<div class="settings-panel" data-tab="display">
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-font-size">Font Size</label>
|
|
<select id="setting-font-size" class="settings-select">
|
|
<option value="11">11</option>
|
|
<option value="12">12</option>
|
|
<option value="13">13</option>
|
|
<option value="14" selected>14</option>
|
|
<option value="16">16</option>
|
|
<option value="18">18</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-hover-delay">Hover Delay</label>
|
|
<select id="setting-hover-delay" class="settings-select">
|
|
<option value="0">Off</option>
|
|
<option value="1000">1000ms</option>
|
|
<option value="1500" selected>1500ms</option>
|
|
<option value="2000">2000ms</option>
|
|
<option value="3000">3000ms</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-grid-columns">Grid Columns</label>
|
|
<select id="setting-grid-columns" class="settings-select">
|
|
<option value="auto" selected>Auto</option>
|
|
<option value="2">2</option>
|
|
<option value="3">3</option>
|
|
<option value="4">4</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="settings-panel hidden" data-tab="sessions">
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-default-session">Default Session</label>
|
|
<select id="setting-default-session" class="settings-select">
|
|
<option value="">(none)</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-sort-order">Sort Order</label>
|
|
<select id="setting-sort-order" class="settings-select">
|
|
<option value="manual">Manual</option>
|
|
<option value="alphabetical">Alphabetical</option>
|
|
<option value="recent">Recent</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field settings-field--column">
|
|
<label class="settings-label">Hidden Sessions</label>
|
|
<div id="setting-hidden-sessions" class="settings-checkbox-list"></div>
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-window-size-largest">Auto-set window size (largest)</label>
|
|
<input type="checkbox" id="setting-window-size-largest" class="settings-checkbox" />
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-auto-open">Auto-open created sessions</label>
|
|
<input type="checkbox" id="setting-auto-open" class="settings-checkbox" checked />
|
|
</div>
|
|
</div>
|
|
<div class="settings-panel hidden" data-tab="notifications">
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-bell-sound">Bell Sound</label>
|
|
<input type="checkbox" id="setting-bell-sound" class="settings-checkbox" />
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label">Desktop Notifications</label>
|
|
<div class="settings-notification-status">
|
|
<span id="notification-status-text" class="settings-status-text">Not requested</span>
|
|
<button id="notification-request-btn" class="settings-action-btn">Request Permission</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="settings-panel hidden" data-tab="new-session">
|
|
<div class="settings-field settings-field--column">
|
|
<label class="settings-label" for="setting-template">Command template</label>
|
|
<textarea id="setting-template" class="settings-textarea" rows="3" placeholder="tmux new-session -d -s {name}"></textarea>
|
|
<span class="settings-helper">{name} is replaced with the session name</span>
|
|
<button id="setting-template-reset" class="settings-action-btn">Reset to default</button>
|
|
</div>
|
|
<div class="settings-field settings-field--column">
|
|
<label class="settings-label" for="setting-delete-template">Delete session command</label>
|
|
<textarea id="setting-delete-template" class="settings-textarea" rows="3" placeholder="tmux kill-session -t {name}"></textarea>
|
|
<span class="settings-helper">{name} is replaced with the session name</span>
|
|
<button id="setting-delete-template-reset" class="settings-action-btn">Reset to default</button>
|
|
</div>
|
|
</div>
|
|
<div class="settings-panel hidden" data-tab="devices">
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-multi-device-enabled">Enable multi-device support</label>
|
|
<input type="checkbox" id="setting-multi-device-enabled" class="settings-checkbox" />
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-device-name">Device Name</label>
|
|
<input type="text" id="setting-device-name" class="settings-input" placeholder="This device" />
|
|
</div>
|
|
<div id="multi-device-fields">
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-view-mode">View Mode</label>
|
|
<select id="setting-view-mode" class="settings-select">
|
|
<option value="flat">Flat</option>
|
|
<option value="grouped">Grouped</option>
|
|
<option value="filtered">Filtered</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field">
|
|
<label class="settings-label" for="setting-view-scope">View Scope</label>
|
|
<select id="setting-view-scope" class="settings-select">
|
|
<option value="all">All Devices</option>
|
|
<option value="local">Local Only</option>
|
|
</select>
|
|
</div>
|
|
<div class="settings-field settings-field--column">
|
|
<label class="settings-label">Remote Instances</label>
|
|
<div id="setting-remote-instances" class="settings-remote-list"></div>
|
|
<button id="add-remote-instance-btn" class="settings-action-btn">+ Add Remote</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</dialog>
|
|
|
|
<!-- ── Scripts ─────────────────────────────────────────────────────────────── -->
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
|
|
<script src="/app.js" defer></script>
|
|
<script src="/terminal.js" defer></script>
|
|
</body>
|
|
</html>
|