uttrflow / uttrflow/uttrflow-swift
The Insights caption drops the start month when the window crosses one: "17–15 June" for a 30-day window
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
The Insights chart caption names its date range as the first day's number and the last day's number and month (`InsightsPresenter.caption`, `Sources/UttrflowUX/InsightsPresentation.swift:229-242`):
```swift
let from = first.formatted(.dateTime.day().locale(locale))
let to = snapshot.now.formatted(.dateTime.day().month(.wide).locale(locale))
return "\(from)–\(to)"
```
When the window starts in an earlier month, the start month is dropped and the range reads backwards. Retention can be 14, 30 or 90 days (`SettingsRetention.offeredDays`, `Sources/UttrflowUX/SettingsChoices.swift:108`), so any window of 30 or 90 days always crosses a month, and a 14-day one does for half of every month.
Measured with a throwaway test using the Insights test fixtures (15 June 2025, `en_GB`, a week of entries):
| Retention | Expected caption | Actual caption |
|---|---|---|
| 14 days | `70 words · 2–15 June` | `70 words · 2–15 June` |
| 30 days | `70 words · 17 May–15 June` | `70 words · 17–15 June` |
| 90 days | `70 words · 18 March–15 June` | `70 words · 18–15 June` |
(A year boundary has the same problem: a 30-day window on 10 January reads "12–10 January".)
## Why it matters
"17–15 June" is a range that cannot exist; it reads as a bug on the page that is meant to summarise someone's own use.
## How to reproduce
In `Tests/UttrflowUXTests/InsightsPresentationTests.swift`, set `settings.transcriptRetentionDays = 30`, build the page over `HistoryFixture.aWeek()`, and check `page.chartCaption == "70 words · 17 May–15 June"`.
## Acceptance criteria
- The start month (and year, when it differs) is shown whenever it differs from the end's; a same-month range still reads "2–15 June".
- Prefer a locale-aware interval format (for example `Date.IntervalFormatStyle` or `DateIntervalFormatter`) over string concatenation, so other locales get their own order.
- Tests cover a same-month window, a cross-month window and a cross-year window.
## Where to start
- `Sources/UttrflowUX/InsightsPresentation.swift:228-242`.
- Tests: `Tests/UttrflowUXTests/InsightsPresentationTests.swift` (`InsightsChartTests`).
- Run `make verify` (export `DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer` first) and read CONTRIBUTING.md.
**Size:** XS, under an hour.
Contributor guide
Research direction
Start in Sources/UttrflowUX/InsightsPresentation.swift:228-242, then read the InsightsChartTests in Tests/UttrflowUXTests/InsightsPresentationTests.swift and the existing date-formatting code. Use the listed retention and fixture scenarios to cover same-month, cross-month, and cross-year captions with locale-aware interval formatting. Run the focused tests, then make verify; done means all three expected captions pass without breaking locale behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- Under an hour
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 92/100