CleanUp and refactor on the Annual Followup
This commit is contained in:
parent
51bf0c7496
commit
7d2508a4de
9 changed files with 519 additions and 180 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -75,3 +75,6 @@ lint/tmp/
|
|||
# App Specific cases
|
||||
app/release/output.json
|
||||
.idea/codeStyles/
|
||||
|
||||
.kotlin/sessions
|
||||
app/release
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -33,6 +33,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.keepScreenOn
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
|
@ -77,6 +78,7 @@ fun MonthSummaryPage(
|
|||
|
||||
MonthSummaryContent(
|
||||
modifier = Modifier
|
||||
.keepScreenOn()
|
||||
.systemBarsPadding()
|
||||
.fillMaxSize(),
|
||||
events = events,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,22 @@ class YearSummaryFactory @Inject constructor() {
|
|||
return events
|
||||
.fold(initial = hashMapOf<Int, HashMap<Int, HashMap<Int, Event>>>()) { acc, event ->
|
||||
acc.also {
|
||||
val years = it.getOrPut(key = event.date.year) { hashMapOf() }
|
||||
val years = it.getOrPut(key = event.date.year) {
|
||||
hashMapOf(
|
||||
Calendar.JANUARY to hashMapOf(),
|
||||
Calendar.FEBRUARY to hashMapOf(),
|
||||
Calendar.MARCH to hashMapOf(),
|
||||
Calendar.APRIL to hashMapOf(),
|
||||
Calendar.MAY to hashMapOf(),
|
||||
Calendar.JUNE to hashMapOf(),
|
||||
Calendar.JULY to hashMapOf(),
|
||||
Calendar.AUGUST to hashMapOf(),
|
||||
Calendar.SEPTEMBER to hashMapOf(),
|
||||
Calendar.OCTOBER to hashMapOf(),
|
||||
Calendar.NOVEMBER to hashMapOf(),
|
||||
Calendar.DECEMBER to hashMapOf(),
|
||||
)
|
||||
}
|
||||
val months = years.getOrPut(key = event.date.month) { hashMapOf() }
|
||||
months[event.date.day] = event
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,14 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.keepScreenOn
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalWindowInfo
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
|
@ -41,13 +44,13 @@ import com.pixelized.headache.ui.navigation.LocalNavigator
|
|||
import com.pixelized.headache.ui.navigation.destination.navigateToEventPage
|
||||
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheet
|
||||
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheetViewModel
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryDayDefault
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryDayUio
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryMonth
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryMonthUio
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.calculate
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
@Stable
|
||||
data class YearUio(
|
||||
|
|
@ -67,6 +70,7 @@ fun YearSummaryPage(
|
|||
YearSummaryContent(
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.keepScreenOn()
|
||||
.fillMaxSize(),
|
||||
uio = uio,
|
||||
onBack = {
|
||||
|
|
@ -86,10 +90,39 @@ fun YearSummaryPage(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberDaySize(
|
||||
column: Int = 3,
|
||||
space: Dp,
|
||||
paddingValues: PaddingValues,
|
||||
): Dp {
|
||||
val density = LocalDensity.current
|
||||
val windowInfo = LocalWindowInfo.current
|
||||
val screenWidth = remember(density, windowInfo) {
|
||||
with(density) {
|
||||
windowInfo.containerSize.width.toDp()
|
||||
}
|
||||
}
|
||||
val (start, _, end, _) = paddingValues.calculate()
|
||||
return (screenWidth - space * (column - 1) - start - end) / (7 * column)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun YearSummaryContent(
|
||||
modifier: Modifier = Modifier,
|
||||
paddingValues: PaddingValues = PaddingValues(
|
||||
start = 16.dp,
|
||||
top = 16.dp,
|
||||
end = 16.dp,
|
||||
bottom = 16.dp + 16.dp + 56.dp,
|
||||
),
|
||||
space: Dp = 8.dp,
|
||||
daySize: Dp = rememberDaySize(
|
||||
column = 3,
|
||||
paddingValues = paddingValues,
|
||||
space = space,
|
||||
),
|
||||
uio: State<List<YearUio>>,
|
||||
onBack: () -> Unit,
|
||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||
|
|
@ -126,24 +159,16 @@ fun YearSummaryContent(
|
|||
)
|
||||
}
|
||||
},
|
||||
content = { paddingValues ->
|
||||
content = { it ->
|
||||
LazyVerticalGrid(
|
||||
modifier = Modifier.padding(paddingValues = paddingValues),
|
||||
columns = GridCells.Adaptive(
|
||||
minSize = YearSummaryDayDefault.size * 7,
|
||||
),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
contentPadding = PaddingValues(
|
||||
start = 16.dp,
|
||||
top = 16.dp,
|
||||
end = 16.dp,
|
||||
bottom = 16.dp + 16.dp + 56.dp,
|
||||
),
|
||||
modifier = Modifier.padding(paddingValues = it),
|
||||
columns = GridCells.Adaptive(minSize = daySize * 7),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = space),
|
||||
contentPadding = paddingValues,
|
||||
) {
|
||||
uio.value.forEachIndexed { index, (year, months) ->
|
||||
item(
|
||||
span = { GridItemSpan(maxCurrentLineSpan) },
|
||||
span = { GridItemSpan(maxLineSpan) },
|
||||
contentType = { "Title" },
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -164,6 +189,7 @@ fun YearSummaryContent(
|
|||
) {
|
||||
YearSummaryMonth(
|
||||
uio = it,
|
||||
daySize = daySize,
|
||||
onMonth = onMonth,
|
||||
)
|
||||
}
|
||||
|
|
@ -174,7 +200,7 @@ fun YearSummaryContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
@Preview()
|
||||
private fun YearSummaryPreview(
|
||||
@PreviewParameter(YearPreviewProvider::class) preview: List<YearUio>,
|
||||
) {
|
||||
|
|
@ -192,6 +218,65 @@ private fun YearSummaryPreview(
|
|||
|
||||
private class YearPreviewProvider() : PreviewParameterProvider<List<YearUio>> {
|
||||
|
||||
private var day = 1
|
||||
|
||||
private fun day(): () -> YearSummaryDayUio = {
|
||||
YearSummaryDayUio(
|
||||
number = day++,
|
||||
headache = false,
|
||||
pills = emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun headache(
|
||||
spifen: Boolean = false,
|
||||
eletriptan: Boolean = false,
|
||||
): () -> YearSummaryDayUio = {
|
||||
YearSummaryDayUio(
|
||||
number = day++,
|
||||
headache = true,
|
||||
pills = listOfNotNull(
|
||||
if (spifen) HeadacheColorPalette.Pill.Spifen400 else null,
|
||||
if (eletriptan) HeadacheColorPalette.Pill.Eletriptan40 else null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// inline to avoid un sequential call to "day()" between default and overridden function parameters.
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private fun week(
|
||||
mon: (() -> YearSummaryDayUio)? = day(),
|
||||
tue: (() -> YearSummaryDayUio)? = day(),
|
||||
wen: (() -> YearSummaryDayUio)? = day(),
|
||||
thu: (() -> YearSummaryDayUio)? = day(),
|
||||
fry: (() -> YearSummaryDayUio)? = day(),
|
||||
sat: (() -> YearSummaryDayUio)? = day(),
|
||||
sun: (() -> YearSummaryDayUio)? = day(),
|
||||
): List<YearSummaryDayUio> = listOfNotNull(
|
||||
mon?.invoke(),
|
||||
tue?.invoke(),
|
||||
wen?.invoke(),
|
||||
thu?.invoke(),
|
||||
fry?.invoke(),
|
||||
sat?.invoke(),
|
||||
sun?.invoke(),
|
||||
)
|
||||
|
||||
private fun month(
|
||||
month: Int,
|
||||
year: Int,
|
||||
vararg weeks: List<YearSummaryDayUio>,
|
||||
): YearSummaryMonthUio {
|
||||
day = 1
|
||||
return YearSummaryMonthUio(
|
||||
date = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, year)
|
||||
set(Calendar.MONTH, month)
|
||||
}.time,
|
||||
weeks = weeks.toList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun year(
|
||||
year: Int,
|
||||
vararg months: YearSummaryMonthUio,
|
||||
|
|
@ -200,76 +285,197 @@ private class YearPreviewProvider() : PreviewParameterProvider<List<YearUio>> {
|
|||
months = months.toList(),
|
||||
)
|
||||
|
||||
private fun month(
|
||||
month: Date,
|
||||
vararg weeks: List<YearSummaryDayUio>,
|
||||
) = YearSummaryMonthUio(
|
||||
date = month,
|
||||
weeks = weeks.toList(),
|
||||
)
|
||||
|
||||
private fun week(
|
||||
vararg days: YearSummaryDayUio,
|
||||
) = days.toList()
|
||||
|
||||
private fun day(
|
||||
number: Int,
|
||||
headache: Boolean = false,
|
||||
pills: List<Color> = emptyList(),
|
||||
) = YearSummaryDayUio(
|
||||
number = number,
|
||||
headache = headache,
|
||||
pills = pills,
|
||||
)
|
||||
|
||||
override val values: Sequence<List<YearUio>> = sequenceOf(
|
||||
listOf(
|
||||
year(
|
||||
year = 2025,
|
||||
month(
|
||||
month = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, 2025)
|
||||
set(Calendar.MONTH, Calendar.JANUARY)
|
||||
}.time,
|
||||
week(day(1), day(2), day(3), day(4), day(5)),
|
||||
week(day(6), day(7), day(8), day(9), day(10), day(11), day(12)),
|
||||
week(day(13), day(14), day(15), day(16), day(17), day(18), day(19)),
|
||||
week(day(20), day(21), day(22), day(23), day(24), day(25), day(26)),
|
||||
week(day(27), day(28), day(29), day(30), day(31)),
|
||||
month = Calendar.JANUARY,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, 2025)
|
||||
set(Calendar.MONTH, Calendar.FEBRUARY)
|
||||
}.time,
|
||||
week(day(1), day(2)),
|
||||
week(day(3), day(4), day(5), day(6), day(7), day(8), day(9)),
|
||||
week(day(10), day(11), day(12), day(13), day(14), day(15), day(16)),
|
||||
week(day(17), day(18), day(19), day(20), day(21), day(22), day(23)),
|
||||
week(day(24), day(25), day(26), day(27), day(28)),
|
||||
month = Calendar.FEBRUARY,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, 2025)
|
||||
set(Calendar.MONTH, Calendar.MARCH)
|
||||
}.time,
|
||||
week(day(1), day(2)),
|
||||
week(day(3), day(4), day(5), day(6), day(7), day(8), day(9)),
|
||||
week(day(10), day(11), day(12), day(13), day(14), day(15), day(16)),
|
||||
week(day(17), day(18), day(19), day(20), day(21), day(22), day(23)),
|
||||
week(day(24), day(25), day(26), day(27), day(28), day(29), day(30)),
|
||||
week(day(31)),
|
||||
month = Calendar.MARCH,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(tue = null, wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, 2025)
|
||||
set(Calendar.MONTH, Calendar.APRIL)
|
||||
}.time,
|
||||
week(day(1), day(2), day(3), day(4), day(5), day(6)),
|
||||
week(day(7), day(8), day(9), day(10), day(11), day(12), day(13)),
|
||||
week(day(14), day(15), day(16), day(17), day(18), day(19), day(20)),
|
||||
week(day(21), day(22), day(23), day(24), day(25), day(26), day(27)),
|
||||
week(day(28), day(29), day(30), day(31)),
|
||||
month = Calendar.APRIL,
|
||||
year = 2025,
|
||||
week(mon = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.MAY,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.JUNE,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null, sat = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(tue = null, wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.JULY,
|
||||
year = 2025,
|
||||
week(mon = null, sun = headache(spifen = true)),
|
||||
week(wen = headache(spifen = true)),
|
||||
week(sat = headache()),
|
||||
week(
|
||||
wen = headache(spifen = true),
|
||||
thu = headache(),
|
||||
sat = headache(spifen = true),
|
||||
),
|
||||
week(wen = headache(), fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.AUGUST,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null, thu = null),
|
||||
week(wen = headache(), fry = headache()),
|
||||
week(fry = headache(spifen = true)),
|
||||
week(tue = headache(spifen = true), fry = headache()),
|
||||
week(
|
||||
tue = headache(spifen = true, eletriptan = true),
|
||||
wen = headache(),
|
||||
sat = headache(spifen = true),
|
||||
),
|
||||
),
|
||||
month(
|
||||
month = Calendar.SEPTEMBER,
|
||||
year = 2025,
|
||||
week(
|
||||
tue = headache(spifen = true, eletriptan = true),
|
||||
wen = headache(spifen = true),
|
||||
fry = headache(),
|
||||
sat = headache(),
|
||||
sun = headache(),
|
||||
),
|
||||
week(
|
||||
sun = headache(spifen = true),
|
||||
),
|
||||
week(
|
||||
wen = headache(spifen = true),
|
||||
tue = headache(),
|
||||
),
|
||||
week(),
|
||||
week(wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.OCTOBER,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.NOVEMBER,
|
||||
year = 2025,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
),
|
||||
month(
|
||||
month = Calendar.DECEMBER,
|
||||
year = 2025,
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
),
|
||||
year(
|
||||
year = 2024,
|
||||
month(
|
||||
month = Calendar.JANUARY,
|
||||
year = 2024,
|
||||
week(mon = null, tue = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.FEBRUARY,
|
||||
year = 2024,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.MARCH,
|
||||
year = 2024,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(tue = null, wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.APRIL,
|
||||
year = 2024,
|
||||
week(mon = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.MAY,
|
||||
year = 2024,
|
||||
week(mon = null, tue = null, wen = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(sun = null),
|
||||
),
|
||||
month(
|
||||
month = Calendar.JUNE,
|
||||
year = 2024,
|
||||
week(mon = null, tue = null, wen = null, thu = null, fry = null, sat = null),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(),
|
||||
week(tue = null, wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
package com.pixelized.headache.ui.page.summary.year.item
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -53,17 +54,22 @@ fun YearSummaryDay(
|
|||
if (day.headache) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.matchParentSize()
|
||||
.padding(vertical = pill + 1.dp)
|
||||
.background(color = HeadacheColorPalette.Pill.Unknown)
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.align(alignment = Alignment.Center),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = when {
|
||||
!isSystemInDarkTheme() && day.headache -> Color.White
|
||||
else -> MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
text = "${day.number}",
|
||||
)
|
||||
|
||||
if (day.headache) {
|
||||
Row(
|
||||
modifier = Modifier.align(alignment = Alignment.BottomCenter),
|
||||
|
|
@ -87,11 +93,14 @@ private fun YearSummaryDayPreview(
|
|||
@PreviewParameter(DayPreviewProvider::class) preview: YearSummaryDayUio,
|
||||
) {
|
||||
HeadacheTheme {
|
||||
Surface {
|
||||
YearSummaryDay(
|
||||
modifier = Modifier.size(size = 16.dp),
|
||||
day = preview,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DayPreviewProvider() : PreviewParameterProvider<YearSummaryDayUio> {
|
||||
override val values: Sequence<YearSummaryDayUio>
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ import android.icu.text.SimpleDateFormat
|
|||
import android.icu.util.Calendar
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
|
@ -20,10 +20,11 @@ import androidx.compose.runtime.Stable
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.capitalize
|
||||
|
|
@ -47,6 +48,7 @@ data class YearSummaryMonthUio(
|
|||
fun YearSummaryMonth(
|
||||
modifier: Modifier = Modifier,
|
||||
formatter: DateFormat = YearSummaryMonthDefault.formatter,
|
||||
daySize: Dp,
|
||||
uio: YearSummaryMonthUio,
|
||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||
) {
|
||||
|
|
@ -64,20 +66,22 @@ fun YearSummaryMonth(
|
|||
style = MaterialTheme.typography.titleMedium,
|
||||
text = remember(uio.date) { formatter.format(uio.date) }.capitalize(),
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.height(height = remember { YearSummaryDayDefault.size * 6 }),
|
||||
Box(
|
||||
modifier = Modifier.size(width = daySize * 7, height = daySize * 6),
|
||||
) {
|
||||
uio.weeks.forEachIndexed { index, week ->
|
||||
Row(
|
||||
modifier = Modifier.width(width = remember { YearSummaryDayDefault.size * 7 }),
|
||||
horizontalArrangement = when (index) {
|
||||
0 -> Arrangement.End
|
||||
else -> Arrangement.Start
|
||||
uio.weeks.forEachIndexed { row, week ->
|
||||
week.forEachIndexed { column, day ->
|
||||
YearSummaryDay(
|
||||
Modifier.offset(
|
||||
x = when (row) {
|
||||
0 -> daySize * (column + 7 - week.size)
|
||||
else -> daySize * column
|
||||
},
|
||||
) {
|
||||
week.forEach { day ->
|
||||
YearSummaryDay(day = day)
|
||||
}
|
||||
y = daySize * row,
|
||||
),
|
||||
size = daySize,
|
||||
day = day,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,6 +96,8 @@ private fun YearSummaryMonthPreview(
|
|||
HeadacheTheme {
|
||||
Surface {
|
||||
YearSummaryMonth(
|
||||
modifier = Modifier.padding(all = 8.dp),
|
||||
daySize = YearSummaryDayDefault.size,
|
||||
uio = preview,
|
||||
onMonth = { },
|
||||
)
|
||||
|
|
@ -101,85 +107,137 @@ private fun YearSummaryMonthPreview(
|
|||
|
||||
private class MonthPreviewProvider() : PreviewParameterProvider<YearSummaryMonthUio> {
|
||||
|
||||
fun day(
|
||||
number: Int,
|
||||
headache: Boolean = false,
|
||||
pills: List<Color> = emptyList(),
|
||||
): YearSummaryDayUio = YearSummaryDayUio(
|
||||
number = number,
|
||||
headache = headache,
|
||||
pills = pills,
|
||||
private var day: Int = 1
|
||||
|
||||
private fun day(): () -> YearSummaryDayUio = {
|
||||
YearSummaryDayUio(
|
||||
number = day++,
|
||||
headache = false,
|
||||
pills = emptyList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun headache(
|
||||
spifen: Boolean = false,
|
||||
eletriptan: Boolean = false,
|
||||
): () -> YearSummaryDayUio = {
|
||||
YearSummaryDayUio(
|
||||
number = day++,
|
||||
headache = true,
|
||||
pills = listOfNotNull(
|
||||
if (spifen) HeadacheColorPalette.Pill.Spifen400 else null,
|
||||
if (eletriptan) HeadacheColorPalette.Pill.Eletriptan40 else null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// inline to avoid un sequential call to "day()" between default and overridden function parameters.
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private fun week(
|
||||
mon: (() -> YearSummaryDayUio)? = day(),
|
||||
tue: (() -> YearSummaryDayUio)? = day(),
|
||||
wen: (() -> YearSummaryDayUio)? = day(),
|
||||
thu: (() -> YearSummaryDayUio)? = day(),
|
||||
fry: (() -> YearSummaryDayUio)? = day(),
|
||||
sat: (() -> YearSummaryDayUio)? = day(),
|
||||
sun: (() -> YearSummaryDayUio)? = day(),
|
||||
): List<YearSummaryDayUio> = listOfNotNull(
|
||||
mon?.invoke(),
|
||||
tue?.invoke(),
|
||||
wen?.invoke(),
|
||||
thu?.invoke(),
|
||||
fry?.invoke(),
|
||||
sat?.invoke(),
|
||||
sun?.invoke(),
|
||||
)
|
||||
|
||||
private fun month(
|
||||
month: Int,
|
||||
vararg weeks: List<YearSummaryDayUio>,
|
||||
): YearSummaryMonthUio {
|
||||
day = 1
|
||||
return YearSummaryMonthUio(
|
||||
date = java.util.Calendar.getInstance().apply {
|
||||
set(java.util.Calendar.YEAR, 2025)
|
||||
set(java.util.Calendar.MONTH, month)
|
||||
}.time,
|
||||
weeks = weeks.toList(),
|
||||
)
|
||||
}
|
||||
|
||||
override val values: Sequence<YearSummaryMonthUio>
|
||||
get() = sequenceOf(
|
||||
YearSummaryMonthUio(
|
||||
date = Calendar.getInstance().apply {
|
||||
set(Calendar.YEAR, 2025)
|
||||
set(Calendar.MONTH, Calendar.JULY)
|
||||
}.time,
|
||||
weeks = listOf(
|
||||
listOf(
|
||||
day(number = 1),
|
||||
day(number = 2),
|
||||
day(number = 3),
|
||||
day(number = 4),
|
||||
month(
|
||||
month = Calendar.MARCH,
|
||||
week(
|
||||
mon = null,
|
||||
tue = null,
|
||||
wen = null,
|
||||
thu = null,
|
||||
fry = null,
|
||||
sat = headache(spifen = true)
|
||||
),
|
||||
listOf(
|
||||
day(number = 5),
|
||||
day(number = 6, headache = true),
|
||||
day(number = 7),
|
||||
day(number = 8, headache = true),
|
||||
day(number = 9),
|
||||
day(number = 10),
|
||||
day(number = 11),
|
||||
week(sat = headache(spifen = true)),
|
||||
week(
|
||||
wen = headache(spifen = true, eletriptan = true),
|
||||
thu = headache(spifen = true, eletriptan = true),
|
||||
fry = headache(spifen = true, eletriptan = true),
|
||||
sat = headache(),
|
||||
sun = headache(spifen = true, eletriptan = true)
|
||||
),
|
||||
listOf(
|
||||
day(number = 12),
|
||||
day(number = 13),
|
||||
day(number = 14),
|
||||
day(
|
||||
number = 15,
|
||||
headache = true,
|
||||
pills = listOf(HeadacheColorPalette.Pill.Spifen400),
|
||||
week(
|
||||
mon = headache(),
|
||||
tue = headache(),
|
||||
sat = headache(spifen = true, eletriptan = true),
|
||||
),
|
||||
day(number = 16),
|
||||
day(number = 17),
|
||||
day(number = 18),
|
||||
),
|
||||
listOf(
|
||||
day(
|
||||
number = 19,
|
||||
headache = true,
|
||||
pills = listOf(HeadacheColorPalette.Pill.Spifen400),
|
||||
),
|
||||
day(number = 20),
|
||||
day(number = 21),
|
||||
day(number = 22, headache = true),
|
||||
day(number = 23),
|
||||
day(number = 24),
|
||||
day(number = 25),
|
||||
),
|
||||
listOf(
|
||||
day(
|
||||
number = 26,
|
||||
headache = true,
|
||||
pills = listOf(
|
||||
HeadacheColorPalette.Pill.Spifen400,
|
||||
HeadacheColorPalette.Pill.Eletriptan40,
|
||||
week(thu = headache(), fry = headache(), sat = headache()),
|
||||
week(
|
||||
mon = headache(spifen = true, eletriptan = true),
|
||||
tue = null, wen = null, thu = null, fry = null, sat = null, sun = null
|
||||
),
|
||||
),
|
||||
day(number = 27, headache = true),
|
||||
day(number = 28),
|
||||
day(number = 29),
|
||||
day(
|
||||
number = 30,
|
||||
headache = true,
|
||||
pills = listOf(HeadacheColorPalette.Pill.Spifen400),
|
||||
month(
|
||||
month = java.util.Calendar.JULY,
|
||||
week(mon = null, sun = headache(spifen = true)),
|
||||
week(wen = headache(spifen = true)),
|
||||
week(sat = headache()),
|
||||
week(
|
||||
wen = headache(spifen = true),
|
||||
thu = headache(),
|
||||
sat = headache(spifen = true),
|
||||
),
|
||||
day(number = 31),
|
||||
week(wen = headache(), fry = null, sat = null, sun = null),
|
||||
),
|
||||
month(
|
||||
month = java.util.Calendar.AUGUST,
|
||||
week(mon = null, tue = null, wen = null, thu = null),
|
||||
week(wen = headache(), fry = headache()),
|
||||
week(fry = headache(spifen = true)),
|
||||
week(tue = headache(spifen = true), fry = headache()),
|
||||
week(
|
||||
tue = headache(spifen = true, eletriptan = true),
|
||||
wen = headache(),
|
||||
sat = headache(spifen = true),
|
||||
),
|
||||
),
|
||||
)
|
||||
month(
|
||||
month = java.util.Calendar.SEPTEMBER,
|
||||
week(
|
||||
tue = headache(spifen = true, eletriptan = true),
|
||||
wen = headache(spifen = true),
|
||||
fry = headache(),
|
||||
sat = headache(),
|
||||
sun = headache(),
|
||||
),
|
||||
week(
|
||||
sun = headache(spifen = true),
|
||||
),
|
||||
week(
|
||||
wen = headache(spifen = true),
|
||||
tue = headache(),
|
||||
),
|
||||
week(),
|
||||
week(wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.pixelized.headache.utils.extention
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.calculateEndPadding
|
||||
import androidx.compose.foundation.layout.calculateStartPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
|
||||
@ReadOnlyComposable
|
||||
@Composable
|
||||
fun PaddingValues.calculate(
|
||||
direction: LayoutDirection = LocalLayoutDirection.current,
|
||||
): ComputedPaddingValue {
|
||||
return ComputedPaddingValue(
|
||||
start = calculateStartPadding(layoutDirection = direction),
|
||||
top = calculateTopPadding(),
|
||||
end = calculateEndPadding(layoutDirection = direction),
|
||||
bottom = calculateBottomPadding(),
|
||||
)
|
||||
}
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
data class ComputedPaddingValue(
|
||||
@Stable
|
||||
val start: Dp,
|
||||
@Stable
|
||||
val top: Dp,
|
||||
@Stable
|
||||
val end: Dp,
|
||||
@Stable
|
||||
val bottom: Dp,
|
||||
) : PaddingValues {
|
||||
override fun calculateLeftPadding(layoutDirection: LayoutDirection): Dp = start
|
||||
|
||||
override fun calculateTopPadding(): Dp = top
|
||||
|
||||
override fun calculateRightPadding(layoutDirection: LayoutDirection): Dp = end
|
||||
|
||||
override fun calculateBottomPadding(): Dp = bottom
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue