fix: 统一运动历史空态文字颜色并补充页面预览与顺序断言
This commit is contained in:
+44
-1
@@ -15,12 +15,16 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.placeholder.ringhealth.AppViewModelProvider
|
||||
import com.placeholder.ringhealth.R
|
||||
import com.placeholder.ringhealth.core.designsystem.MetricGreen
|
||||
import com.placeholder.ringhealth.core.designsystem.RingHealthTheme
|
||||
import com.placeholder.ringhealth.core.designsystem.TextSecondary
|
||||
import com.placeholder.ringhealth.domain.model.WorkoutRecord
|
||||
|
||||
/** 运动历史子页:展示全部运动记录。 */
|
||||
@Composable
|
||||
@@ -29,7 +33,15 @@ fun WorkoutHistoryScreen(
|
||||
viewModel: WorkoutViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||
) {
|
||||
val state by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
WorkoutHistoryContent(state = state, modifier = modifier)
|
||||
}
|
||||
|
||||
/** 无状态运动历史内容,便于 Preview。 */
|
||||
@Composable
|
||||
private fun WorkoutHistoryContent(
|
||||
state: WorkoutUiState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
// 必须先判 loading 再判空(ledger Ruling R25):Mock 仓库有 200ms 延迟,
|
||||
// records 在加载完成前就是 emptyList,若先判空会先闪一下「暂无运动记录」,
|
||||
// 数据到了再跳成列表 —— 用户看到的是「明明有记录却说没有」。
|
||||
@@ -47,7 +59,7 @@ fun WorkoutHistoryScreen(
|
||||
Text(
|
||||
text = stringResource(R.string.workout_empty),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
color = TextSecondary,
|
||||
)
|
||||
}
|
||||
return
|
||||
@@ -62,3 +74,34 @@ fun WorkoutHistoryScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 预览入口:以固定示例数据渲染 [WorkoutHistoryContent],便于在 IDE 中免真机查看历史页效果。 */
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun WorkoutHistoryContentPreview() {
|
||||
RingHealthTheme {
|
||||
WorkoutHistoryContent(
|
||||
state = WorkoutUiState(
|
||||
loading = false,
|
||||
records = listOf(
|
||||
WorkoutRecord(
|
||||
id = "preview-0",
|
||||
type = "户外跑步",
|
||||
startTime = 1_757_000_000_000L,
|
||||
durationMinutes = 42,
|
||||
distanceKm = 5.20,
|
||||
calories = 286,
|
||||
),
|
||||
WorkoutRecord(
|
||||
id = "preview-1",
|
||||
type = "健走",
|
||||
startTime = 1_756_900_000_000L,
|
||||
durationMinutes = 31,
|
||||
distanceKm = 2.80,
|
||||
calories = 143,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
@@ -34,6 +35,7 @@ import com.placeholder.ringhealth.core.common.formatDate
|
||||
import com.placeholder.ringhealth.core.common.formatDistance
|
||||
import com.placeholder.ringhealth.core.common.formatDuration
|
||||
import com.placeholder.ringhealth.core.designsystem.MetricGreen
|
||||
import com.placeholder.ringhealth.core.designsystem.RingHealthTheme
|
||||
import com.placeholder.ringhealth.core.designsystem.TextSecondary
|
||||
import com.placeholder.ringhealth.core.designsystem.component.HealthCard
|
||||
import com.placeholder.ringhealth.core.designsystem.component.SectionHeader
|
||||
@@ -139,3 +141,35 @@ internal fun WorkoutRecordCard(record: WorkoutRecord, modifier: Modifier = Modif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 预览入口:以固定示例数据渲染 [WorkoutContent],便于在 IDE 中免真机查看运动页效果。 */
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun WorkoutContentPreview() {
|
||||
RingHealthTheme {
|
||||
WorkoutContent(
|
||||
state = WorkoutUiState(
|
||||
loading = false,
|
||||
records = listOf(
|
||||
WorkoutRecord(
|
||||
id = "preview-0",
|
||||
type = "户外跑步",
|
||||
startTime = 1_757_000_000_000L,
|
||||
durationMinutes = 42,
|
||||
distanceKm = 5.20,
|
||||
calories = 286,
|
||||
),
|
||||
WorkoutRecord(
|
||||
id = "preview-1",
|
||||
type = "健走",
|
||||
startTime = 1_756_900_000_000L,
|
||||
durationMinutes = 31,
|
||||
distanceKm = 2.80,
|
||||
calories = 143,
|
||||
),
|
||||
),
|
||||
),
|
||||
onOpenHistory = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -12,6 +12,7 @@ import kotlinx.coroutines.test.setMain
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@@ -46,7 +47,8 @@ class WorkoutViewModelTest {
|
||||
val state = viewModel.uiState.value
|
||||
assertFalse(state.loading)
|
||||
assertEquals(5, state.records.size)
|
||||
// Mock 的运动记录是倒序生成的,最近的在最前
|
||||
assertEquals("户外跑步", state.records.first().type)
|
||||
// 列表必须按时间倒序(最近的在最前):直接比首尾时间戳,而不是比记录类型
|
||||
// —— Mock 数据的首尾类型恰好相同,用类型断言无法察觉顺序被反转。
|
||||
assertTrue(state.records.first().startTime > state.records.last().startTime)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user