refactor: retire the brand before mantra, and keep the three records of it
Phase 0 of docs/curated-to-mantra.md, item 2. The app has been Mantra since
before this repository had a docs/ directory, and four things still said Torch,
the brand before it: the theme composable, `TorchTheme`, at 116 sites; the
user agent, `UserAgent.APP_NAME` and `CLIENT_NAME`; two error strings a user
could actually be shown ("tell X to use Torch", "finished setting up Torch");
and iOS, where `Config.xcconfig` built `PRODUCT_NAME=Torch` under the bundle id
`ac.aux.compose.Aux` and the project's product reference was still `Aux.app` --
two brands ago. All four now say Mantra.
**This is done natively, before anything is pulled from the fork, so that the
fork's theme maps onto a name that means something.** The Curated fork retired
Torch itself in d26cf6c7 (`TorchTheme` -> `CuratedTheme`, later `CurareTheme`).
The pull rewrites every fork commit into this repository's names, and until
now the only honest target for `CurareTheme` was `TorchTheme` -- the brand
before last -- which would have had every pulled screen wrapping itself in a
name the app stopped using long ago. `MantraTheme` is what the rewrite maps to
from here; docs/scripts/curated-unbrand.py's theme, `UserAgent` and iOS rules
are changed in this commit for that reason, and the comment that said "change
here if Phase 0 renames it" goes with them. Retiring Torch as part of the pull
instead -- by taking the rewritten d26cf6c7 -- was rejected because that commit
would then be a fork commit renaming something the fork never had, and because
the iOS half of the debt was never the fork's to pay.
**The user agent went last, and the reason it could go at all is written where
the next reader will look.** `CLIENT_NAME` is the `client` tag on every relay
list this app publishes, which is why it was left alone when the top bar was
fixed: it goes on the wire, so it read as a network identity question. It is
attribution and nothing derives from it, which is the difference between it
and the two `mantra/` hash tags that must never move; the comment on the
`HomeScreen` bar and the paragraph in material-design-conformance.md that both
said "still says Torch" now say that, in order, rather than describing a state
this commit ends.
**Three records keep the old name on purpose.** material-design-conformance.md:278
records a finding -- the top bar once read "Torch" while the window title read
"Mantra" -- and changing it would falsify the record. The paragraph at :654 is
rewritten rather than deleted because it was a statement of current state, and
the current state changed. `NavigationRoutingTest`'s "Introducing... Torch"
fixture is the string a stranded user actually saw, and the test is about the
stranding. Nothing else in the tree says Torch.
**iOS is unverified.** The build gates the apple targets behind `isMacOsX` and
this was built on linux; the xcconfig and pbxproj edits are the same shape the
fork's went through, and this is the first time this repository has named
itself there. Build it on a Mac before believing it.
:composeApp:compileDebugKotlinAndroid and :composeApp:compileKotlinJvm clean;
:composeApp:jvmTest 736 tests, 0 failures; :composeApp:testDebugUnitTest 403
tests, 0 failures; :composeApp:m3Audit all budgets met.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -121,7 +121,7 @@ Three gaps:
|
||||
today; the trap springs the first time an expressive component does.
|
||||
|
||||
2. **The medium and high contrast schemes are dead code.** All four are declared
|
||||
`private val`; `TorchTheme` only ever selects `darkScheme` or `lightScheme`.
|
||||
`private val`; `MantraTheme` only ever selects `darkScheme` or `lightScheme`.
|
||||
There is no plumbing to the platform's contrast setting, so the two schemes
|
||||
that would honour it are unreachable. The accessibility foundation's first
|
||||
principle is *honour individuals* — *"supporting varying preferences and
|
||||
@@ -138,7 +138,7 @@ Two entry points render outside the theme:
|
||||
under the **default** `MaterialTheme`. Its `MaterialTheme.colorScheme.error`
|
||||
and `typography.headlineSmall` are baseline M3, not this app's. It is the
|
||||
first screen a desktop user sees.
|
||||
- `Profile.kt:183` and 50 other `@Preview` bodies wrap in `TorchTheme` by hand,
|
||||
- `Profile.kt:183` and 50 other `@Preview` bodies wrap in `MantraTheme` by hand,
|
||||
which is correct, but there is no preview that exercises dark, high-contrast
|
||||
or a wide window — so nothing catches the two problems below.
|
||||
|
||||
@@ -418,7 +418,7 @@ find-and-replace.
|
||||
Keep the existing hex values for the roles already defined so nothing shifts
|
||||
visually; this phase adds, it does not restyle.
|
||||
|
||||
2. **Reach the contrast schemes.** *Built.* `TorchTheme` takes a `ThemeContrast`
|
||||
2. **Reach the contrast schemes.** *Built.* `MantraTheme` takes a `ThemeContrast`
|
||||
defaulted from a new `platformThemeContrast()` expect/actual, and the six-way
|
||||
selection table lives in common code as `appColorScheme`. The old
|
||||
`themeColorScheme` expect took four arguments and did both jobs; it splits into
|
||||
@@ -441,7 +441,7 @@ find-and-replace.
|
||||
|
||||
3. **Give the theme its other three slots.** *Built.* The expressive-vs-standard
|
||||
question was put to the product owner on 2026-09-08 and answered
|
||||
**expressive**, so `TorchTheme` calls `MaterialExpressiveTheme` with all four
|
||||
**expressive**, so `MantraTheme` calls `MaterialExpressiveTheme` with all four
|
||||
slots passed explicitly — colour, `MotionScheme.expressive()`, `MantraShapes`,
|
||||
`AuxTypography`. Explicitly, because `MaterialExpressiveTheme` would otherwise
|
||||
default them to `expressiveLightColorScheme()` and friends, which is Material's
|
||||
@@ -472,10 +472,10 @@ find-and-replace.
|
||||
`container`/`on`/`onContainer`. `CreateProfileScreen.kt:311` and `:329` then
|
||||
stop pairing them with `Color.White`/`Color.DarkGray` by eye.
|
||||
|
||||
6. **Wrap the desktop gate.** *Built.* `Main.kt` moves `TorchTheme` outside the
|
||||
6. **Wrap the desktop gate.** *Built.* `Main.kt` moves `MantraTheme` outside the
|
||||
`unlocked` branch, so `PassphraseGate` — the first screen a desktop user sees —
|
||||
stops composing under the default `MaterialTheme`. `MantraApp` keeps its own
|
||||
`TorchTheme`, so the unlocked branch is wrapped twice: android and ios enter
|
||||
`MantraTheme`, so the unlocked branch is wrapped twice: android and ios enter
|
||||
through `MantraApp` and would lose the theme entirely if it moved out, and a
|
||||
second application of the same values costs one `CompositionLocalProvider`.
|
||||
|
||||
@@ -651,8 +651,12 @@ the whole sentence is, and several of them are pluralisations —
|
||||
`(if (n == 2) "event" else "events")` — which want a real plural resource rather than a
|
||||
format argument. `m3-extract-formatted.py --remaining` lists them.
|
||||
|
||||
`UserAgent.APP_NAME` still says "Torch". It goes on the wire to relay operators, so it is
|
||||
a network identity question rather than a content one.
|
||||
`UserAgent.APP_NAME` and `CLIENT_NAME` said "Torch" until the pull described in
|
||||
[curated-to-mantra.md](./curated-to-mantra.md) retired the brand for good, in its Phase 0.
|
||||
They were left for last on purpose: `CLIENT_NAME` goes on the wire as the `client` tag on
|
||||
every relay list this app publishes, so it was a network identity question rather than a
|
||||
content one. It could move because it is attribution and nothing derives from it -- unlike
|
||||
the two `mantra/` hash tags, which are inputs to key derivation and must never move.
|
||||
|
||||
---
|
||||
|
||||
@@ -729,13 +733,13 @@ panes last because both were product decisions.
|
||||
see below.
|
||||
|
||||
2. **`Breakpoint`**, the five-value enum with `ofWidth` as a pure function so the
|
||||
thresholds are assertable without a Compose runtime. `TorchTheme` classifies
|
||||
thresholds are assertable without a Compose runtime. `MantraTheme` classifies
|
||||
once and provides `LocalBreakpoint`, so no two screens can disagree about the
|
||||
window they are both in.
|
||||
|
||||
It reads `currentWindowDpSize()` rather than `currentWindowAdaptiveInfo()`,
|
||||
because the latter also computes a `Posture` from the platform's fold state —
|
||||
on android, `WindowInfoTracker` and an activity. This call sits in `TorchTheme`,
|
||||
on android, `WindowInfoTracker` and an activity. This call sits in `MantraTheme`,
|
||||
which wraps all 51 `@Preview` bodies in the tree, and a preview context is not
|
||||
an activity.
|
||||
|
||||
@@ -950,9 +954,9 @@ reduced. And a crossfade is told from a cut by the one frame in which *both*
|
||||
states are composed.
|
||||
|
||||
**A test found a design flaw rather than a bug.** The reduced case read 54dp of
|
||||
slide at first, because the test provided `LocalReducedMotion` around `TorchTheme`
|
||||
slide at first, because the test provided `LocalReducedMotion` around `MantraTheme`
|
||||
and the theme overwrote it. The fix is not in the test: `reducedMotion` is now a
|
||||
`TorchTheme` parameter defaulted to the platform, exactly as `contrast` is,
|
||||
`MantraTheme` parameter defaulted to the platform, exactly as `contrast` is,
|
||||
because a value nothing can override is a value nothing can test — and because the
|
||||
desktop actual is a hardcoded `false` that a settings screen will need to override
|
||||
anyway.
|
||||
@@ -1017,7 +1021,7 @@ finding that out is most of what it was worth.
|
||||
High contrast is deliberately not in the annotation. Contrast is a property of
|
||||
the scheme rather than of a screen, `ColorSchemeContrastTest` measures every
|
||||
pair in all six, and there is no `@Preview` parameter for it — it needs
|
||||
`TorchTheme(contrast = …)` in the body. `ThemeGallery` covers the six once,
|
||||
`MantraTheme(contrast = …)` in the body. `ThemeGallery` covers the six once,
|
||||
over components rather than screens, with `dynamicColor = false` because an
|
||||
android 12+ preview would otherwise paint all six columns from the wallpaper.
|
||||
It is the only place the medium and high contrast schemes can be seen at all.
|
||||
@@ -1104,7 +1108,7 @@ Phases 1–5 can be worked in parallel by different people if 1 lands first;
|
||||
`ExperimentalMaterial3ExpressiveApi` opt-ins and the pinned alpha both point
|
||||
expressive, but it is a product decision with a visible outcome, and it should
|
||||
be made deliberately rather than inherited from an import.
|
||||
- **Whether dynamic colour should keep overriding the brand.** `TorchTheme` defaults
|
||||
- **Whether dynamic colour should keep overriding the brand.** `MantraTheme` defaults
|
||||
`dynamicColor = true`, and on Android 12+ that wins unconditionally — so on
|
||||
essentially every current Android device, none of the six schemes below is used
|
||||
and the app renders in whatever the user's wallpaper produced. Verified on an API
|
||||
|
||||
Reference in New Issue
Block a user