Skip to content

Conversation

@eulicesl
Copy link
Owner

Summary

This PR adds Apple Calendar and Notes export functionality to complement the existing Apple Reminders integration for action items.

Features

  • Export Dropdown: Users can select their preferred export destination (Reminders, Calendar, or Notes)
  • Apple Calendar: Export action items as calendar events with configurable duration
  • Apple Notes: Export action items via iOS share sheet to Apple Notes
  • Persistent Preferences: User's export choice is saved and remembered

Implementation Details

New Files Added

  • app/ios/Runner/AppleCalendarService.swift - EventKit integration for Calendar
  • app/ios/Runner/AppleNotesService.swift - Share sheet integration for Notes
  • app/lib/services/apple_calendar_service.dart - Dart wrapper for Calendar
  • app/lib/services/apple_notes_service.dart - Dart wrapper for Notes
  • app/lib/models/action_item_integration.dart - Export destination enum
  • app/lib/backend/preferences_export_extension.dart - Preference storage

Files Modified

  • app/ios/Runner/AppDelegate.swift - Registered new method channels
  • app/lib/pages/action_items/widgets/action_item_tile_widget.dart - Added export dropdown UI

Testing Instructions

  1. Run flutter pub get
  2. Build and run on iOS device/simulator
  3. Navigate to Action Items page
  4. Use dropdown to select export destination
  5. Tap export button to test each integration

Compatibility

  • iOS 10.0+ for Calendar (EventKit)
  • iOS 9.0+ for Notes (Share Sheet)
  • Fully backward compatible with existing functionality

Extends action item export functionality to support Apple Calendar and Notes in addition to existing Reminders support.

New features:
- Export dropdown for selecting destination (Reminders/Calendar/Notes)
- Apple Calendar integration via EventKit
- Apple Notes integration via share sheet
- Persistent storage of user's export preference

Implementation:
- Added AppleCalendarService.swift and AppleNotesService.swift for iOS
- Created Dart service wrappers for Calendar and Notes
- Extended ActionItemTileWidget with dropdown export UI
- Added ActionItemIntegration enum for managing destinations
- Updated AppDelegate to register new method channels
Copilot AI review requested due to automatic review settings August 17, 2025 18:13
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR extends the existing Apple Reminders integration by adding Apple Calendar and Notes export functionality for action items. Users can now select their preferred export destination through a dropdown interface, with their choice being persisted across sessions.

Key changes include:

  • Added Apple Calendar integration using EventKit to create calendar events
  • Added Apple Notes integration using iOS share sheet functionality
  • Implemented export destination selection UI with persistent user preferences

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/lib/services/apple_notes_service.dart Dart service wrapper for Apple Notes share sheet integration
app/lib/services/apple_calendar_service.dart Dart service wrapper for Apple Calendar EventKit integration
app/lib/pages/action_items/widgets/action_item_tile_widget.dart Updated widget to support multiple export destinations with dropdown UI
app/lib/models/action_item_integration.dart Enum defining available export destinations and their display properties
app/lib/backend/preferences_export_extension.dart Extension for persisting user's export destination preference
app/ios/Runner/AppleNotesService.swift Native iOS service for Notes share sheet functionality
app/ios/Runner/AppleCalendarService.swift Native iOS service for Calendar event creation using EventKit
app/ios/Runner/AppDelegate.swift Updated to register new method channels for Notes and Calendar services

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

final formattedContent = '''
Action Item: $description
Created: ${DateTime.now().toLocal()}
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

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

[nitpick] The DateTime formatting is inconsistent between services. Consider using a consistent format across all services or creating a shared utility function for date formatting.

Copilot uses AI. Check for mistakes.

class _ActionItemTileWidgetState extends State<ActionItemTileWidget> {
// Track which integration is currently selected for export. This defaults
// to Apple Reminders but is loaded from saved preferences on init.
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

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

[nitpick] The comment mentions defaulting to Apple Reminders, but the actual default assignment is on line 43. Consider moving the comment closer to the assignment or combining them for clarity.

Suggested change
// to Apple Reminders but is loaded from saved preferences on init.
// Track which integration is currently selected for export.
// Defaults to Apple Reminders but is loaded from saved preferences on init.

Copilot uses AI. Check for mistakes.
result(completed)
}
}
if let controller = UIApplication.shared.keyWindow?.rootViewController {
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

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

Using keyWindow is deprecated in iOS 13+. Consider using UIApplication.shared.connectedScenes to find the active window scene and its root view controller for better compatibility.

Suggested change
if let controller = UIApplication.shared.keyWindow?.rootViewController {
var rootViewController: UIViewController?
if #available(iOS 13.0, *) {
// Find the active window scene
if let windowScene = UIApplication.shared.connectedScenes
.compactMap({ $0 as? UIWindowScene })
.first(where: { $0.activationState == .foregroundActive }) {
rootViewController = windowScene.windows
.first(where: { $0.isKeyWindow })?.rootViewController
}
} else {
rootViewController = UIApplication.shared.keyWindow?.rootViewController
}
if let controller = rootViewController {

Copilot uses AI. Check for mistakes.
event.notes = notes
// Default event duration: now + 1 hour
event.startDate = Date()
event.endDate = Date().addingTimeInterval(3600)
Copy link

Copilot AI Aug 17, 2025

Choose a reason for hiding this comment

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

The hardcoded 3600 seconds (1 hour) should be extracted as a named constant to improve readability and maintainability.

Suggested change
event.endDate = Date().addingTimeInterval(3600)
event.endDate = Date().addingTimeInterval(Self.defaultEventDurationSeconds)

Copilot uses AI. Check for mistakes.
- Fixed status indicator colors to match upstream (blue for pending, green for exported)
- Added Apple Notes and Calendar icon assets from PR 2770
- Updated ActionItemIntegration to use proper icon assets
- Ensures consistent visual design across all export integrations
@eulicesl eulicesl force-pushed the feat/apple-export-clean branch from 54b90e9 to 2ce2f00 Compare August 17, 2025 18:48
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.

Bugbot free trial expires on August 31, 2025
Learn more in the Cursor dashboard.

false;
}
return false;
}
Copy link

Choose a reason for hiding this comment

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

Bug: Local State Loss Causes Export Inconsistency

Export state for Apple Notes and Calendar is managed locally and lost on widget rebuilds, unlike Apple Reminders which persists via parent state. This causes Notes and Calendar items to incorrectly show as not exported after navigation or rebuilds, creating an inconsistent user experience.

Fix in Cursor Fix in Web

@eulicesl eulicesl closed this Aug 19, 2025
eulicesl pushed a commit that referenced this pull request Oct 24, 2025
closes BasedHardware#3241

before:


https://github.com/user-attachments/assets/d00d815c-8419-4c1b-96fb-ec20365fba44

logs:

```
flutter: ----------------FIREBASE CRASHLYTICS----------------
flutter: Bad state: No element
flutter: 
#0      ListBase.firstWhere (dart:collection/list.dart:132:5)
#1      SharedPreferencesUtil.disableApp (package:omi/backend/preferences.dart:255:22)
#2      _AppDetailPageState._toggleApp (package:omi/pages/apps/app_detail/app_detail.dart:1129:13)
#3      _AppDetailPageState.build.<anonymous closure> (package:omi/pages/apps/app_detail/app_detail.dart:576:48)
#4      _AnimatedLoadingButtonState._handleOnPressed (package:omi/widgets/animated_loading_button.dart:38:27)
#5      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1204:21)
#6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
#7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
#8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
#9      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:353:7)
#10     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:173:27)
#11
```

after:


https://github.com/user-attachments/assets/26ea5c91-e73a-44f4-ba76-4b804876c5df

<img width="1032" height="257" alt="Screenshot 2025-10-18 at 11 15
52 PM"
src="https://github.com/user-attachments/assets/44e4e46b-b654-4599-84ee-8ee0920b1cd3"
/>
@eulicesl eulicesl deleted the feat/apple-export-clean branch October 24, 2025 12:27
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.

2 participants