Add actionable push notifications for iOS and Android

iOS:
- Add notification categories with action buttons (complete, view, cancel, etc.)
- Handle notification actions in AppDelegate with API calls
- Add navigation to specific task from notification tap
- Register UNNotificationCategory for each task state

Android:
- Add NotificationActionReceiver BroadcastReceiver for handling actions
- Update MyFirebaseMessagingService to show action buttons
- Add deep link handling in MainActivity for task navigation
- Register receiver in AndroidManifest.xml

Shared:
- Add navigateToTaskId parameter to App for cross-platform navigation
- Add notification observers in MainTabView/AllTasksView for refresh

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-05 14:23:25 -06:00
parent 771f5d2bd3
commit 2965ec4031
19 changed files with 945 additions and 18 deletions

View File

@@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
private var deepLinkResetToken by mutableStateOf<String?>(null)
private var navigateToTaskId by mutableStateOf<Int?>(null)
private lateinit var billingManager: BillingManager
override fun onCreate(savedInstanceState: Bundle?) {
@@ -54,8 +55,9 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
// Initialize BillingManager for subscription management
billingManager = BillingManager.getInstance(applicationContext)
// Handle deep link from intent
// Handle deep link and notification navigation from intent
handleDeepLink(intent)
handleNotificationNavigation(intent)
// Request notification permission and setup FCM
setupFCM()
@@ -68,6 +70,10 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
deepLinkResetToken = deepLinkResetToken,
onClearDeepLinkToken = {
deepLinkResetToken = null
},
navigateToTaskId = navigateToTaskId,
onClearNavigateToTask = {
navigateToTaskId = null
}
)
}
@@ -180,6 +186,15 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleDeepLink(intent)
handleNotificationNavigation(intent)
}
private fun handleNotificationNavigation(intent: Intent?) {
val taskId = intent?.getIntExtra(NotificationActionReceiver.EXTRA_NAVIGATE_TO_TASK, -1)
if (taskId != null && taskId != -1) {
Log.d("MainActivity", "Navigating to task from notification: $taskId")
navigateToTaskId = taskId
}
}
private fun handleDeepLink(intent: Intent?) {