From f789a15338aa2132a0f045b9bdb51202eb7c4a72 Mon Sep 17 00:00:00 2001 From: QIU Date: Wed, 5 Aug 2026 08:50:01 +0000 Subject: [PATCH] fix(status): AMSAT page load failure, refresh spinner, retry button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - P0: fetchStatus() now runs on Dispatchers.IO - the previous synchronous URLConnection on the main thread threw NetworkOnMainThreadException and showed "load failed" on every open - P1: refresh button rotates a vector icon (ic_refresh) instead of the "↻" text glyph, whose off-center font metrics made the spinner orbit around a shifted pivot - P2: error state gains a Retry button (4 locales); amsat_refresh string added (5 locales) - versionCode 456 (bump for reinstalling over 455), versionName stays 4.5.5 --- .../core/data/repository/AmSatRepository.kt | 8 +++--- .../src/main/res/values-id/strings.xml | 2 ++ .../src/main/res/values-in/strings.xml | 2 ++ .../src/main/res/values-tr/strings.xml | 2 ++ .../src/main/res/values-zh/strings.xml | 2 ++ .../src/main/res/values/strings.xml | 2 ++ .../feature/status/SatStatusScreen.kt | 25 ++++++++++++++----- .../src/main/res/drawable/ic_refresh.xml | 12 +++++++++ gradle/libs.versions.toml | 2 +- 9 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 feature/status/src/main/res/drawable/ic_refresh.xml diff --git a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/AmSatRepository.kt b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/AmSatRepository.kt index 3b92bdbb..2686c87b 100644 --- a/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/AmSatRepository.kt +++ b/core/data/src/main/java/com/rtbishop/look4sat/core/data/repository/AmSatRepository.kt @@ -8,20 +8,22 @@ import com.rtbishop.look4sat.core.domain.model.SatSlot import com.rtbishop.look4sat.core.domain.model.SatStatus import com.rtbishop.look4sat.core.domain.model.SatStatusPage import com.rtbishop.look4sat.core.domain.repository.IAmSatRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import java.util.Calendar import java.util.TimeZone /** AMSAT status repository: official API v1 -> SatStatusPage (replaces the HTML parser). */ class AmSatRepository(private val apiClient: AmSatApiClient) : IAmSatRepository { - override suspend fun fetchStatus(): SatStatusPage? { + override suspend fun fetchStatus(): SatStatusPage? = withContext(Dispatchers.IO) { val nowSec = System.currentTimeMillis() / 1000 val names = apiClient.fetchCatalog() val reports = apiClient.fetchAllReports(hours = 168) - if (names.isEmpty() && reports.isEmpty()) return null + if (names.isEmpty() && reports.isEmpty()) return@withContext null val statuses = buildStatuses(names, reports, nowSec) val reportMap = reports.associate { it.id to toSatReport(it) } - return SatStatusPage(System.currentTimeMillis(), statuses, reportMap) + SatStatusPage(System.currentTimeMillis(), statuses, reportMap) } /** Build one SatStatus (6 days x 12 slots) per catalog satellite, slotting reports by age. */ diff --git a/core/presentation/src/main/res/values-id/strings.xml b/core/presentation/src/main/res/values-id/strings.xml index 93acfc05..e7a1ef22 100644 --- a/core/presentation/src/main/res/values-id/strings.xml +++ b/core/presentation/src/main/res/values-id/strings.xml @@ -46,6 +46,8 @@ Log AMSAT Status Satelit AMSAT + Segarkan + Coba lagi Diperbarui: Aktif TLM/beacon diff --git a/core/presentation/src/main/res/values-in/strings.xml b/core/presentation/src/main/res/values-in/strings.xml index bedaa6c5..f5dc4c16 100644 --- a/core/presentation/src/main/res/values-in/strings.xml +++ b/core/presentation/src/main/res/values-in/strings.xml @@ -46,6 +46,8 @@ Log AMSAT Status Satelit AMSAT + Segarkan + Coba lagi Diperbarui: Aktif TLM/beacon diff --git a/core/presentation/src/main/res/values-tr/strings.xml b/core/presentation/src/main/res/values-tr/strings.xml index 93aa4127..1140df02 100644 --- a/core/presentation/src/main/res/values-tr/strings.xml +++ b/core/presentation/src/main/res/values-tr/strings.xml @@ -47,6 +47,8 @@ Günlük AMSAT AMSAT Uydu Durumu + Yenile + Tekrar dene Güncellendi: Aktif TLM/işaret diff --git a/core/presentation/src/main/res/values-zh/strings.xml b/core/presentation/src/main/res/values-zh/strings.xml index 5a19f412..82d4b412 100644 --- a/core/presentation/src/main/res/values-zh/strings.xml +++ b/core/presentation/src/main/res/values-zh/strings.xml @@ -48,6 +48,8 @@ 日志 AMSAT AMSAT 卫星状态 + 刷新 + 重试 更新: 活跃 仅遥测 diff --git a/core/presentation/src/main/res/values/strings.xml b/core/presentation/src/main/res/values/strings.xml index adb749cd..75fdb622 100644 --- a/core/presentation/src/main/res/values/strings.xml +++ b/core/presentation/src/main/res/values/strings.xml @@ -49,6 +49,8 @@ Log AMSAT AMSAT Satellite Status + Refresh + Retry Updated: Active TLM/Beacon diff --git a/feature/status/src/main/java/com/rtbishop/look4sat/feature/status/SatStatusScreen.kt b/feature/status/src/main/java/com/rtbishop/look4sat/feature/status/SatStatusScreen.kt index 71bd74b6..c22fa7d2 100644 --- a/feature/status/src/main/java/com/rtbishop/look4sat/feature/status/SatStatusScreen.kt +++ b/feature/status/src/main/java/com/rtbishop/look4sat/feature/status/SatStatusScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -20,6 +21,8 @@ import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items @@ -56,6 +59,7 @@ import com.rtbishop.look4sat.core.domain.model.SatSlot import com.rtbishop.look4sat.core.domain.model.SatStatus import com.rtbishop.look4sat.core.domain.repository.IMainContainer import com.rtbishop.look4sat.core.presentation.R +import com.rtbishop.look4sat.feature.status.R as StatusR import java.util.Calendar // ========== Official status colors (amsat.org/status originals) ========== @@ -97,11 +101,18 @@ fun SatStatusScreen(container: IMainContainer) { } } uiState.error != null && uiState.statuses.isEmpty() -> { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { Text( text = stringResource(id = R.string.amsat_load_failed), color = MaterialTheme.colorScheme.error ) + TextButton(onClick = { viewModel.refresh() }) { + Text(text = stringResource(id = R.string.amsat_retry)) + } } } else -> { @@ -169,11 +180,13 @@ private fun StatusHeader( if (isRefreshing) { CircularProgressIndicator(modifier = Modifier.size(18.dp), strokeWidth = 2.dp) } else { - Text( - text = "↻", - fontSize = 20.sp, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier.rotate(angle) + Image( + painter = painterResource(id = StatusR.drawable.ic_refresh), + contentDescription = stringResource(id = R.string.amsat_refresh), + modifier = Modifier + .size(18.dp) + .rotate(angle), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary) ) } } diff --git a/feature/status/src/main/res/drawable/ic_refresh.xml b/feature/status/src/main/res/drawable/ic_refresh.xml new file mode 100644 index 00000000..fa87eaf6 --- /dev/null +++ b/feature/status/src/main/res/drawable/ic_refresh.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 687c5ecd..32890d54 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] #noinspection UnusedVersionCatalogEntry -appVersionCode = "455" +appVersionCode = "456" #noinspection UnusedVersionCatalogEntry appVersionName = "4.5.5" #noinspection UnusedVersionCatalogEntry