Repository navigation
Android: let Today choose ring gauges or the liquid vessels - #2320
Merged
Merged
Conversation
ryanbr
force-pushed
the
feat/today-gauge-style-toggle
branch
from
September 18, 2026 10:39
4af9b60 to
081c1e0
Compare
#2311 swapped Today's hero gauges from liquid vessels to GlowRing arcs. The rings are the better default and stay the default, but the vessels were a look people chose NOOP for, so keep them available instead of deleting them outright. Adds noop.todayRingGauges, default true, with a toggle beside "Reduce motion in NOOP" in Settings. It is deliberately NOT Apple's noop.liquidTodayEnabled: that key picks between two whole Today SCREENS there, while this picks a gauge inside the single Android one. Sharing one key would bind two unrelated meanings together and make a later divergence on either platform quietly wrong. Three gauge sites branch: the hero, the 26dp vital row and the 30dp card row. Two things the vessel rendering needs that the ring does not, both restored rather than left at their defaults: - onTap. The vessel's animated render owns a clickable that CONSUMES the touch, so a clickable parent never sees a tap landing on it (#1995). That is why #2311 could move the handlers up to HeroRingColumn.onRingTap and drop the forwarding. With the vessel selectable again the forwarding comes back, for that rendering only. The two small sites pass animated = false, which attaches no clickable, so they need none. - The empty-hero cost gate. The vessels ran static until the row had a real score, so a brand-new user's launch churn was not fighting four live canvases (Android's equivalent of the iOS dataLoaded gate on HeroScoreCell). Reduce Motion would have masked its absence, so this would only have shown up on a fresh install with motion on. GlowRing needs no equivalent: it springs once to its target and then sits still. Strings added in all 8 Android locales. Tests pin the default, since an install that has never opened Settings has to get rings, and a pref defaulting the other way would silently undo a shipped change for everyone who upgrades.
ryanbr
force-pushed
the
feat/today-gauge-style-toggle
branch
from
September 18, 2026 11:48
081c1e0 to
6262c57
Compare
6 of 12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #2311, which swapped Today's hero gauges from liquid vessels to GlowRing arcs.
The rings are the better default and stay the default. But @andigandhi asked on #2311 whether the vessels could be kept as a choice, and that is a fair ask: the liquid look was something people picked NOOP for. This keeps both, with the new look as what everyone gets unless they say otherwise.
The preference
noop.todayRingGauges, defaulttrue, toggled beside "Reduce motion in NOOP" in Settings, in the ordinary display section rather than an experimental one, since neither option is a prototype.It is deliberately not Apple's
noop.liquidTodayEnabled. That key picks between two whole Today SCREENS on iOS (LiquidTodayViewvsTodayView); this picks a gauge inside the single Android one. Sharing one key would bind two unrelated meanings together and make a later divergence on either platform quietly wrong. I said as much on #2311 and the code comment records it, so the next person to look does not "unify" them.What branches
Three gauge sites: the hero, the 26dp vital row, and the 30dp card row. Both renderings take the same bindings (same fraction, same value, same value-sampled tint), so whichever is on agrees with every other surface showing the metric.
Two things the vessel needs that the ring does not, and both had to be restored rather than left at their defaults:
onTap. The vessel's animated render owns aclickablethat CONSUMES the touch, so a clickable parent never sees a tap landing on it. That was #1995, and it is why #2311 could move the handlers up toHeroRingColumn.onRingTapand drop the forwarding entirely. With the vessel selectable again the forwarding comes back, for that rendering only. The two small sites passanimated = false, which attaches no clickable, so a tap reaches the parent by itself and they need nothing.The empty-hero cost gate. The vessels ran static until the row had a real score, so a brand-new user's launch churn was not fighting four live canvases: Android's equivalent of the iOS
dataLoadedgate onHeroScoreCell. #2311 removed that line along with the vessels, and my first pass here let it fall back toanimated = true. Reduce Motion poses the vessels still regardless, so the miss would only have surfaced on a fresh install with motion ON, which is the worst moment to find it.GlowRingneeds no equivalent: it springs once to its target and then sits still.Strings
Two, added to all 8 Android locales, translated rather than English echoes. Keys minted with the standard
l10n_<screen>_<slug>_<sha1[:8]>algorithm.Verification
compileFullDebugKotlinclean (the two warnings inTodayScreen.ktare pre-existing and in untouched regions).--no-build-cache --rerun-tasks: 733 classes, 6259 tests, 0 failures, XML mtime checked against the clock. Main's baseline is 732/6256, so the delta is exactly the one new class and its three tests.i18n_audit.py --ci origin/main --platform android: green. No new hardcoded literals, no new English-only translations, no new locale gaps.doc_comment_lint.py: clean.Three tests pin the preference. The load-bearing one is the absent-key case: an install that has never opened Settings has to get rings, because a pref defaulting the other way would silently undo a shipped change for everyone who upgrades, and reading a key nobody has written is the state most installs are in.
Not covered by the suite: the vessel rendering itself is a Compose canvas, so the visual result and the restored tap behaviour want a look on a device before this lands.