Repository navigation
Apple Watch W1.1: Now alive on one screen, pages without scrolling, graphic complications - #49
Conversation
…nd graphic complications Fredrik's notes on W1 (14 Oct 2026): the watch widgets let text run outside and should hold little text; the app should have the phone's live view and pages instead of scrolling. - Now: the status line, one node's figure large, the phone's live trace (LiveSeries drawn by LiveTraceSurface in TraceInk), glowing only while live, and the other nodes small. A tap on a small one traces it. The mode sits behind a toolbar button. - Every page fits one screen at the standard sizes; at text sizes too large for the watch it scrolls rather than cut a reading off. The car's commands are one row of glyph buttons. - Complications: no sentences. Rectangular is a glyph, one time, the price now and the plan unrolled as a strip; corner is the price with the day's range as a gauge; inline is the price; the cheap card is a glyph, its hours, one figure and the hours ahead with the window standing out. Every text has one line and may shrink. - LiveTraceSurface takes `paused`, so a trace that is not live holds still. WatchNow.Reading gives its signed watts for the trace, and each node the phone's scale floor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omes next, Now waits for live in the tour Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The receipt now takes the place of what the car does, its goal and next window, until the page is left; a settled receipt then goes. The page no longer keeps a room of its own for the receipt, so it fits 46 mm without scrolling and the swipe turns the page. The commands are one row of glyph buttons, 30 pt high. The watch's strip view is now DialStrip, so it does not shadow the PlanStrip value that the phone's plan lane adds to FTWShared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Now's trace takes the height that is left, at least 24 pt, so the page fits 41 mm without scrolling and the swipe turns the page. On 46 mm the trace is as tall as before. The car's meter goes under its level when both do not fit on one line, as with "20 % antaget", rather than cutting the word. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BlockBars keeps W1.1's highlight and takes PlanDial.levels from #53. DialStrip, the rectangle's strip, now reads PlanDial. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #53 the watch's plan page draws the shared face at the app size, and on a dial about 100 pt across the goal ("80 %") landed on the hand's time and price in the middle. The goal now shows only on a dial at least 200 pt across, which the phone's always is. 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: 06c185acd9
ℹ️ 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".
| /// 19:30". The whole plan is the dial. | ||
| private func next(_ m: PlanGlance.Moment) -> String { | ||
| guard let what = m.nextWhat else { return m.summary } | ||
| return [what, m.nextUntil].compactMap { $0 }.joined(separator: " ") |
There was a problem hiding this comment.
Include the start time for future plan events
When the next event has not started, this still combines its description only with nextUntil, so a plan whose next charge runs from 01:00–04:45 is presented as “Car charges … until 04:45,” incorrectly implying that charging is already underway. PlanGlance exposes nextWhen specifically to distinguish future events; include it or use the existing future-event sentence formatting.
Useful? React with 👍 / 👎.
| } | ||
| .animation(Theme.spring, value: figure.value) | ||
| .accessibilityElement(children: .combine) | ||
| .accessibilityLabel("\(figure.title), \(figure.value) \(figure.unit), \(figure.word)") |
There was a problem hiding this comment.
Announce the hero node's displayed charge level
When the battery or car is selected as the hero, the visible trailing text is figure.level, but this explicit accessibility label replaces the combined child content with figure.word and omits that percentage. VoiceOver users therefore lose the battery/car level that the previous combined row exposed; include figure.level in the label when present.
Useful? React with 👍 / 👎.
| .accessibilityElement(children: .ignore) | ||
| .accessibilityLabel(face.plan.summary) |
There was a problem hiding this comment.
Announce when the rectangular plan is stale
For a plan older than an hour, the rectangular complication visually replaces the event with a clock and the plan's read time, but ignoring its children and labeling it only with face.plan.summary drops that staleness information. VoiceOver consequently reads the old plan without saying that it is old; include the plan age/read time in the replacement label when face.plan.isGrey.
Useful? React with 👍 / 👎.
Polish for the Apple Watch app after W1 (#43), from Fredrik's notes on 0.4.0 and 0.4.1 (14 Oct 2026):
The app: four pages, nothing to scroll
watchOS's vertical paging (
TabViewwith.verticalPage), one idea per page, each on one screen at 41 and 46 mm. The Crown turns the pages, except on the plan, where it steps the hand; a swipe goes on from there.● LIVE · FTW STYR), one node's figure large, and the phone's live trace under it:LiveSeriesdrawn byLiveTraceSurfaceinTraceInk, the node view's material from iPhone: the node view streams, the live trace as its hero (WP6) #41 and iPhone: history and ahead on the engine, in the live trace's material, the chart small and growing (WP7) #44. The trace keeps three minutes. It glows only while the phone passes on live frames, and holds still in ink when it does not. Under it the other nodes sit small, as a glyph and a figure. A tap on one traces it, and the watch remembers the choice. The home's use is traced first, because it moves whenever something in the house switches. The mode sits behind the toolbar's button.At text sizes too large for the watch, a page scrolls rather than cut a reading off.
No dial on Now. Now already holds the status line, the large figure, the trace and four small figures. A dial small enough to fit beside them reads as texture, and the plan is one turn of the Crown away.
Complications: pictures, at most one figure
Every text has one line and may shrink rather than run outside. A plan older than an hour turns grey, and its time shows where the next event's time was. A fresh plan no longer prints its age in the rectangle; the box replans every quarter hour.
Pictures
Watch simulators on watchOS 27, paired with an iPhone simulator that runs the demo, taken after merging main (#53's shared dial). Pages come from the
WatchTourUI test.46 mm
41 mm
On 41 mm the face's middle module shows the Smart Stack's top, which on this simulator holds other apps. The rectangle, the corner and the cheap card on 41 mm still need pictures: this watch has no Infograph face and no FTW card pinned in its stack, and setting those up needs the simulator panel's grant for this watch.
Recordings
MP4: paging, Crown.
The Crown clip comes from
testCrownScrub, which turns the Crown throughXCUIDevice.rotateDigitalCrown. In the simulator each synthesized turn takes about five seconds, even with the laptop idle, so the clip shows each frame once and drops the frames where nothing moved. Each turn in the test moves the hand several quarters. The paging clip runs at real speed.Outside the watch targets
FTWCharts/LiveTrace.swift:LiveTraceSurfacetakespaused(default false). The phone draws as before.FTWShared/Watch:WatchNow.Reading.signedWandNode.floorW(the phone'sscaleFloorW), andCheapWindow.short.The shared dial (#53)
Main is merged in. W1.1 draws the plan page and the circular complication with #53's
PlanDialView, and the rectangle's strip (DialStrip) readsPlanDial.BlockBarskeeps itshighlightand takesPlanDial.levels.One change in the shared face: on a watch-sized dial the car's goal ("80 %") landed on the hand's time and price in the middle, so
PlanDialFacenow shows the goal only on a dial at least 200 pt across. The phone's dial (up to 340 pt) still shows it. The plan lane knows.The strip and WP10's
PlanStrip(#52) both unroll the plan. The view is namedDialStripso the names do not meet. Drawing the rectangle fromPlanStripis a possible follow-up; WP10's drawing carries hour labels and readouts made for the phone.Proof
swift testafter the merge: 214 and 365 tests, all pass.FTWWatchscheme, build.WatchTourafter the merge:testPagingpasses on 41 and 46 mm,testCrownScrubon 46 mm.Not checked
simctlcannot set a watch simulator's text size, and the launch argument that works on the phone changed nothing here. Each page falls back to scrolling rather than cutting a reading.🤖 Generated with Claude Code