1616 */
1717package com.shub39.grit.core.habits.presentation.ui
1818
19- import androidx.compose.animation.AnimatedContent
2019import androidx.compose.animation.AnimatedVisibility
2120import androidx.compose.animation.fadeIn
2221import androidx.compose.animation.fadeOut
23- import androidx.compose.animation.togetherWith
2422import androidx.compose.foundation.background
2523import androidx.compose.foundation.layout.Box
2624import androidx.compose.foundation.layout.Column
@@ -41,6 +39,7 @@ import androidx.compose.material3.TopAppBarDefaults
4139import androidx.compose.material3.TopAppBarScrollBehavior
4240import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
4341import androidx.compose.runtime.Composable
42+ import androidx.compose.runtime.LaunchedEffect
4443import androidx.compose.runtime.derivedStateOf
4544import androidx.compose.runtime.getValue
4645import androidx.compose.runtime.remember
@@ -58,6 +57,7 @@ import com.shub39.grit.core.habits.presentation.HabitsAction
5857import com.shub39.grit.core.habits.presentation.ui.component.HabitListFABs
5958import com.shub39.grit.core.habits.presentation.ui.sections.AnalyticsPage
6059import com.shub39.grit.core.habits.presentation.ui.sections.Calendar
60+ import com.shub39.grit.core.habits.presentation.ui.sections.CalendarHeatMap
6161import com.shub39.grit.core.habits.presentation.ui.sections.HabitsList
6262import com.shub39.grit.core.habits.presentation.ui.sections.OverallAnalytics
6363import com.shub39.grit.core.navigation.horizontalTransitionMetadata
@@ -81,6 +81,8 @@ private sealed interface HabitRoutes : NavKey {
8181 @Serializable data object OverallAnalytics : HabitRoutes
8282
8383 @Serializable data object Calendar : HabitRoutes
84+
85+ @Serializable data object CalendarHeatMap : HabitRoutes
8486}
8587
8688private val config = SavedStateConfiguration {
@@ -90,6 +92,7 @@ private val config = SavedStateConfiguration {
9092 subclass(HabitRoutes .HabitAnalytics ::class , HabitRoutes .HabitAnalytics .serializer())
9193 subclass(HabitRoutes .OverallAnalytics ::class , HabitRoutes .OverallAnalytics .serializer())
9294 subclass(HabitRoutes .Calendar ::class , HabitRoutes .Calendar .serializer())
95+ subclass(HabitRoutes .CalendarHeatMap ::class , HabitRoutes .CalendarHeatMap .serializer())
9396 }
9497 }
9598}
@@ -180,6 +183,9 @@ fun HabitsGraph(
180183 isUserSubscribed = isUserSubscribed,
181184 onAction = onAction,
182185 modifier = Modifier .background(MaterialTheme .colorScheme.background),
186+ onNavigateToCalendarHeatMap = {
187+ backstack.add(HabitRoutes .CalendarHeatMap )
188+ },
183189 )
184190 }
185191
@@ -195,6 +201,19 @@ fun HabitsGraph(
195201 modifier = Modifier .background(MaterialTheme .colorScheme.surface),
196202 )
197203 }
204+
205+ entry<HabitRoutes .CalendarHeatMap >(metadata = horizontalTransitionMetadata()) {
206+ CalendarHeatMap (
207+ state = state,
208+ onNavigateBack = {
209+ if (backstack.size != 1 ) backstack.removeLastOrNull()
210+ },
211+ modifier = Modifier .background(MaterialTheme .colorScheme.surface),
212+ onChangeSelectedDay = {
213+ onAction(HabitsAction .FetchCompletedHabitsForDate (it))
214+ },
215+ )
216+ }
198217 },
199218 )
200219 } else {
@@ -256,68 +275,96 @@ private fun ExpandedScreen(
256275 shape = RoundedCornerShape (topStart = 28 .dp),
257276 modifier = Modifier .weight(1f ),
258277 ) {
259- val motionScheme = MaterialTheme .motionScheme
260- AnimatedContent (
261- targetState = state.analyticsHabitId,
262- transitionSpec = {
263- fadeIn(motionScheme.fastEffectsSpec()) togetherWith
264- fadeOut(motionScheme.fastEffectsSpec())
265- },
266- ) { analyticsHabitId ->
267- if (analyticsHabitId != null ) {
268- val backstack = rememberNavBackStack(config, HabitRoutes .HabitAnalytics )
278+ val backstack = rememberNavBackStack(config, HabitRoutes .HabitAnalytics )
269279
270- NavDisplay (
271- backStack = backstack,
272- entryProvider =
273- entryProvider {
274- entry<HabitRoutes .HabitAnalytics > {
275- AnalyticsPage (
276- state = state,
277- onAction = onAction,
278- onNavigateBack = {
279- onAction(HabitsAction .PrepareAnalytics (null ))
280- },
281- onNavigateToPaywall = onNavigateToPaywall,
282- onNavigateToCalendar = {
283- backstack.add(HabitRoutes .Calendar )
284- },
285- isUserSubscribed = isUserSubscribed,
286- )
287- }
288-
289- entry<HabitRoutes .Calendar >(
290- metadata = horizontalTransitionMetadata()
291- ) {
292- Calendar (
293- state = state,
294- onNavigateBack = {
295- if (backstack.size != 1 )
296- backstack.removeLastOrNull()
297- },
298- onDateClick = { habit, date ->
299- onAction(HabitsAction .InsertStatus (habit, date))
300- },
301- modifier =
302- Modifier .background(
303- MaterialTheme .colorScheme
304- .surfaceContainerHighest
305- ),
306- )
307- }
308- },
309- )
310- } else {
311- OverallAnalytics (
312- state = state,
313- onNavigateBack = {},
314- showNavigateBack = false ,
315- onNavigateToPaywall = onNavigateToPaywall,
316- isUserSubscribed = isUserSubscribed,
317- onAction = onAction,
318- )
319- }
280+ LaunchedEffect (state.analyticsHabitId) {
281+ backstack.add(
282+ if (state.analyticsHabitId != null ) {
283+ HabitRoutes .HabitAnalytics
284+ } else {
285+ HabitRoutes .OverallAnalytics
286+ }
287+ )
320288 }
289+
290+ NavDisplay (
291+ backStack = backstack,
292+ entryProvider =
293+ entryProvider {
294+ entry<HabitRoutes .HabitAnalytics >(
295+ metadata = verticalTransitionMetadata()
296+ ) {
297+ AnalyticsPage (
298+ state = state,
299+ onAction = onAction,
300+ onNavigateBack = {
301+ onAction(HabitsAction .PrepareAnalytics (null ))
302+ },
303+ onNavigateToPaywall = onNavigateToPaywall,
304+ onNavigateToCalendar = { backstack.add(HabitRoutes .Calendar ) },
305+ isUserSubscribed = isUserSubscribed,
306+ modifier =
307+ Modifier .background(
308+ MaterialTheme .colorScheme.surfaceContainerHighest
309+ ),
310+ )
311+ }
312+
313+ entry<HabitRoutes .Calendar >(metadata = horizontalTransitionMetadata()) {
314+ Calendar (
315+ state = state,
316+ onNavigateBack = {
317+ if (backstack.size != 1 ) backstack.removeLastOrNull()
318+ },
319+ onDateClick = { habit, date ->
320+ onAction(HabitsAction .InsertStatus (habit, date))
321+ },
322+ modifier =
323+ Modifier .background(
324+ MaterialTheme .colorScheme.surfaceContainerHighest
325+ ),
326+ )
327+ }
328+
329+ entry<HabitRoutes .OverallAnalytics >(
330+ metadata = verticalTransitionMetadata()
331+ ) {
332+ OverallAnalytics (
333+ state = state,
334+ onNavigateBack = {},
335+ showNavigateBack = false ,
336+ onNavigateToPaywall = onNavigateToPaywall,
337+ isUserSubscribed = isUserSubscribed,
338+ onAction = onAction,
339+ onNavigateToCalendarHeatMap = {
340+ backstack.add(HabitRoutes .CalendarHeatMap )
341+ },
342+ modifier =
343+ Modifier .background(
344+ MaterialTheme .colorScheme.surfaceContainerHighest
345+ ),
346+ )
347+ }
348+
349+ entry<HabitRoutes .CalendarHeatMap >(
350+ metadata = horizontalTransitionMetadata()
351+ ) {
352+ CalendarHeatMap (
353+ state = state,
354+ onNavigateBack = {
355+ if (backstack.size != 1 ) backstack.removeLastOrNull()
356+ },
357+ modifier =
358+ Modifier .background(
359+ MaterialTheme .colorScheme.surfaceContainerHighest
360+ ),
361+ onChangeSelectedDay = {
362+ onAction(HabitsAction .FetchCompletedHabitsForDate (it))
363+ },
364+ )
365+ }
366+ },
367+ )
321368 }
322369 }
323370 }
0 commit comments