Skip to content

fix: sweep whole screens at large text and fix the overflows it found - #714

Open
kurexw wants to merge 8 commits into
OpenStrap:mainfrom
kurexw:fix/large-text-screen-sweep
Open

kurexw wants to merge 8 commits into
OpenStrap:mainfrom
kurexw:fix/large-text-screen-sweep

Conversation

@kurexw

@kurexw kurexw commented Nov 13, 2026 •

Copy link
Copy Markdown

Builds on #713 (its commit is the first one here). Review or merge #713 first; this PR's own changes are the later commits.

Summary

ui2_component_sweep_test checks every gallery component at phone text sizes, but no screen is in the gallery, so cards a screen builds for itself were never checked. This PR adds test/ui2_screen_sweep_test.dart:

  • renders all 14 screens that take preloaded data (Sleep, Readiness, HR zones, Circadian, Day strain, Day steps, Cycle, Home, Health, Investigate, Metric detail, Day timeline, Beats, What changed) at 390 pt;
  • uses the bundled Manrope font, so text measures as on a phone;
  • runs in all eight shipped languages (en, de, es, fr, hi, ru, th, zh), at 1×, 2× and 3.1× text;
  • fails on any RenderFlex overflow and names the screen and source line.

It found these, all fixed here or in #713. The other ten screens are clean at every size in every language. With these fixtures, some show a partial state (HR zones with no measured ceiling, Circadian before a rhythm is established, Home before band data), but each was checked to render its content (no spinner, 8 to 55 text widgets), not an empty shell:

Screen Overflow Fix
Readiness score and band label inside the fixed 150 pt ring, 260 pt too tall at 3.1× FittedBox(scaleDown) inside the ring
HR zones bpm range, 7 pt too wide at 3.1× at large text the range may wrap; at 1× the row is unchanged
Cycle (#713) day-card caption: 91 pt at 3.1× in English, 67 pt at 2× in German in #713
Cycle, German 3.1× MetricRow value 32 pt too wide at large text the value may wrap

MetricRow (shared component). At large text (bigText, scale above 1.3) the row already gives the value a line of its own, but the value still couldn't wrap. That's fine for numbers, but a value that is a phrase overflowed. On that layout only, the value is now Flexible with no line limit. The one-line layout and its "never truncate a measurement" rule are untouched.

Testing

  • flutter test test/ui2_screen_sweep_test.dart: 24 cases (8 languages × 3 sizes, 14 screens each) pass, in about 4 s. With the three lib/ changes stashed, it fails and names exactly the overflows above.
  • Every test file matching ui2/gallery/readiness/zones/health/sleep/graphs/russian/layout (114 files, --concurrency=1): 1,550 passed. That includes ui2_component_sweep_test, which sweeps MetricRow at 1.0–3.1×.
  • In a parallel run of the same slice, ui2_sleep_detail_load_failure_test and ui2_wellness_load_failure_test failed once. Both pass alone and serially, on this branch and on main, so they look flaky under load, not affected by this change.
  • flutter analyze: no issues.

No screenshots: there's no device build here. At 1× the layouts are unchanged (the sweep's 1× runs were already clean before the fixes).

Risks and rollback

  • MetricRow is used app-wide, but the change applies only to the large-text layout, and the component sweep covers it.

  • The readiness number shrinks inside the ring at very large text instead of spilling out of it.

  • Revert the commits to roll back.

  • Tests pass

  • Analyze passes

  • No secrets or debug code

  • Self-review completed

  • Human approval required before merge

🤖 Generated with Claude Code

Summary by Sourcery

Make UI2 screens resilient to large text and localized content while adding comprehensive screen-level overflow coverage.

New Features:

  • Add a localized, large-text screen sweep covering 14 UI2 screens across eight languages and three text scales.

Bug Fixes:

  • Prevent readiness content from overflowing its score ring at very large text sizes.
  • Allow heart-rate zone ranges, cycle labels, and metric values to wrap instead of overflowing on narrow screens or in longer languages.

Enhancements:

  • Preserve existing one-line measurement behavior while making phrase-valued MetricRows wrap in their large-text layout.

Tests:

  • Add focused cycle layout coverage at default and large text sizes.
  • Add whole-screen overflow coverage using realistic fixtures, bundled fonts, shipped locales, and phone-width constraints.

uvtqt and others added 3 commits November 13, 2026 19:13
The card's headline row put the cycle day and "counted from your last
logged start" side by side with nothing allowed to wrap, and its header
put the label before a Spacer and the phase pill. At a 390 pt phone
width the headline overflowed at default size in the test font, and both
rows overflowed at large system text (iOS reaches 3.1x).

The caption is Flexible now, and the header is a Wrap: label and pill
side by side when they fit, the pill on its own line when not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The component sweep covers the gallery, and no screen is in it. A new
sweep renders seven screens from preloaded data at 390 pt with the
bundled font, in English and German, at 1x, 2x and 3.1x text. On top
of the cycle-day card (previous commit) it found:

- Readiness: the score and band label inside the fixed 150 pt ring were
  260 pt taller than the ring at 3.1x. They now scale down to fit it.
- Heart-rate zones: the bpm range overflowed its row at 3.1x. At large
  text it may now wrap; at 1x the row is unchanged.
- MetricRow: at large text the value gets its own line but still could
  not wrap, so a value that is a phrase (the cycle "What applies to
  you" row, in German) overflowed. It wraps there now; the one-line
  layout is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

UI

Allow heart-rate zone ranges to wrap only at large text sizes and keep the bpm unit attached to its range.

  • lib/ui2/activity/zones.dart L474-481, L495-514

Let large-text MetricRow values wrap on their own line while preserving the one-line layout and its measurement behavior.

  • lib/ui2/grammar.dart L1811-1820, L1826-1832, L1881

Make the cycle-day header and caption wrap when their text and phase pill do not fit.

  • lib/ui2/screens/cycle_screen.dart L482-490, L496-499, L509-520

Scale the readiness score and band label down to fit inside the fixed-size ring at large text sizes.

  • lib/ui2/screens/readiness_detail.dart L300-316

Tests

Add a localized, multi-size screen sweep and focused cycle-card tests to catch text overflows across screens and cycle layouts.

  • test/cycle_day_row_overflow_test.dart L1-73
  • test/ui2_screen_sweep_test.dart L1-339

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Several UI widgets now wrap, ellipsize, or scale text to fit their available space. The changes affect zone ranges, metric values, cycle information, and the readiness score display.

Changes: UI text layout

Layer / File(s) Summary
Zone and metric value layout
lib/ui2/activity/zones.dart, lib/ui2/grammar.dart
Zone BPM ranges and units render together as rich text. Metric values wrap at large text sizes and ellipsize at other sizes.
Cycle summary layout
lib/ui2/screens/cycle_screen.dart
The day and optional phase pill can flow onto multiple lines. The cycle-count descriptor can wrap within its row.
Readiness score sizing
lib/ui2/screens/readiness_detail.dart
The score and band label scale down within the padded area of the ring.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: abdulsaheel

Merge Risk: Minimal · up to 40ee2

Merge Risk: ⚪ Minimal · up to 40ee2

The change fixes text overflows on several screens at large text sizes. The readiness ring text is scaled to fit and grows less than the text setting would imply, which is an acceptable tradeoff. No merge-blocking risk remains.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: a whole-screen sweep at large text and the overflow fixes it found. The raw summary shows fixes in Readiness, HR zones, Cycle, and MetricRow, which match the title's '…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Full details: Title check

Explanation

The title names the main change: a whole-screen sweep at large text and the overflow fixes it found. The raw summary shows fixes in Readiness, HR zones, Cycle, and MetricRow, which match the title's 'fix' scope. The title is specific and describes the primary intent, though it is slightly long at 69 characters.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: OpenStrap/edge
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: 825486c
  • Layers: Repository YAML
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 5a978831-a5e6-4325-8101-814cb39c2f13
Commits

Reviewing files that changed from the base of the PR and between 825486c and d816de6.

Files ignored due to path filters: 2

  • test/cycle_day_row_overflow_test.dart is excluded by !test/**
  • test/ui2_screen_sweep_test.dart is excluded by !test/**
Files selected for processing: 4

  • lib/ui2/activity/zones.dart
  • lib/ui2/grammar.dart
  • lib/ui2/screens/cycle_screen.dart
  • lib/ui2/screens/readiness_detail.dart

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="lib/ui2/activity/zones.dart" line_range="507" />
<code_context>
+            style: F.n17.copyWith(color: p.ink2),
+          ),
+          TextSpan(
+            text: ' ${l?.activityZonesBpmUnit ?? 'bpm'}',
+            style: F.cap.copyWith(color: p.ink3),
+          ),
</code_context>
<issue_to_address>
**Bpm unit separates from range**

When large text constrains the range column to a width that fits the numbers but not the numbers plus unit, the ordinary space creates a line-break opportunity, so when the range and unit do not fit the allocated width but the range does, `Text.rich` puts “bpm” on a separate line from the reading.

Use a nonbreaking space between the range and its unit.
</issue_to_address>

### Comment 2
<location path="test/cycle_day_row_overflow_test.dart" line_range="44-46" />
<code_context>
+  addTearDown(t.view.reset);
+  final app = AppState.forTesting()..repo = _Repo(median: median);
+  addTearDown(app.dispose);
+  await t.pumpWidget(ChangeNotifierProvider<AppState>.value(
+    value: app,
+    child: MediaQuery(
+      data: MediaQueryData(textScaler: TextScaler.linear(scale)),
+      child: MaterialApp(
</code_context>
<issue_to_address>
**Cycle tests never apply large text**

When the dedicated cycle tests run their 3.1× cases, `MaterialApp` installs its own `MediaQuery`, overriding the scaler wrapped around it, so both scale variants run at the default size and the long no-median caption's large-text overflow goes undetected.

Set the `MediaQuery` scaler inside `MaterialApp.builder`, as the screen sweep does.
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: test/cycle_day_row_overflow_test.dart:46


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread lib/ui2/activity/zones.dart Resolved
Comment thread test/cycle_day_row_overflow_test.dart Resolved
uvtqt and others added 5 commits November 13, 2026 19:45
… Beats, What changed

Every screen that takes preloaded data is now swept, 14 in all. The seven
added here are clean in English and German at 1x, 2x and 3.1x; each was
checked to render its content (no spinner, 8 to 55 text widgets), not an
empty shell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review on OpenStrap#713: at large text a long phase name ended in an ellipsis.
The pill wraps there now and stays one line at default sizes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review on OpenStrap#714: the ordinary space before the unit was a break point, so
at large text "bpm" could wrap onto a line of its own. A no-break space
keeps it with the number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All eight are clean; a long translation added later now fails here.

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

This branch has not been deployed

No deployments
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