uttrflow / uttrflow/uttrflow-swift

Home says "Listening · ready" with the ring lit when the speech model was never downloaded

Open
#672 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

With the speech model not downloaded, the main window tells the user everything is ready.

- Home's status comes from `HomePresenter.status(blocked:speechModel:)` (`Sources/UttrflowUX/HomePresentation.swift:378-382`). It is "Not listening" only for a missing permission, and the model's own line only for a `SpeechModelLoad`. The app passes `speechReadiness.load(since:now:)` (`Sources/Uttrflow/AppDelegate.swift:61-63`, `:1405`), and `SpeechModelReadiness.load` returns `nil` for `.notInstalled` (`Sources/UttrflowUX/MenuBarPresentation.swift:32`). So with no model, Home shows **"Listening · ready"** with the ring lit (`isReady: true`), and the subtitle "Nothing dictated yet. Hold the shortcut anywhere and talk." (`HomePresentation.swift:445`).
- The Dictation page's blocking state is `MainPresenter.obstruction(in:)`, which checks permissions only (`Sources/UttrflowUX/MainPresentation.swift:181-210`). With no model its empty state invites "Hold ⌥Space anywhere and talk" (`Sources/UttrflowUX/MainDictationPresentation.swift:392-401`).
- The menu bar, on the same state, says "Setup hasn't finished" (`MenuBarPresentation.swift:388-389`), so two surfaces disagree.

Separately, "Listening · ready" is the wording at rest. Everywhere else "Listening" means the microphone is open: the menu bar's "Listening…" (`MenuBarPresentation.swift:508`) and the floating button's "Listening. Let go to finish." (`Sources/UttrflowPipeline/DictationPresenter.swift:47`). A resting status that says "Listening" suggests the microphone is always on.

## Why it matters

A user who skipped or cancelled the download (a choice onboarding offers) opens the app, sees a green "Listening · ready", holds the shortcut, and gets a failure. The page that should explain what is missing says the opposite. For a privacy-minded user, "Listening" at rest reads as the microphone being open.

## How to reproduce

Remove the installed speech model for the dev bundle, launch with onboarding already finished, and open Home and Dictation. Or in a test: `HomePresenter.page(for:)` with `speechModel: nil` and all permissions granted returns status "Listening · ready", whatever `SpeechModelReadiness` the app holds.

## Acceptance criteria

- Home and the Dictation page know when the speech model is not installed (or failed to load) and show it: status not ready, and a notice with the download action (the action itself is #671's fix; the notice can use `RecoveryAction.downloadSpeechModel` either way).
- The resting status no longer uses "Listening"; for example "Ready" (the menu bar's word) and "Not ready".
- Home, Dictation and the menu bar agree for `.notInstalled`, `.loading`, `.loadFailed` and `.ready`.
- Tests: `Tests/UttrflowUXTests/HomePresentationTests.swift:255` and `Tests/UttrflowUXTests/SpeechModelLoadingSurfacesTests.swift:50` updated, plus a case for a missing model on both pages.

Contributor guide

Open the contributing guide

Research direction

Start with HomePresenter.status and page(for:) in Sources/UttrflowUX/HomePresentation.swift, then compare MainPresenter.obstruction and the empty state in MainPresentation.swift and MainDictationPresentation.swift. Run the cases in Tests/UttrflowUXTests/HomePresentationTests.swift and SpeechModelLoadingSurfacesTests.swift; done means Home, Dictation, and the menu bar agree for missing, loading, failed, and ready model states, with updated wording and missing-model coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
desktop
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.