Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@shub39
Copy link
Owner

@shub39 shub39 commented Sep 5, 2025

Summary by CodeRabbit

  • New Features

    • Weekly analytics add a time-range selector (4/8/16 weeks) and chart filtering.
    • Analytics cards show contextual icons (calendar, map, week, day, graphs).
  • UI/UX

    • Refreshed card headers, improved week label styling, fixed overlay height, and smoother task card resizing.
    • Added labels including “Weeks,” “Streak Analysis,” and “Rolling Completions.”
  • Bug Fixes

    • Long-press editing no longer opens completed tasks.
  • Chores

    • App version bumped to 5.0.0.

@coderabbitai
Copy link

coderabbitai bot commented Sep 5, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Bumps app version to 5.0.0, adds WeeklyTimePeriod and a time-range selector for weekly analytics, updates AnalyticsCard API to accept an icon and adjusts overlay sizing, applies iconized headers across callers, extends chart data window, tweaks task UI/interaction, and adds a "weeks" string resource.

Changes

Cohort / File(s) Summary
Version bump
app/build.gradle.kts
Update appVersionCode 4330 → 5000 and appVersionName "4.3.3" → "5.0.0".
Time-range domain
app/src/main/java/com/shub39/grit/habits/domain/WeeklyTimePeriod.kt
New enum class WeeklyTimePeriod (WEEKS_16, WEEKS_8, WEEKS_4) with extension toWeeks().
AnalyticsCard API/UI
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt
Composable signature adds icon: ImageVector; header replaced by Row with Icon + Text; overlay sizing changed to fixed height (heightIn(300.dp) / fillMaxSize()); imports updated.
Iconized card callers & header styling
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/CalendarMap.kt, .../HabitHeatMap.kt, .../WeekDayBreakdown.kt, .../WeeklyBooleanHeatmap.kt
Callers pass specific Icons.Rounded.* into AnalyticsCard; heatmap/weekly headers get padded circular background and color adjustments.
Weekly analytics selector & graphs
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyActivity.kt, .../WeeklyGraph.kt
Add LazyRow ToggleButtons for WeeklyTimePeriod with rememberSaveable state; filter chart data with takeLast(period.toWeeks()); WeeklyGraph signature extended (adds primary: Color and onAction callback); AnalyticsCard usage updated.
Chart data window
app/src/main/java/com/shub39/grit/habits/presentation/util.kt
prepareLineChartData now uses totalWeeks = 15, extends generated points and date lookback accordingly.
Tasks UI/interaction tweaks
app/src/main/java/com/shub39/grit/tasks/presentation/ui/component/TaskCard.kt, .../tasks/presentation/ui/section/TaskList.kt
TaskCard adds animateContentSize() and font-size tweak; TaskList long-press edit disabled for completed tasks.
Strings
app/src/main/res/values/strings.xml
Add string resource weeks = "Weeks".
Metadata
fastlane/metadata/android/en-US/full_description.txt
Update features list (add reminders; add "Material3 theme and look").

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as WeeklyGraph UI
  participant Selector as Time Selector (LazyRow)
  participant Enum as WeeklyTimePeriod
  participant Chart as LineChart

  User->>UI: Open Weekly analytics
  UI->>Selector: render period buttons (entries)
  User->>Selector: select period
  Selector-->>UI: onToggle(period)
  UI->>Enum: period.toWeeks()
  UI->>Chart: takeLast(N weeks) and render filtered data
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I hop and hum — version five has sprung,
Weeks to pick, three buttons sung.
Tiny icons crown every card,
Charts trimmed neat and not too hard.
I nibble bugs and stitch the map — hooray for this new hop and clap! 🥕✨


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 541d1bd and 7793ab8.

⛔ Files ignored due to path filters (5)
  • fastlane/metadata/android/en-US/images/phoneScreenshots/1.png is excluded by !**/*.png
  • fastlane/metadata/android/en-US/images/phoneScreenshots/2.png is excluded by !**/*.png
  • fastlane/metadata/android/en-US/images/phoneScreenshots/3.png is excluded by !**/*.png
  • fastlane/metadata/android/en-US/images/phoneScreenshots/5.png is excluded by !**/*.png
  • fastlane/metadata/android/en-US/images/phoneScreenshots/6.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • app/src/main/res/values/strings.xml (1 hunks)
  • fastlane/metadata/android/en-US/full_description.txt (1 hunks)
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (16)
app/src/main/java/com/shub39/grit/tasks/presentation/ui/component/TaskCard.kt (2)

65-65: Smooth size transitions are welcome; consider a gentler spring to reduce list jank.

Default animateContentSize() can feel a bit snappy inside LazyColumn. A softer spring improves perceived smoothness during expand/collapse.

Apply:

-        modifier = modifier.animateContentSize(),
+        modifier = modifier.animateContentSize(
+            animationSpec = androidx.compose.animation.core.spring(
+                stiffness = androidx.compose.animation.core.Spring.StiffnessMediumLow
+            )
+        ),

107-109: 11.sp is below common accessibility guidance; bump to 12.sp.

Small text tends to become hard to read. 12.sp keeps it compact but friendlier.

-                            style = MaterialTheme.typography.labelSmall.copy(
-                                fontSize = 11.sp
-                            )
+                            style = MaterialTheme.typography.labelSmall.copy(fontSize = 12.sp)
app/src/main/java/com/shub39/grit/tasks/presentation/ui/section/TaskList.kt (1)

277-279: UX check: long‑press no longer edits completed tasks. Intentional?

New guard (!editState && !task.status) blocks editing finished items via long‑press. If that’s desired—cool. If not, consider allowing edit regardless of status, or provide an alternate entry point for completed tasks.

If you want to keep long‑press editing for all:

-                                            if (!editState && !task.status) {
+                                            if (!editState) {
                                                 editTask = task
-                                            }
+                                            }
app/src/main/res/values/strings.xml (1)

123-125: Pluralization for “week(s)”.

If you ever introduce a 1‑week option, switch this to plurals to localize correctly.

Example to add alongside (no breaking change now):

<plurals name="weeks_quantity">
    <item quantity="one">%d Week</item>
    <item quantity="other">%d Weeks</item>
</plurals>
app/src/main/java/com/shub39/grit/habits/presentation/util.kt (1)

21-21: Remove “15 means 16 weeks” off‑by‑one confusion; make the window explicit.

Using 15 to emit 16 data points is easy to misread. Make the lookback size explicit and iterate 0 until lookbackWeeks.

-    val totalWeeks = 15
+    // Generate 16 data points (last 16 full weeks including current week)
+    val lookbackWeeks = 16
@@
-    val startDateOfPeriod = today.minusWeeks(totalWeeks.toLong()).with(weekFields.dayOfWeek(), 1)
+    val startDateOfPeriod = today
+        .minusWeeks((lookbackWeeks - 1).toLong())
+        .with(weekFields.dayOfWeek(), 1)
@@
-    val values = (0..totalWeeks).map { i ->
-        val currentWeekStart = today.minusWeeks(totalWeeks - i.toLong()).with(weekFields.dayOfWeek(), 1)
+    val values = (0 until lookbackWeeks).map { i ->
+        val currentWeekStart = today
+            .minusWeeks((lookbackWeeks - 1 - i).toLong())
+            .with(weekFields.dayOfWeek(), 1)

Optional follow‑up: accept lookbackWeeks as a parameter (default 16) so UI periods can drive data length directly.

Also applies to: 23-23, 33-35

app/src/main/java/com/shub39/grit/habits/domain/WeeklyTimePeriod.kt (1)

5-7: Optional: order smallest→largest for nicer UX

Toggle sequences commonly progress 4, 8, 16. If you prefer that:

-    WEEKS_16(16),
-    WEEKS_8(8),
-    WEEKS_4(4);
+    WEEKS_4(4),
+    WEEKS_8(8),
+    WEEKS_16(16);
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt (1)

40-60: Accessibility: mark header as a semantic heading

Improves screen-reader navigation.

-        Row(
-            modifier = Modifier
-                .fillMaxWidth()
-                .padding(16.dp),
+        Row(
+            modifier = Modifier
+                .fillMaxWidth()
+                .padding(16.dp)
+                .semantics { heading() },

Add imports:

import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/HabitHeatMap.kt (1)

64-70: Improve week header text contrast on secondaryContainer

For consistent accessibility, prefer onSecondaryContainer over secondary on a secondaryContainer background.

Apply this diff:

-                        .background(
-                            color = MaterialTheme.colorScheme.secondaryContainer,
-                            shape = CircleShape
-                        )
+                        .background(
+                            color = MaterialTheme.colorScheme.secondaryContainer,
+                            shape = CircleShape
+                        )
@@
-                        color = MaterialTheme.colorScheme.secondary,
+                        color = MaterialTheme.colorScheme.onSecondaryContainer,

Also applies to: 73-73

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyBooleanHeatmap.kt (1)

73-79: Match text color to container for better contrast

Same contrast note as HabitHeatMap: use onSecondaryContainer atop secondaryContainer.

Apply this diff:

-                        .background(
-                            color = MaterialTheme.colorScheme.secondaryContainer,
-                            shape = CircleShape
-                        )
+                        .background(
+                            color = MaterialTheme.colorScheme.secondaryContainer,
+                            shape = CircleShape
+                        )
@@
-                        color = MaterialTheme.colorScheme.secondary,
+                        color = MaterialTheme.colorScheme.onSecondaryContainer,

Also applies to: 82-82

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyGraph.kt (3)

49-50: Make rememberSaveable robust for enums

Enums may not be saved/restored across process death without a saver. Provide a Saver for WeeklyTimePeriod.

Apply this diff:

@@
-import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.saveable.Saver
@@
-    var selectedTimePeriod by rememberSaveable { mutableStateOf(WeeklyTimePeriod.WEEKS_8) }
+    val periodSaver = Saver<WeeklyTimePeriod, String>(
+        save = { it.name },
+        restore = { WeeklyTimePeriod.valueOf(it) }
+    )
+    var selectedTimePeriod by rememberSaveable(stateSaver = periodSaver) {
+        mutableStateOf(WeeklyTimePeriod.WEEKS_8)
+    }

66-73: Consider a segmented single-choice control for better a11y semantics

The ToggleButtons emulate single selection but don’t convey group semantics. If available in your Material3 version, consider SingleChoiceSegmentedButtonRow + SegmentedButton.


70-71: Use plurals for localization (“N weeks”)

Hardcoding “weeks” can be incorrect in some locales. Prefer pluralStringResource.

Apply this diff (requires adding R.plurals.weeks):

+import androidx.compose.ui.res.pluralStringResource
@@
-                    Text(text = "${period.toWeeks()} ${stringResource(R.string.weeks)}")
+                    val weeks = period.toWeeks()
+                    Text(text = pluralStringResource(R.plurals.weeks, weeks, weeks))
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyActivity.kt (4)

66-69: Respect isChecked in ToggleButton to avoid forcing selection

This ensures proper single-select behavior and prevents re-selecting on deselect taps.

-                ToggleButton(
-                    checked = period == selectedTimePeriod,
-                    onCheckedChange = { selectedTimePeriod = period }
-                ) {
+                ToggleButton(
+                    checked = period == selectedTimePeriod,
+                    onCheckedChange = { isChecked ->
+                        if (isChecked) selectedTimePeriod = period
+                    }
+                ) {

65-66: Add stable keys to LazyRow items

Keys reduce unnecessary recompositions and preserve state if the list changes.

-            items(WeeklyTimePeriod.entries) { period ->
+            items(items = WeeklyTimePeriod.entries, key = { it.name }) { period ->

70-71: Use plurals for proper i18n (“1 week” vs “2 weeks”)

Switch to pluralStringResource and add a plurals entry.

-                    Text(text = "${period.toWeeks()} ${stringResource(R.string.weeks)}")
+                    Text(text = pluralStringResource(R.plurals.weeks, period.toWeeks(), period.toWeeks()))

Add import outside this hunk:

import androidx.compose.ui.res.pluralStringResource

Add to strings.xml:

<plurals name="weeks">
    <item quantity="one">%d week</item>
    <item quantity="other">%d weeks</item>
</plurals>

93-95: Scale X-axis grid lines with selected period

Improves readability when switching between shorter and longer ranges.

-                    lineCount = 10,
+                    lineCount = selectedTimePeriod.toWeeks().coerceAtMost(10),
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8f336fb and 541d1bd.

📒 Files selected for processing (13)
  • app/build.gradle.kts (1 hunks)
  • app/src/main/java/com/shub39/grit/habits/domain/WeeklyTimePeriod.kt (1 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt (3 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/CalendarMap.kt (2 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/HabitHeatMap.kt (3 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeekDayBreakdown.kt (2 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyActivity.kt (4 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyBooleanHeatmap.kt (3 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyGraph.kt (4 hunks)
  • app/src/main/java/com/shub39/grit/habits/presentation/util.kt (2 hunks)
  • app/src/main/java/com/shub39/grit/tasks/presentation/ui/component/TaskCard.kt (4 hunks)
  • app/src/main/java/com/shub39/grit/tasks/presentation/ui/section/TaskList.kt (1 hunks)
  • app/src/main/res/values/strings.xml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyActivity.kt (1)
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt (1)
  • AnalyticsCard (27-88)
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyGraph.kt (1)
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt (1)
  • AnalyticsCard (27-88)
🔇 Additional comments (10)
app/build.gradle.kts (1)

14-15: Version bump looks good.

VersionCode 5000 and VersionName 5.0.0 align with the major feature addition.

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt (2)

47-51: LGTM: icon rendering

Icon tint and placement align with the new header style.


30-30: Public API change accepted – all call sites updated

Verified that every AnalyticsCard(…) invocation (6 occurrences across WeeklyGraph, WeeklyActivity, HabitHeatMap, WeeklyBooleanHeatmap, CalendarMap, and WeekDayBreakdown) now supplies the icon argument, so the source-breaking change is fully covered.

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/CalendarMap.kt (2)

49-50: LGTM: passes calendar icon to AnalyticsCard

Call-site matches the updated API.


11-12: No action needed: material-icons-extended is declared in the version catalog (gradle/libs.versions.toml:33).

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeekDayBreakdown.kt (1)

5-6: Adoption of AnalyticsCard icon looks good

Header icon wiring is correct and consistent with the new AnalyticsCard API.

Also applies to: 42-42

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/HabitHeatMap.kt (1)

40-40: Icon integration LGTM

Using Icons.Rounded.Map aligns with the new card header pattern.

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyBooleanHeatmap.kt (1)

49-49: Icon integration LGTM

Icons.Rounded.ViewWeek is a good semantic choice for this card.

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyGraph.kt (1)

96-100: Safe slicing of series values — LGTM

takeLast(selectedTimePeriod.toWeeks()) safely handles shorter series and keeps color/label via copy.

app/src/main/java/com/shub39/grit/habits/presentation/ui/component/WeeklyActivity.kt (1)

75-81: Verify empty-data handling for LineChart

Preview passes an empty list; some chart libs crash on empty series. If it doesn’t handle empty lists, gate the chart and show a placeholder.

Example guard:

val chartValues = lineChartData.takeLast(selectedTimePeriod.toWeeks())
if (chartValues.isEmpty()) {
    Text(text = stringResource(R.string.no_data))
} else {
    LineChart(
        // ...
        data = listOf(
            Line(
                // ...
-               values = lineChartData.takeLast(selectedTimePeriod.toWeeks()),
+               values = chartValues,
                // ...
            )
        ),
        // ...
    )
}

Add string if needed:

<string name="no_data">No data yet</string>

Also applies to: 101-106

Comment on lines +9 to +17
companion object {
fun WeeklyTimePeriod.toWeeks(): Int {
return when (this) {
WEEKS_16 -> 16
WEEKS_8 -> 8
WEEKS_4 -> 4
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Fix: member extension is out of scope; calls like period.toWeeks() won’t resolve

An extension declared inside a companion object is a member extension and isn’t visible at call sites like your UI composables. Convert to an enum ctor property (simplest) and drop the companion.

-enum class WeeklyTimePeriod {
-    WEEKS_16,
-    WEEKS_8,
-    WEEKS_4;
-
-    companion object {
-        fun WeeklyTimePeriod.toWeeks(): Int {
-            return when (this) {
-                WEEKS_16 -> 16
-                WEEKS_8 -> 8
-                WEEKS_4 -> 4
-            }
-        }
-    }
-}
+enum class WeeklyTimePeriod(val weeks: Int) {
+    WEEKS_16(16),
+    WEEKS_8(8),
+    WEEKS_4(4);
+}

Follow-up: replace selectedTimePeriod.toWeeks() with selectedTimePeriod.weeks.

🤖 Prompt for AI Agents
In app/src/main/java/com/shub39/grit/habits/domain/WeeklyTimePeriod.kt around
lines 9 to 17, the member extension declared inside the companion object is out
of scope for call sites (e.g., UI composables) so change the enum to carry the
week value as an enum constructor property: add a constructor parameter (val
weeks: Int) to WeeklyTimePeriod, set each enum constant with its week value
(e.g., WEEKS_16(16), etc.), remove the companion object and the extension
function, and then update all call sites to use selectedTimePeriod.weeks instead
of selectedTimePeriod.toWeeks().

contentAlignment = Alignment.Center,
modifier = Modifier
.heightIn(max = 300.dp)
.heightIn(300.dp)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Set fixed overlay height (min-only currently allows growth)

.heightIn(300.dp) sets min height, not max. Use an exact 300.dp to prevent oversized overlays.

-                    .heightIn(300.dp)
+                    .heightIn(min = 300.dp, max = 300.dp)
🤖 Prompt for AI Agents
In
app/src/main/java/com/shub39/grit/habits/presentation/ui/component/AnalyticsCard.kt
around line 66, the modifier uses .heightIn(300.dp) which only sets a minimum
height and allows the overlay to grow; replace it with an exact height modifier
(e.g., .height(300.dp)) so the overlay is fixed at 300.dp and cannot oversized.

@shub39 shub39 merged commit d9f07ed into master Sep 5, 2025
1 of 2 checks passed
@shub39 shub39 deleted the dev branch September 5, 2025 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant