uttrflow / uttrflow/uttrflow-swift

VoiceOver's label for a clipboard row leaves out whether it is pinned, a picture's size or that its file is gone, and a note's checklist progress

Open Beginner friendly
#585 0 comments 0 reactions 0 assignees View on GitHub
accessibility area:clipboard bug good first issue P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

`QuickPanelSpeech.label(for:)` (`Sources/Uttrflow/Panel/QuickPanelRowAppearance.swift:42-48`) builds a row's spoken label from four parts: kind, alias, summary (or "hidden") and time.

```swift
[noun(for: row.kind), row.alias, body, row.when]
```

The row's children are ignored for accessibility (`QuickPanelView.swift:464`), so anything drawn on the row but missing from this list is invisible to VoiceOver:

- **Pinned.** The pin glyph (`QuickPanelView.swift:538-542`). `PanelRow.isPinned` is not spoken.
- **A picture's measurements.** A picture row's summary is empty, so it reads only "Image, 2 minutes ago". The "2880 × 1800 · 1 MB" or source and size text (`PanelRow.measurements`) is not spoken.
- **A missing picture.** "The picture is no longer on this Mac" is also `measurements`, so a broken row sounds like a working one.
- **Checklist progress.** "2 of 5" (`PanelRow.checklist`) is not spoken.
- **Collection.** `PanelRow.category` is not spoken while browsing a tab that mixes collections.

The code language chip has its own label ("swift code", `:521`), but it is a child of the ignored element, so it is not heard either.

## Why it matters

Picture rows are indistinguishable from each other by ear, and a missing picture sounds pasteable. A VoiceOver user cannot tell which clips they pinned.

## Acceptance criteria

- The label includes, where present: "pinned", the picture's measurements (or the missing-picture sentence), checklist progress, the code language, and the collection.
- A masked row still speaks nothing of the clip's content: no language, no checklist.
- New cases in `QuickPanelSpeechTests` (`Tests/UttrflowTests/QuickPanelRowAppearanceTests.swift:77`) cover a pinned row, a picture row, a missing-picture row, a note with boxes and a masked row with a language.

## Where to start

- `Sources/Uttrflow/Panel/QuickPanelRowAppearance.swift:40-67`
- Test to extend: `Tests/UttrflowTests/QuickPanelRowAppearanceTests.swift` (`QuickPanelSpeechTests`)
- Before pushing, run `make verify` (export `DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer` first). It is the same command CI runs, and it enforces the 95% coverage floor per module.
- Read [CONTRIBUTING.md](https://github.com/uttrflow/uttrflow-swift/blob/main/CONTRIBUTING.md) first, and say on this issue that you are taking it.

**Size:** S, about 1 to 2 hours.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md first, then inspect QuickPanelSpeech.label(for:) in Sources/Uttrflow/Panel/QuickPanelRowAppearance.swift:40-67 and the QuickPanelSpeechTests in Tests/UttrflowTests/QuickPanelRowAppearanceTests.swift. Add the specified accessibility-label cases, including masking behavior, and run make verify with DEVELOPER_DIR set as described.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.