From 63e5b4535efa20301f2982ea45505de1520d3fab Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Tue, 30 Dec 2025 09:15:25 +0000 Subject: [PATCH] fix: restore and display configuration status after force-stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add loadConfigurationStatus() function to check if plugin/fetcher are configured - Call loadConfigurationStatus() on page load and app resume (visibility change) - Add logging to getConfig() to track configuration restoration from database - UI now shows ✅ Configured status after force-stop recovery Previously, after force-stop recovery: - Configuration was stored in database but UI didn't check for it - configStatus and fetcherStatus remained as 'Not configured' even though config existed - No logging to track when configuration was restored The fix: - loadConfigurationStatus() queries database for native_fetcher_config - Updates UI status indicators (configStatus, fetcherStatus) based on database state - Called automatically on page load and when app becomes visible - Android logs 'DNP-CONFIG: Configuration restored from database' when config is loaded This ensures the 'Ready to test...' UI block shows correct configuration status after force-stop recovery, matching the actual database state. --- .../DailyNotificationPlugin.kt | 4 ++ www/index.html | 66 +++++++++++++++++-- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt index 4058e42..e10c447 100644 --- a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt +++ b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt @@ -2072,6 +2072,8 @@ open class DailyNotificationPlugin : Plugin() { val options = call.getObject("options") val timesafariDid = options?.getString("timesafariDid") + Log.d(TAG, "DNP-CONFIG: Loading config from database: key=$key, timesafariDid=${timesafariDid?.take(20)}...") + val entity = if (timesafariDid != null) { getDatabase().notificationConfigDao().getConfigByKeyAndDid(key, timesafariDid) } else { @@ -2079,8 +2081,10 @@ open class DailyNotificationPlugin : Plugin() { } if (entity != null) { + Log.i(TAG, "DNP-CONFIG: Configuration restored from database: key=$key, configType=${entity.configType}, hasValue=${entity.configValue.isNotEmpty()}") call.resolve(configToJson(entity)) } else { + Log.d(TAG, "DNP-CONFIG: Configuration not found in database: key=$key") call.resolve(JSObject().apply { put("config", null) }) } } catch (e: Exception) { diff --git a/www/index.html b/www/index.html index 4e85d40..4682dbe 100644 --- a/www/index.html +++ b/www/index.html @@ -346,6 +346,60 @@ } } + // Load configuration status (plugin settings and native fetcher) + function loadConfigurationStatus() { + console.log('[Config Check] Checking configuration status...'); + const configStatus = document.getElementById('configStatus'); + const fetcherStatus = document.getElementById('fetcherStatus'); + + if (!window.DailyNotification) { + console.warn('[Config Check] DailyNotification plugin not available'); + configStatus.innerHTML = '❌ Plugin unavailable'; + fetcherStatus.innerHTML = '❌ Plugin unavailable'; + return; + } + + // Check if plugin settings are configured + // Plugin settings are stored internally, so we check by trying to get status + // For now, we'll check if native fetcher config exists as a proxy + // TODO: Add explicit plugin settings check method + window.DailyNotification.getConfig({ key: 'native_fetcher_config' }) + .then(result => { + console.log('[Config Check] Native fetcher config result:', JSON.stringify(result)); + if (result && result.config && result.config.configValue) { + try { + const configValue = JSON.parse(result.config.configValue); + if (configValue.apiBaseUrl && configValue.apiBaseUrl.length > 0) { + console.log('[Config Check] ✅ Native fetcher is configured'); + fetcherStatus.innerHTML = '✅ Configured'; + } else { + console.log('[Config Check] ⚠️ Native fetcher config exists but is empty'); + fetcherStatus.innerHTML = '❌ Not configured'; + } + } catch (e) { + console.warn('[Config Check] Failed to parse config value:', e); + fetcherStatus.innerHTML = '❌ Error'; + } + } else { + console.log('[Config Check] ❌ Native fetcher config not found'); + fetcherStatus.innerHTML = '❌ Not configured'; + } + + // For plugin settings, we assume configured if native fetcher is configured + // This is a heuristic - in production, add explicit check + if (fetcherStatus.innerHTML.includes('✅')) { + configStatus.innerHTML = '✅ Configured'; + } else { + configStatus.innerHTML = '❌ Not configured'; + } + }) + .catch(error => { + console.error('[Config Check] Failed to check configuration:', error); + configStatus.innerHTML = '❌ Error'; + fetcherStatus.innerHTML = '❌ Error'; + }); + } + function loadChannelStatus() { const channelStatus = document.getElementById('channelStatus'); @@ -568,11 +622,12 @@ // Load plugin status automatically on page load window.addEventListener('load', () => { console.log('Page loaded, loading plugin status...'); - // Small delay to ensure Capacitor is ready - setTimeout(() => { - loadPluginStatus(); - loadPermissionStatus(); - loadChannelStatus(); + // Small delay to ensure Capacitor is ready + setTimeout(() => { + loadPluginStatus(); + loadPermissionStatus(); + loadChannelStatus(); + loadConfigurationStatus(); // Initialize last known next notification time if (window.DailyNotification) { @@ -600,6 +655,7 @@ loadPluginStatus(); loadPermissionStatus(); loadChannelStatus(); + loadConfigurationStatus(); // Also check for recent notifications that might have been missed if (window.DailyNotification) {