Skip to content

feat(mobile): Material 3 selection controls on Android - #2342

Merged
DoodleBears merged 13 commits into
mainfrom
claude/project-thread-m7tsnr
Oct 21, 2026
Merged

DoodleBears merged 13 commits into
mainfrom
claude/project-thread-m7tsnr

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain · project thread

Why the change

On Android the app drew its own segmented control, slider, chips and radio dots, and used an AppCompat switch, even though Material 3 has native components for all of them. DESIGN.md → Native first and the android-material skill (#2339, #2338) say to use them.

Refs: the first focused PR from the Android Material 3 audit in the project thread. Main is merged in, including #2349's native segmented controls.

Special things to note

  • Merge risk: JS only and Android only. @expo/ui 58's Jetpack Compose components already ship in the installed build, and no native inputs change. Each new *.android.tsx can be deleted on its own to revert that control.
  • Merging feat(mobile): plain sheet titles, native segmented controls and a lighter chat soft edge #2349: main added a plain Compose segmented.android.tsx. This branch keeps its version, which adds the remount fix, the large-text radio fallback and the transparent unselected container, and now takes SegmentedProps from segmented.tsx. segmented-native.test.tsx from main passes against it.
  • Fixes found on the emulator and included here:
    • The Usage row drew a rounded inner corner on its first render, because the Compose row read the option count only once. The row is now rebuilt when the options change.
    • At the largest system text, "4 weeks" and "12 weeks" wrapped mid-word and the segments ended up with uneven heights. Segment labels are now single-line. When the labels cannot fit on one row at the current text size, Segmented becomes a radio list of the same options.
    • In dark mode, unselected segments and chips read as black holes. They now use a transparent container with a visible outline, which is M3's default.
  • Verification:
    • pnpm lint, mobile and root tsc, oxfmt and vitest apps/mobile/test (119 files passed, 7 skipped), including material-controls-android.test.tsx and segmented-native.test.tsx.
    • Same checklist on two devices, light and dark, default and largest (2.0) text, dev client built from main 55c8848 plus this PR and fix(mobile): Android Back closes in-screen surfaces first #2343. Everything passed on both:
      • Android 16 emulator (API 36, gesture navigation).
      • Physical Xiaomi phone (Android 16 / HyperOS 3, arm64, Chinese UI).
    • What was checked:
      • Usage segments: only the outer ends are rounded, and the unselected segments are transparent with an outline in both themes. At 2.0 they fall back to a radio list (Today / 7 days / 4 weeks / 12 weeks), one per line, with nothing cut off.
      • Activity filter sheet: radios and the Unread only switch work, and nothing is cut off at 2.0.
      • Chat background Type, Preview and Fill/Fit rows plus the slider (60→90% on the emulator, 60→88% on the phone).
      • Computer look chips and routine cadence and day chips: outlined with a transparent container, and the selected state is correct.
  • CI test plan: affected (mobile only).

Change outline

  • On Android:
    • Segmented uses Compose SingleChoiceSegmentedButtonRow, with a radio-list fallback at large text.
    • PercentageSlider uses Compose Slider.
    • Chip uses FilterChip.
    • The Activity options sheet uses a leading Compose RadioButton through RadioMark.
    • Unread only uses Toggle, which is Compose Switch on Android.
  • DESIGN.md: the primitives list and the Activity options rule name the Android components and the fallback.

Physical phone (Xiaomi, Android 16; status bar and computer name redacted). All 16 captures are in .github/pr-screenshots/2342-android-material/phone/.

Usage, light Usage, dark Usage, largest text Activity filter, dark
2342-android-material/phone/usage-light.png 2342-android-material/phone/usage-dark.png 2342-android-material/phone/usage-font200-light.png 2342-android-material/phone/activity-filter-dark.png
Background slider, dark Look chips, dark Routine chips, light Activity filter, largest text
2342-android-material/phone/bg-slider-dragged-dark.png 2342-android-material/phone/look-chips-dark.png 2342-android-material/phone/routine-chips-light.png 2342-android-material/phone/activity-filter-font200-light.png

Android 16 emulator:

Screen Light Dark
Usage 2342-android-material/usage-light.png 2342-android-material/usage-dark.png
Activity filter 2342-android-material/activity-filter-light.png 2342-android-material/activity-filter-dark.png
Unread only (on / off) 2342-android-material/activity-unread-on-light.png 2342-android-material/activity-unread-off-dark.png
Chat background 2342-android-material/bg-top-light.png 2342-android-material/bg-top-dark.png
Background slider, 90% 2342-android-material/bg-slider-dragged-light.png 2342-android-material/bg-slider-dragged-dark.png
Computer look chips 2342-android-material/look-chips-light.png 2342-android-material/look-chips-dark.png
Routine chips 2342-android-material/routine-chips-light.png 2342-android-material/routine-chips-dark.png

https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T


Generated by Claude Code

Segmented, PercentageSlider and Chip gain Android variants built on
@expo/ui Jetpack Compose (segmented buttons, Slider, FilterChip). The
Activity options sheet uses a Compose RadioButton through a new RadioMark
primitive, and its unread-only switch moves to the Toggle primitive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 23 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 479676a4-18e4-40d2-aa78-5b3e6852764f
📥 Commits

Reviewing files that changed from the base of the PR and between a204016 and 15aa893.

⛔ Files ignored due to path filters: 32
  • .github/pr-screenshots/2342-android-material/activity-filter-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-filter-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-filter-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-unread-off-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-unread-on-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-slider-dragged-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-slider-dragged-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-top-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-top-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/look-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/look-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/activity-filter-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/activity-filter-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/activity-filter-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/activity-unread-off-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/activity-unread-on-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/bg-slider-dragged-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/bg-slider-dragged-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/bg-top-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/bg-top-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/look-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/look-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/routine-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/routine-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/usage-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/usage-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/phone/usage-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/routine-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/routine-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-light.png is excluded by !**/*.png
📒 Files selected for processing: 9
  • apps/mobile/DESIGN.md
  • apps/mobile/src/ui/primitives/chip.android.tsx
  • apps/mobile/src/ui/primitives/percentage-slider.android.tsx
  • apps/mobile/src/ui/primitives/radio-mark.android.tsx
  • apps/mobile/src/ui/primitives/radio-mark.tsx
  • apps/mobile/src/ui/primitives/segmented.android.tsx
  • apps/mobile/src/ui/shell/activity-filters.tsx
  • apps/mobile/test/material-controls-android.test.tsx
  • changes/2342-android-material-controls.md
📝 Walkthrough

This change adds Android Material 3 primitives for chips, sliders, and radio marks. Segmented controls now switch to a radio list when labels do not fit. Activity filters use shared radio and toggle controls.

Changes: Android Material controls

Layer / File(s) Summary
Add native Material controls
apps/mobile/src/ui/primitives/chip.android.tsx, apps/mobile/src/ui/primitives/percentage-slider.android.tsx, apps/mobile/src/ui/primitives/radio-mark.tsx, apps/mobile/src/ui/primitives/radio-mark.android.tsx, apps/mobile/test/material-controls-android.test.tsx, apps/mobile/DESIGN.md, changes/2342-android-material-controls.md
Added themed Android chip and slider components and shared radio-mark components. The slider supports accessibility adjustments in five-point steps. Tests cover slider adjustments and decorative radio rendering. The design inventory and changelog describe the controls.
Render segmented options responsively
apps/mobile/src/ui/primitives/segmented.android.tsx, apps/mobile/test/material-controls-android.test.tsx
Segmented controls render as a Compose row when labels fit. When they do not fit, the control renders a radio list. Tests cover selection, option changes, and fallback at increased font scale.
Use shared controls in Activity filters
apps/mobile/src/ui/shell/activity-filters.tsx, apps/mobile/DESIGN.md
Activity option indicators now use RadioMark on non-iOS platforms. The unread-only filter now uses Toggle with a label and raised styling; its filter update behavior remains unchanged.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to ff99f

No demonstrated issue with the new Android controls currently blocks merging.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 7 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check Warning The description covers the change purpose, issue reference, merge risk, verification commands, CI plan, change outline, Android runtime checks, and screenshot paths. It does not satisfy the required E… Add the complete iOS and Android acceptance matrix for default, intermediate, and maximum system font sizes in light and dark modes. Record native interactions and matching screenshots for each case. List every blocked or unrun case separat…
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title is concise and clearly identifies the main change: adding Material 3 selection controls on Android.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 7 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Full details: Description check

Explanation

The description covers the change purpose, issue reference, merge risk, verification commands, CI plan, change outline, Android runtime checks, and screenshot paths. It does not satisfy the required Expo/React Native acceptance matrix because it omits iOS results, intermediate font-size results, explicit light/dark coverage for every required font-size case, and a separate list of blocked or unrun cases. The screenshots are referenced by file paths rather than embedded GitHub-rendered images.

Resolution

Add the complete iOS and Android acceptance matrix for default, intermediate, and maximum system font sizes in light and dark modes. Record native interactions and matching screenshots for each case. List every blocked or unrun case separately. Embed sanitized before/after screenshots in the description, or document the concrete capture blocker and runnable review path.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • 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

Comment @coderabbitai help to get the list of available commands.

@DoodleBears DoodleBears self-assigned this Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
Compose reads each SegmentedButton's position from its parent once, so a
row that grows from two to four options (Usage, once longer periods are
supported) kept the two-item shapes: the selected middle segment drew a
rounded end. Key the row on its option values.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
claude and others added 2 commits October 19, 2026 20:39
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
Captured on an Android 16 x86_64 emulator with gesture navigation and a
debug dev client built from main plus #2342 and #2343. Light and dark at the default font, plus the largest font (2.0) for Usage and the Activity filter.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DoodleBears added a commit that referenced this pull request Oct 19, 2026
Captured on an Android 16 x86_64 emulator with gesture navigation and a
debug dev client built from main plus #2342 and #2343. Before/after pairs for Back on the attach tray, full client and drawer, and held back swipes.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-m7tsnr

# Conflicts:
#	apps/mobile/DESIGN.md
#	apps/mobile/src/ui/shell/activity-filters.tsx
…parent container

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
DoodleBears pushed a commit that referenced this pull request Oct 19, 2026
…uses the list shape

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T
Recaptured on an Android 16 x86_64 emulator with gesture navigation and a
fresh debug dev client built from main 55c8848 plus #2342 and #2343. Light and dark at the default font, plus the radio-list fallback at the largest font (2.0).
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DoodleBears added a commit that referenced this pull request Oct 19, 2026
Recaptured on an Android 16 x86_64 emulator with gesture navigation and a
fresh debug dev client built from main 55c8848 plus #2342 and #2343. Back on the attach tray, full client and drawer; the predictive-swipe frames are dropped with the claim.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-m7tsnr

# Conflicts:
#	apps/mobile/DESIGN.md
#	apps/mobile/src/ui/primitives/segmented.android.tsx
@DoodleBears
DoodleBears marked this pull request as ready for review October 19, 2026 23:24

@coderabbitai coderabbitai 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.

🔇 Additional comments: 10
apps/mobile/src/ui/primitives/radio-mark.tsx: 1

1-32: LGTM!

apps/mobile/src/ui/primitives/radio-mark.android.tsx: 1

1-18: LGTM!

apps/mobile/src/ui/primitives/chip.android.tsx: 1

1-39: LGTM!

apps/mobile/src/ui/primitives/percentage-slider.android.tsx: 1

1-55: LGTM!

apps/mobile/test/material-controls-android.test.tsx: 1

1-195: LGTM!

apps/mobile/DESIGN.md: 1

47-47: LGTM!

Also applies to: 288-288

changes/2342-android-material-controls.md: 1

1-11: LGTM!

apps/mobile/src/ui/primitives/segmented.android.tsx: 2

48-85: LGTM!

Also applies to: 87-117


40-47: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Measure the container width, not the window width.

segmentsFit receives useWindowDimensions().width and subtracts a fixed space.x5 * 2 margin. The real space for a Segmented is its parent's width. A drawer page, a SheetStack page or a padded settings group can have more than space.x5 of horizontal inset. In that case the estimate says the labels fit, but they do not. The row then renders, and ComposeText maxLines={1} softWrap={false} clips the labels. DESIGN.md Line 288 says this must never happen.

labelWidth uses 0.5 em per Latin character. That value is close to the Roboto average, so wide labels have little error margin. A container measurement removes the inset error, which is the larger one.

Read the width from onLayout on the outer View. Fall back to the window width until the first layout arrives.

♻️ Proposed change
-  const { width, fontScale } = useWindowDimensions();
+  const window = useWindowDimensions();
+  const [measured, setMeasured] = useState<number | undefined>();
+  const width = measured ?? window.width - space.x5 * 2;
+  const fontScale = window.fontScale;

Change segmentsFit so that it compares against width directly, without subtracting space.x5 * 2. Add onLayout={(e) => setMeasured(e.nativeEvent.layout.width)} to the outer View in both branches.

apps/mobile/src/ui/shell/activity-filters.tsx: 1

2-12: LGTM!

Also applies to: 70-70, 205-209


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 37c8ec7f-39df-484c-9a37-e2d16d54c0a0
📥 Commits

Reviewing files that changed from the base of the PR and between d03e2cb and ff99f81.

⛔ Files ignored due to path filters: 16
  • .github/pr-screenshots/2342-android-material/activity-filter-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-filter-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-filter-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-unread-off-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/activity-unread-on-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-slider-dragged-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-slider-dragged-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-top-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/bg-top-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/look-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/look-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/routine-chips-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/routine-chips-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-font200-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2342-android-material/usage-light.png is excluded by !**/*.png
📒 Files selected for processing: 9
  • apps/mobile/DESIGN.md
  • apps/mobile/src/ui/primitives/chip.android.tsx
  • apps/mobile/src/ui/primitives/percentage-slider.android.tsx
  • apps/mobile/src/ui/primitives/radio-mark.android.tsx
  • apps/mobile/src/ui/primitives/radio-mark.tsx
  • apps/mobile/src/ui/primitives/segmented.android.tsx
  • apps/mobile/src/ui/shell/activity-filters.tsx
  • apps/mobile/test/material-controls-android.test.tsx
  • changes/2342-android-material-controls.md

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

Captured on a Xiaomi phone (Android 16, HyperOS 3, arm64, gesture
navigation) running a debug dev client of main 55c8848 plus #2342 and
#2343, in the zh-CN locale. Light and dark, plus the radio-list fallback at font scale 2.0. Status bar and computer names are
redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
DoodleBears added a commit that referenced this pull request Oct 20, 2026
Captured on a Xiaomi phone (Android 16, HyperOS 3, arm64, gesture
navigation) running a debug dev client of main 55c8848 plus #2342 and
#2343, in the zh-CN locale. 2c shows Back leaving the full client although the WebView had a history entry. Status bar and computer names are
redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@DoodleBears
DoodleBears merged commit 139c3fe into main Oct 21, 2026
11 checks passed
DoodleBears added a commit that referenced this pull request Oct 21, 2026
* feat(mobile): Android predictive back and Back for in-screen surfaces

Turn on android.predictiveBackGestureEnabled. Back closes the composer's
attach tray through Expo Router's usePreventRemove, and the full client
steps back through its web history before leaving; the floating exit
still leaves at once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* chore(mobile): name the #2343 change fragment

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* docs(mobile): add Android emulator screenshots for #2343

Captured on an Android 16 x86_64 emulator with gesture navigation and a
debug dev client built from main plus #2342 and #2343. Before/after pairs for Back on the attach tray, full client and drawer, and held back swipes.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(mobile): recapture Android emulator screenshots for #2343

Recaptured on an Android 16 x86_64 emulator with gesture navigation and a
fresh debug dev client built from main 55c8848 plus #2342 and #2343. Back on the attach tray, full client and drawer; the predictive-swipe frames are dropped with the claim.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(mobile): add physical-phone screenshots for #2343

Captured on a Xiaomi phone (Android 16, HyperOS 3, arm64, gesture
navigation) running a debug dev client of main 55c8848 plus #2342 and
#2343, in the zh-CN locale. 2c shows Back leaving the full client although the WebView had a history entry. Status bar and computer names are
redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
DoodleBears pushed a commit that referenced this pull request Oct 21, 2026
The radio-list fallback for segmented rows from #2342 now uses the
segmented-list corners and gap from this PR.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QbudM552v4qrLMzopz7j7k
DoodleBears added a commit that referenced this pull request Oct 21, 2026
)

* feat(mobile): use Material 3 selection controls on Android

Segmented, PercentageSlider and Chip gain Android variants built on
@expo/ui Jetpack Compose (segmented buttons, Slider, FilterChip). The
Activity options sheet uses a Compose RadioButton through a new RadioMark
primitive, and its unread-only switch moves to the Toggle primitive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* chore(mobile): add #2342 change fragment and drop prohibited comments

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* fix(mobile): rebuild Android segmented row when its options change

Compose reads each SegmentedButton's position from its parent once, so a
row that grows from two to four options (Usage, once longer periods are
supported) kept the two-item shapes: the selected middle segment drew a
rounded end. Key the row on its option values.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* feat(mobile): use Material 3 segmented lists for Android grouped rows

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* chore(mobile): add #2348 change fragment

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* fix(mobile): fall back to a radio list when Android segments cannot fit

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* docs(mobile): add Android emulator screenshots for #2342

Captured on an Android 16 x86_64 emulator with gesture navigation and a
debug dev client built from main plus #2342 and #2343. Light and dark at the default font, plus the largest font (2.0) for Usage and the Activity filter.
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(mobile): outline unselected Android segments and chips on a transparent container

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* fix(mobile): keep segmentCorners in a pure design module so the root typecheck stays on Node timers

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJ8gcMTgoRjSRBNFswZT9T

* docs(mobile): recapture Android emulator screenshots for #2342

Recaptured on an Android 16 x86_64 emulator with gesture navigation and a
fresh debug dev client built from main 55c8848 plus #2342 and #2343. Light and dark at the default font, plus the radio-list fallback at the largest font (2.0).
Computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(mobile): add physical-phone screenshots for #2348

Captured on a Xiaomi phone (Android 16, HyperOS 3, arm64, gesture navigation,
zh-CN) running an arm64 debug dev client of main 48f35fb with this branch's
JavaScript, in light, dark and font scale 2.0. Settings groups and the Activity filter sheet: gaps between rows, large outer and small inner corners.
Status bar and computer names are redacted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
@DoodleBears
DoodleBears deleted the claude/project-thread-m7tsnr branch October 28, 2026 04:24
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.

2 participants