From 096b5a4d17c85fa5f87db3e72364e9c3506d1e64 Mon Sep 17 00:00:00 2001 From: cirakg Date: Sun, 25 Oct 2026 12:46:42 +0100 Subject: feat(pin): exactly 4 digits, entered on the 4th digit The keypad has no OK key; the 4th digit submits, so a tap that also arrives as START can no longer submit a partial PIN (the likely cause of "Wrong PIN" before the code opened). PINs set by earlier versions still unlock and are then replaced by a 4-digit one. Opening an entry ignores a second request from the same tap. A Require PIN sent from the phone while the watch is locked now applies at the next PIN instead of waiting for Confirm all. The linter skips .claude. Co-Authored-By: Claude Opus 5.5 --- source/ui/OtpView.mc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source/ui/OtpView.mc') diff --git a/source/ui/OtpView.mc b/source/ui/OtpView.mc index faf94d0..1c0c0bd 100644 --- a/source/ui/OtpView.mc +++ b/source/ui/OtpView.mc @@ -258,6 +258,11 @@ class OtpView extends WatchUi.View { // Input on the OTP detail: START or a tap gives the next HOTP code; BACK closes. class OtpDelegate extends WatchUi.BehaviorDelegate { + // One tap can arrive twice (as START and as a tap); a second "next + // code" within this time is ignored so the counter moves only once. + static const NEXT_DEBOUNCE_MS = 500; + private var _lastNextMs as Number? = null; + function initialize() { BehaviorDelegate.initialize(); } @@ -294,6 +299,12 @@ class OtpDelegate extends WatchUi.BehaviorDelegate { if (v == null || !v.isHotp()) { return; } + var now = System.getTimer(); + var last = _lastNextMs; + if (last != null && now - last >= 0 && now - last < NEXT_DEBOUNCE_MS) { + return; + } + _lastNextMs = now; try { AppState.theVault().setCounter(v.header.id, v.header.counter + 1); } catch (e instanceof VaultError) { -- cgit v1.2.3