Skip to content

fix(charge): show skin temperature in the reader's unit in the Charge breakdown - #2904

Open
UtkuDenizAltiok wants to merge 1 commit into
ryanbr:mainfrom
UtkuDenizAltiok:fix/charge-skin-temp-unit
Open

UtkuDenizAltiok wants to merge 1 commit into
ryanbr:mainfrom
UtkuDenizAltiok:fix/charge-skin-temp-unit

Conversation

@UtkuDenizAltiok

Copy link
Copy Markdown

What

The Charge breakdown's skin-temperature row ("What shaped it") printed the engine's Celsius deviation to everyone, even when Settings asks for Fahrenheit. The English text also had no degree sign. It happened on both platforms:

  • Apple shows the engine's valueText verbatim, which is Celsius-only by contract: +0.4 C vs baseline.
  • Android formats the typed value with a Celsius-only string: %1$s C vs baseline.

Now the row reads +0.4 °C vs baseline, or +0.8 °F vs baseline for a Fahrenheit reader. Apple's separate relative row (+0.3 °C vs your normal) follows the same rule.

How

  • The engine text is unchanged. It stays pinned byte-for-byte across Swift and Kotlin. Only the display layer changes, formatting the row from the night's raw deviation.

  • The conversion is for a difference: ×9/5 with no +32 offset, applied to the unrounded value. For example, 0.44 °C is 0.792 °F, so the row shows +0.8, not the +0.7 a rounded +0.4 would give.

  • Rounding is explicit and shared: once, half away from zero. This is the display rule RecoveryScorer.displayRounded already applies to breathing. While testing this I found two formatter differences at round-off points:

    • Foundation's locale formatter rounds a tie the other way from Java's. 0.25 printed +0.2 on Apple and +0.3 on Android.
    • Foundation prints -+0.0 for a negative zero, and the old hand-built sign on Apple's relative row printed +-0.0.

    Anything that rounds to zero now prints +0.0 on both platforms, as Kotlin's displayRounded already did.

  • Apple: ChargeBreakdownFormat.skinTempDeviationFigure and displayDriver. ChargeBreakdownSection reads the temperature preference the way other temperature read-outs do, so all three hosts are covered (Today's Charge sheet, Intelligence, Coupled).

  • Android: chargeDriverTempDeviation in TodayScreen.kt and a new today_driver_value_temp_deviation_fahrenheit string in every locale. The Italian Celsius string also gets its missing degree sign.

Verification

  • Oracle, as AGENTS.md asks: the Swift twin was compiled standalone over 21 inputs per unit (ties, both zeroes, signs, small values). Its stdout is pasted verbatim as the expected values in ChargeDriverTempDeviationTest. The same ties are pinned in ChargeBreakdownFormatTests.
  • StrandTests on macOS: 2306 tests, 0 failures. NOOPiOS simulator build passes.
  • Android (fork CI, android.yml on this head): run 42167206054 green at 2d482919 (Build debug APK and Run unit tests both success)
  • i18n_audit.py --ci upstream/main exit 0; doc_comment_lint.py clean; Tools 338 OK; parity acceptance OK.

🤖 Generated with Claude Code

… breakdown

The "What shaped it" skin-temperature row printed the engine's Celsius
deviation to everyone, with no degree sign in English ("+0.4 C vs
baseline"), even when Settings asks for Fahrenheit. Both platforms did it:
Apple shows the engine's Celsius-only valueText verbatim, Android formatted
the typed value with a Celsius-only string.

The engine text stays as it is (it is pinned byte-for-byte across Swift and
Kotlin). The display layer now formats the row from the night's raw
deviation in the reader's unit: "+0.4 °C vs baseline" or "+0.8 °F vs
baseline". A difference converts by 9/5 with no +32 offset, from the
unrounded value (0.44 °C is 0.792 °F, so +0.8, not the +0.7 a rounded +0.4
would give). Apple's separate relative row ("vs your normal") follows the
same rule.

Rounding is explicit and shared: half away from zero, once, the display rule
RecoveryScorer.displayRounded already applies to breathing. Foundation's
locale formatter rounds a tie the other way from Java's (0.25 printed +0.2
on Apple and +0.3 on Android) and prints "-+0.0" for a negative zero; the
old hand-built sign on Apple's relative row printed "+-0.0". Anything that
rounds to zero now prints +0.0 on both platforms.

Apple: ChargeBreakdownFormat.skinTempDeviationFigure / displayDriver;
ChargeBreakdownSection reads the unit preference the way other temperature
read-outs do, so all three hosts (Today sheet, Intelligence, Coupled) are
covered. Android: chargeDriverTempDeviation in TodayScreen.kt and a new
today_driver_value_temp_deviation_fahrenheit string in every locale; the
Italian Celsius string gains its missing degree sign.

Verified by oracle: the Swift twin compiled standalone over 21 inputs per
unit, its stdout pasted verbatim as the Kotlin test's expected values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UtkuDenizAltiok added a commit to UtkuDenizAltiok/noop that referenced this pull request Nov 6, 2026
DX23876 pushed a commit to DX23876/noop that referenced this pull request Nov 8, 2026
Adopted from ryanbr#2899 and ryanbr#2904 (by @UtkuDenizAltiok), merged by
hand because both edit the same block, plus the same fix for the Forge
design.

- The classic Charge breakdown (Today, Intelligence, Coupled, macOS)
  drew the scorer's "Skin temperature" driver row and then a separate
  SkinTempDeviationRow for the same deviation. The extra row now shows
  only when no driver row already reports it (ryanbr#2899).
- Both rows printed the engine's Celsius figure without a degree sign
  to everyone, Fahrenheit readers included. They now show the reader's
  unit ("+0.4 °C" / "+0.8 °F vs baseline"); a difference converts by
  9/5 with no +32 offset (ryanbr#2904). The engine text stays unchanged.
- Forge's Charge page and Today driver rows (ForgeToday.driverValue)
  always printed "°C vs usual". They now use the same figure in the
  reader's unit; the key "%@ °C vs usual" becomes "%@ vs usual" with the
  existing translations minus the hard-coded unit.
- Polish "%@ względem bazy" reads "%@ względem wartości bazowej".

The Android (Kotlin) hunks are left out and can follow separately; this
change covers the Apple apps only.

Not compiled here (no Swift toolchain in this environment).

Analysis migration required: no

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015AWc14WNvMmSF4RHP6ww4d
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