Skip to content

feat(ios): Now chooses a pass and shows its figures - #139

Merged
frahlg merged 3 commits into
mainfrom
ios-now-passes
Nov 1, 2026
Merged

frahlg merged 3 commits into
mainfrom
ios-now-passes

Conversation

@frahlg

@frahlg frahlg commented Nov 1, 2026

Copy link
Copy Markdown
Member

Why

Fredrik picked proposal 5 for Now on 1 November 2026 ("Planen, runda 3" on the design canvas): the battery's runs as passes you can tap, the prices under the chosen one in its colour, and three figures for it under the strip. This is step 2 of four. It stacks on #138 (the price from zero); merge that first.

Change

  • PlanPass (FTWShared, tested) turns the plan's events into passes on the strip's quarters: each battery run (gives or stores) and each car window. Each has three figures:
    • Battery gives: BATTERY start / until, LEVEL 62 → 24 % / gives 4.8 kWh, TOP PRICE / during the pass.
    • Battery stores: the same, then AVG PRICE / from the grid, or SOURCE The sun / nothing bought when the box's reason is solar_surplus.
    • Car: CAR start / until, GOAL 80 % / ready by 07:00, AVG PRICE / energy.
      The level reads "→ 24 %" when the plan gives no start level. The energy counts from now on.
  • Now's strip: a tap on a pass chooses it, with a 28 pt wide tap target at least (each lane takes its half where a battery run and a car window share minutes). The chosen pass is drawn in full colour over a faint column of its colour, and the bars under it take its colour. The battery's other runs tint their bars faintly. The figures replace the sentence. With no pass the sentence stays, and a finger's quarter line still takes their place while it reads.
  • Phosphor's colours, not the proposal's: gold gives power, cyan stores, violet for the car. Nothing glows.
  • Words in English and Swedish (Plan.strings). CLAUDE.md says how the strip behaves.

Evidence

  • swift test in appleApp/FTWKit: 636 tests in 95 suites and 342 Swift Testing tests pass locally, among them thePassesAndTheirFigures and aRunOnSpareSunBuysNothing.
  • Built for the iOS Simulator (FTW scheme, with the watch). Demo on an iPhone 17, iOS 26.5. The car's pass was chosen with a tap in the simulator.
Opens on the battery After a tap on the car Light

Not checked: VoiceOver on the pass buttons, the largest text size, and a device.

🤖 Generated with Claude Code

frahlg and others added 2 commits November 1, 2026 15:11
Erik, 1 November 2026: Now's strip made 450 against 550 öre look five
times dearer. It put the window's cheapest quarter at the floor and the
dearest at the top.

Every price bar now reads one PriceScale: zero at the foot and a round
top just over the dearest (1, 1.5, 2, 2.5, 3, 4, 5, 6 or 8 times a power
of ten). Now's strip draws the bars from zero, marks half the top and the
top with figures in a gutter on the right, and carries the price now on
as a dashed line. A price below zero hangs under the zero line. The dial's
ticks, the lock-screen glyphs, the plan widget and the watch's bars take
the same scale in eight steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fredrik picked proposal 5 for Now on 1 November 2026. Each run of the
battery and each car window on the strip is a pass (PlanPass, FTWShared,
tested). A tap chooses one: it stands in full colour over a faint column
of its colour, the bars under it take that colour, and three figures
under the strip say when it runs, what it does to the level and the
price it meets. The strip opens on the battery's run under way or next.
A run on spare sun says it buys nothing. With no pass, the sentence
stays; under a finger, the quarter's line still takes its place.

The colours are Phosphor's, not the proposal's: gold gives power, cyan
stores, violet for the car. Nothing glows, since a plan is not live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T14:19:59.324881Z 389c79c PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 389c79ccdc

ℹ️ 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".

public let figures: [Figure]
/// The pass in one line, for VoiceOver.
public let spoken: String
public var id: String { "\(kind.rawValue)-\(Int64(startMs))" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep pass identity stable as the current minute advances

When a user selects an ongoing car window while a battery pass also exists, the selection resets at the next minute refresh. PlanGlance.events clips an ongoing event's startMs to nowMs, so deriving the ID from that timestamp changes it every minute even when the plan is unchanged. PlanSection rebuilds the strip each minute, and chosen then cannot find chosenID and falls back to the battery pass. Preserve the underlying run/window identity independently of the clipped display start so the selected pass remains selected.

Useful? React with 👍 / 👎.

Comment on lines +89 to +92
.overlay(alignment: .topLeading) {
PassTargets(strip: strip, layout: layout, chosenID: $chosenID)
.frame(width: canvas.width, height: canvas.height, alignment: .topLeading)
.offset(x: canvas.minX, y: canvas.minY)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Let drags on pass targets reach the scrub gesture

A drag starting on a battery or car pass now hits a button in this overlay, but the scrub DragGesture is attached only to plan, inside the underlying NavigationLink. Because the overlay is a sibling rather than a descendant of that gesture-bearing view, those touches cannot reach follow, so scrubbing no longer works when initiated on the pass targets. Attach the scrub gesture to a common ancestor or explicitly handle drags on the targets while retaining tap-to-select behavior.

Useful? React with 👍 / 👎.

… ci]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@frahlg
frahlg changed the base branch from ios-price-scale to main November 1, 2026 17:48
@frahlg
frahlg merged commit d47f5ba into main Nov 1, 2026
@frahlg
frahlg deleted the ios-now-passes branch November 1, 2026 17:49
@frahlg frahlg mentioned this pull request Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant