diff --git a/ui/flutter/lib/app/application/app_runtime_controller.dart b/ui/flutter/lib/app/application/app_runtime_controller.dart index 0b551b2d..68230cee 100644 --- a/ui/flutter/lib/app/application/app_runtime_controller.dart +++ b/ui/flutter/lib/app/application/app_runtime_controller.dart @@ -53,6 +53,7 @@ class AppRuntimeState { class AppRuntimeController extends AsyncNotifier { static StartConfig? _defaultStartConfig; Future _preferenceWrites = Future.value(); + bool _analyticsStarted = false; @override Future build() async { @@ -73,6 +74,7 @@ class AppRuntimeController extends AsyncNotifier { startConfig ..apiEnable = true ..mcpEnable = config.api.mcpEnable; + await _initAnalytics(config); } else { startConfig ..apiEnable = config.api.enable @@ -253,7 +255,8 @@ class AppRuntimeController extends AsyncNotifier { } Future _initAnalytics(DownloaderConfig config) async { - if (!AnalyticsConfig.isConfigured || !config.extra.analyticsEnabled) return; + if (_analyticsStarted || !AnalyticsConfig.isConfigured || !config.extra.analyticsEnabled) return; + _analyticsStarted = true; try { final generatedClientId = await Analytics.instance.init(fallbackClientId: config.extra.deviceId); if (generatedClientId != null) { @@ -262,6 +265,7 @@ class AppRuntimeController extends AsyncNotifier { } unawaited(Analytics.instance.logAppOpen()); } catch (error, stackTrace) { + _analyticsStarted = false; logger.w('GA4 init failed', error, stackTrace); } } diff --git a/ui/flutter/lib/app/application/downloader_config_init.dart b/ui/flutter/lib/app/application/downloader_config_init.dart index dfe82c16..acc8d1ac 100644 --- a/ui/flutter/lib/app/application/downloader_config_init.dart +++ b/ui/flutter/lib/app/application/downloader_config_init.dart @@ -19,7 +19,7 @@ Future loadDownloaderConfig({ config = await load(); } catch (error, stackTrace) { onLoadError?.call(error, stackTrace); - config = DownloaderConfig(); + config = DownloaderConfig()..extra.analyticsEnabled = false; loaded = false; } final changed = await initDownloaderConfig(config, defaultDownloadDir: defaultDownloadDir); diff --git a/ui/flutter/test/app/application/downloader_config_init_test.dart b/ui/flutter/test/app/application/downloader_config_init_test.dart index 704a0aed..f91cdb97 100644 --- a/ui/flutter/test/app/application/downloader_config_init_test.dart +++ b/ui/flutter/test/app/application/downloader_config_init_test.dart @@ -32,8 +32,22 @@ void main() { // The in-memory fallback still gets usable defaults. expect(config.downloadDir, '/downloads'); expect(config.categories, hasLength(4)); + expect(config.extra.analyticsEnabled, isFalse); }); + for (final analyticsEnabled in [false, true]) { + test('preserves the saved analytics preference ($analyticsEnabled)', () async { + final stored = configWith()..extra.analyticsEnabled = analyticsEnabled; + final config = await loadDownloaderConfig( + load: () async => stored, + save: (_) async {}, + defaultDownloadDir: () async => '/downloads', + ); + + expect(config.extra.analyticsEnabled, analyticsEnabled); + }); + } + test('skips persist when init changed nothing', () async { var saved = 0; await loadDownloaderConfig(