Made dictation follow caret instead of appending - #917
Merged
Conversation
VegardHV
force-pushed
the
vhv/keyboard-attached-dictation-button
branch
from
July 23, 2026 14:20
5f358de to
1c1660e
Compare
VegardHV
force-pushed
the
vhv/keyboard-attached-dictation-button
branch
from
July 23, 2026 14:21
1c1660e to
8742f47
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves the experimental text-field dictation experience by inserting recognized speech at the current caret position (replacing any active selection), and refactors the dictation UI so the microphone is hosted on/near the keyboard (Android overlay + iOS input accessory) rather than inside individual input components.
Changes:
- Add
DictationTextInserter(with unit tests) to insert dictated text at caret/selection, including basic spacing rules and caret updates. - Introduce a shared dictation session coordinator (
DictationSessionCoordinator) and main-thread delivery wrapper to manage a single active session and route streamed results safely. - Move dictation microphone UI out of
MultiLineInputFieldand into platform keyboard surfaces (Android popup overlay; iOS toolbar accessory), plus a new sample page and localized “Stop dictation” label.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/tests/unittests/Components/TextFields/DictationTextInserterTests.cs |
New unit tests covering caret insertion, selection replacement, and clamping behavior. |
src/library/DIPS.Mobile.UI/Resources/LocalizedStrings/LocalizedStrings/DUILocalizedStrings.resx |
Adds StopDictation localized key (nb). |
src/library/DIPS.Mobile.UI/Resources/LocalizedStrings/LocalizedStrings/DUILocalizedStrings.en.resx |
Adds StopDictation localized key (en). |
src/library/DIPS.Mobile.UI/Resources/LocalizedStrings/LocalizedStrings/DUILocalizedStrings.Designer.cs |
Adds generated accessor for StopDictation. |
src/library/DIPS.Mobile.UI/Components/TextFields/InputFields/MultiLineInputField/MultiLineInputField.Dictation.cs |
Removes prior dictation-in-field implementation. |
src/library/DIPS.Mobile.UI/Components/TextFields/InputFields/MultiLineInputField/MultiLineInputField.cs |
Removes dictation button wiring and simplifies button visibility; adjusts Save behavior to hide buttons correctly when dirty. |
src/library/DIPS.Mobile.UI/Components/TextFields/InputFields/MultiLineInputField/MultiLineInputField.Animations.cs |
Removes dictation breathing/border animations tied to the old in-field mic button. |
src/library/DIPS.Mobile.UI/Components/TextFields/InputFields/MultiLineInputField/Dictation/IDictationDelegate.cs |
Removes old file (interface moved/renamed file). |
src/library/DIPS.Mobile.UI/Components/TextFields/InputFields/MultiLineInputField/Dictation/IDictationConsumerDelegate.cs |
Reintroduces IDictationConsumerDelegate with XML docs (file rename + doc additions). |
src/library/DIPS.Mobile.UI/Components/TextFields/Entry/iOS/MauiDoneAccessoryView.cs |
Extends MAUI’s iOS done accessory toolbar with an optional microphone button and active/idle visuals + accessibility labels. |
src/library/DIPS.Mobile.UI/Components/TextFields/Entry/iOS/EntryHandler.cs |
iOS Entry handler now wires the accessory microphone to start/stop dictation sessions and show errors. |
src/library/DIPS.Mobile.UI/Components/TextFields/Entry/EntryHandler.Dictation.cs |
Implements dictation result insertion into Entry using DictationTextInserter. |
src/library/DIPS.Mobile.UI/Components/TextFields/Entry/Android/EntryHandler.cs |
Android Entry handler coordinates focus/blur with the dictation overlay + session coordinator. |
src/library/DIPS.Mobile.UI/Components/TextFields/Editor/iOS/EditorHandler.cs |
iOS Editor handler now wires the accessory microphone to start/stop dictation sessions and show errors. |
src/library/DIPS.Mobile.UI/Components/TextFields/Editor/EditorHandler.Dictation.cs |
Implements dictation result insertion into Editor using DictationTextInserter. |
src/library/DIPS.Mobile.UI/Components/TextFields/Editor/Android/EditorHandler.cs |
Android Editor handler coordinates focus/blur with the dictation overlay + session coordinator. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/MainThreadDictationConsumer.cs |
Ensures dictation results are delivered on the main thread and drops late results after cancellation. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/DictationTextInserter.cs |
New insertion/clamping logic returning updated text + caret index. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/DictationSessionCoordinator.cs |
New coordinator for a single active dictation session, cancellation, and consumer routing. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/DictationFeature.cs |
Centralized “is dictation available” check (experimental feature + delegate configured). |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/DictationErrorDialog.cs |
Centralized error dialog display for dictation start failures. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/Android/DictationKeyboardOverlay.Positioning.cs |
Keyboard inset tracking + popup show/hide/reposition logic for the Android overlay mic. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/Android/DictationKeyboardOverlay.cs |
Android overlay lifecycle: attach/detach per activity, subscribe to coordinator, teardown on activity destroyed. |
src/library/DIPS.Mobile.UI/Components/TextFields/Dictation/Android/DictationKeyboardOverlay.Button.cs |
Android overlay microphone button construction, active/idle icon swap, and session start/stop behavior. |
src/app/Components/ComponentsSamples/TextFields/TextFieldsSamples.xaml |
Adds navigation entry for the new keyboard dictation sample page and adjusts dividers. |
src/app/Components/ComponentsSamples/TextFields/KeyboardDictation/KeyboardDictationSamplePage.xaml.cs |
New sample page code-behind. |
src/app/Components/ComponentsSamples/TextFields/KeyboardDictation/KeyboardDictationSamplePage.xaml |
New sample page demonstrating dictation across Entry/Editor/MultiLineInputField. |
CHANGELOG.md |
Adds entries for dictation caret insertion + keyboard-hosted microphone, and the MultiLineInputField save/unfocus fix. |
eirinsvi
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of Change
Dictation results are now inserted into the caret position instead of appending to the end of the text. Selection of text is also accounted for, replacing selected text with dictation, as normal typing would.
Todos