mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-29 15:15:27 -07:00
fix: i18n cleanup + readiness checklist effect cadence + ChordPicker shadow
- DictationReadinessChecklist was constructing downloadByModel as a fresh Map every render and listing it in the cleanup effect's deps. With the 1 s polling cadence and arbitrary parent rerenders the effect ran more often than it needed to. Memoised the Map on activeTasks; the effect now keys off the memo's identity.
- zh-CN persona tooltipActive/ariaLabelActive matched their inactive twins byte-for-byte ("以人物设定朗读"). The other locales differentiate the active state with a -ing / -中 suffix; zh-CN now reads "正以人物设定朗读" when active.
- personalityPlaceholder was a ~290-character paragraph that doubled as both the example text and the explanation, repeating most of what personalityHint already said. Trimmed to the example only and folded the explanation + leave-blank consequence into the hint, across all four locales.
- Refinement model size keys were size06 / size17 / size4. Renamed the 4B variant to size40 so the decimal padding is consistent.
- ChordPicker's open-effect bound a window.setTimeout id to a local `t`, shadowing the i18n `t` from useTranslation. Renamed to timeoutId.
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
||||
Keyboard,
|
||||
Loader2,
|
||||
} from 'lucide-react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useEffect, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
@@ -103,10 +103,16 @@ export function DictationReadinessChecklist({
|
||||
},
|
||||
});
|
||||
|
||||
const downloadByModel = new Map<string, ActiveDownloadTask>();
|
||||
for (const dl of activeTasks?.downloads ?? []) {
|
||||
if (dl.status === 'downloading') downloadByModel.set(dl.model_name, dl);
|
||||
}
|
||||
// Memo so the Map identity is stable across renders that don't change
|
||||
// activeTasks — otherwise the cleanup effect below saw a fresh Map every
|
||||
// render and re-fired on every 1 s poll tick.
|
||||
const downloadByModel = useMemo(() => {
|
||||
const m = new Map<string, ActiveDownloadTask>();
|
||||
for (const dl of activeTasks?.downloads ?? []) {
|
||||
if (dl.status === 'downloading') m.set(dl.model_name, dl);
|
||||
}
|
||||
return m;
|
||||
}, [activeTasks]);
|
||||
|
||||
// When a download disappears from activeTasks, it just finished — refetch
|
||||
// readiness immediately so the row flips to ✓ instead of waiting up to 5s
|
||||
@@ -122,7 +128,7 @@ export function DictationReadinessChecklist({
|
||||
}
|
||||
}
|
||||
prevActive.current = current;
|
||||
}, [activeTasks, queryClient, downloadByModel]);
|
||||
}, [downloadByModel, queryClient]);
|
||||
|
||||
const downloadMutation = useMutation({
|
||||
mutationFn: async ({ modelName }: { gate: ReadinessGate; modelName: string }) =>
|
||||
|
||||
@@ -65,8 +65,8 @@ export function ChordPicker({
|
||||
setCaptured(initialKeys);
|
||||
setUnsupportedAttempt(null);
|
||||
// Defer focus to the next paint so the dialog is mounted.
|
||||
const t = window.setTimeout(() => captureRef.current?.focus(), 50);
|
||||
return () => window.clearTimeout(t);
|
||||
const timeoutId = window.setTimeout(() => captureRef.current?.focus(), 50);
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
}
|
||||
return;
|
||||
}, [open, initialKeys]);
|
||||
|
||||
@@ -427,7 +427,7 @@ export function CapturesPage() {
|
||||
{t('settings.captures.refinement.model.size17', { tail: t('settings.captures.refinement.model.tail.fast') })}
|
||||
</SelectItem>
|
||||
<SelectItem value="4B">
|
||||
{t('settings.captures.refinement.model.size4', { tail: t('settings.captures.refinement.model.tail.fullQuality') })}
|
||||
{t('settings.captures.refinement.model.size40', { tail: t('settings.captures.refinement.model.tail.fullQuality') })}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
Reference in New Issue
Block a user