uttrflow / uttrflow/uttrflow-swift
Pinning or unpinning a clip that fails to save says nothing, unlike every other panel change
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Every change the panel asks the store for goes through `apply(_:)`. When the store refuses, it shows the failure on the panel: F10, `panel?.notice = .writeFailed(failure.userMessage)` (`Sources/Uttrflow/AppDelegate.swift:869-881`).
Pin and Unpin do not use that path:
```swift
// Sources/Uttrflow/AppDelegate.swift:988-993
private func setPinned(_ isPinned: Bool, of id: UUID) {
Task { [clipboard] in
_ = try? await clipboard.setPinned(isPinned, of: id, keeping: retention)
await refreshPanelIfOpen()
}
}
```
`ClipboardStore.save` updates memory before it writes (`ClipboardStore.swift:457-458`). When the disk refuses, the pin still shows as set for the rest of the session and then silently disappears at the next launch. Pinning is also what keeps a clip from ageing out, so the clip the user meant to keep can be deleted by retention.
## Acceptance criteria
- A refused pin or unpin shows the same `writeFailed` notice as a refused alias or move.
- Preferably, pin and unpin become `PanelChange` cases (`Sources/UttrflowUX/PanelChange.swift`) so they go through `apply` like the rest. The decision is then testable in `Tests/UttrflowUXTests`, where a test can show `.pin(id)` producing `.applyAndRedraw(.setPinned(id, true))`.
## Where to start
- `Sources/Uttrflow/AppDelegate.swift:954-955` and `:988-993`
- `Sources/UttrflowUX/PanelChange.swift`, `Sources/UttrflowUX/PanelPresentation.swift:45-64` (`PanelIntent.key`)
- Tests to extend: the `PanelChange` and `PanelIntent` tests in `Tests/UttrflowUXTests`
- 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 2 hours.
Contributor guide
Research direction
Read CONTRIBUTING.md first, then inspect setPinned in Sources/Uttrflow/AppDelegate.swift and the PanelChange and PanelIntent definitions in Sources/UttrflowUX. Extend the PanelChange and PanelIntent tests in Tests/UttrflowUXTests, and run make verify with DEVELOPER_DIR set; done means refused pin or unpin changes produce the writeFailed notice.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100