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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.placeholder.ringhealth.AppViewModelProvider
|
import com.placeholder.ringhealth.AppViewModelProvider
|
||||||
import com.placeholder.ringhealth.R
|
import com.placeholder.ringhealth.R
|
||||||
import com.placeholder.ringhealth.core.designsystem.MetricGreen
|
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
|
@Composable
|
||||||
@@ -29,7 +33,15 @@ fun WorkoutHistoryScreen(
|
|||||||
viewModel: WorkoutViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
viewModel: WorkoutViewModel = viewModel(factory = AppViewModelProvider.Factory),
|
||||||
) {
|
) {
|
||||||
val state by viewModel.uiState.collectAsStateWithLifecycle()
|
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 延迟,
|
// 必须先判 loading 再判空(ledger Ruling R25):Mock 仓库有 200ms 延迟,
|
||||||
// records 在加载完成前就是 emptyList,若先判空会先闪一下「暂无运动记录」,
|
// records 在加载完成前就是 emptyList,若先判空会先闪一下「暂无运动记录」,
|
||||||
// 数据到了再跳成列表 —— 用户看到的是「明明有记录却说没有」。
|
// 数据到了再跳成列表 —— 用户看到的是「明明有记录却说没有」。
|
||||||
@@ -47,7 +59,7 @@ fun WorkoutHistoryScreen(
|
|||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.workout_empty),
|
text = stringResource(R.string.workout_empty),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = TextSecondary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
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.formatDistance
|
||||||
import com.placeholder.ringhealth.core.common.formatDuration
|
import com.placeholder.ringhealth.core.common.formatDuration
|
||||||
import com.placeholder.ringhealth.core.designsystem.MetricGreen
|
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.TextSecondary
|
||||||
import com.placeholder.ringhealth.core.designsystem.component.HealthCard
|
import com.placeholder.ringhealth.core.designsystem.component.HealthCard
|
||||||
import com.placeholder.ringhealth.core.designsystem.component.SectionHeader
|
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.After
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -46,7 +47,8 @@ class WorkoutViewModelTest {
|
|||||||
val state = viewModel.uiState.value
|
val state = viewModel.uiState.value
|
||||||
assertFalse(state.loading)
|
assertFalse(state.loading)
|
||||||
assertEquals(5, state.records.size)
|
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