fix(workspace): keep the cursor in a block that turns into a code block
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m58s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m58s
Converting via /code or ``` swapped the text field for the code editor's and left the focus nowhere, so further typing triggered app shortcuts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9124809f54
commit
cc68d3f334
2 files changed
+19
No files matched your search
@@ -9,8 +9,10 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
|||||||
### Added
|
### Added
|
||||||
- Eigene Spracherkennung (optional): Mit `STT_URL` schickt MindSift Aufnahmen an einen selbst betriebenen Whisper-Server (OpenAI-kompatibel, z. B. speaches) statt an Google oder Microsoft. Einstellung nur per Umgebungsvariablen (`STT_*`) inklusive Grenzwerten; `docker-compose.yml` bringt den Dienst `whisper` als Profil mit, das Modell lädt MindSift beim ersten Start selbst. Administration → Server & Isolation zeigt den aktiven Modus und bietet eine Testaufnahme. In der Demo bleibt es bei der Browser-Erkennung.
|
- Eigene Spracherkennung (optional): Mit `STT_URL` schickt MindSift Aufnahmen an einen selbst betriebenen Whisper-Server (OpenAI-kompatibel, z. B. speaches) statt an Google oder Microsoft. Einstellung nur per Umgebungsvariablen (`STT_*`) inklusive Grenzwerten; `docker-compose.yml` bringt den Dienst `whisper` als Profil mit, das Modell lädt MindSift beim ersten Start selbst. Administration → Server & Isolation zeigt den aktiven Modus und bietet eine Testaufnahme. In der Demo bleibt es bei der Browser-Erkennung.
|
||||||
- API: `POST /voice/transcribe`, `GET /admin/voice`; `/auth/status` meldet `voice.mode`.
|
- API: `POST /voice/transcribe`, `GET /admin/voice`; `/auth/status` meldet `voice.mode`.
|
||||||
|
- Code-Blöcke in Notizen: Sprachauswahl (rund 50 Sprachen, bei Bedarf nachgeladen), Farben beim Tippen im Stil von VS Code Dark+/Light+ für alle Themes, „Kopieren“, Tab/Shift+Tab rückt ein und aus. `/code yaml` oder ```` ```yaml ```` legt die Sprache direkt fest.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Workspace-Seitenleiste wie ein Datei-Explorer: angeheftete Notizen oben, darunter Ordner und Notizen ohne Zwischenüberschriften.
|
||||||
- Spracheingabe in Quick Dump, im mobilen Erfassen-Sheet und beim Halten des +-Knopfs folgt der Server-Einstellung: mit eigenem Whisper-Server funktioniert sie in allen Browsern (auch Firefox), mit Live-Wellen während der Aufnahme und „Wird erkannt…“ danach. Ohne Unterstützung im Browser oder mit `STT_DISABLED=true` ist das Mikrofon ausgeblendet statt einer Fehlermeldung.
|
- Spracheingabe in Quick Dump, im mobilen Erfassen-Sheet und beim Halten des +-Knopfs folgt der Server-Einstellung: mit eigenem Whisper-Server funktioniert sie in allen Browsern (auch Firefox), mit Live-Wellen während der Aufnahme und „Wird erkannt…“ danach. Ohne Unterstützung im Browser oder mit `STT_DISABLED=true` ist das Mikrofon ausgeblendet statt einer Fehlermeldung.
|
||||||
|
|
||||||
## [0.6.1] - 2026-10-29
|
## [0.6.1] - 2026-10-29
|
||||||
|
|||||||
@@ -289,6 +289,20 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
|||||||
adjustHeight();
|
adjustHeight();
|
||||||
}, [localContent, block.type, block.level, activeFocus, adjustHeight]);
|
}, [localContent, block.type, block.level, activeFocus, adjustHeight]);
|
||||||
|
|
||||||
|
// Turning the block into another type (slash menu, ``` or markdown shortcut) can swap the text field
|
||||||
|
// for a new one (e.g. the code editor); the cursor must stay in the block so typing goes on there
|
||||||
|
const refocusAfterTypeChangeRef = useRef(false);
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (!refocusAfterTypeChangeRef.current) return;
|
||||||
|
refocusAfterTypeChangeRef.current = false;
|
||||||
|
const ta = textareaRef.current;
|
||||||
|
if (ta && document.activeElement !== ta) {
|
||||||
|
ta.focus();
|
||||||
|
const end = ta.value.length;
|
||||||
|
ta.setSelectionRange(end, end);
|
||||||
|
}
|
||||||
|
}, [block.type]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener('resize', adjustHeight);
|
window.addEventListener('resize', adjustHeight);
|
||||||
// The field can be measured while hidden (phone layout shows the editor only after selecting a note);
|
// The field can be measured while hidden (phone layout shows the editor only after selecting a note);
|
||||||
@@ -335,6 +349,7 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
setLocalContent(clean);
|
setLocalContent(clean);
|
||||||
localContentRef.current = clean;
|
localContentRef.current = clean;
|
||||||
|
if (cmd.type !== block.type) refocusAfterTypeChangeRef.current = true;
|
||||||
flushDebounce(clean, {
|
flushDebounce(clean, {
|
||||||
type: cmd.type,
|
type: cmd.type,
|
||||||
...(langOverride !== undefined ? { lang: langOverride } : {}),
|
...(langOverride !== undefined ? { lang: langOverride } : {}),
|
||||||
@@ -423,6 +438,7 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeOverride) {
|
if (typeOverride) {
|
||||||
|
refocusAfterTypeChangeRef.current = true;
|
||||||
flushDebounce(val, {
|
flushDebounce(val, {
|
||||||
type: typeOverride,
|
type: typeOverride,
|
||||||
...(langOverride !== undefined ? { lang: langOverride } : {}),
|
...(langOverride !== undefined ? { lang: langOverride } : {}),
|
||||||
@@ -578,6 +594,7 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
|||||||
const resolvedLang = rawLang ? resolveLanguageId(rawLang) || rawLang.toLowerCase() : '';
|
const resolvedLang = rawLang ? resolveLanguageId(rawLang) || rawLang.toLowerCase() : '';
|
||||||
setLocalContent('');
|
setLocalContent('');
|
||||||
localContentRef.current = '';
|
localContentRef.current = '';
|
||||||
|
refocusAfterTypeChangeRef.current = true;
|
||||||
flushDebounce('', {
|
flushDebounce('', {
|
||||||
type: 'code',
|
type: 'code',
|
||||||
lang: resolvedLang,
|
lang: resolvedLang,
|
||||||
|
|||||||
Reference in new issue
Block a user