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 Specific cases
|
||||||
app/release/output.json
|
app/release/output.json
|
||||||
.idea/codeStyles/
|
.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.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.keepScreenOn
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
|
@ -77,6 +78,7 @@ fun MonthSummaryPage(
|
||||||
|
|
||||||
MonthSummaryContent(
|
MonthSummaryContent(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.keepScreenOn()
|
||||||
.systemBarsPadding()
|
.systemBarsPadding()
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
events = events,
|
events = events,
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ class YearSummaryFactory @Inject constructor() {
|
||||||
firstDayOfWeek = Calendar.MONDAY
|
firstDayOfWeek = Calendar.MONDAY
|
||||||
setMinimalDaysInFirstWeek(1)
|
setMinimalDaysInFirstWeek(1)
|
||||||
}
|
}
|
||||||
val monthLastDayCalendar = Calendar.getInstance().apply {
|
val monthLastDayCalendar = Calendar.getInstance().apply {
|
||||||
firstDayOfWeek = Calendar.MONDAY
|
firstDayOfWeek = Calendar.MONDAY
|
||||||
setMinimalDaysInFirstWeek(1)
|
setMinimalDaysInFirstWeek(1)
|
||||||
}
|
}
|
||||||
val currentDayCalendar = Calendar.getInstance().apply {
|
val currentDayCalendar = Calendar.getInstance().apply {
|
||||||
firstDayOfWeek = Calendar.MONDAY
|
firstDayOfWeek = Calendar.MONDAY
|
||||||
setMinimalDaysInFirstWeek(1)
|
setMinimalDaysInFirstWeek(1)
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,22 @@ class YearSummaryFactory @Inject constructor() {
|
||||||
return events
|
return events
|
||||||
.fold(initial = hashMapOf<Int, HashMap<Int, HashMap<Int, Event>>>()) { acc, event ->
|
.fold(initial = hashMapOf<Int, HashMap<Int, HashMap<Int, Event>>>()) { acc, event ->
|
||||||
acc.also {
|
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() }
|
val months = years.getOrPut(key = event.date.month) { hashMapOf() }
|
||||||
months[event.date.day] = event
|
months[event.date.day] = event
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,14 @@ import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
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.navigation.destination.navigateToEventPage
|
||||||
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheet
|
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheet
|
||||||
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheetViewModel
|
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.YearSummaryDayUio
|
||||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryMonth
|
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.page.summary.year.item.YearSummaryMonthUio
|
||||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
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.Calendar
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data class YearUio(
|
data class YearUio(
|
||||||
|
|
@ -67,6 +70,7 @@ fun YearSummaryPage(
|
||||||
YearSummaryContent(
|
YearSummaryContent(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.systemBarsPadding()
|
.systemBarsPadding()
|
||||||
|
.keepScreenOn()
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
uio = uio,
|
uio = uio,
|
||||||
onBack = {
|
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)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun YearSummaryContent(
|
fun YearSummaryContent(
|
||||||
modifier: Modifier = Modifier,
|
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>>,
|
uio: State<List<YearUio>>,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||||
|
|
@ -126,24 +159,16 @@ fun YearSummaryContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
content = { paddingValues ->
|
content = { it ->
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
modifier = Modifier.padding(paddingValues = paddingValues),
|
modifier = Modifier.padding(paddingValues = it),
|
||||||
columns = GridCells.Adaptive(
|
columns = GridCells.Adaptive(minSize = daySize * 7),
|
||||||
minSize = YearSummaryDayDefault.size * 7,
|
horizontalArrangement = Arrangement.spacedBy(space = space),
|
||||||
),
|
contentPadding = paddingValues,
|
||||||
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,
|
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
uio.value.forEachIndexed { index, (year, months) ->
|
uio.value.forEachIndexed { index, (year, months) ->
|
||||||
item(
|
item(
|
||||||
span = { GridItemSpan(maxCurrentLineSpan) },
|
span = { GridItemSpan(maxLineSpan) },
|
||||||
contentType = { "Title" },
|
contentType = { "Title" },
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -164,6 +189,7 @@ fun YearSummaryContent(
|
||||||
) {
|
) {
|
||||||
YearSummaryMonth(
|
YearSummaryMonth(
|
||||||
uio = it,
|
uio = it,
|
||||||
|
daySize = daySize,
|
||||||
onMonth = onMonth,
|
onMonth = onMonth,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +200,7 @@ fun YearSummaryContent(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview()
|
||||||
private fun YearSummaryPreview(
|
private fun YearSummaryPreview(
|
||||||
@PreviewParameter(YearPreviewProvider::class) preview: List<YearUio>,
|
@PreviewParameter(YearPreviewProvider::class) preview: List<YearUio>,
|
||||||
) {
|
) {
|
||||||
|
|
@ -192,6 +218,65 @@ private fun YearSummaryPreview(
|
||||||
|
|
||||||
private class YearPreviewProvider() : PreviewParameterProvider<List<YearUio>> {
|
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(
|
private fun year(
|
||||||
year: Int,
|
year: Int,
|
||||||
vararg months: YearSummaryMonthUio,
|
vararg months: YearSummaryMonthUio,
|
||||||
|
|
@ -200,76 +285,197 @@ private class YearPreviewProvider() : PreviewParameterProvider<List<YearUio>> {
|
||||||
months = months.toList(),
|
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(
|
override val values: Sequence<List<YearUio>> = sequenceOf(
|
||||||
listOf(
|
listOf(
|
||||||
year(
|
year(
|
||||||
year = 2025,
|
year = 2025,
|
||||||
month(
|
month(
|
||||||
month = Calendar.getInstance().apply {
|
month = Calendar.JANUARY,
|
||||||
set(Calendar.YEAR, 2025)
|
year = 2025,
|
||||||
set(Calendar.MONTH, Calendar.JANUARY)
|
week(mon = null, tue = null),
|
||||||
}.time,
|
week(),
|
||||||
week(day(1), day(2), day(3), day(4), day(5)),
|
week(),
|
||||||
week(day(6), day(7), day(8), day(9), day(10), day(11), day(12)),
|
week(),
|
||||||
week(day(13), day(14), day(15), day(16), day(17), day(18), day(19)),
|
week(sat = null, sun = null),
|
||||||
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(
|
month(
|
||||||
month = Calendar.getInstance().apply {
|
month = Calendar.FEBRUARY,
|
||||||
set(Calendar.YEAR, 2025)
|
year = 2025,
|
||||||
set(Calendar.MONTH, Calendar.FEBRUARY)
|
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||||
}.time,
|
week(),
|
||||||
week(day(1), day(2)),
|
week(),
|
||||||
week(day(3), day(4), day(5), day(6), day(7), day(8), day(9)),
|
week(),
|
||||||
week(day(10), day(11), day(12), day(13), day(14), day(15), day(16)),
|
week(sat = null, sun = null),
|
||||||
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(
|
month(
|
||||||
month = Calendar.getInstance().apply {
|
month = Calendar.MARCH,
|
||||||
set(Calendar.YEAR, 2025)
|
year = 2025,
|
||||||
set(Calendar.MONTH, Calendar.MARCH)
|
week(mon = null, tue = null, wen = null, thu = null, fry = null),
|
||||||
}.time,
|
week(),
|
||||||
week(day(1), day(2)),
|
week(),
|
||||||
week(day(3), day(4), day(5), day(6), day(7), day(8), day(9)),
|
week(),
|
||||||
week(day(10), day(11), day(12), day(13), day(14), day(15), day(16)),
|
week(),
|
||||||
week(day(17), day(18), day(19), day(20), day(21), day(22), day(23)),
|
week(tue = null, wen = null, thu = null, fry = null, sat = null, sun = null),
|
||||||
week(day(24), day(25), day(26), day(27), day(28), day(29), day(30)),
|
|
||||||
week(day(31)),
|
|
||||||
),
|
),
|
||||||
month(
|
month(
|
||||||
month = Calendar.getInstance().apply {
|
month = Calendar.APRIL,
|
||||||
set(Calendar.YEAR, 2025)
|
year = 2025,
|
||||||
set(Calendar.MONTH, Calendar.APRIL)
|
week(mon = null),
|
||||||
}.time,
|
week(),
|
||||||
week(day(1), day(2), day(3), day(4), day(5), day(6)),
|
week(),
|
||||||
week(day(7), day(8), day(9), day(10), day(11), day(12), day(13)),
|
week(),
|
||||||
week(day(14), day(15), day(16), day(17), day(18), day(19), day(20)),
|
week(thu = null, fry = null, sat = null, sun = null),
|
||||||
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(
|
||||||
|
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
|
package com.pixelized.headache.ui.page.summary.year.item
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
|
|
@ -53,17 +54,22 @@ fun YearSummaryDay(
|
||||||
if (day.headache) {
|
if (day.headache) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.matchParentSize()
|
||||||
.padding(vertical = pill + 1.dp)
|
.padding(vertical = pill + 1.dp)
|
||||||
.background(color = HeadacheColorPalette.Pill.Unknown)
|
.background(color = HeadacheColorPalette.Pill.Unknown)
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.align(alignment = Alignment.Center),
|
modifier = Modifier.align(alignment = Alignment.Center),
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
color = when {
|
||||||
|
!isSystemInDarkTheme() && day.headache -> Color.White
|
||||||
|
else -> MaterialTheme.colorScheme.onSurface
|
||||||
|
},
|
||||||
text = "${day.number}",
|
text = "${day.number}",
|
||||||
)
|
)
|
||||||
|
|
||||||
if (day.headache) {
|
if (day.headache) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.align(alignment = Alignment.BottomCenter),
|
modifier = Modifier.align(alignment = Alignment.BottomCenter),
|
||||||
|
|
@ -87,9 +93,12 @@ private fun YearSummaryDayPreview(
|
||||||
@PreviewParameter(DayPreviewProvider::class) preview: YearSummaryDayUio,
|
@PreviewParameter(DayPreviewProvider::class) preview: YearSummaryDayUio,
|
||||||
) {
|
) {
|
||||||
HeadacheTheme {
|
HeadacheTheme {
|
||||||
YearSummaryDay(
|
Surface {
|
||||||
day = preview,
|
YearSummaryDay(
|
||||||
)
|
modifier = Modifier.size(size = 16.dp),
|
||||||
|
day = preview,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ import android.icu.text.SimpleDateFormat
|
||||||
import android.icu.util.Calendar
|
import android.icu.util.Calendar
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
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.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -20,10 +20,11 @@ import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
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.HeadacheTheme
|
||||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||||
import com.pixelized.headache.utils.extention.capitalize
|
import com.pixelized.headache.utils.extention.capitalize
|
||||||
|
|
@ -47,6 +48,7 @@ data class YearSummaryMonthUio(
|
||||||
fun YearSummaryMonth(
|
fun YearSummaryMonth(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
formatter: DateFormat = YearSummaryMonthDefault.formatter,
|
formatter: DateFormat = YearSummaryMonthDefault.formatter,
|
||||||
|
daySize: Dp,
|
||||||
uio: YearSummaryMonthUio,
|
uio: YearSummaryMonthUio,
|
||||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
@ -64,20 +66,22 @@ fun YearSummaryMonth(
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
text = remember(uio.date) { formatter.format(uio.date) }.capitalize(),
|
text = remember(uio.date) { formatter.format(uio.date) }.capitalize(),
|
||||||
)
|
)
|
||||||
Column(
|
Box(
|
||||||
modifier = Modifier.height(height = remember { YearSummaryDayDefault.size * 6 }),
|
modifier = Modifier.size(width = daySize * 7, height = daySize * 6),
|
||||||
) {
|
) {
|
||||||
uio.weeks.forEachIndexed { index, week ->
|
uio.weeks.forEachIndexed { row, week ->
|
||||||
Row(
|
week.forEachIndexed { column, day ->
|
||||||
modifier = Modifier.width(width = remember { YearSummaryDayDefault.size * 7 }),
|
YearSummaryDay(
|
||||||
horizontalArrangement = when (index) {
|
Modifier.offset(
|
||||||
0 -> Arrangement.End
|
x = when (row) {
|
||||||
else -> Arrangement.Start
|
0 -> daySize * (column + 7 - week.size)
|
||||||
},
|
else -> daySize * column
|
||||||
) {
|
},
|
||||||
week.forEach { day ->
|
y = daySize * row,
|
||||||
YearSummaryDay(day = day)
|
),
|
||||||
}
|
size = daySize,
|
||||||
|
day = day,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,6 +96,8 @@ private fun YearSummaryMonthPreview(
|
||||||
HeadacheTheme {
|
HeadacheTheme {
|
||||||
Surface {
|
Surface {
|
||||||
YearSummaryMonth(
|
YearSummaryMonth(
|
||||||
|
modifier = Modifier.padding(all = 8.dp),
|
||||||
|
daySize = YearSummaryDayDefault.size,
|
||||||
uio = preview,
|
uio = preview,
|
||||||
onMonth = { },
|
onMonth = { },
|
||||||
)
|
)
|
||||||
|
|
@ -101,85 +107,137 @@ private fun YearSummaryMonthPreview(
|
||||||
|
|
||||||
private class MonthPreviewProvider() : PreviewParameterProvider<YearSummaryMonthUio> {
|
private class MonthPreviewProvider() : PreviewParameterProvider<YearSummaryMonthUio> {
|
||||||
|
|
||||||
fun day(
|
private var day: Int = 1
|
||||||
number: Int,
|
|
||||||
headache: Boolean = false,
|
private fun day(): () -> YearSummaryDayUio = {
|
||||||
pills: List<Color> = emptyList(),
|
YearSummaryDayUio(
|
||||||
): YearSummaryDayUio = YearSummaryDayUio(
|
number = day++,
|
||||||
number = number,
|
headache = false,
|
||||||
headache = headache,
|
pills = emptyList(),
|
||||||
pills = pills,
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
override val values: Sequence<YearSummaryMonthUio>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
YearSummaryMonthUio(
|
month(
|
||||||
date = Calendar.getInstance().apply {
|
month = Calendar.MARCH,
|
||||||
set(Calendar.YEAR, 2025)
|
week(
|
||||||
set(Calendar.MONTH, Calendar.JULY)
|
mon = null,
|
||||||
}.time,
|
tue = null,
|
||||||
weeks = listOf(
|
wen = null,
|
||||||
listOf(
|
thu = null,
|
||||||
day(number = 1),
|
fry = null,
|
||||||
day(number = 2),
|
sat = headache(spifen = true)
|
||||||
day(number = 3),
|
|
||||||
day(number = 4),
|
|
||||||
),
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
listOf(
|
|
||||||
day(number = 12),
|
|
||||||
day(number = 13),
|
|
||||||
day(number = 14),
|
|
||||||
day(
|
|
||||||
number = 15,
|
|
||||||
headache = true,
|
|
||||||
pills = listOf(HeadacheColorPalette.Pill.Spifen400),
|
|
||||||
),
|
|
||||||
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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
day(number = 27, headache = true),
|
|
||||||
day(number = 28),
|
|
||||||
day(number = 29),
|
|
||||||
day(
|
|
||||||
number = 30,
|
|
||||||
headache = true,
|
|
||||||
pills = listOf(HeadacheColorPalette.Pill.Spifen400),
|
|
||||||
),
|
|
||||||
day(number = 31),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
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)
|
||||||
|
),
|
||||||
|
week(
|
||||||
|
mon = headache(),
|
||||||
|
tue = headache(),
|
||||||
|
sat = headache(spifen = true, eletriptan = true),
|
||||||
|
),
|
||||||
|
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
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
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