chore: sprint A — мелкая полировка
#15 a11y: <html lang> синхронизируется с settings.language через ThemeProvider — screen-readers больше не читают EN-текст с русским акцентом и наоборот. #14 dev:simulateMatchEnd channel вынесен в IPC enum (IPC.devSimulateMatchEnd) — main/preload не разойдутся в hardcoded строках. #34 ChallengeEditor: multiplier клампится к [0.5, 1000] (max="1000", Math.min(1000, ...)). Совпадает с validate.ts — раньше save с 9999 молча отклонялся IPC, теперь UI не даёт ввести. #28 package.json: добавлен `test:coverage` script.
This commit is contained in:
@@ -275,7 +275,7 @@ export function registerIpc(): void {
|
||||
// otherwise fabricate arbitrary match-end events at will.
|
||||
if (!app.isPackaged) {
|
||||
ipcMain.handle(
|
||||
'dev:simulateMatchEnd',
|
||||
IPC.devSimulateMatchEnd,
|
||||
(_e, id: GameId, stats: Record<string, number>) => {
|
||||
simulateMatchEnd(id, stats)
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ const api = {
|
||||
id: GameId,
|
||||
stats: Record<string, number>
|
||||
): Promise<void> =>
|
||||
ipcRenderer.invoke('dev:simulateMatchEnd', id, stats)
|
||||
ipcRenderer.invoke(IPC.devSimulateMatchEnd, id, stats)
|
||||
}
|
||||
: {}),
|
||||
|
||||
|
||||
@@ -264,11 +264,18 @@ function ChallengeEditor({
|
||||
type="number"
|
||||
step="0.5"
|
||||
min="0.5"
|
||||
max="1000"
|
||||
value={draft.multiplier}
|
||||
onChange={(e) =>
|
||||
setDraft({
|
||||
...draft,
|
||||
multiplier: Math.max(0.5, Number(e.target.value) || 1)
|
||||
// Клампим к диапазону [0.5, 1000] — совпадает с validate.ts
|
||||
// (multiplier ∈ [0, 1000]). Без max=1000 пользователь мог
|
||||
// ввести 9999 и save молча отклонялся IPC-валидатором.
|
||||
multiplier: Math.max(
|
||||
0.5,
|
||||
Math.min(1000, Number(e.target.value) || 1)
|
||||
)
|
||||
})
|
||||
}
|
||||
className="ios-input font-mono-num"
|
||||
|
||||
@@ -25,5 +25,15 @@ export function ThemeProvider({
|
||||
else document.documentElement.classList.remove('dark')
|
||||
}, [settings?.theme, osTheme])
|
||||
|
||||
// Синхронизируем <html lang> с языком приложения. Без этого screen-readers
|
||||
// продолжают читать английский текст как кириллицу (или ломаются) при
|
||||
// переключении на EN, и наоборот — это a11y-баг.
|
||||
useEffect(() => {
|
||||
const lang = settings?.language ?? 'ru'
|
||||
if (document.documentElement.lang !== lang) {
|
||||
document.documentElement.lang = lang
|
||||
}
|
||||
}, [settings?.language])
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ export const IPC = {
|
||||
markChallengeDone: 'challenge:markDone',
|
||||
closeMatchSummary: 'matchSummary:close',
|
||||
|
||||
// Dev-only IPC (handler ungated в prod, см. ipc.ts). Держим в enum чтобы
|
||||
// main/preload/renderer не разошлись в hardcoded-строках.
|
||||
devSimulateMatchEnd: 'dev:simulateMatchEnd',
|
||||
|
||||
// Auto-updater
|
||||
updaterStatus: 'updater:status',
|
||||
updaterCheck: 'updater:check',
|
||||
|
||||
Reference in New Issue
Block a user