Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.github.quarck.calnotify.prefs

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
Expand All @@ -45,6 +46,12 @@ class NavigationSettingsFragmentX : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.navigation_preferences, rootKey)

// Set up click handler for "About Upcoming Events" help
findPreference<Preference>("upcoming_events_help")?.setOnPreferenceClickListener {
showUpcomingEventsHelpDialog()
true
}

// Set up click handler for "Switch to Classic View" button
findPreference<Preference>("switch_to_classic_view")?.setOnPreferenceClickListener {
showSwitchToClassicViewDialog()
Expand All @@ -58,6 +65,25 @@ class NavigationSettingsFragmentX : PreferenceFragmentCompat() {
}
}

private fun showUpcomingEventsHelpDialog() {
val ctx = context ?: return
AlertDialog.Builder(ctx)
.setTitle(R.string.upcoming_events_help_dialog_title)
.setMessage(R.string.upcoming_events_help_dialog_message)
.setPositiveButton(R.string.upcoming_events_help_view_full_docs) { _, _ ->
openUpcomingEventsDocumentation()
}
.setNegativeButton(android.R.string.ok, null)
.show()
}

private fun openUpcomingEventsDocumentation() {
val ctx = context ?: return
val docsUrl = ctx.getString(R.string.upcoming_events_docs_url)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(docsUrl))
startActivity(intent)
}

private fun showSwitchToClassicViewDialog() {
val ctx = context ?: return
AlertDialog.Builder(ctx)
Expand Down
12 changes: 12 additions & 0 deletions android/app/src/main/res/drawable/ic_help_outline_24dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Material icon: help_outline -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
</vector>
8 changes: 8 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -733,4 +733,12 @@
<string name="switch_to_new_view_summary">Enable new UI and restart with the tabbed navigation view</string>
<string name="switch_to_new_view_confirm">Switch to new view? The app will restart.</string>
<string name="restarting">Restarting…</string>

<!-- Upcoming Events Help -->
<string name="upcoming_events_help_title">About Upcoming Events</string>
<string name="upcoming_events_help_summary">Learn how the Upcoming tab works</string>
<string name="upcoming_events_help_dialog_title">Upcoming Events</string>
<string name="upcoming_events_help_dialog_message">The Upcoming tab shows calendar events that are scheduled to fire reminders within your configured lookahead window.\n\n• Events appear based on when their reminder fires, not the event start time\n• Once a reminder fires, the event moves to the Active tab\n• Configure how far ahead to look in the settings below\n\nLookahead Modes:\n• Fixed hours: Show events X hours ahead (default: 8 hours)\n• Day boundary: Show events until a configurable \"new day\" time (for night owls)</string>
<string name="upcoming_events_help_view_full_docs">View Full Documentation</string>
<string name="upcoming_events_docs_url" translatable="false">https://github.com/williscool/CalendarNotification/blob/master/docs/features/UPCOMING_EVENTS_README.md</string>
</resources>
7 changes: 7 additions & 0 deletions android/app/src/main/res/xml/navigation_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
android:summary="@string/use_new_navigation_ui_summary"
android:defaultValue="true" />

<!-- Help/Learn more about Upcoming Events -->
<Preference
android:key="upcoming_events_help"
android:title="@string/upcoming_events_help_title"
android:summary="@string/upcoming_events_help_summary"
android:icon="@drawable/ic_help_outline_24dp" />
Copy link

Choose a reason for hiding this comment

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

Help preference visible when feature is disabled

Low Severity

The upcoming_events_help preference is always visible, even when the new navigation UI is disabled via the use_new_navigation_ui checkbox. The other Upcoming Events settings (lookahead mode, boundary hour, fixed hours) are correctly hidden when the feature is disabled because their parent PreferenceCategory has android:dependency="use_new_navigation_ui". The help preference lacks this dependency, so users see "Learn how the Upcoming tab works" even when there's no Upcoming tab.

Fix in Cursor Fix in Web


<PreferenceCategory
android:title="@string/upcoming_events_category"
android:key="_upcoming_events"
Expand Down
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@

- [Data Sync Setup](DATA_SYNC_README.md) - Supabase/PowerSync configuration

## Features

User-facing feature documentation:

- [Upcoming Events View](features/UPCOMING_EVENTS_README.md) - See events before reminders fire (new tabbed UI)

## Testing Infrastructure

- [Dependency Injection Patterns](testing/dependency_injection_patterns.md) - Manual DI for testability ⭐ *Key Reference*
Expand Down
123 changes: 123 additions & 0 deletions docs/features/UPCOMING_EVENTS_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Upcoming Events View

See what's coming up on your calendar before notifications fire—so you can plan your day and never be surprised by imminent events.

## Overview

The Upcoming Events view displays calendar events that are scheduled to fire reminders within a configurable lookahead window. This lets you:

- **See what's coming** - Preview your schedule before reminders fire
- **Plan ahead** - Know what meetings or events are approaching
- **Never be caught off guard** - No more "I forgot about that meeting in 5 minutes!"

Events appear in the Upcoming tab based on when their reminder is scheduled to fire, not the event start time. Once a reminder fires, the event moves to the Active tab.

## How to Access

The app uses a bottom navigation bar with three tabs:

| Tab | Icon | Description |
|-----|------|-------------|
| **Active** | 🔔 | Events with fired reminders (notifications you've received) |
| **Upcoming** | ⏰ | Events with reminders scheduled to fire soon |
| **Dismissed** | 🗑️ | Events you've dismissed (the "Bin") |

![Bottom Navigation](images/bottom-navigation.png)
*Bottom navigation showing the three tabs*

Tap the clock icon (⏰) to view upcoming events.

## The Upcoming Tab

![Upcoming Events Tab](images/upcoming-events-tab.png)
*The Upcoming tab showing events scheduled to fire within your lookahead window*

Events are sorted by alert time (when the reminder will fire). Each event card shows:
- Event title and time
- Calendar color indicator
- How long until the reminder fires

## Configuring the Lookahead Window

You can customize how far ahead the app looks for upcoming events. Go to **Settings → Navigation & UI → Upcoming Events**.

![Lookahead Settings](images/lookahead-settings.png)
*Configure how far ahead to show upcoming events*

### Lookahead Modes

#### Fixed Hours (Default)

Shows events with reminders scheduled to fire within a fixed number of hours from now.

| Setting | What You'll See |
|---------|-----------------|
| 4 hours | Events firing in the next 4 hours |
| 8 hours (default) | Events firing in the next 8 hours |
| 24 hours | Events firing in the next day |

**Best for:** Most users who want simple, predictable behavior.

#### Day Boundary Mode

Shows events until a configurable "day boundary" time. This is designed for people who think in terms of "today" vs "tomorrow" rather than hours.

**How it works:**
- Before the boundary hour: Show events until the boundary (you're "still in yesterday")
- After the boundary hour: Show events until tomorrow's boundary (your "new day" has begun)

**Example with 4 AM boundary:**

| Current Time | You'll See Events Until | Why |
|--------------|-------------------------|-----|
| 1:00 AM | 4:00 AM today | Still "last night" mentally |
| 5:00 AM | 4:00 AM tomorrow | "Today" has begun |
| 10:00 PM | 4:00 AM tomorrow | Winding down the day |

**Best for:** Night owls who stay up past midnight but don't want to see "tomorrow's" events until they've actually slept.

## Switching Between Classic and New UI

If you prefer the original single-list view without tabs, you can switch back:

1. Go to **Settings → Navigation & UI**
2. Tap **"Switch to Classic View"**
3. Confirm the restart

![Switch View Setting](images/switch-view-setting.png)
*Toggle between new tabbed UI and classic view*

To switch back to the new tabbed view later, use **"Switch to New View"** in the same settings screen.

## Tips

- **Pull down to refresh** - Swipe down on any tab to refresh the event list
- **Events update automatically** - As time passes, events move from Upcoming → Active as their reminders fire
- **Calendar colors** - Events show their calendar's color for easy identification

## Coming Soon

Future updates will add:
- **Pre-snooze** - Snooze upcoming events before they fire
- **Pre-mute** - Mute an event's notification in advance
- **Pre-dismiss** - Skip an event entirely before the reminder
- **Calendar filtering** - Show only events from specific calendars

## Troubleshooting

### "No upcoming events" but I know I have events

1. **Check the lookahead window** - Your events may be outside the configured lookahead. Try increasing the hours in Settings → Navigation & UI → Hours to Look Ahead.

2. **Check calendar selection** - Make sure the calendar containing your events is enabled in Settings → Handled Calendars.

3. **Pull down to refresh** - Swipe down on the Upcoming tab to trigger a fresh scan.

### Events not appearing in the right order

Events are sorted by **reminder time**, not event start time. An event at 5 PM with a 1-hour reminder will appear before an event at 3 PM with a 15-minute reminder.

## Related Documentation

- [Data Sync Setup](../DATA_SYNC_README.md) - Sync events across devices
- [Calendar Monitoring Architecture](../architecture/calendar_monitoring.md) - Technical details on how events are tracked
Loading