fix: WASM/JS compatibility — replace JVM-only APIs with multiplatform alternatives
String.format(), toSortedMap(), and @Volatile are not available on WASM/JS targets. Replace with multiplatform-safe formatFloat() helper, entries.sortedBy(), and remove the unnecessary @Volatile annotation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+3
-2
@@ -17,6 +17,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.shahondin1624.lib.components.TestTags
|
||||
import org.shahondin1624.lib.functions.formatFloat
|
||||
import org.shahondin1624.lib.components.UiConstants
|
||||
import org.shahondin1624.model.magic.AdeptPower
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
@@ -112,7 +113,7 @@ fun AdeptPowerPanel(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = "%.1f / %.1f PP".format(totalPowerPointsUsed, powerPointBudget),
|
||||
text = "${formatFloat(totalPowerPointsUsed, 1)} / ${formatFloat(powerPointBudget, 1)} PP",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = if (totalPowerPointsUsed > powerPointBudget) MaterialTheme.colorScheme.error
|
||||
@@ -181,7 +182,7 @@ private fun AdeptPowerEntryRow(
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = "%.1f PP".format(power.powerPointCost),
|
||||
text = "${formatFloat(power.powerPointCost, 1)} PP",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
|
||||
+5
-4
@@ -18,6 +18,7 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.shahondin1624.lib.components.TestTags
|
||||
import org.shahondin1624.lib.components.UiConstants
|
||||
import org.shahondin1624.lib.functions.formatFloat
|
||||
import org.shahondin1624.model.attributes.AttributeType
|
||||
import org.shahondin1624.model.characterdata.Augmentation
|
||||
import org.shahondin1624.model.characterdata.AugmentationGrade
|
||||
@@ -139,7 +140,7 @@ fun AugmentationPanel(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = "%.2f".format(totalEssenceCost),
|
||||
text = formatFloat(totalEssenceCost, 2),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colorScheme.error
|
||||
@@ -160,7 +161,7 @@ fun AugmentationPanel(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = "%.2f / %.1f".format(currentEssence, baseEssence),
|
||||
text = "${formatFloat(currentEssence, 2)} / ${formatFloat(baseEssence, 1)}",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = if (currentEssence <= 0f) MaterialTheme.colorScheme.error
|
||||
@@ -212,7 +213,7 @@ private fun AugmentationEntryRow(
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = "%.2f".format(augmentation.essenceCost),
|
||||
text = formatFloat(augmentation.essenceCost, 2),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier.padding(horizontal = 8.dp)
|
||||
@@ -379,7 +380,7 @@ fun AugmentationEditDialog(
|
||||
// Show computed essence cost
|
||||
if (essenceCost != null) {
|
||||
Text(
|
||||
text = "Effective cost: ${"%.2f".format(essenceCost * grade.essenceMultiplier)}",
|
||||
text = "Effective cost: ${formatFloat(essenceCost * grade.essenceMultiplier, 2)}",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
||||
+1
-1
@@ -269,7 +269,7 @@ private fun AttributesSummaryCard(state: CharacterCreationState) {
|
||||
|
||||
@Composable
|
||||
private fun SkillsSummaryCard(state: CharacterCreationState) {
|
||||
val allocatedSkills = state.skillAllocations.filter { it.value > 0 }.toSortedMap()
|
||||
val allocatedSkills = state.skillAllocations.filter { it.value > 0 }.entries.sortedBy { it.key }
|
||||
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ fun SkillAllocationStep(
|
||||
|
||||
// Group skills by attribute
|
||||
val grouped = allTalents.groupBy { it.attribute }
|
||||
for ((attrType, talents) in grouped.toSortedMap(compareBy { it.name })) {
|
||||
for ((attrType, talents) in grouped.entries.sortedBy { it.key.name }) {
|
||||
Text(
|
||||
text = attrType.name,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
|
||||
@@ -8,9 +8,25 @@ import kotlin.math.roundToInt
|
||||
*
|
||||
* Examples: 5.7f -> "5.7", 6.0f -> "6.0", 0.0f -> "0.0"
|
||||
*/
|
||||
fun formatEssence(value: Float): String {
|
||||
val rounded = (value * 10).roundToInt() / 10.0
|
||||
val intPart = rounded.toInt()
|
||||
val decPart = ((rounded - intPart) * 10).roundToInt()
|
||||
return "$intPart.$decPart"
|
||||
fun formatEssence(value: Float): String = formatFloat(value, 1)
|
||||
|
||||
/**
|
||||
* Formats a float to [decimals] decimal places without platform-specific String.format.
|
||||
* Works on all KMP targets (JVM, JS, WASM, iOS).
|
||||
*
|
||||
* Examples: formatFloat(3.14159f, 2) -> "3.14", formatFloat(5.0f, 1) -> "5.0"
|
||||
*/
|
||||
fun formatFloat(value: Float, decimals: Int): String {
|
||||
val factor = pow10(decimals)
|
||||
val rounded = (value * factor).roundToInt()
|
||||
val intPart = rounded / factor.toInt()
|
||||
val decPart = kotlin.math.abs(rounded % factor.toInt())
|
||||
val sign = if (value < 0 && intPart == 0) "-" else ""
|
||||
return "$sign$intPart.${decPart.toString().padStart(decimals, '0')}"
|
||||
}
|
||||
|
||||
private fun pow10(n: Int): Float {
|
||||
var result = 1f
|
||||
repeat(n) { result *= 10f }
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import io.github.aakira.napier.Napier
|
||||
*/
|
||||
object AppLogger {
|
||||
|
||||
@Volatile
|
||||
private var initialized = false
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user