uttrflow / uttrflow/uttrflow-swift

Quiet outcomes on the floating button show no words and vanish after 2 s, including "copied, not typed"

Open
#558 0 comments 0 reactions 0 assignees View on GitHub
area:dictation bug P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

Three outcomes are drawn as a small glyph and cleared after `successLingers` (2 s, `Sources/Uttrflow/AppDelegate.swift:201, 1784-1799`):

1. **Copied instead of typed.** `DictationPresenter` sets `primaryLine: "Copied — press ⌘V"` and a preview (`Sources/UttrflowPipeline/DictationPresenter.swift:57-73`), but `DockView.clipboardNotice` draws only a "⌘V" keycap at rest; the sentence "Typing is blocked — paste it" and the Fix button appear only while the pointer is over the button (`Sources/Uttrflow/Dock/DockView.swift:226-248`). The state is `.inserted`, so it gets the 2-second success linger even though the words are not in the document.
2. **Nothing heard.** `waveform.slash` is drawn as a struck level with no text (`DockView.swift:208-209, 460-478`), also 2 s.
3. **Too short.** `SpeechEngineError.audioTooShort` has the one message that tells the user what to do ("Hold the shortcut a moment longer", `SpeechEngineError.swift:25-26`), but the pipeline converts it to `.nothingHeard` before it reaches the interface (`Sources/UttrflowPipeline/DictationPipeline.swift:582-585`), so that sentence is never shown.

## Why it matters

In the copied case the user's words are not where they were looking. A user who glanced away for two seconds sees nothing change and assumes the dictation failed or landed. The struck-level glyph is not self-explanatory to a new user, and a hold-to-talk user tapping the key too briefly never learns why.

## How to reproduce

Revoke Accessibility for the dev build and dictate into TextEdit: watch the button without moving the pointer to it. Separately, hold the shortcut in silence.

## Acceptance criteria

- When words were copied rather than typed, the resting form says so in words and stays until the user pastes, dismisses it, or starts another dictation (or at least as long as a failure notice).
- "Didn't catch that" is readable without hovering.
- Either the "too short" message is reachable for a hold that recorded less than the recogniser's minimum, or `audioTooShort`'s message is removed as dead copy.
- Presenter tests cover what each of these forms shows at rest.

Contributor guide

Open the contributing guide

Research direction

Start with the cited success-linger handling in Sources/Uttrflow/AppDelegate.swift, the resting-state branches in Sources/Uttrflow/Dock/DockView.swift, and DictationPresenter.swift. Trace audioTooShort through Sources/UttrflowPipeline/DictationPipeline.swift, then run the presenter tests. Done means each outcome is readable at rest and the copied notice remains visible until an accepted dismissal condition.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
accessibility, desktop, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.