mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-02 03:15:36 +00:00
Send one request per keypress carrying the measured duration
The browser now times the press with performance.now() and posts hold_ms once, instead of sending down and up as two requests. Halves the round trips per key and makes press duration independent of the link. Deletes test_sends_down_and_up_not_just_tap: it asserted the behaviour being replaced, so keeping it would have meant asserting the bug. MIN_HOLD_MS is injected into the page from webui.py so the two agree on the floor, which exists because anything under the firmware's 20 ms debounce does not register at all -- a very fast click still has to ask for 60 ms. Verified over a simulated 400 ms link: three keys in 1.58 s where the old design needed ~2.45 s, and a 120 ms press opens the menu (gScreenToDisplay 0 -> 1) with DOWN then moving the cursor. The generated page also passes node --check.
This commit is contained in:
1 parent
e7f3f9da76
commit
7fe605eeaf
2 files changed
+40
-22
No files matched your search
+17
-12
@@ -218,21 +218,23 @@ def render_index(scale: int) -> str:
|
||||
<div class="pad">{grid}</div>
|
||||
</div>
|
||||
<div id="status">connecting...</div>
|
||||
<p class="hint">Hold a key to send a long press: over 400 ms the firmware
|
||||
<p class="hint">How long you hold a key is measured here and sent as a number,
|
||||
so a slow link cannot turn a tap into a long press. Over 400 ms the firmware
|
||||
treats it as held, which is a different event. Arrows move, Enter is MENU,
|
||||
Esc is EXIT, digits map straight through. No PTT button -- the keypad model
|
||||
has no PTT line.</p>
|
||||
</div>
|
||||
<script>
|
||||
const BINDINGS = {json.dumps(KEY_BINDINGS)};
|
||||
const held = new Set();
|
||||
const MIN_HOLD_MS = {MIN_HOLD_MS};
|
||||
const pressedAt = new Map();
|
||||
|
||||
async function send(key, action) {{
|
||||
async function sendKey(key, holdMs) {{
|
||||
try {{
|
||||
await fetch('/api/key', {{
|
||||
method: 'POST',
|
||||
headers: {{'Content-Type': 'application/json'}},
|
||||
body: JSON.stringify({{key: key, action: action}})
|
||||
body: JSON.stringify({{key: key, hold_ms: Math.round(holdMs)}})
|
||||
}});
|
||||
}} catch (err) {{
|
||||
document.getElementById('status').textContent = 'send failed: ' + err;
|
||||
@@ -244,18 +246,21 @@ function mark(key, on) {{
|
||||
.forEach(el => el.classList.toggle('active', on));
|
||||
}}
|
||||
|
||||
// Press duration is decided by the browser, not the server.
|
||||
// One request per key, carrying the duration as a number. Sending 'down' and
|
||||
// 'up' as two requests would put the network round trip inside the press: at
|
||||
// 400 ms RTT every tap arrived as a ~407 ms hold, which the firmware dispatches
|
||||
// as a held key and MAIN_Key_MENU ignores.
|
||||
function down(key) {{
|
||||
if (held.has(key)) return;
|
||||
held.add(key);
|
||||
if (pressedAt.has(key)) return;
|
||||
pressedAt.set(key, performance.now());
|
||||
mark(key, true);
|
||||
send(key, 'down');
|
||||
}}
|
||||
function up(key) {{
|
||||
if (!held.has(key)) return;
|
||||
held.delete(key);
|
||||
const started = pressedAt.get(key);
|
||||
if (started === undefined) return;
|
||||
pressedAt.delete(key);
|
||||
mark(key, false);
|
||||
send(key, 'up');
|
||||
sendKey(key, Math.max(performance.now() - started, MIN_HOLD_MS));
|
||||
}}
|
||||
|
||||
document.querySelectorAll('.key').forEach(btn => {{
|
||||
@@ -281,7 +286,7 @@ addEventListener('keyup', ev => {{
|
||||
}});
|
||||
// Release on blur, so losing focus mid-press cannot leave a key stuck down.
|
||||
addEventListener('blur', () => {{
|
||||
[...held].forEach(up);
|
||||
[...pressedAt.keys()].forEach(up);
|
||||
fetch('/api/release-all', {{method: 'POST'}}).catch(() => {{}});
|
||||
}});
|
||||
|
||||
|
||||
Reference in new issue
Block a user