Skip to content

Restructure Train by Voice composer into a 3-step accordion#661

Open
shreeraman96 wants to merge 4 commits into
mainfrom
fix/train-by-voice-accordion-648
Open

Restructure Train by Voice composer into a 3-step accordion#661
shreeraman96 wants to merge 4 commits into
mainfrom
fix/train-by-voice-accordion-648

Conversation

@shreeraman96

@shreeraman96 shreeraman96 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes #648, where Train by Voice / Teach Pronunciation under Custom Dictionary showed no interactive prompts and left the Start button permanently inactive. This replaces the flat replacement composer with a guided 3-step accordion (① Word → ② Record → ③ Verify & Save) that always surfaces the next action, and hardens the underlying step state machine.

Changes:

  • Restructure the composer into a 3-step accordion with per-step status glyphs; extract pure step-derivation + readiness logic into a new SwiftUI-free, unit-tested DictionaryTrainingStepModel (DictionaryTrainingSnapshot groups the training state)
  • Reset the hasReachedVerify latch on every teardown path (Try Again, capture removal, mode toggle) so Verify never dead-ends with Save disabled
  • Reset lastAnnouncedTrainingStep on teardown and announce any forward step edge (incl. word → verify) for correct VoiceOver cues
  • Make Record/Verify headers non-interactive while the word is empty; surface save-failure errors in the Verify step
  • Move the trainingReplacement onChange onto the always-mounted accordion so programmatic word writes still reset progress
  • Add unit tests for step derivation, the readiness predicates, and edge cases (empty-word latch, case-insensitivity, pronunciation boundaries)

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

Closes #648

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version: 26.5 (Tahoe)
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources — 0 violations
  • Ran formatter locally: swiftformat --config .swiftformat — changed files pass
  • Ran tests locally: DictionaryTrainingStepModelTests — 20/20 passing

Screenshots / Video

Step 1 : Enter the word to teach

image

Step 2 : Record

image

Step 3 : Verify & save

image

Manual Add

image

Research preview

image

Before all shown at once

image

Notes

  • No shared-package (FluidIntelligence) changes — no cross-repo impact.
  • Findings from a two-model deep review + PR bot review (latch not reset on teardown, missing Verify-step error feedback, VoiceOver announcement gaps, empty-word dead-ends) are all fixed.

@github-actions github-actions Bot added needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 20, 2026
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

The PR Policy check is blocking this PR because required template information is missing.

Please update the PR description with:

  • Screenshots / Video

Visual files detected:

  • Sources/Fluid/UI/CustomDictionaryView.swift
  • Sources/Fluid/UI/DictionaryTrainingStepModel.swift

Screenshots or video are required for UI, UX, settings, onboarding, overlay, menu bar, or visual behavior changes. If this PR has no visual changes, check the no-visual-change box in the template.

If this remains incomplete for 48 hours after opening, the PR may be closed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 903a026ba3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 715 to 720
private var trainingVerifyStepBody: some View {
VStack(alignment: .leading, spacing: self.theme.metrics.spacing.sm) {
self.trainingFinalOutputPanel

Button {
Task { await self.addTrainedReplacement() }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Show verification errors in the Verify step

When advanced voice matching is enabled and addTrainedReplacement() fails to save the pronunciation profile, it sets trainingHasError and trainingStatusMessage while leaving the accordion on Verify. Because the footer that renders those errors is now only included in trainingRecordStepBody, this Verify body shows no failure feedback after the Add Replacement attempt fails, unlike the previous always-visible footer. Include the error/footer in this step as well so the user can see and recover from save failures.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the flat "Train by Voice" composer with a guided 3-step accordion (① Word → ② Record → ③ Verify & Save) and hardens the underlying step state machine to fix the bug where interactive prompts were absent and the Start button was permanently inactive.

  • Extracts pure step-derivation and readiness logic into DictionaryTrainingStepModel (SwiftUI-free, fully unit-tested with 20 tests covering derivation, readiness predicates, latch behavior, pronunciation-matching branches, and subtitle copy).
  • Consolidates all teardown paths (resetTraining, resetTrainingVerificationAttempts, removeTrainingVariant, handleTrainingReplacementChange, handlePronunciationMatchingChange) to call resetTrainingStepLatches(), which atomically resets both the hasReachedVerifyStep latch and the lastAnnouncedTrainingStep VoiceOver deduplication latch.
  • Adds the always-visible error label outside collapsed step bodies so save-failure messages surface regardless of which accordion panel is open.

Confidence Score: 5/5

Safe to merge. The change is well-scoped to the Train by Voice composer and introduces no shared-package changes.

All teardown paths atomically reset both step latches. The VoiceOver deduplication guard lowers correctly on backward transitions and re-fires on forward re-advances. The trainingStepStatus function correctly distinguishes a latch-held Verify from a genuinely ready Verify. The extracted model is SwiftUI-free and covered by 20 unit tests that anchor against the production readiness threshold constant.

Files Needing Attention: No files require special attention.

Reviews (6): Last reviewed commit: "fix: address accordion review findings" | Re-trigger Greptile

Comment thread Sources/Fluid/UI/CustomDictionaryView.swift Outdated
Comment thread Sources/Fluid/UI/CustomDictionaryView.swift
Comment thread Sources/Fluid/UI/DictionaryTrainingStepModel.swift Outdated
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

FluidVoice PR build ready

Download FluidVoice-PR-661-98109795bc7f

The artifact contains the ad-hoc-signed app ZIP, Xcode archive, build manifest, and installation instructions. It expires 5 days after the build.

Install the app

  1. Extract the downloaded artifact, then extract FluidVoice-PR-661.app.zip.

  2. Move FluidVoice Restructure Train by Voice composer into a 3-step accordion #661.app into the /Applications folder.

  3. Open Terminal and remove the download quarantine marker:

    xattr -dr com.apple.quarantine "/Applications/FluidVoice #661.app"
    
  4. In Applications, Control-click FluidVoice Restructure Train by Voice composer into a 3-step accordion #661.app and choose Open.

  5. If macOS still blocks it, open System Settings → Privacy & Security, click Open Anyway, and confirm.

This build has its own app identity, so its permissions are separate from the release version of FluidVoice.

View workflow run

@github-actions github-actions Bot removed needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 20, 2026
@shreeraman96
shreeraman96 force-pushed the fix/train-by-voice-accordion-648 branch from 6cac7d6 to a99cfbd Compare July 20, 2026 23:51
@github-actions

Copy link
Copy Markdown

This pull request has been marked stale because it has had no activity for 5 days. It will be closed in 2 days if there is no further activity. Add the keep-open or pinned label to prevent automatic closure.

@github-actions github-actions Bot added the stale label Jul 26, 2026
shreeraman arunachalam karikalan added 3 commits July 26, 2026 13:59
Splits the flat replacement composer into Word -> Record -> Verify & Save
steps with an extracted, unit-tested step-derivation model.

- Extract pure step logic into DictionaryTrainingStepModel (SwiftUI-free)
- Render composer as a 3-step accordion with per-step status glyphs
- Reset hasReachedVerify latch on every teardown path (Try Again, capture
  removal, mode toggle) so Verify never dead-ends with Save disabled
- Reset lastAnnouncedTrainingStep and announce any forward step edge
  (including word->verify) for correct VoiceOver cues
- Make Record/Verify headers non-interactive while the word is empty
- Move trainingReplacement onChange to the always-mounted accordion so
  programmatic word writes still reset progress
- Add unit tests for step derivation, readiness predicates, and edges
- Reset lastAnnouncedTrainingStep on all teardown paths so the step-3
  VoiceOver cue fires again on retry (resetTrainingVerificationAttempts,
  removeTrainingVariant)
- Show save-failure errors in the Verify step body (footer previously
  lived only in the Record body)
- Drop the unused trainingVariantsIsEmpty param from isOutputCovered
- Introduce DictionaryTrainingSnapshot to collapse the step-model param
  packs (fixes function_parameter_count) and move accordion helpers into
  an extension (fixes type_body_length); no behavior change
@shreeraman96
shreeraman96 force-pushed the fix/train-by-voice-accordion-648 branch from a99cfbd to b9ddb2e Compare July 26, 2026 21:00
- Show real progress in Record subtitle when Verify is latched after a miss
- Render heard-variant chips and already-correct caption in the Verify body
- Move training error label to an always-visible spot below the accordion
- Distinguish 'No replacement needed' from 'Ready to save' in Verify header
- Lower VoiceOver announcement latch on backward step transitions
- Defer word-field focus until the step body is mounted
- Dedupe coverage and recording-lock predicates; extract resetTrainingStepLatches()
- Pin latch-state subtitle copy in tests; use production readyCoveredCount
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] train by voice and teach pronunciation not working

1 participant