uttrflow / uttrflow/uttrflow-swift

Pinning or unpinning a clip that fails to save says nothing, unlike every other panel change

Open Beginner friendly
#581 0 comments 0 reactions 0 assignees View on GitHub
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

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.