[bug][ui][dictation] Иконка диктовки залипает серой (disabled) после collab-досинка: DictationGroup читает editor.isEditable нереактивно #311
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Симптом
На странице, которую пользователь может редактировать (тело печатается, collab досинкался), иконка микрофона диктовки в байлайне (и в fixed-toolbar) остаётся серой/
disabled. AI-кнопка «искры» рядом при этом активна. Наведение на серый микрофон ничего не поясняет (это отдельная проблема — см. #309).Репро
settings.ai.dictation = true) в режиме edit.showStatic → false).disabled, хотя тело нормально печатается.Подтверждение диагноза / обходной путь: переключить режим view ↔ edit —
PageBylineперерендерится,editor.isEditableперечитается (ужеtrue), и микрофон оживает.Корень
DictationGroupберёт editable-состояние из нереактивного поляeditor.isEditableпрямо в рендере:apps/client/src/features/editor/components/fixed-toolbar/groups/dictation-group.tsx:83→disabled={!editor.isEditable}editorприходит изpageEditorAtom(atom<Editor | null>,apps/client/src/features/editor/atoms/editor-atoms.ts:5) — это ссылка на объект редактора. Когда после синка вызываетсяeditor.setEditable(true)(гейт #218,apps/client/src/features/editor/page-editor.tsx:465-472), меняется внутреннее состояние TipTap, но ссылка на объект та же → значение атома «не меняется» → подписчики (PageByline/DictationGroup) не перерендериваются.Тело редактора эту же задачу решает правильно — через реактивный
useEditorState:apps/client/src/features/editor/page-editor.tsx:362-367DictationGroup/MicButtonuseEditorStateне используют → залипают на снимкеisEditable, который был на момент их последнего рендера (в pre-sync окне =false).Почему именно застревает:
PageByline— соседPageEditor, а не его потомок. СостояниеshowStaticживёт в локальном стейтеPageEditorи наружу не выходит,pageEditorAtomне меняется (та же ссылка). Значит после досинка ничто не заставляет байлайн перерендериться, иdisabled=trueзастревает навсегда, пока что-то другое (переключение режима, навигация) случайно не перерисует байлайн.Ожидаемое поведение
Как только тело становится редактируемым, иконка диктовки должна автоматически активироваться (и деактивироваться обратно, когда тело теряет editable).
Фикс (точечный)
Читать editable реактивно — тем же приёмом, что и тело:
Чинит оба места, где рендерится
DictationGroup: байлайн (apps/client/src/features/editor/full-editor.tsx:254) и fixed-toolbar. Исходное намерение #218 (нет диктовки до досинка) сохраняется — просто становится реактивным.Затронутые файлы
apps/client/src/features/editor/components/fixed-toolbar/groups/dictation-group.tsx— правка.page-editor.tsx(гейтsetEditable/showStatic),full-editor.tsx(PageByline),dictation/components/mic-button.tsx(пропdisabled).Связанное