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),