Fix lit pads not highlighting; stop swallowing haptics errors

A lit pad kept its grey text and only its border turned orange, so pads
looked unhighlighted next to every other key. Cause was cascade order,
not logic: .pad is a single-class selector like .lit, so equal
specificity meant whichever came last won, and .pad was declared after.
The state classes now sit at the bottom of the file with a comment
saying why, and a lit pad computes rgb(255,74,0) for text and border.

native.ts reported nothing when haptics failed because I wrote
catch(() => {}) and discarded the reason. It now reports once per
distinct failure - enough to read in logcat, quiet enough not to spam on
every key press.

That reporting shows the software path is fine: isNativePlatform true,
Haptics available and bridged, VIBRATE granted, and both impact and
vibrate resolve without rejecting. So the silence is below the bridge -
most likely the phone's own touch-vibration setting - and not something
this code can detect.

141 tests, typecheck clean, installed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 21:05:01 +03:00
parent d0f872fc8b
commit 6889167fcf
2 changed files with 63 additions and 45 deletions

View File

@@ -9,18 +9,33 @@ import { Haptics, ImpactStyle, NotificationType } from "@capacitor/haptics";
const isNative = (): boolean => Capacitor.isNativePlatform();
/**
* Swallowing these was a mistake: haptics did nothing on the device and the
* reason had been discarded. Report once per distinct failure — enough to read
* in logcat, quiet enough not to spam on every key press.
*/
const reported = new Set<string>();
function report(where: string, error: unknown): void {
const message = error instanceof Error ? error.message : String(error);
const key = where + ":" + message;
if (reported.has(key)) return;
reported.add(key);
console.error("haptics " + where + " failed:", message);
}
/** A light tick under every key press, as the reference's buzz() did. */
export function tapFeedback(): void {
if (!isNative()) return;
void Haptics.impact({ style: ImpactStyle.Light }).catch(() => {});
Haptics.impact({ style: ImpactStyle.Light }).catch((e) => report("impact", e));
}
/** Shaped feedback on a graded answer: right and wrong should feel different. */
export function gradeFeedback(correct: boolean): void {
if (!isNative()) return;
void Haptics.notification({
Haptics.notification({
type: correct ? NotificationType.Success : NotificationType.Error,
}).catch(() => {});
}).catch((e) => report("notification", e));
}
export function exitApp(): void {