fix: shift range from a pinned note in its folder; kanban fits the window; list toolbar; quick dump targets only select; aligned bullets; steady search field; browser voice waits 5 s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m28s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-01 16:12:01 +01:00
1 parent 5a9c5bac37
commit e2b9daba75
26 files changed
+208 -138

No files matched your search

+15 -1
View File
@@ -21,6 +21,8 @@ const LIVE_SILENCE_MS = 800;
const LIVE_TICK_MS = 200;
const LIVE_SPEECH_LEVEL = 0.02;
const MIN_RESTART_INTERVAL_MS = 300;
// Browser recognition on a tap: it stops only after this much silence, not at the first short pause
const BROWSER_SILENCE_STOP_MS = 5000;
/**
* Microphone input for one button: start, stop (text arrives), cancel (nothing arrives). How the text
@@ -38,6 +40,7 @@ export function useVoiceInput({ onText, onError, continuous = false, live = fals
const timerRef = useRef<number | null>(null);
const segmentTimerRef = useRef<number | null>(null);
const restartTimerRef = useRef<number | null>(null);
const silenceTimerRef = useRef<number | null>(null);
const cancelledRef = useRef(false);
const stoppedRef = useRef(false);
const transcriptRef = useRef('');
@@ -59,6 +62,8 @@ export function useVoiceInput({ onText, onError, continuous = false, live = fals
segmentTimerRef.current = null;
if (restartTimerRef.current !== null) window.clearTimeout(restartTimerRef.current);
restartTimerRef.current = null;
if (silenceTimerRef.current !== null) window.clearTimeout(silenceTimerRef.current);
silenceTimerRef.current = null;
};
useEffect(() => {
@@ -240,8 +245,17 @@ export function useVoiceInput({ onText, onError, continuous = false, live = fals
const recognition = new Recognition();
recognition.lang = 'de-DE';
recognition.interimResults = true;
recognition.continuous = continuous || live;
// A tap (neither hold nor dictation) listens through short pauses and ends after 5 s of silence
const stopOnSilence = !continuous && !live;
recognition.continuous = continuous || live || stopOnSilence;
const armSilenceStop = () => {
if (!stopOnSilence) return;
if (silenceTimerRef.current !== null) window.clearTimeout(silenceTimerRef.current);
silenceTimerRef.current = window.setTimeout(() => void stop(), BROWSER_SILENCE_STOP_MS);
};
armSilenceStop();
recognition.onresult = (event: any) => {
armSilenceStop();
const parts: string[] = [];
for (let i = 0; i < event.results.length; i++) parts.push(event.results[i][0].transcript);
const sessionText = joinSpeechResults(parts);