perf: DayCell produceState 上移到页面级,减少协程数量
CalendarMonthPage 统一预计算整月 42 天的 lunarData(1 个协程), 通过参数传入 DayCell,避免每个单元格独立启动 produceState(42 协程)。 - holidayBadges produceState 扩展为 lunarDataMap,存储完整 DayCellInfo - DayCell 添加可选 lunarData 参数,条件分支调用 DayCellImpl - WeekPager 保持向后兼容(不传 lunarData 时内部获取) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e175bb07da
commit
da46204de4
@ -25,6 +25,7 @@ import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.minus
|
||||
import kotlinx.datetime.number
|
||||
import kotlinx.datetime.plus
|
||||
import plus.rua.project.DayCellInfo
|
||||
import plus.rua.project.LunarCache
|
||||
import plus.rua.project.ShiftKind
|
||||
|
||||
@ -69,27 +70,26 @@ fun CalendarMonthPage(
|
||||
val density = LocalDensity.current
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
val holidayBadges by produceState(
|
||||
initialValue = emptyMap<LocalDate, String?>(),
|
||||
val lunarDataMap by produceState(
|
||||
initialValue = emptyMap<LocalDate, DayCellInfo>(),
|
||||
key1 = year,
|
||||
key2 = month
|
||||
) {
|
||||
val map = mutableMapOf<LocalDate, String?>()
|
||||
val map = mutableMapOf<LocalDate, DayCellInfo>()
|
||||
for (dayData in days) {
|
||||
val info = LunarCache.default.getOrCompute(dayData.date)
|
||||
map[dayData.date] = info.holidayBadge
|
||||
map[dayData.date] = LunarCache.default.getOrCompute(dayData.date)
|
||||
}
|
||||
value = map
|
||||
}
|
||||
|
||||
val holidayEdges = remember(holidayBadges, year, month) {
|
||||
val holidayEdges = remember(lunarDataMap, year, month) {
|
||||
val map = mutableMapOf<LocalDate, HolidayEdgeInfo>()
|
||||
for (dayData in days) {
|
||||
val date = dayData.date
|
||||
val badge = holidayBadges[date]
|
||||
val badge = lunarDataMap[date]?.holidayBadge
|
||||
if (badge == null) continue
|
||||
val prevBadge = holidayBadges[date.minus(DatePeriod(days = 1))]
|
||||
val nextBadge = holidayBadges[date.plus(DatePeriod(days = 1))]
|
||||
val prevBadge = lunarDataMap[date.minus(DatePeriod(days = 1))]?.holidayBadge
|
||||
val nextBadge = lunarDataMap[date.plus(DatePeriod(days = 1))]?.holidayBadge
|
||||
map[date] = HolidayEdgeInfo(
|
||||
isStart = prevBadge != badge,
|
||||
isEnd = nextBadge != badge
|
||||
@ -128,6 +128,7 @@ fun CalendarMonthPage(
|
||||
shiftKindAt = shiftKindAt,
|
||||
showLegalHoliday = showLegalHoliday,
|
||||
holidayEdges = holidayEdges,
|
||||
lunarDataMap = lunarDataMap,
|
||||
onDateClick = onDateClick,
|
||||
onRowHeightMeasured = onRowHeightMeasured,
|
||||
interactionSource = interactionSource
|
||||
@ -150,6 +151,7 @@ private fun WeekRow(
|
||||
shiftKindAt: (LocalDate) -> ShiftKind?,
|
||||
showLegalHoliday: Boolean,
|
||||
holidayEdges: Map<LocalDate, HolidayEdgeInfo>,
|
||||
lunarDataMap: Map<LocalDate, DayCellInfo>,
|
||||
onDateClick: (LocalDate) -> Unit,
|
||||
onRowHeightMeasured: ((Int) -> Unit)?,
|
||||
interactionSource: MutableInteractionSource,
|
||||
@ -235,7 +237,8 @@ private fun WeekRow(
|
||||
holidayEdgeInfo = holidayEdges[dayData.date],
|
||||
onClick = { onDateClick(dayData.date) },
|
||||
modifier = Modifier.weight(1f),
|
||||
interactionSource = interactionSource
|
||||
interactionSource = interactionSource,
|
||||
lunarData = lunarDataMap[dayData.date]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,15 +72,61 @@ fun DayCell(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
lunarCache: LunarCache = LunarCache.default
|
||||
lunarCache: LunarCache = LunarCache.default,
|
||||
lunarData: DayCellInfo? = null,
|
||||
) {
|
||||
val lunarData by produceState(
|
||||
initialValue = DayCellInfo("", false, null),
|
||||
key1 = date,
|
||||
key2 = lunarCache
|
||||
) {
|
||||
value = lunarCache.getOrCompute(date)
|
||||
if (lunarData != null) {
|
||||
DayCellImpl(
|
||||
date = date,
|
||||
isCurrentMonth = isCurrentMonth,
|
||||
isSelected = isSelected,
|
||||
isToday = isToday,
|
||||
shiftKind = shiftKind,
|
||||
showLegalHoliday = showLegalHoliday,
|
||||
holidayEdgeInfo = holidayEdgeInfo,
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
interactionSource = interactionSource,
|
||||
lunarData = lunarData,
|
||||
)
|
||||
} else {
|
||||
val computed by produceState(
|
||||
initialValue = DayCellInfo("", false, null),
|
||||
key1 = date,
|
||||
key2 = lunarCache
|
||||
) {
|
||||
value = lunarCache.getOrCompute(date)
|
||||
}
|
||||
DayCellImpl(
|
||||
date = date,
|
||||
isCurrentMonth = isCurrentMonth,
|
||||
isSelected = isSelected,
|
||||
isToday = isToday,
|
||||
shiftKind = shiftKind,
|
||||
showLegalHoliday = showLegalHoliday,
|
||||
holidayEdgeInfo = holidayEdgeInfo,
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
interactionSource = interactionSource,
|
||||
lunarData = computed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DayCellImpl(
|
||||
date: LocalDate,
|
||||
isCurrentMonth: Boolean,
|
||||
isSelected: Boolean,
|
||||
isToday: Boolean,
|
||||
shiftKind: ShiftKind?,
|
||||
showLegalHoliday: Boolean,
|
||||
holidayEdgeInfo: HolidayEdgeInfo?,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier,
|
||||
interactionSource: MutableInteractionSource,
|
||||
lunarData: DayCellInfo,
|
||||
) {
|
||||
val annotationText = lunarData.annotationText
|
||||
val isAnnotationHighlight = lunarData.isAnnotationHighlight
|
||||
val holidayBadge = lunarData.holidayBadge
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user