Skip to content

Comments

feat: upcoming event page time filter pill#252

Open
williscool wants to merge 9 commits intomasterfrom
feat/upcoming_event_page_time_filter_pill
Open

feat: upcoming event page time filter pill#252
williscool wants to merge 9 commits intomasterfrom
feat/upcoming_event_page_time_filter_pill

Conversation

@williscool
Copy link
Owner

@williscool williscool commented Feb 24, 2026

fixes: #216


Note

Medium Risk
Touches persistent settings and upcoming lookahead calculation that controls which events are queried, so mis-parsing/clamping or UI wiring bugs could change the visible upcoming window; changes are localized and covered by new tests.

Overview
Adds an Upcoming tab “time” chip that opens a new UpcomingTimeFilterBottomSheet to switch between Day boundary mode and fixed lookahead presets; selection is persisted to Settings (not FilterState) and triggers an upcoming list refresh.

Extends settings to support millisecond-based fixed lookahead (upcomingEventsFixedLookaheadMillis, clamped to a 30-day scan window with legacy fallback from upcomingEventsFixedHours) and configurable preset lists stored as a comma-separated string; updates Preferences UI to edit these presets via a new UpcomingTimePresetPreferenceX dialog.

Enhances duration parsing/formatting to support weeks (w) and adds human-readable preset labels; includes new layouts/strings and expands unit tests around presets, clamping, and lookahead calculation.

Written by Cursor Bugbot for commit ac0e865. This will update automatically on new commits. Configure here.

@williscool williscool changed the title feat/upcoming event page time filter pill feat: upcoming event page time filter pill Feb 24, 2026
@github-actions
Copy link

Build artifacts for PR #252 (commit 7516aa8) are available:

You can download these artifacts from the "Artifacts" section of the workflow run.

@github-actions
Copy link

github-actions bot commented Feb 24, 2026

Code Coverage Report

Overall Project 34.68% -0.96% 🍏
Files changed 21.59%

Module Coverage
app 42.22% -1.03%
x8664Debug 27.31% -0.89%
Files
Module File Coverage
app Consts.kt 98.9% 🍏
Settings.kt 65.13% -4.23%
MainActivityModern.kt 50.71% -2.67%
PreferenceUtils.kt 47.35% -18.66%
UpcomingEventsLookahead.kt 42.68% 🍏
DateTimeUtils.kt 35.28% -6.06%
NavigationSettingsFragmentX.kt 0% -11.54%
UpcomingTimePresetPreferenceX.kt 0% -87.37%
UpcomingTimeFilterBottomSheet.kt 0% -97.91%
x8664Debug UpcomingEventsLookahead.kt 100% 🍏
PreferenceUtils.kt 74.93% -0.84% 🍏
DateTimeUtils.kt 62.34% -6.06%
MainActivityModern.kt 50.41% -2.67%
Settings.kt 30.33% -0.86% 🍏
NavigationSettingsFragmentX.kt 0% -11.54%
UpcomingTimePresetPreferenceX.kt 0% -87.37%
UpcomingTimeFilterBottomSheet.kt 0% -97.91%
Consts.kt 0% 🍏

@github-actions
Copy link

📊 Code Coverage Summary

Coverage Type Coverage
Overall 27.33
Changed Files 37.28

View detailed coverage report

@github-actions
Copy link

Build artifacts for PR #252 (commit 3df7d47) are available:

You can download these artifacts from the "Artifacts" section of the workflow run.

@github-actions
Copy link

📊 Code Coverage Summary

Coverage Type Coverage
Overall 27.32
Changed Files 36.97

View detailed coverage report

@williscool williscool enabled auto-merge (squash) February 24, 2026 07:16
@github-actions
Copy link

Build artifacts for PR #252 (commit 3e7cabc) are available:

You can download these artifacts from the "Artifacts" section of the workflow run.

@github-actions
Copy link

📊 Code Coverage Summary

Coverage Type Coverage
Overall 27.31
Changed Files 39.11

View detailed coverage report

@github-actions
Copy link

Build artifacts for PR #252 (commit ac0e865) are available:

You can download these artifacts from the "Artifacts" section of the workflow run.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

id = DAY_BOUNDARY_RADIO_ID
val hourStr = DateTimeUtils.formatHourOfDay(settings.upcomingEventsDayBoundaryHour)
text = getString(R.string.upcoming_time_day_boundary, hourStr)
setPadding(0, 24, 0, 24)
Copy link

Choose a reason for hiding this comment

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

Hardcoded pixel values cause density-dependent sizing

Medium Severity

setPadding(0, 24, 0, 24) on the RadioButtons and the divider height of 2 use raw pixel values instead of density-independent pixels. On xxxhdpi screens (4x), 24px is only ~6dp (very cramped), while on mdpi screens (1x) it's a generous 24dp. The rest of the codebase correctly uses resources.getDimensionPixelSize(R.dimen....) for programmatic dimensions (e.g., PreActionActivity.kt). These values need dp-to-px conversion or dimen resources to render consistently across devices.

Additional Locations (2)

Fix in Cursor Fix in Web

return if (minutes == 1L) "1 minute" else "$minutes minutes"
}
return "$seconds seconds"
}
Copy link

Choose a reason for hiding this comment

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

Human-readable time strings are hardcoded in English

Low Severity

formatPresetHumanReadable returns hardcoded English strings like "hours", "days", "weeks" that appear in user-facing chip text and the bottom sheet options. Unlike other user-facing text in the app which uses Android string resources (getString(R.string.…)), this function isn't localizable. Since it's a PreferenceUtils utility without Context, it can't access resources — the callers in MainActivityModern and UpcomingTimeFilterBottomSheet (which do have Context) would need to handle formatting instead, or the function signature would need to accept a Context parameter.

Fix in Cursor Fix in Web

}
}
}
}
Copy link

Choose a reason for hiding this comment

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

Preset preference class duplicates existing SnoozePresetPreferenceX

Low Severity

UpcomingTimePresetPreferenceX is a near-duplicate of the existing SnoozePresetPreferenceX. Both extend DialogPreference, have an inner Dialog class extending PreferenceDialogFragmentCompat, bind an EditText, parse via PreferenceUtils.parseSnoozePresets(), reformat on save, persist via persistString, and show error alerts. The differences (label TextView, negative-value filtering, max-count threshold) are minor enough to share a base class or parameterized implementation.

Fix in Cursor Fix in Web

val presets = PreferenceUtils.parseSnoozePresets(value)
if (presets != null) {
// Filter out negative values
val validPresets = presets.filter { it > 0 }
Copy link

Choose a reason for hiding this comment

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

Dialog validates positivity but not max lookahead constraint

Medium Severity

The dialog's validPresets filter only checks it > 0, but Settings.upcomingTimePresets filters with it > 0 && it <= MAX_LOOKAHEAD_MILLIS. If a user enters presets that are all positive but exceed 30 days (e.g., "5w, 6w"), the dialog accepts and persists them (non-empty positive list), but the read path silently drops all of them. This leaves the UpcomingTimeFilterBottomSheet with zero fixed interval options and no way to select a fixed mode — despite the dialog telling the user the save succeeded.

Additional Locations (1)

Fix in Cursor Fix in Web

@github-actions
Copy link

📊 Code Coverage Summary

Coverage Type Coverage
Overall 34.68
Changed Files 42.14

View detailed coverage report

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.

Feature: Time filter for Upcoming tab

1 participant