diff --git a/core/presentation/src/main/res/values-zh/strings.xml b/core/presentation/src/main/res/values-zh/strings.xml
index 8b708652..32bb2233 100644
--- a/core/presentation/src/main/res/values-zh/strings.xml
+++ b/core/presentation/src/main/res/values-zh/strings.xml
@@ -178,4 +178,36 @@
\n• xdsopl 和 Robot36 贡献者!
该应用程序不提供任何保修.
+
+ 过境匹配
+ 你的位置
+ 友台位置
+ 你
+ 友台
+ 正在计算双方共同可见窗口…
+ 请修正提示后重新查询
+ 找到 %d 个匹配 · 点击卡片展开曲线
+ 未找到共同可见窗口,调整时间或仰角后重试
+ 输入双方位置后点击查询
+ 计算中
+ 有错误
+ %d 个匹配
+ 无匹配
+ 待查询
+ 填入当前位置
+ 纬度
+ 经度
+ 网格
+ 支持 4/6/8 位 Maidenhead 网格;也可直接输入经纬度
+ 最小仰角:%d°
+ 时间范围
+ 计算中…
+ 查询匹配
+ 你:%d°
+ 友台:%d°
+ 双方轨迹
+ 查看雷达
+ 站点A
+ 站点B
+
diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml
index d476eb45..674d4fd2 100644
--- a/core/presentation/src/main/res/values/strings.xml
+++ b/core/presentation/src/main/res/values/strings.xml
@@ -214,4 +214,36 @@
The app comes with no warranty
+
+ Pass Match
+ Your Station
+ Opposite Station
+ You
+ Opposite
+ Calculating mutual visibility windows…
+ Fix the reported issues and retry
+ %d matches found · tap a card to expand
+ No mutual windows found. Adjust time or min elevation and retry
+ Enter both stations, then tap Query
+ Calculating
+ Error
+ %d matches
+ No matches
+ Idle
+ Use current
+ Lat
+ Lon
+ Grid
+ Supports 4/6/8-char Maidenhead grid; or enter lat/lon directly
+ Min elevation: %d°
+ Time range
+ Calculating…
+ Query Match
+ You: %d°
+ Opposite: %d°
+ Both tracks
+ Open Radar
+ Station A
+ Station B
+
diff --git a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/ElevationCurveChart.kt b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/ElevationCurveChart.kt
index fccf053a..7822d896 100644
--- a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/ElevationCurveChart.kt
+++ b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/ElevationCurveChart.kt
@@ -24,6 +24,7 @@ import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.ui.res.stringResource
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
@@ -40,6 +41,7 @@ import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import com.rtbishop.look4sat.core.presentation.R
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@@ -226,8 +228,8 @@ fun ElevationCurveChart(
modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 4.dp),
horizontalArrangement = Arrangement.SpaceEvenly
) {
- Text("● Station A", color = colorA, fontSize = 12.sp)
- Text("● Station B", color = colorB, fontSize = 12.sp)
+ Text(stringResource(R.string.mutual_station_a), color = colorA, fontSize = 12.sp)
+ Text(stringResource(R.string.mutual_station_b), color = colorB, fontSize = 12.sp)
}
}
}
diff --git a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt
index 7886a33f..efd774cd 100644
--- a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt
+++ b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt
@@ -90,7 +90,7 @@ fun MutualScreen(
},
topInfo = {
Text(
- text = "Pass Match",
+ text = stringResource(R.string.mutual_title),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
@@ -198,7 +198,7 @@ private fun MutualContent(
) {
if (isVertical) {
StationInputCard(
- title = "Your Station",
+ title = stringResource(R.string.mutual_station_you),
titleColor = MaterialTheme.colorScheme.primary,
lat = state.stationALat,
lon = state.stationALon,
@@ -214,7 +214,7 @@ private fun MutualContent(
currentPositionAction = onUseCurrentPosition
)
StationInputCard(
- title = "opposite station",
+ title = stringResource(R.string.mutual_station_opposite),
titleColor = MaterialTheme.colorScheme.tertiary,
lat = state.stationBLat,
lon = state.stationBLon,
@@ -234,7 +234,7 @@ private fun MutualContent(
horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
StationInputCard(
- title = "Your Station",
+ title = stringResource(R.string.mutual_station_you),
titleColor = MaterialTheme.colorScheme.primary,
lat = state.stationALat,
lon = state.stationALon,
@@ -251,7 +251,7 @@ private fun MutualContent(
modifier = Modifier.weight(1f)
)
StationInputCard(
- title = "opposite station",
+ title = stringResource(R.string.mutual_station_opposite),
titleColor = MaterialTheme.colorScheme.tertiary,
lat = state.stationBLat,
lon = state.stationBLon,
@@ -294,8 +294,8 @@ private fun MutualContent(
startTime = pass.startTime,
endTime = pass.endTime,
maxElev = maxOf(pass.maxElevationA, pass.maxElevationB, 10.0),
- labelA = "You",
- labelB = "opposite"
+ labelA = stringResource(R.string.mutual_label_you),
+ labelB = stringResource(R.string.mutual_label_opposite)
)
MutualPassCard(
pass = pass,
@@ -341,20 +341,22 @@ private fun MutualStatusChip(state: MutualUiState) {
}
}
+@Composable
private fun mutualStatusText(state: MutualUiState): String = when {
- state.isCalculating -> "Calculating mutual visibility windows..."
- state.errorMessage != null -> "Fix the reported issues and retry"
- state.mutualPasses.isNotEmpty() -> "${state.mutualPasses.size} matches found · tap a card to expand"
- state.hasSearched -> "No mutual windows found. Adjust time or min elevation and retry"
- else -> "Enter both stations, then tap Query"
+ state.isCalculating -> stringResource(R.string.mutual_status_calculating)
+ state.errorMessage != null -> stringResource(R.string.mutual_status_error)
+ state.mutualPasses.isNotEmpty() -> stringResource(R.string.mutual_status_matches, state.mutualPasses.size)
+ state.hasSearched -> stringResource(R.string.mutual_status_none)
+ else -> stringResource(R.string.mutual_status_idle)
}
+@Composable
private fun mutualStatusChipText(state: MutualUiState): String = when {
- state.isCalculating -> "Calculating"
- state.errorMessage != null -> "Error"
- state.mutualPasses.isNotEmpty() -> "${state.mutualPasses.size} matches"
- state.hasSearched -> "No matches"
- else -> "Idle"
+ state.isCalculating -> stringResource(R.string.mutual_chip_calculating)
+ state.errorMessage != null -> stringResource(R.string.mutual_chip_error)
+ state.mutualPasses.isNotEmpty() -> stringResource(R.string.mutual_chip_matches, state.mutualPasses.size)
+ state.hasSearched -> stringResource(R.string.mutual_chip_none)
+ else -> stringResource(R.string.mutual_chip_idle)
}
@Composable
@@ -393,7 +395,7 @@ private fun StationInputCard(
)
if (currentPositionAction != null) {
OutlinedButton(onClick = currentPositionAction) {
- Text("Use current", style = MaterialTheme.typography.bodySmall)
+ Text(stringResource(R.string.mutual_use_current), style = MaterialTheme.typography.bodySmall)
}
}
}
@@ -405,7 +407,7 @@ private fun StationInputCard(
OutlinedTextField(
value = lat,
onValueChange = onLatChange,
- label = { Text("Lat") },
+ label = { Text(stringResource(R.string.mutual_lat)) },
placeholder = { Text(latPlaceholder) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
singleLine = true,
@@ -414,7 +416,7 @@ private fun StationInputCard(
OutlinedTextField(
value = lon,
onValueChange = onLonChange,
- label = { Text("Lon") },
+ label = { Text(stringResource(R.string.mutual_lon)) },
placeholder = { Text(lonPlaceholder) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
singleLine = true,
@@ -425,15 +427,15 @@ private fun StationInputCard(
OutlinedTextField(
value = grid,
onValueChange = onGridChange,
- label = { Text("Grid") },
+ label = { Text(stringResource(R.string.mutual_grid)) },
placeholder = { Text(gridPlaceholder) },
- supportingText = { Text("Supports 4/6/8-char Maidenhead grid; or enter lat/lon directly") },
+ supportingText = { Text(stringResource(R.string.mutual_grid_hint)) },
singleLine = true,
modifier = Modifier.fillMaxWidth()
)
Text(
- text = "Min elevation: ${minElev.toInt()}°",
+ text = stringResource(R.string.mutual_min_elevation, minElev.toInt()),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
@@ -461,7 +463,7 @@ private fun MatchSearchCard(
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
Text(
- text = "Time range",
+ text = stringResource(R.string.mutual_time_range),
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Medium
)
@@ -492,7 +494,7 @@ private fun MatchSearchCard(
)
Spacer(Modifier.width(8.dp))
}
- Text(if (isCalculating) "Calculating..." else "Query Match")
+ Text(if (isCalculating) stringResource(R.string.mutual_calculating) else stringResource(R.string.mutual_query))
}
}
}
@@ -558,12 +560,12 @@ private fun MutualPassCard(
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
- text = "You: ${pass.maxElevationA}°",
+ text = stringResource(R.string.mutual_elevation_you, pass.maxElevationA.toInt()),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.primary
)
Text(
- text = "opposite: ${pass.maxElevationB}°",
+ text = stringResource(R.string.mutual_elevation_opposite, pass.maxElevationB.toInt()),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.tertiary
)
@@ -579,7 +581,7 @@ private fun MutualPassCard(
// Dual-station radar track (polar plot)
if (visibleTracks.isNotEmpty()) {
Text(
- text = "Both tracks",
+ text = stringResource(R.string.mutual_both_tracks),
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.onSurfaceVariant
@@ -587,8 +589,8 @@ private fun MutualPassCard(
MutualRadarView(
trackSamples = visibleTracks,
progress = dragProgress,
- labelA = "You",
- labelB = "opposite"
+ labelA = stringResource(R.string.mutual_label_you),
+ labelB = stringResource(R.string.mutual_label_opposite)
)
Spacer(Modifier.height(8.dp))
}
@@ -613,7 +615,7 @@ private fun MutualPassCard(
modifier = Modifier.height(16.dp).width(16.dp)
)
Spacer(Modifier.width(6.dp))
- Text("Open Radar")
+ Text(stringResource(R.string.mutual_open_radar))
}
}
}