chore(release): v3.0.0 — iOS native fetcher, starred plans, chained dual (iOS + Android)

BREAKING CHANGE (iOS): configureNativeFetcher now requires
DailyNotificationPlugin.registerNativeFetcher(_) first, aligned with Android.

iOS:
- Add NativeNotificationContentFetcher SPI, registry, FetchContext, timeout helper
- Add updateStarredPlans / getStarredPlans; persist daily_notification_timesafari.starredPlanIds
- Chained dual: prefetch only on scheduleDualNotification; arm one-shot UN after fetch
- configureNativeFetcher invokes fetcher.configure; BG fetch prefers registered fetcher
- Public NotificationContent for host implementations

Android:
- Dual notify alarm scheduled after dual FetchWorker completes (DualScheduleNotifyScheduler)
- Persist dual_notify_schedule_id; remove upfront NotifyReceiver for dual setup

Docs: CONSUMING_APP_HANDOFF_IOS_NATIVE_FETCHER_AND_CHAINED_DUAL.md; CHANGELOG 3.0.0
Made-with: Cursor
This commit is contained in:
Jose Olarte III
2026-04-02 16:48:06 +08:00
parent 9121b1e0f7
commit fbb5a94071
12 changed files with 544 additions and 146 deletions

View File

@@ -381,7 +381,8 @@
fetcherStatus.innerHTML = '❌ Error';
}
} else {
console.log('[Config Check] ❌ Native fetcher config not found');
console.log('[Config Check] ❌ Native fetcher config not found in database');
console.log('[Config Check] This may be normal after app uninstall/reinstall (database wiped)');
fetcherStatus.innerHTML = '❌ Not configured';
}
@@ -395,8 +396,15 @@
})
.catch(error => {
console.error('[Config Check] Failed to check configuration:', error);
configStatus.innerHTML = '❌ Error';
fetcherStatus.innerHTML = '❌ Error';
// Don't show error if database might not be ready yet (recovery in progress)
if (error.message && error.message.includes('database')) {
console.log('[Config Check] Database may not be ready yet, will retry...');
fetcherStatus.innerHTML = '⏳ Checking...';
configStatus.innerHTML = '⏳ Checking...';
} else {
configStatus.innerHTML = '❌ Error';
fetcherStatus.innerHTML = '❌ Error';
}
});
}
@@ -650,8 +658,15 @@
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
console.log('[Visibility] App became visible, refreshing UI status...');
// Small delay to allow recovery to complete
// Longer delay to allow recovery to complete (force-stop recovery can take a few seconds)
// Also refresh immediately, then again after delay to catch any late recovery
loadPluginStatus();
loadPermissionStatus();
loadChannelStatus();
loadConfigurationStatus();
setTimeout(() => {
console.log('[Visibility] Delayed refresh after recovery period...');
loadPluginStatus();
loadPermissionStatus();
loadChannelStatus();
@@ -692,7 +707,7 @@
console.error('[Visibility] Failed to get notification status:', error);
});
}
}, 1000); // Wait 1 second for recovery to complete
}, 3000); // Wait 3 seconds for recovery to complete (force-stop recovery can take time)
}
});