- Inject .tile--loading skeleton tile into #session-grid immediately after
POST /api/sessions succeeds, giving instant visual feedback while the
backend creates the tmux session (which may take several seconds)
- Remove the placeholder when the poll finds the session or on timeout
- Add shimmer animation via @keyframes shimmer to style.css
- Tile placed after original .tile-body pre rule to avoid selector-substring
match in _extract_rule_block CSS tests
- Extract getVisibleSessions() helper to consolidate hidden-session
filter used by renderGrid() and renderSidebar() (DRY reduction)
- Add comment to terminal.js magic literal 600 noting it matches
MOBILE_THRESHOLD in app.js
- Move TERMINAL_JS_PATH and _TERMINAL_JS module fixtures to the top
of the test file alongside JS_PATH and _JS for consistency
- Strengthen test_render_grid_uses_visible_for_empty_state_check to
assert visible.length specifically, distinguishing it from
test_render_grid_creates_visible_array
- Update renderGrid/renderSidebar filter tests to assert getVisibleSessions()
call; add test_get_visible_sessions_filters_hidden_sessions to cover
the extracted helper directly
- terminal.js createTerminal(): read fontSize from localStorage 'muxplex.display',
default 14, apply Math.min(storedFontSize, 12) mobile cap
- app.js renderGrid(): filter hidden sessions via _serverSettings.hidden_sessions,
create visible array, apply alphabetical sort via localeCompare when sort_order is
'alphabetical'; 'recent'/'manual' use server-provided order
- app.js renderSidebar(): apply same hidden sessions filter, use visible array
- app.js DOMContentLoaded: call loadServerSettings() after startPolling() in restoreState().then()
- tests: 13 new tests in test_frontend_js.py covering all spec requirements
Co-authored-by: Amplifier <amplifier@example.com>
Removing terminal WheelEvent dispatch and sidebar scrollTop handlers.
CSS fixes retained (touch-action:pan-y, overscroll-behavior:contain,
flex-shrink:0). Testing mouse-only baseline across all devices before
deciding on the right mobile scroll approach.
Old: variable deltaY*3 per touchmove — Android batches events causing
burst-scroll then pause (jumpy). New: accumulate pixels across events,
fire fixed deltaY=120 per SCROLL_PX pixels. Each scroll step is
identical regardless of when Android delivers touchmove events.
SCROLL_PX=20 → ~40px swipe = 2 scroll clicks. Accumulator resets on
touchstart and touchend. macOS/iPad/mouse-wheel path unchanged.
scrollLines() only moves xterm.js's local scrollback buffer (outside).
WheelEvent dispatch goes through xterm.js's mouse reporting path —
if tmux mouse mode is on, escape sequences reach the PTY so tmux and
applications (vim, less, etc.) handle the scroll (inside).
Same behavior as mouse wheel on desktop.
Terminal: add touchstart/touchmove/touchend IIFE on #terminal-container.
Vertical swipe delta translated to _term.scrollLines(n). touchmove is
non-passive (required for e.preventDefault to block page scroll while
swiping inside terminal). mouse wheel scroll unaffected (separate wheel
event path in xterm.js).
Sidebar: add touch-action:pan-y + overscroll-behavior:contain to
.sidebar-list. Tells browser explicitly that vertical panning is allowed
and prevents scroll chaining when reaching list ends.