diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties index fb65f3b3ff..88b7323475 100644 --- a/build-logic/gradle.properties +++ b/build-logic/gradle.properties @@ -25,8 +25,7 @@ org.gradle.jvmargs=-Xmx2g -XX:+UseParallelGC -Dfile.encoding=UTF-8 org.gradle.parallel=true org.gradle.caching=true org.gradle.configuration-cache=true -# Kept in sync with the root gradle.properties -- see its comment for why (wasmJs web target, -# feat/web-wasmjs-target). +# Kept in sync with the root gradle.properties -- see its comment for why. org.gradle.isolated-projects=false org.gradle.configureondemand=false diff --git a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/DateFormatter.wasmJs.kt b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/DateFormatter.wasmJs.kt index 60f8260186..388e5a7470 100644 --- a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/DateFormatter.wasmJs.kt +++ b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/DateFormatter.wasmJs.kt @@ -20,12 +20,7 @@ package org.meshtastic.core.common.util import kotlin.math.abs -/** - * `Intl.DateTimeFormat`'s `dateStyle`/`timeStyle` map directly onto the JVM desktop actual's `FormatStyle.SHORT` / - * `FormatStyle.MEDIUM` (`"short"`/`"medium"` respectively), so the per-function style mapping here mirrors - * `JvmPlatformUtils.kt`'s `DateFormatter` object function-for-function rather than Android's more elaborate - * `DateUtils`-based one. - */ +// Mirrors JvmPlatformUtils.kt's DateFormatter (short/medium styles), not Android's DateUtils-based one. actual object DateFormatter { actual fun formatRelativeTime(timestampMillis: Long): String { diff --git a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/JsIntlApi.kt b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/JsIntlApi.kt index ca161f0363..0f09d98ce5 100644 --- a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/JsIntlApi.kt +++ b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/JsIntlApi.kt @@ -19,16 +19,7 @@ package org.meshtastic.core.common.util -/** - * Raw `Intl`/browser JS interop, isolated to this one file so nothing else in `wasmJsMain` needs to touch `external` - * declarations or `js()` snippets directly. Everything above this layer (`DateFormatter`, `DecimalFormatting`, - * `LocalizedUnitFormatting`, `MeasurementSystem` actuals) talks only to the small Kotlin-shaped API declared here -- - * the same "isolate raw JS interop to one file" discipline `core:ble`'s `WebBluetoothApi.kt` applies to Web Bluetooth. - * - * There is no ICU on this platform; every formatter here is backed by the browser's own `Intl` implementation - * (https://tc39.es/ecma402/), which is CLDR-driven the same way Android's `android.icu` is, just with a coarser options - * surface. - */ +// Raw Intl/browser JS interop, isolated to this one file (mirrors core:ble's WebBluetoothApi.kt). internal external interface JsNumberFormat : JsAny { fun format(value: Double): String } @@ -44,9 +35,7 @@ internal external interface JsRelativeTimeFormat : JsAny { /** `navigator.language`, a BCP-47 tag like `"en-US"`, or `""` when unavailable. */ internal fun browserLanguage(): String = js("(navigator.language || '')") -// `locale || undefined` lets an empty string (see [browserLanguage]) fall through to Intl's own default-locale -// resolution instead of throwing on an invalid empty BCP-47 tag. - +// `locale || undefined` falls through to Intl's default-locale resolution for an empty tag. private fun newNumberFormat(locale: String, options: JsAny): JsNumberFormat = js("new Intl.NumberFormat(locale || undefined, options)") @@ -56,8 +45,7 @@ private fun newDateTimeFormat(locale: String, options: JsAny): JsDateTimeFormat private fun newRelativeTimeFormat(locale: String, options: JsAny): JsRelativeTimeFormat = js("new Intl.RelativeTimeFormat(locale || undefined, options)") -// `roundingMode` (ES2023) is simply ignored by engines that predate it -- an unrecognized key in an Intl options -// object is never an error -- so it is always safe to request half-up rounding here. +// roundingMode (ES2023) is ignored, not an error, on engines that predate it. private fun decimalOptions(fractionDigits: Int): JsAny = js("({ minimumFractionDigits: fractionDigits, maximumFractionDigits: fractionDigits, roundingMode: 'halfExpand' })") @@ -99,9 +87,6 @@ internal fun timeOnlyFormatter(locale: String, style: String): JsDateTimeFormat internal fun dateTimeFormatter(locale: String, dateStyle: String, timeStyle: String): JsDateTimeFormat = newDateTimeFormat(locale, dateTimeStyleOptions(dateStyle, timeStyle)) -/** - * An `Intl.RelativeTimeFormat` with `numeric: 'auto'`, so small deltas render as "now"/"yesterday" where the CLDR data - * for [locale] has an idiomatic word for them, rather than always spelling out a count. - */ +/** `numeric: 'auto'` so small deltas render as "now"/"yesterday" where CLDR has a word for them. */ internal fun relativeTimeFormatter(locale: String): JsRelativeTimeFormat = newRelativeTimeFormat(locale, relativeTimeOptions()) diff --git a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/MeasurementSystem.wasmJs.kt b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/MeasurementSystem.wasmJs.kt index 49f4b25d32..b4d8ee6ec8 100644 --- a/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/MeasurementSystem.wasmJs.kt +++ b/core/common/src/wasmJsMain/kotlin/org/meshtastic/core/common/util/MeasurementSystem.wasmJs.kt @@ -16,16 +16,11 @@ */ package org.meshtastic.core.common.util -// There is no browser API for a measurement-system *override* the way Android 14+'s regional preferences expose -// one, so honoring MEASUREMENT_SYSTEM_EXTENSION (see MeasurementSystem.kt) is not possible here -- this is an -// accepted, honest platform gap, not an oversight. Region-based inference via the module's own -// measurementSystemForRegion is the best signal available, the same fallback the JVM desktop actual uses below -// Android P. +// No browser API for a measurement-system override (unlike Android 14+); region-based inference is the +// best available signal, same fallback the JVM actual uses below Android P. actual fun getSystemMeasurementSystem(): MeasurementSystem = measurementSystemForRegion(currentRegionCode()) -// Likewise, there is no browser API for the OS regional-preferences temperature unit. CLDR's unitPreferenceData -// region list is small and static, so it is reused verbatim from the JVM actual rather than treated as -// JVM-specific logic. +// No browser API for this either; CLDR's region list is reused verbatim from the JVM actual. actual fun getSystemTemperatureUnit(): TemperatureUnit = when (currentRegionCode()) { "US", "BS", @@ -49,12 +44,7 @@ actual fun currentLocaleQualifier(): String { private data class ParsedLocale(val language: String, val region: String) -/** - * Parses `navigator.language` (a BCP-47 tag like `"en-US"`, or `"zh-Hans-CN"`) into a language and region, by hand - * rather than via the `Intl.Locale` API's `.maximize()` -- that would infer a region for a language-only tag (an - * ICU-quality nicety), but a plain split is enough to answer these three functions honestly, and keeps this file free - * of another `js()` surface. - */ +/** Parses `navigator.language` (e.g. `"en-US"`) into language + region by hand, no `Intl.Locale`. */ private fun parsedBrowserLocale(): ParsedLocale { val tag = browserLanguage() if (tag.isBlank()) return ParsedLocale(DEFAULT_LANGUAGE, "") diff --git a/gradle.properties b/gradle.properties index 50b0848bd7..9d436149c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,13 +20,8 @@ ksp.project.isolation.enabled=true # --- Gradle --- org.gradle.caching=true org.gradle.configuration-cache=true -# Disabled for the wasmJs web target (feat/web-wasmjs-target): registering a second Gradle -# project's wasmJs() target under Isolated Projects trips a violation inside Kotlin Gradle -# Plugin's own cross-project IncrementalModuleInfoBuildService -- confirmed via a real build, -# not fixable per-module, and unrelated to wasmJs's browser()/npm tooling (a separate, -# also-confirmed IP incompatibility). JetBrains' own docs say JS/Wasm + Isolated Projects isn't -# supported yet. Re-enable once upstream closes that gap, if reinstating IP's build-speed/IDE-sync -# benefit outweighs carrying wasmJs as a target by then. +# Disabled for the wasmJs web target: multiple projects registering wasmJs() trips a KGP-internal +# Isolated Projects violation (IncrementalModuleInfoBuildService), not fixable per-module. org.gradle.isolated-projects=false org.gradle.jvmargs=-Xmx8g -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:ReservedCodeCacheSize=512m -XX:MaxMetaspaceSize=2g -Xss2m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Djava.awt.headless=true -Dapple.awt.UIElement=true org.gradle.parallel=true