Repository navigation
feat(ios): the whole plan in lanes, and a marked scale - #129
Conversation
Anders' TestFlight feedback, 28 October 2026. - The plan view's lanes show the whole plan the box sent, to its last slot or car window (PlanGlance.reach): at least twelve hours, never past the end of tomorrow. In the evening that is tomorrow's last priced quarter. The rows follow and name tomorrow where the clock would read as tonight. The dial, Now's strip and the widgets keep their spans. - The lanes' hours count from midnight (00 06 12 18, or every three), not from whatever hour now is. - Power charts mark zero with "0" and up to two round rungs between the ends (YDomain.rungs), none within half a step of an end. Scale labels take the language's decimal mark: "7,5 kW". - Two battery runs of the same kind are said once: "nu–20:45 och 21:00–21:30 laddar batteriet ur". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12f19d653a
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let count = untilMs.map { max(Self.count, Int((($0 - first) / Self.quarterMs).rounded(.up))) } ?? Self.count | ||
| let grid = SlotGrid(firstMs: first, stepMs: Self.quarterMs, count: count, fromMs: first, toMs: first + Double(count) * Self.quarterMs) |
There was a problem hiding this comment.
Reset the lane selection when the quarter count shrinks
When someone holds a finger over the last quarter of lanes spanning more than 24 hours, advancing into the next quarter can now shrink this array (for example, from 112 quarters to 111 for an unchanged plan end). PlanLanesCard preserves scrub.index when its dial changes, and LanesMark passes that index directly to dial.what(i), dial.time(i), and dial.price(i). The retained index 111 therefore becomes out of bounds and crashes the app on redraw. Clear or remap the selection when the grid changes, and bounds-check it before reading the new dial.
Useful? React with 👍 / 👎.
- Tomorrow is named at the same clock time too (>= not >): at 20:00 a run 20:00–22:00 tomorrow read as now. The 12 h window hid it; the lanes and the price widget's 48 h reach it. Same rule in PriceGlance. - The lanes' hours count from the household's midnight, as the rows do, not the phone's. - The finger's clock names the day past one turn: "I MORGON 21:00". - No rungs under a 10 W span, where they would round to the watt; the search starts at the step that can win. - The watch's trace has no gutter: no rungs and no "0" there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The whole plan in the lanes, a marked scale, one headline clause (#129), for TestFlight. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Two things Anders Rauge sent from TestFlight on 28 October 2026, and one I saw in his screenshots.
"Saknar möjlighet att se planen i ett längre perspektiv"
The box plans over every published price, up to 48 h (
mpc/service.go: "the plan covers the published prices"), and the app gets the whole plan. The lanes cut it at twelve hours (PlanGlance.horizonMs). At 20:23 his box had planned to midnight the next day, about 28 h, and he saw the first twelve.PlanGlance.reach). The span is at least twelve hours and never runs past the end of tomorrow, so every clock on them reads as today or tomorrow. In the evening that is tomorrow's last priced quarter; before 13:00 it is about twelve hours, as before.MomentcarriestoMs. Only the lanes ask forwhole:; the dial (one turn), Now's strip, the widgets and the watch keep their spans.Moment.times). An end at midnight reads 24:00, as the plan's sentences already do.PlanDialbuiltuntilMs:the lanes' end; the face stays 96 quarters.No new button, setting or data.
"Hade gärna sett några streck på y-skalan"
The charts marked only the two ends, and zero was a hairline with no figure, so "2 kW" at the foot of his chart did not read as 2 kW the other way.
YDomain.rungs,ChartAxes.draw). His −2…7.5 kW chart reads 7,5 · 5 · 2,5 · 0 · 2 kW; the demo battery's −3…5 kW reads 5 · 2,5 · 0 · 3 kW.ChartGutter.scaleLabels).PowerFormat.scale, which the Grid today widget also uses).The headline said "laddar batteriet ur" twice
"nu–20:45 laddar batteriet ur · 21:00–21:30 laddar batteriet ur" now reads "nu–20:45 och 21:00–21:30 laddar batteriet ur". Only two runs of the same kind next to each other merge; different moves keep a clause each.
Overlap
#107 (draft, line widths) edits other lines of
PlanView.swiftandHistoryCharts.swift: the legend, the level line's style and the ghost bars. No hunk here touches them.Review
An agent read the diff and probed it. Fixed in b2199fc:
>for>=): at 20:00 a run 20:00–22:00 tomorrow read as now. The 12 h window hid it; the lanes reach it, and so does the price widget's 48 h, which shares the rule (PriceGlance.misleads).trailing: 0), so it draws no rungs and no "0".Checked by the review with no fault:
reachacross both DST changes,toMsagainst every filter in a moment, the 12 h readers (all on the dial, Now, widgets, watch),DialMemo, the finger's span, and 1,179 domains forrungs(never more than two, never a loop).Evidence (this Mac)
swift testinappleApp/FTWKit: 957 tests green after b2199fc, new ones:twoRunsOfTheSameKindAreSaidOnce,theLanesReachTheWholePlan,aRowNamesTomorrowWhereTheClockWouldMislead,aScaleIsMarkedAtUpToTwoRoundRungs, and the gutter test updated.🤖 Generated with Claude Code