Add year summary feature
This commit is contained in:
parent
62c3639a9e
commit
51bf0c7496
26 changed files with 852 additions and 41 deletions
6
.idea/deploymentTargetSelector.xml
generated
6
.idea/deploymentTargetSelector.xml
generated
|
|
@ -5,9 +5,6 @@
|
|||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="testPill()">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="EventFactoryText">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
|
|
@ -17,6 +14,9 @@
|
|||
<SelectionState runConfigName="EventEditPreview">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="YearPreview">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -13,6 +13,7 @@ import com.pixelized.headache.ui.navigation.destination.calendarChooserDestinati
|
|||
import com.pixelized.headache.ui.navigation.destination.eventDestinationEntry
|
||||
import com.pixelized.headache.ui.navigation.destination.homeDestinationEntry
|
||||
import com.pixelized.headache.ui.navigation.destination.monthSummaryDestinationEntry
|
||||
import com.pixelized.headache.ui.navigation.destination.yearSummaryDestinationEntry
|
||||
|
||||
val LocalNavigator = staticCompositionLocalOf<Navigator> {
|
||||
error("Local Navigation no yet ready")
|
||||
|
|
@ -42,6 +43,7 @@ fun MainNavDisplay(
|
|||
calendarChooserDestinationEntry()
|
||||
eventDestinationEntry()
|
||||
monthSummaryDestinationEntry()
|
||||
yearSummaryDestinationEntry()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.pixelized.headache.ui.navigation.destination
|
|||
import androidx.navigation3.runtime.EntryProviderBuilder
|
||||
import androidx.navigation3.runtime.entry
|
||||
import com.pixelized.headache.ui.navigation.Navigator
|
||||
import com.pixelized.headache.ui.page.summary.MonthSummaryPage
|
||||
import com.pixelized.headache.ui.page.summary.month.MonthSummaryPage
|
||||
|
||||
data object MonthSummaryDestination
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package com.pixelized.headache.ui.navigation.destination
|
||||
|
||||
import androidx.navigation3.runtime.EntryProviderBuilder
|
||||
import androidx.navigation3.runtime.entry
|
||||
import com.pixelized.headache.ui.navigation.Navigator
|
||||
import com.pixelized.headache.ui.page.summary.year.YearSummaryPage
|
||||
|
||||
|
||||
data object YearSummaryDestination
|
||||
|
||||
fun EntryProviderBuilder<*>.yearSummaryDestinationEntry() {
|
||||
entry<YearSummaryDestination> {
|
||||
YearSummaryPage()
|
||||
}
|
||||
}
|
||||
|
||||
fun Navigator.navigateToYearSummary() {
|
||||
goTo(YearSummaryDestination)
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import com.pixelized.headache.R
|
||||
import com.pixelized.headache.ui.common.error.HandleErrorMessage
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.capitalize
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Date
|
||||
|
|
@ -223,20 +224,60 @@ private class EventEditPreviewPreviewProvider : PreviewParameterProvider<EventEd
|
|||
id = null,
|
||||
date = Date(),
|
||||
pills = listOf(
|
||||
EventPillEditUio(id = 0, label = "Paracétamol 1000", 0),
|
||||
EventPillEditUio(id = 1, label = "Ibuprofène 400", 0),
|
||||
EventPillEditUio(id = 2, label = "Spifen 400", 0),
|
||||
EventPillEditUio(id = 3, label = "Élétriptan 40", 0),
|
||||
EventPillEditUio(
|
||||
id = 0,
|
||||
color = HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
label = "Paracétamol 1000",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 1,
|
||||
color = HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
label = "Ibuprofène 400",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 2,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
label = "Spifen 400",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 3,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
label = "Élétriptan 40",
|
||||
amount = 0,
|
||||
),
|
||||
)
|
||||
),
|
||||
EventEditBottomSheetUio(
|
||||
id = 1,
|
||||
date = Date(),
|
||||
pills = listOf(
|
||||
EventPillEditUio(id = 0, label = "Paracétamol 1000", 0),
|
||||
EventPillEditUio(id = 1, label = "Ibuprofène 400", 0),
|
||||
EventPillEditUio(id = 2, label = "Spifen 400", 2),
|
||||
EventPillEditUio(id = 3, label = "Élétriptan 40", 1),
|
||||
EventPillEditUio(
|
||||
id = 0,
|
||||
color = HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
label = "Paracétamol 1000",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 1,
|
||||
color = HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
label = "Ibuprofène 400",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 2,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
label = "Spifen 400",
|
||||
amount = 2,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = 3,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
label = "Élétriptan 40",
|
||||
amount = 1,
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.pixelized.headache.ui.page.event.edit
|
|||
|
||||
import android.icu.util.Calendar
|
||||
import com.pixelized.headache.repository.event.Event
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.event
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
|
@ -18,21 +19,25 @@ class EventEditFactory @Inject constructor() {
|
|||
pills = listOf(
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.IBUPROFENE_400.value,
|
||||
color = HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
label = "Paracétamol 1000",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.PARACETAMOL_1000.value,
|
||||
color = HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
label = "Ibuprofène 400",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.SPIFEN_400.value,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
label = "Spifen 400",
|
||||
amount = 0,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.ELETRIPTAN_40.value,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
label = "Élétriptan 40",
|
||||
amount = 0,
|
||||
),
|
||||
|
|
@ -61,21 +66,25 @@ class EventEditFactory @Inject constructor() {
|
|||
pills = listOf(
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.IBUPROFENE_400.value,
|
||||
color = HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
label = "Paracétamol 1000",
|
||||
amount = ibuprofeneAmount,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.PARACETAMOL_1000.value,
|
||||
color = HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
label = "Ibuprofène 400",
|
||||
amount = paracetamolAmount,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.SPIFEN_400.value,
|
||||
color = HeadacheColorPalette.Pill.Spifen400,
|
||||
label = "Spifen 400",
|
||||
amount = spifenAmount,
|
||||
),
|
||||
EventPillEditUio(
|
||||
id = Event.Pill.Id.ELETRIPTAN_40.value,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
label = "Élétriptan 40",
|
||||
amount = eletriptanAmount,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ import androidx.compose.animation.fadeOut
|
|||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
|
|
@ -26,16 +29,19 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
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
|
||||
|
||||
@Stable
|
||||
data class EventPillEditUio(
|
||||
val id: Long,
|
||||
val color: Color,
|
||||
val label: String,
|
||||
val amount: Int,
|
||||
)
|
||||
|
|
@ -87,6 +93,18 @@ fun EventPillEdit(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
text = "-",
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.CenterVertically)
|
||||
.size(12.dp)
|
||||
.background(color = item.color)
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
|
|
@ -148,6 +166,7 @@ private fun EventPillEditPreview() {
|
|||
EventPillEdit(
|
||||
item = EventPillEditUio(
|
||||
id = 0,
|
||||
color = HeadacheColorPalette.Pill.Eletriptan40,
|
||||
label = "Élétriptan 40",
|
||||
amount = 2,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.pixelized.headache.ui.navigation.LocalNavigator
|
|||
import com.pixelized.headache.ui.navigation.destination.navigateToCalendarChooserPage
|
||||
import com.pixelized.headache.ui.navigation.destination.navigateToEventPage
|
||||
import com.pixelized.headache.ui.navigation.destination.navigateToMonthSummary
|
||||
import com.pixelized.headache.ui.navigation.destination.navigateToYearSummary
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -45,6 +46,9 @@ fun HomePage() {
|
|||
onMonthSummary = {
|
||||
navigation.navigateToMonthSummary()
|
||||
},
|
||||
onYearSummary = {
|
||||
navigation.navigateToYearSummary()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +59,7 @@ private fun HomePageContent(
|
|||
onCalendarChooser: () -> Unit,
|
||||
onEvent: () -> Unit,
|
||||
onMonthSummary: () -> Unit,
|
||||
onYearSummary: () -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
|
|
@ -87,6 +92,12 @@ private fun HomePageContent(
|
|||
onClick = onMonthSummary,
|
||||
)
|
||||
}
|
||||
item {
|
||||
NavigationItem(
|
||||
label = stringResource(R.string.year_summary_title),
|
||||
onClick = onYearSummary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
package com.pixelized.headache.ui.page.summary.item
|
||||
package com.pixelized.headache.ui.page.summary.month
|
||||
|
||||
import android.icu.util.Calendar
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.pixelized.headache.repository.event.Event
|
||||
import com.pixelized.headache.ui.page.summary.MonthSummaryPillItemUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryBoxUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryCell
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryItemUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryPillItemUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryTitleUio
|
||||
import com.pixelized.headache.utils.extention.event
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class MonthSummaryFactory @Inject constructor() {
|
||||
private val calendar = Calendar.getInstance()
|
||||
|
|
@ -86,11 +89,11 @@ class MonthSummaryFactory @Inject constructor() {
|
|||
date = calendar.apply { event = entry.key }.time,
|
||||
headacheRatio = entry.value.size.toFloat() / monthMaxDay,
|
||||
headacheAmount = entry.value.size,
|
||||
headacheColor = Color.Red,
|
||||
headacheColor = Color.Companion.Red,
|
||||
pillRatio = pillAmount.takeIf { it > 0 }
|
||||
?.let { it.toFloat() / maxPillAmount.toFloat() },
|
||||
pillAmount = pillAmount,
|
||||
pillColor = Color.Blue,
|
||||
pillColor = Color.Companion.Blue,
|
||||
)
|
||||
}
|
||||
.sortedByDescending { it.date }
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary
|
||||
package com.pixelized.headache.ui.page.summary.month
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.fadeIn
|
||||
|
|
@ -44,13 +44,14 @@ 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.item.MonthSummaryBox
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryBoxUio
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryCell
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryItem
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryItemUio
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryTitle
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryTitleUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryBox
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryBoxUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryCell
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryItem
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryItemUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryPillItemUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryTitle
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryTitleUio
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import java.util.Date
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
package com.pixelized.headache.ui.page.summary
|
||||
package com.pixelized.headache.ui.page.summary.month
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.headache.repository.event.Event
|
||||
import com.pixelized.headache.repository.event.EventRepository
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryCell
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryFactory
|
||||
import com.pixelized.headache.ui.page.summary.item.MonthSummaryTitleUio
|
||||
import com.pixelized.headache.ui.page.summary.month.item.MonthSummaryCell
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary.item
|
||||
package com.pixelized.headache.ui.page.summary.month.item
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.icu.text.SimpleDateFormat
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary.item
|
||||
package com.pixelized.headache.ui.page.summary.month.item
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import java.util.Date
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary.item
|
||||
package com.pixelized.headache.ui.page.summary.month.item
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.icu.text.SimpleDateFormat
|
||||
|
|
@ -14,14 +14,13 @@ import androidx.compose.material3.Surface
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
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.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.headache.ui.page.summary.MonthSummaryPillItem
|
||||
import com.pixelized.headache.ui.page.summary.MonthSummaryPillItemUio
|
||||
import com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.capitalize
|
||||
|
|
@ -68,11 +67,10 @@ fun MonthSummaryItem(
|
|||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = spacing.width)
|
||||
) {
|
||||
formatter.format(item.date)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
text = formatter.format(item.date).capitalize(),
|
||||
text = remember(formatter, item.date) { formatter.format(item.date) }.capitalize(),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary
|
||||
package com.pixelized.headache.ui.page.summary.month.item
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.headache.ui.page.summary.item
|
||||
package com.pixelized.headache.ui.page.summary.month.item
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.icu.text.SimpleDateFormat
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package com.pixelized.headache.ui.page.summary.year
|
||||
|
||||
import android.icu.util.Calendar
|
||||
import com.pixelized.headache.repository.event.Event
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryDayUio
|
||||
import com.pixelized.headache.ui.page.summary.year.item.YearSummaryMonthUio
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class YearSummaryFactory @Inject constructor() {
|
||||
|
||||
fun convertToUio(
|
||||
events: Collection<Event>,
|
||||
): List<YearUio> {
|
||||
|
||||
val monthFirstDayCalendar = Calendar.getInstance().apply {
|
||||
firstDayOfWeek = Calendar.MONDAY
|
||||
setMinimalDaysInFirstWeek(1)
|
||||
}
|
||||
val monthLastDayCalendar = Calendar.getInstance().apply {
|
||||
firstDayOfWeek = Calendar.MONDAY
|
||||
setMinimalDaysInFirstWeek(1)
|
||||
}
|
||||
val currentDayCalendar = Calendar.getInstance().apply {
|
||||
firstDayOfWeek = Calendar.MONDAY
|
||||
setMinimalDaysInFirstWeek(1)
|
||||
}
|
||||
|
||||
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 months = years.getOrPut(key = event.date.month) { hashMapOf() }
|
||||
months[event.date.day] = event
|
||||
}
|
||||
}
|
||||
.map { yearEntry ->
|
||||
YearUio(
|
||||
year = yearEntry.key,
|
||||
months = yearEntry.value.map { monthEntry ->
|
||||
monthFirstDayCalendar.apply {
|
||||
set(Calendar.YEAR, yearEntry.key)
|
||||
set(Calendar.MONTH, monthEntry.key)
|
||||
set(Calendar.DAY_OF_MONTH, 1)
|
||||
set(Calendar.MILLISECONDS_IN_DAY, 1)
|
||||
}
|
||||
monthLastDayCalendar.apply {
|
||||
time = monthFirstDayCalendar.time
|
||||
add(Calendar.MONTH, 1)
|
||||
add(Calendar.DAY_OF_MONTH, -1)
|
||||
}
|
||||
currentDayCalendar.apply {
|
||||
time = monthFirstDayCalendar.time
|
||||
}
|
||||
val initial = MutableList(
|
||||
size = monthLastDayCalendar.get(Calendar.WEEK_OF_MONTH),
|
||||
) {
|
||||
mutableListOf<YearSummaryDayUio>()
|
||||
}
|
||||
val weeks = (1..monthLastDayCalendar.get(Calendar.DAY_OF_MONTH))
|
||||
.fold(initial = initial) { accumulator, dayNumber ->
|
||||
val event: Event? = monthEntry.value.get(dayNumber)
|
||||
val weekIndex = currentDayCalendar
|
||||
.apply {
|
||||
set(Calendar.YEAR, yearEntry.key)
|
||||
set(Calendar.MONTH, monthEntry.key)
|
||||
set(Calendar.DAY_OF_MONTH, dayNumber)
|
||||
set(Calendar.MILLISECONDS_IN_DAY, 1)
|
||||
}
|
||||
.get(Calendar.WEEK_OF_MONTH) - 1
|
||||
val day = YearSummaryDayUio(
|
||||
number = dayNumber,
|
||||
headache = event != null,
|
||||
pills = event?.pills?.map { it.color } ?: emptyList(),
|
||||
)
|
||||
accumulator.also { acc ->
|
||||
acc[weekIndex] = acc.get(index = weekIndex).also { week ->
|
||||
week.add(day)
|
||||
}
|
||||
}
|
||||
}
|
||||
YearSummaryMonthUio(
|
||||
date = monthFirstDayCalendar.time,
|
||||
weeks = weeks,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
.sortedByDescending { it.year }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
package com.pixelized.headache.ui.page.summary.year
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
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.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.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.pixelized.headache.R
|
||||
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 java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
@Stable
|
||||
data class YearUio(
|
||||
val year: Int,
|
||||
val months: List<YearSummaryMonthUio>,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun YearSummaryPage(
|
||||
viewModel: YearSummaryViewModel = hiltViewModel(),
|
||||
editViewModel: EventEditBottomSheetViewModel = hiltViewModel(),
|
||||
) {
|
||||
val navigation = LocalNavigator.current
|
||||
val uio = viewModel.events.collectAsStateWithLifecycle()
|
||||
|
||||
YearSummaryContent(
|
||||
modifier = Modifier
|
||||
.systemBarsPadding()
|
||||
.fillMaxSize(),
|
||||
uio = uio,
|
||||
onBack = {
|
||||
navigation.popBackstack()
|
||||
},
|
||||
onMonth = {
|
||||
navigation.navigateToEventPage(date = it.date)
|
||||
},
|
||||
onAddEvent = {
|
||||
editViewModel.show()
|
||||
},
|
||||
)
|
||||
|
||||
EventEditBottomSheet(
|
||||
viewModel = editViewModel,
|
||||
onDismissRequest = { editViewModel.dismiss() },
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun YearSummaryContent(
|
||||
modifier: Modifier = Modifier,
|
||||
uio: State<List<YearUio>>,
|
||||
onBack: () -> Unit,
|
||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||
onAddEvent: () -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = onBack,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(text = stringResource(R.string.year_summary_title))
|
||||
},
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
shape = CircleShape,
|
||||
onClick = onAddEvent,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Add,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
content = { paddingValues ->
|
||||
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,
|
||||
),
|
||||
) {
|
||||
uio.value.forEachIndexed { index, (year, months) ->
|
||||
item(
|
||||
span = { GridItemSpan(maxCurrentLineSpan) },
|
||||
contentType = { "Title" },
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
top = when (index) {
|
||||
0 -> 0.dp
|
||||
else -> 16.dp
|
||||
}
|
||||
),
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
text = "$year",
|
||||
)
|
||||
}
|
||||
items(
|
||||
items = months,
|
||||
key = { it.date.time },
|
||||
contentType = { "Month" },
|
||||
) {
|
||||
YearSummaryMonth(
|
||||
uio = it,
|
||||
onMonth = onMonth,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun YearSummaryPreview(
|
||||
@PreviewParameter(YearPreviewProvider::class) preview: List<YearUio>,
|
||||
) {
|
||||
HeadacheTheme {
|
||||
Surface {
|
||||
YearSummaryContent(
|
||||
uio = remember { mutableStateOf(preview) },
|
||||
onBack = { },
|
||||
onMonth = { },
|
||||
onAddEvent = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class YearPreviewProvider() : PreviewParameterProvider<List<YearUio>> {
|
||||
|
||||
private fun year(
|
||||
year: Int,
|
||||
vararg months: YearSummaryMonthUio,
|
||||
) = YearUio(
|
||||
year = year,
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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)),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.pixelized.headache.ui.page.summary.year
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.headache.repository.event.EventRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class YearSummaryViewModel @Inject constructor(
|
||||
eventRepository: EventRepository,
|
||||
summaryFactory: YearSummaryFactory,
|
||||
) : ViewModel() {
|
||||
|
||||
val events: StateFlow<List<YearUio>> = eventRepository
|
||||
.eventsListFlow()
|
||||
.map(summaryFactory::convertToUio)
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.Lazily,
|
||||
initialValue = emptyList(),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package com.pixelized.headache.ui.page.summary.year.item
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
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.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
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
|
||||
|
||||
@Stable
|
||||
object YearSummaryDayDefault {
|
||||
@Stable
|
||||
val size: Dp = 16.dp
|
||||
|
||||
@Stable
|
||||
val pill: Dp = 2.dp
|
||||
}
|
||||
|
||||
@Stable
|
||||
data class YearSummaryDayUio(
|
||||
val number: Int,
|
||||
val headache: Boolean,
|
||||
val pills: List<Color>,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun YearSummaryDay(
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = YearSummaryDayDefault.size,
|
||||
pill: Dp = YearSummaryDayDefault.pill,
|
||||
day: YearSummaryDayUio,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size = size)
|
||||
.then(other = modifier),
|
||||
) {
|
||||
if (day.headache) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(vertical = pill + 1.dp)
|
||||
.background(color = HeadacheColorPalette.Pill.Unknown)
|
||||
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.align(alignment = Alignment.Center),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
text = "${day.number}",
|
||||
)
|
||||
if (day.headache) {
|
||||
Row(
|
||||
modifier = Modifier.align(alignment = Alignment.BottomCenter),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 1.dp),
|
||||
) {
|
||||
day.pills.forEach {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(color = it)
|
||||
.size(size = pill)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun YearSummaryDayPreview(
|
||||
@PreviewParameter(DayPreviewProvider::class) preview: YearSummaryDayUio,
|
||||
) {
|
||||
HeadacheTheme {
|
||||
YearSummaryDay(
|
||||
day = preview,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class DayPreviewProvider() : PreviewParameterProvider<YearSummaryDayUio> {
|
||||
override val values: Sequence<YearSummaryDayUio>
|
||||
get() = sequenceOf(
|
||||
YearSummaryDayUio(
|
||||
number = 1,
|
||||
headache = false,
|
||||
pills = emptyList(),
|
||||
),
|
||||
YearSummaryDayUio(
|
||||
number = 2,
|
||||
headache = true,
|
||||
pills = emptyList(),
|
||||
),
|
||||
YearSummaryDayUio(
|
||||
number = 3,
|
||||
headache = true,
|
||||
pills = listOf(
|
||||
HeadacheColorPalette.Pill.Eletriptan40,
|
||||
),
|
||||
),
|
||||
YearSummaryDayUio(
|
||||
number = 3,
|
||||
headache = true,
|
||||
pills = listOf(
|
||||
HeadacheColorPalette.Pill.Eletriptan40,
|
||||
HeadacheColorPalette.Pill.Ibuprofene400,
|
||||
HeadacheColorPalette.Pill.Spifen400,
|
||||
HeadacheColorPalette.Pill.Paracetamol1000,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
package com.pixelized.headache.ui.page.summary.year.item
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.icu.text.DateFormat
|
||||
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.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
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 com.pixelized.headache.ui.theme.HeadacheTheme
|
||||
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
|
||||
import com.pixelized.headache.utils.extention.capitalize
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
@Stable
|
||||
data object YearSummaryMonthDefault {
|
||||
@SuppressLint("ConstantLocale")
|
||||
@Stable
|
||||
val formatter = SimpleDateFormat("MMMM", Locale.getDefault())
|
||||
}
|
||||
|
||||
@Stable
|
||||
data class YearSummaryMonthUio(
|
||||
val date: Date,
|
||||
val weeks: List<List<YearSummaryDayUio>>,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun YearSummaryMonth(
|
||||
modifier: Modifier = Modifier,
|
||||
formatter: DateFormat = YearSummaryMonthDefault.formatter,
|
||||
uio: YearSummaryMonthUio,
|
||||
onMonth: (YearSummaryMonthUio) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = ripple(bounded = false),
|
||||
onClick = { onMonth(uio) }
|
||||
)
|
||||
.then(other = modifier),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.align(alignment = Alignment.Start),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
text = remember(uio.date) { formatter.format(uio.date) }.capitalize(),
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.height(height = remember { YearSummaryDayDefault.size * 6 }),
|
||||
) {
|
||||
uio.weeks.forEachIndexed { index, week ->
|
||||
Row(
|
||||
modifier = Modifier.width(width = remember { YearSummaryDayDefault.size * 7 }),
|
||||
horizontalArrangement = when (index) {
|
||||
0 -> Arrangement.End
|
||||
else -> Arrangement.Start
|
||||
},
|
||||
) {
|
||||
week.forEach { day ->
|
||||
YearSummaryDay(day = day)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun YearSummaryMonthPreview(
|
||||
@PreviewParameter(MonthPreviewProvider::class) preview: YearSummaryMonthUio,
|
||||
) {
|
||||
HeadacheTheme {
|
||||
Surface {
|
||||
YearSummaryMonth(
|
||||
uio = preview,
|
||||
onMonth = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MonthPreviewProvider() : PreviewParameterProvider<YearSummaryMonthUio> {
|
||||
|
||||
fun day(
|
||||
number: Int,
|
||||
headache: Boolean = false,
|
||||
pills: List<Color> = emptyList(),
|
||||
): YearSummaryDayUio = YearSummaryDayUio(
|
||||
number = number,
|
||||
headache = headache,
|
||||
pills = pills,
|
||||
)
|
||||
|
||||
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),
|
||||
),
|
||||
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),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ object HeadacheColorPalette {
|
|||
val Ibuprofene400 = Additional.Blue
|
||||
val Paracetamol1000 = Additional.Green
|
||||
val Spifen400 = Additional.Yellow
|
||||
val Eletriptan40 = Additional.Pink
|
||||
val Eletriptan40 = Additional.VeryLightPink
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@
|
|||
|
||||
<string name="calendar_chooser_title">Choix du calendrier</string>
|
||||
<string name="event_title">Évennement migraineux</string>
|
||||
<string name="month_summary_title">Suivi des migraines</string>
|
||||
<string name="month_summary_title">Suivi mensuel</string>
|
||||
<string name="year_summary_title">Suivi annuel</string>
|
||||
</resources>
|
||||
|
|
@ -8,5 +8,6 @@
|
|||
|
||||
<string name="calendar_chooser_title">Choose your calendar</string>
|
||||
<string name="event_title">Headache event</string>
|
||||
<string name="month_summary_title">Headache summary</string>
|
||||
<string name="month_summary_title">Monthly follow-up</string>
|
||||
<string name="year_summary_title">Annual follow-up</string>
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue