refactor: replay ui to terminal style

This commit is contained in:
2026-05-16 22:35:35 +08:00
parent 1ee963ce2e
commit d5982f15f9
4 changed files with 848 additions and 142 deletions
+93 -103
View File
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="zh-CN">
<html lang="zh-CN" data-theme="auto">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -8,121 +8,111 @@
</head>
<body>
<div class="app-shell">
<header class="topbar">
<div class="brand-lockup">
<div class="chip-mark" aria-hidden="true">TX</div>
<div class="brand-meta">
<h1>Texas Hold X Replay</h1>
<p id="subtitle">等待加载游戏数据</p>
</div>
<header class="terminal-header">
<div class="window-row" aria-hidden="true">
<span class="window-dot red"></span>
<span class="window-dot yellow"></span>
<span class="window-dot green"></span>
<span class="window-title">txh-replay@web:~</span>
</div>
<div class="status-strip" aria-live="polite">
<span id="sourceBadge" class="badge badge-gold">No Data</span>
<span id="pollBadge" class="badge badge-blue">Auto Off</span>
<div class="title-row">
<div>
<h1>Texas Hold X Replay</h1>
<p id="subtitle">awaiting game snapshot</p>
</div>
<div class="status-strip" aria-live="polite">
<span id="sourceBadge" class="status-pill">NO DATA</span>
<span id="pollBadge" class="status-pill">AUTO OFF</span>
<label class="theme-control">
<span>theme</span>
<select id="themeMode" aria-label="Theme mode">
<option value="auto">auto</option>
<option value="dark">dark</option>
<option value="light">light</option>
</select>
</label>
</div>
</div>
</header>
<main class="layout-grid">
<!-- Stage zone: pure visualization (table, seats, animations).
Placed first in DOM so mobile/tablet layouts keep it on top. -->
<section class="stage-zone" aria-label="牌桌动画回放">
<div class="stage-head">
<div class="stage-head-left">
<span id="handBadge" class="badge badge-gold">Hand -</span>
<strong id="streetLabel">未加载</strong>
</div>
<div class="stage-head-right">
<span id="potLabel" class="badge badge-gold">Pot 0</span>
</div>
<main class="terminal-grid">
<section class="terminal-panel source-panel" aria-label="数据源">
<div class="panel-title"><span>$</span> /source</div>
<label>
<span>game service</span>
<input id="serverUrl" type="url" value="http://127.0.0.1:8000" placeholder="http://127.0.0.1:8000" />
</label>
<label>
<span>game id</span>
<input id="gameId" type="text" value="game1" placeholder="game1" />
</label>
<div class="button-row">
<button id="fetchBtn" class="primary-btn" type="button">fetch</button>
<label class="file-btn">
upload json
<input id="fileInput" type="file" accept="application/json,.json" />
</label>
</div>
<div id="table" class="poker-table">
<!-- felt-shell encapsulates the rounded green felt with overflow:hidden,
so player speech bubbles drawn in seat-layer can overflow freely
above and below the table without being clipped. -->
<div class="felt-shell" aria-hidden="true">
<div class="felt-rail"></div>
<div class="felt-surface">
<div class="felt-grid"></div>
<div class="felt-glow"></div>
<div class="felt-mark">TX</div>
</div>
</div>
<div class="community-area">
<div id="boardCards" class="card-row board"></div>
<div id="tableMessage" class="table-message">上传 JSON 或从游戏服务获取快照</div>
</div>
<div id="seatLayer" class="seat-layer"></div>
<div class="auto-grid">
<label class="toggle-line">
<input id="autoPoll" type="checkbox" />
<span>auto poll</span>
</label>
<label>
<span>seconds</span>
<input id="pollSeconds" type="number" min="5" max="300" value="12" />
</label>
</div>
</section>
<!-- Interaction zone: data source + replay controls + summary. -->
<section class="control-panel" aria-label="数据与播放控制">
<div class="panel-section">
<h2>数据源</h2>
<label>
<span>游戏服务</span>
<input id="serverUrl" type="url" value="http://127.0.0.1:8000" placeholder="http://127.0.0.1:8000" />
</label>
<label>
<span>Game ID</span>
<input id="gameId" type="text" value="game1" placeholder="game1" />
</label>
<div class="button-row">
<button id="fetchBtn" class="primary-btn" type="button">获取</button>
<label class="file-btn">
上传 JSON
<input id="fileInput" type="file" accept="application/json,.json" />
</label>
</div>
<div class="auto-grid">
<label class="toggle-line">
<input id="autoPoll" type="checkbox" />
<span>自动获取</span>
</label>
<label>
<span>间隔秒</span>
<input id="pollSeconds" type="number" min="5" max="300" value="12" />
</label>
</div>
<section class="terminal-panel controls-panel" aria-label="回放控制">
<div class="panel-title"><span>$</span> /replay</div>
<label>
<span>hand</span>
<select id="handSelect"></select>
</label>
<label>
<span>pace</span>
<input id="pace" type="range" min="0.75" max="1.8" step="0.05" value="1" />
</label>
<div class="transport-row">
<button id="prevBtn" type="button">prev</button>
<button id="playBtn" class="primary-btn" type="button">play</button>
<button id="nextBtn" type="button">next</button>
<button id="resetBtn" type="button">reset</button>
</div>
<div class="panel-section">
<h2>回放</h2>
<label>
<span>手牌</span>
<select id="handSelect"></select>
</label>
<label>
<span>节奏</span>
<input id="pace" type="range" min="0.75" max="1.8" step="0.05" value="1" />
</label>
<div class="transport-row">
<button id="prevBtn" type="button" title="上一帧"></button>
<button id="playBtn" class="primary-btn" type="button" title="播放/暂停"></button>
<button id="nextBtn" type="button" title="下一帧"></button>
<button id="resetBtn" type="button" title="重置"></button>
</div>
<div class="progress-wrap">
<div id="progressBar"></div>
</div>
</div>
<div class="panel-section dense">
<h2>牌局摘要</h2>
<dl class="stat-list">
<div><dt>状态</dt><dd id="gameStatus">-</dd></div>
<div><dt>玩家</dt><dd id="playerCount">-</dd></div>
<div><dt>总手数</dt><dd id="handCount">-</dd></div>
<div><dt>盲注</dt><dd id="blindLevel">-</dd></div>
</dl>
<div class="progress-shell" aria-hidden="true">
<div id="progressBar"></div>
</div>
</section>
<aside class="event-panel" aria-label="事件日志">
<div class="panel-section">
<h2>事件</h2>
<ol id="eventLog" class="event-log"></ol>
<section class="terminal-panel summary-panel" aria-label="牌局摘要">
<div class="panel-title"><span>$</span> /state</div>
<dl class="stat-list">
<div><dt>status</dt><dd id="gameStatus">-</dd></div>
<div><dt>players</dt><dd id="playerCount">-</dd></div>
<div><dt>hands</dt><dd id="handCount">-</dd></div>
<div><dt>blinds</dt><dd id="blindLevel">-</dd></div>
</dl>
</section>
<section class="terminal-panel display-panel" aria-label="命令行牌局回放">
<div class="display-head">
<div>
<span id="handBadge" class="prompt-chip">hand -</span>
<span id="streetLabel" class="prompt-chip">idle</span>
<span id="potLabel" class="prompt-chip">pot 0</span>
</div>
<span id="frameLabel" class="frame-label">frame 0/0</span>
</div>
<div class="terminal-screen" tabindex="0">
<pre id="tableOutput" class="table-output">txh-replay&gt; waiting for game data</pre>
</div>
</section>
<aside class="terminal-panel log-panel" aria-label="事件日志">
<div class="panel-title"><span>$</span> /events</div>
<ol id="eventLog" class="event-log"></ol>
</aside>
</main>
</div>