From 7d2508a4dec22e29de3c551380d2c4339567ac47 Mon Sep 17 00:00:00 2001 From: "Andres Gomez, Thomas (ITDV RL)" Date: Mon, 22 Sep 2025 16:21:09 +0200 Subject: [PATCH] CleanUp and refactor on the Annual Followup --- .gitignore | 5 +- app/release/baselineProfiles/0/app-release.dm | Bin 4568 -> 4581 bytes app/release/baselineProfiles/1/app-release.dm | Bin 4520 -> 4543 bytes .../ui/page/summary/month/MonthSummaryPage.kt | 2 + .../page/summary/year/YearSummaryFactory.kt | 21 +- .../ui/page/summary/year/YearSummaryPage.kt | 360 ++++++++++++++---- .../page/summary/year/item/YearSummaryDay.kt | 21 +- .../summary/year/item/YearSummaryMonth.kt | 244 +++++++----- .../extention/PaddingValueEx+calculate.kt | 46 +++ 9 files changed, 519 insertions(+), 180 deletions(-) create mode 100644 app/src/main/java/com/pixelized/headache/utils/extention/PaddingValueEx+calculate.kt diff --git a/.gitignore b/.gitignore index ab7bd38..c81e610 100644 --- a/.gitignore +++ b/.gitignore @@ -74,4 +74,7 @@ lint/tmp/ .DS_Store # App Specific cases app/release/output.json -.idea/codeStyles/ \ No newline at end of file +.idea/codeStyles/ + +.kotlin/sessions +app/release \ No newline at end of file diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm index 9773a27447879a819c976987c4cbc5d1380cbc1d..f3c8975c83144b16da34d0776931eddae74ef7c6 100644 GIT binary patch literal 4581 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 diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm index 4b8215a676b675860eab6879f7fdd8b3c273e21c..fb2a7fd61d4260a53ff95e68d5096ec9e83d2040 100644 GIT binary patch literal 4543 zcmWIWW@Zs#;Nak3Fl#c4W_P zV3@(jz)->XHYPhq=Bntv*IW1YJ-*SV^2G7PEENaUMMnY~*+e(Fc}8FP=Falhku{fx z_3OeAUas7=s|s4+EmwrPh5Kq8<*|nxfhvw!R4j4xO?=erSspFoS11T z`m5*TF$qESV_wfSj_q-*UPW!;ah zS+`p1UNz?(TOc6+#pR~&FO9zs68EobOqc(e(Y;KYUClmYEC1m=iM21(^|O1G_sba< zt}xtQBA@U;!Ta^0o1)p}68=)B_IPDzOy99`#o;oC=bH|Qy=wnELtERa;@jeDMH|u* z|GloW{bwLod*G$5-{mVzGI8Bo&ps@D)-xgBQTVMgEF+;)zna+a-GTu8**P5~ftWr{)WP_AQY-VfoN- zp~p_ex?XilcX+*76>{C@fwpMz-u3=hD=gWUIqM`czkT@QYZPZQQx!8P~)Df~ISb>hZnzZ(nIZ9Kb~{hYx8LH~UpBoxHA+}OPF-o(1HhIHwgDSMp~ zwyfvPy5w-}XVF|$al2}TI-BQ=pDy^VJ2*l1pH1_5`3Dz&i{IMu!ur%D)2{(`zg{Hs zX3KndEZKc6T+im_r_);(3(WmyoOzD>&sno?8o$in*k8Kx`sMa(Q>2B@Nv;um@RI9Q z(a-5@U()*~>uY^Kb#>*-3A4|5KhwD}<`;)Zwaz8S@9HBIWdZ~Dmx)fvwJ@Me45 zmrT1e_MgHxKimB>>r~Gq)6l9#CFfn{oI5|$V&6(B;pZlQPJUf9;a%xL8J4%~Z|na` zmMB)Q?$m!eJL|=x-#eW)ElN64%VpE@Q>OLCBO6Yegm1|@JAUv9>^Z}H;DYhQ@|(}u zjktQ7e~3D{@3^$9ahF`P_3RN}*L#_J z`MWM=te@ij_;tb8zlE`^cF$zyovHXxT^Z#bqWAh=RAc+mfE%YQJtA()n|^O#?w|Mg z!NWgCcAEaVSy*Aq|G8=Ydua`BlODsDk(b?GrRr_!}|VMM%0t!(&TTh%wg=N=Y4)3amNY}Z?}_};nx z$66m3fAie=+3EK@gKS;?4@ZmcDv5vZDyY}p{_#)1>2K#*ZqF?LwZ>8A*z$)n4ere} zW0T#!Vq@s8ybslqB!rLjEj`n_4@c}J{zKeHwOG-Q2U+_7xsHLFbu7nYu1 zy=C#8T|vg-+C6kKXUxvCh%?eCYb7IpJ~E(-@mEO z=5r9=?~8o>|79JE_SjFUJG6A4^AW@FUEiF}e{zsNc79`keb&DCmb((d1=-C}m#;pI zx$|n@iruEm0@O_uYTX-s(wzg|?n^yBWhL`;Fm2zBRB{ zyx8f#&cJu0**BSY>
4tgh8Q65`gZe>?5_PKQL`gf% z3`M+_esR|pJbW%VpD!bxBkS4qqRiJZSNAO8yuRe3)yJKdPZ!L;FX+{gYWOo-vM0Ycg)*7Y4J<#=9LRgwr`6JJ})#|Vd+Wf@R&8( zQ{v zWD{55QJVvI&$r6xKa&1?U8l0mF!VWp<=q#NfnIWH^?IufA0^3Dkg zeIhpXJ)&!q4SIZ>6O7XZl_pMjf9uC)?HvC)7mdT)pLaw~-&((BU(M|2mEWFxejePD zt2=$`GVK$6Zux1yBbmL{Ne8~Z6Qkc>Q@L~N%*tt(5AU3K*oWm*s;j1Eht;OsN`q}O zw%4w`u&?0zc~9}?_628RdZ&pTI~Ho!{#)&yTii>D7S*JfLgNR$I(Nd)mO1Sc6hHSi z>(qLmY5V^_FWb3c`L&MtFZXZ!WacUN515y1Cspucd5^JL?v*XATek%t4m1w=?$0{M zT6D^$vZ6I7ug|(a%l_G!N%!ODxz?#Y%_z2fy8iWxlP9n4ebRa8XYHHFY1`w@ns%#h zpX9jh=W6XR(>1F$E!(o|em%4O@!!++_awfbv-zLc!Bn|i}R|B zlbPG9i`8a&rsn7*zdifz-SM}#uc_U=nRecAwpD8U??u*sd@XzUZyjXyp7(9$=JJF3 zcPuh~eLG$iYq{}$YjE|i_s(Hjn+4*<&rX~7gJE`75~0@ZC`2L4i#HOc-{hJT&SZ1H*|HW)a=a+v!&wX3# zo~(4RRphx!2mi4%n;Xw8@H(=a)js1Xr*>{n%cXn&zcw?!zRvT`V;84!3p?YN!}dSi zV?7x^?wX-{|H>&&p~uaS)@)fY>5{e9iX9%?zKNWOkGy;F-kUswxzfARbt4rjYOZV7 zN|m2?FyH+0r0w%PTNdAzt#YU+y4bW~md4(BQ+YD~NnA2hzhAm1rb2Jpy-UeayQ1XVgpPl}q@y)zv zCiCCt&sK2oE_>HE+yBIyBQDxupVV^t3KZD6T3FXau^L-P@6pto)W6qW;6!=V!qtnH zzFqQTap0XIhqH4U($>`9nS1}!H9HQ!^rii*3-&x;+xYy9G82mo_w$*o|2t=DpDq7x zm!Cer_ImcRn>{tj6D3~?2*-U5J(eQ8W#wx>&ieQDxmiafHx{xSv0(1-^78u-%@_S# z_V=CSXDnrlw$#>qy;Yr=AK+cG`}gII3#}hzS}M&j+rw1+-nz;4T1o!I=xsY*&+9qr z`%8IQwTAAt%2bV)62%u&&;L`)t=p6OcYWPnr!9ZZ%vaxlxodN;A|@=fFQ*DpW%d9QiR-H*S0 z8J~piE?7{Z+x_wFOX6mR&|4nY2E58pj&*Yi*Wx4Eyhtm%)Ve#CWvvKF$Bjx9eyWia? zb3NbmT)$Q=?VZ`$`QlxQ{dt%2?k&{w-=%G=CY*h&WWve{clY!0fAhkBr|7(q&*drm z@0c(4Gv<{Z=a(ryQZ z>atL)@yg+Rt10{WcTJkhy>b866VEnApWFX%l0NgJXZv2Rt!3DInX#dx=|58mzvcd( zyBd@pYS>9XW<#E@Yv$@r31jUH4JmkVtX1FX0{5e9-184Te00+ zwy-C^w6;_^S1@;`^P~?dd>cJ0pNYj4-;54Sx$#BgXQ<3t{maW@b#~_b$lE`AhhA|Gz-sz`bwQ@zg+*lK{zRW)Ods1r4?!=9%TUI4*zIH4NiD$Jt+%(sC_tR)0F>n*Y_! zTLo?!`=9JuSLyVQ)BLwMTcLm%C@ryn@hK2wVqoB50;MHJCJ_e2s0ng91C5#>4Wgi> otpIOSoyeww(jh|U3qI7*m)rnvRyL3{69W@NDFXw8i6Dpv04^)#H~;_u literal 4520 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 V@MdKLNi#7pF_bbeFvtpmcmRK|`@aAH diff --git a/app/src/main/java/com/pixelized/headache/ui/page/summary/month/MonthSummaryPage.kt b/app/src/main/java/com/pixelized/headache/ui/page/summary/month/MonthSummaryPage.kt index 97fd466..40ab528 100644 --- a/app/src/main/java/com/pixelized/headache/ui/page/summary/month/MonthSummaryPage.kt +++ b/app/src/main/java/com/pixelized/headache/ui/page/summary/month/MonthSummaryPage.kt @@ -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, diff --git a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryFactory.kt b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryFactory.kt index 088574f..6b11433 100644 --- a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryFactory.kt +++ b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryFactory.kt @@ -17,11 +17,11 @@ class YearSummaryFactory @Inject constructor() { firstDayOfWeek = Calendar.MONDAY setMinimalDaysInFirstWeek(1) } - val monthLastDayCalendar = Calendar.getInstance().apply { + val monthLastDayCalendar = Calendar.getInstance().apply { firstDayOfWeek = Calendar.MONDAY setMinimalDaysInFirstWeek(1) } - val currentDayCalendar = Calendar.getInstance().apply { + val currentDayCalendar = Calendar.getInstance().apply { firstDayOfWeek = Calendar.MONDAY setMinimalDaysInFirstWeek(1) } @@ -29,7 +29,22 @@ class YearSummaryFactory @Inject constructor() { return events .fold(initial = hashMapOf>>()) { 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 } diff --git a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryPage.kt b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryPage.kt index 5b48ec6..026bcfe 100644 --- a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryPage.kt +++ b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/YearSummaryPage.kt @@ -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>, 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, ) { @@ -192,6 +218,65 @@ private fun YearSummaryPreview( private class YearPreviewProvider() : PreviewParameterProvider> { + 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 = 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, + ): 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> { months = months.toList(), ) - private fun month( - month: Date, - vararg weeks: List, - ) = YearSummaryMonthUio( - date = month, - weeks = weeks.toList(), - ) - - private fun week( - vararg days: YearSummaryDayUio, - ) = days.toList() - - private fun day( - number: Int, - headache: Boolean = false, - pills: List = emptyList(), - ) = YearSummaryDayUio( - number = number, - headache = headache, - pills = pills, - ) - override val values: Sequence> = 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), ), ) ), diff --git a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryDay.kt b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryDay.kt index 7785374..c3040b0 100644 --- a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryDay.kt +++ b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryDay.kt @@ -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,9 +93,12 @@ private fun YearSummaryDayPreview( @PreviewParameter(DayPreviewProvider::class) preview: YearSummaryDayUio, ) { HeadacheTheme { - YearSummaryDay( - day = preview, - ) + Surface { + YearSummaryDay( + modifier = Modifier.size(size = 16.dp), + day = preview, + ) + } } } diff --git a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryMonth.kt b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryMonth.kt index eefd335..1946042 100644 --- a/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryMonth.kt +++ b/app/src/main/java/com/pixelized/headache/ui/page/summary/year/item/YearSummaryMonth.kt @@ -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 - }, - ) { - week.forEach { day -> - YearSummaryDay(day = day) - } + uio.weeks.forEachIndexed { row, week -> + week.forEachIndexed { column, day -> + YearSummaryDay( + Modifier.offset( + x = when (row) { + 0 -> daySize * (column + 7 - week.size) + else -> daySize * column + }, + 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 { - fun day( - number: Int, - headache: Boolean = false, - pills: List = 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 = listOfNotNull( + mon?.invoke(), + tue?.invoke(), + wen?.invoke(), + thu?.invoke(), + fry?.invoke(), + sat?.invoke(), + sun?.invoke(), ) + private fun month( + month: Int, + vararg weeks: List, + ): 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 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), - ), + month( + month = Calendar.MARCH, + week( + mon = null, + tue = null, + wen = null, + thu = null, + fry = null, + sat = headache(spifen = true) ), - ) + 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), + ), ) } \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/headache/utils/extention/PaddingValueEx+calculate.kt b/app/src/main/java/com/pixelized/headache/utils/extention/PaddingValueEx+calculate.kt new file mode 100644 index 0000000..efa49a0 --- /dev/null +++ b/app/src/main/java/com/pixelized/headache/utils/extention/PaddingValueEx+calculate.kt @@ -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 +} \ No newline at end of file