diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e4fd064..8a7550b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -489,7 +489,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -511,7 +511,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -530,7 +530,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -547,7 +547,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -679,7 +679,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -702,7 +702,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 71; + CURRENT_PROJECT_VERSION = 73; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index c18990d..22d3c17 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -43,7 +43,7 @@ CFBundleSignature ???? CFBundleVersion - 71 + 73 LSRequiresIPhoneOS NSBluetoothAlwaysUsageDescription diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml index b74dd9c..5e09600 100644 --- a/ios/fastlane/report.xml +++ b/ios/fastlane/report.xml @@ -5,22 +5,22 @@ - + - + - + - + diff --git a/lib/providers/app_provider.dart b/lib/providers/app_provider.dart index 1bbd0f6..f079740 100644 --- a/lib/providers/app_provider.dart +++ b/lib/providers/app_provider.dart @@ -50,6 +50,8 @@ class AppProvider with ChangeNotifier { bool get isVoiceCompressorEnabled => _isVoiceCompressorEnabled; bool _isVoiceLimiterEnabled = true; bool get isVoiceLimiterEnabled => _isVoiceLimiterEnabled; + bool _autoAddDiscoveredContacts = false; + bool get autoAddDiscoveredContacts => _autoAddDiscoveredContacts; static const Duration _packetRetryDelay = Duration(milliseconds: 1200); static const int _maxPacketRetryAttempts = 4; @@ -79,6 +81,7 @@ class AppProvider with ChangeNotifier { _loadVoiceBandPassFilterEnabled(); _loadVoiceCompressorEnabled(); _loadVoiceLimiterEnabled(); + _loadAutoAddDiscoveredContacts(); _startPacketCapturePersistence(); _syncDrawingsOnStartup(); // Sync drawings immediately after providers load _isInitialized = true; @@ -96,7 +99,9 @@ class AppProvider with ChangeNotifier { final prefix = log.rawData.length <= 12 ? log.rawData : log.rawData.sublist(0, 12); - final prefixHex = prefix.map((b) => b.toRadixString(16).padLeft(2, '0')).join(); + final prefixHex = prefix + .map((b) => b.toRadixString(16).padLeft(2, '0')) + .join(); return '${log.timestamp.microsecondsSinceEpoch}|' '${log.direction.name}|${log.responseCode ?? -1}|' '${log.rawData.length}|$prefixHex'; @@ -300,6 +305,30 @@ class AppProvider with ChangeNotifier { } } + /// Load auto-add discovered contacts setting from shared preferences. + Future _loadAutoAddDiscoveredContacts() async { + try { + final prefs = await SharedPreferences.getInstance(); + _autoAddDiscoveredContacts = + prefs.getBool('auto_add_discovered_contacts') ?? false; + notifyListeners(); + } catch (e) { + debugPrint('Error loading auto-add discovered contacts setting: $e'); + } + } + + /// Toggle auto-add discovered contacts on/off. + Future toggleAutoAddDiscoveredContacts(bool enabled) async { + try { + _autoAddDiscoveredContacts = enabled; + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('auto_add_discovered_contacts', enabled); + notifyListeners(); + } catch (e) { + debugPrint('Error saving auto-add discovered contacts setting: $e'); + } + } + /// Initialize tile cache service Future _initializeTileCache() async { try { @@ -794,13 +823,22 @@ class AppProvider with ChangeNotifier { } }); } else { - contactsProvider.addPendingAdvert( - publicKey, - devicePublicKey: connectionProvider.deviceInfo.publicKey, - ); - debugPrint( - ' Unknown contact - added to pending adverts list and waiting for details', - ); + if (_autoAddDiscoveredContacts) { + debugPrint(' Unknown contact - auto-add enabled, fetching details'); + Future.delayed(const Duration(milliseconds: 100), () { + if (connectionProvider.deviceInfo.isConnected) { + connectionProvider.getContact(publicKey); + } + }); + } else { + contactsProvider.addPendingAdvert( + publicKey, + devicePublicKey: connectionProvider.deviceInfo.publicKey, + ); + debugPrint( + ' Unknown contact - added to pending adverts list and waiting for details', + ); + } } }; @@ -1151,7 +1189,6 @@ class AppProvider with ChangeNotifier { }); } - /// Insert or update a voice placeholder message for binary raw-data packets. /// /// Binary voice packets arrive without a chat message, so we synthesise one diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 4716ff7..8f05397 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -661,6 +661,19 @@ class _SettingsScreenState extends State { }, ), ), + Consumer( + builder: (context, appProvider, child) => SwitchListTile( + secondary: const Icon(Icons.person_add_alt_1), + title: const Text('Auto-add discovered contacts'), + subtitle: const Text( + 'Automatically fetch and add new contacts when they are discovered', + ), + value: appProvider.autoAddDiscoveredContacts, + onChanged: (value) async { + await appProvider.toggleAutoAddDiscoveredContacts(value); + }, + ), + ), Consumer( builder: (context, appProvider, child) => SwitchListTile( secondary: const Icon(Icons.map_outlined),