From 75610695c2fed89dd5688ef62d35d7418ff5a4c4 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sat, 28 Feb 2026 19:11:11 -0800 Subject: [PATCH 01/12] Add contact settings and discovery features - Implemented contact settings in localization files for Swedish, Ukrainian, and Chinese. - Added new DiscoveryContact model to handle discovered contacts. - Created DiscoveryScreen to display discovered contacts with filtering and sorting options. - Integrated contact discovery storage to persist discovered contacts. - Updated settings screen to include options for automatic contact addition. - Enhanced app bar and list filter widgets for better user experience. - Fixed variable naming inconsistencies in contact model. --- lib/connector/meshcore_connector.dart | 119 ++++++-- lib/connector/meshcore_protocol.dart | 52 +++- lib/l10n/app_en.arb | 22 +- lib/l10n/app_localizations.dart | 108 +++++++ lib/l10n/app_localizations_bg.dart | 61 ++++ lib/l10n/app_localizations_de.dart | 61 ++++ lib/l10n/app_localizations_en.dart | 61 ++++ lib/l10n/app_localizations_es.dart | 61 ++++ lib/l10n/app_localizations_fr.dart | 61 ++++ lib/l10n/app_localizations_it.dart | 61 ++++ lib/l10n/app_localizations_nl.dart | 61 ++++ lib/l10n/app_localizations_pl.dart | 61 ++++ lib/l10n/app_localizations_pt.dart | 61 ++++ lib/l10n/app_localizations_ru.dart | 61 ++++ lib/l10n/app_localizations_sk.dart | 61 ++++ lib/l10n/app_localizations_sl.dart | 61 ++++ lib/l10n/app_localizations_sv.dart | 61 ++++ lib/l10n/app_localizations_uk.dart | 61 ++++ lib/l10n/app_localizations_zh.dart | 61 ++++ lib/models/contact.dart | 2 +- lib/models/discovery_contact.dart | 137 +++++++++ lib/screens/contacts_screen.dart | 16 ++ lib/screens/discovery_screen.dart | 347 +++++++++++++++++++++++ lib/screens/settings_screen.dart | 113 +++++++- lib/services/ble_debug_log_service.dart | 4 +- lib/storage/contact_discovery_store.dart | 59 ++++ lib/widgets/app_bar.dart | 15 +- lib/widgets/list_filter_widget.dart | 90 ++++++ 28 files changed, 1958 insertions(+), 41 deletions(-) create mode 100644 lib/models/discovery_contact.dart create mode 100644 lib/screens/discovery_screen.dart create mode 100644 lib/storage/contact_discovery_store.dart diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index ef19f02..c142f84 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:crypto/crypto.dart' as crypto; +import 'package:meshcore_open/models/discovery_contact.dart'; import 'package:pointycastle/export.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; @@ -24,6 +25,7 @@ import '../storage/channel_message_store.dart'; import '../storage/channel_order_store.dart'; import '../storage/channel_settings_store.dart'; import '../storage/channel_store.dart'; +import '../storage/contact_discovery_store.dart'; import '../storage/contact_settings_store.dart'; import '../storage/contact_store.dart'; import '../storage/message_store.dart'; @@ -111,6 +113,7 @@ class MeshCoreConnector extends ChangeNotifier { final List _scanResults = []; final List _contacts = []; + final List _discoveredContacts = []; final List _channels = []; final Map> _conversations = {}; final Map> _channelMessages = {}; @@ -155,6 +158,12 @@ class MeshCoreConnector extends ChangeNotifier { bool _batteryRequested = false; bool _awaitingSelfInfo = false; bool _preserveContactsOnRefresh = false; + bool _autoAddUsers = false; + bool _autoAddRepeaters = false; + bool _autoAddRoomServers = false; + bool _autoAddSensors = false; + bool _overwriteOldest = false; + static const int _defaultMaxContacts = 32; static const int _defaultMaxChannels = 8; int _maxContacts = _defaultMaxContacts; @@ -195,6 +204,7 @@ class MeshCoreConnector extends ChangeNotifier { final ChannelSettingsStore _channelSettingsStore = ChannelSettingsStore(); final ContactSettingsStore _contactSettingsStore = ContactSettingsStore(); final ContactStore _contactStore = ContactStore(); + final ContactDiscoveryStore _discoveryContactStore = ContactDiscoveryStore(); final ChannelStore _channelStore = ChannelStore(); final UnreadStore _unreadStore = UnreadStore(); List _cachedChannels = []; @@ -242,6 +252,10 @@ class MeshCoreConnector extends ChangeNotifier { ); } + List get discoveredContacts { + return List.unmodifiable(_discoveredContacts); + } + List get channels => List.unmodifiable(_channels); bool get isConnected => _state == MeshCoreConnectionState.connected; bool get isLoadingContacts => _isLoadingContacts; @@ -258,6 +272,11 @@ class MeshCoreConnector extends ChangeNotifier { int? get currentBwHz => _currentBwHz; int? get currentSf => _currentSf; int? get currentCr => _currentCr; + bool? get autoAddUsers => _autoAddUsers; + bool? get autoAddRepeaters => _autoAddRepeaters; + bool? get autoAddRoomServers => _autoAddRoomServers; + bool? get autoAddSensors => _autoAddSensors; + bool? get autoAddOverwriteOldest => _overwriteOldest; bool? get clientRepeat => _clientRepeat; int? get firmwareVerCode => _firmwareVerCode; Map? get currentCustomVars => _currentCustomVars; @@ -602,6 +621,13 @@ class MeshCoreConnector extends ChangeNotifier { } } + Future loadDiscoveredContactCache() async { + final cached = await _discoveryContactStore.loadContacts(); + _discoveredContacts + ..clear() + ..addAll(cached); + } + Future loadChannelSettings({int? maxChannels}) async { _channelSmazEnabled.clear(); final channelCount = maxChannels ?? _maxChannels; @@ -852,6 +878,9 @@ class MeshCoreConnector extends ChangeNotifier { // Fetch channels so we can track unread counts for incoming messages unawaited(getChannels()); + + // Load discovered contacts from storage + unawaited(loadDiscoveredContactCache()); } catch (e) { debugPrint("Connection error: $e"); await disconnect(manual: false); @@ -972,6 +1001,7 @@ class MeshCoreConnector extends ChangeNotifier { _deviceDisplayName = null; _deviceId = null; _contacts.clear(); + _discoveredContacts.clear(); _conversations.clear(); _loadedConversationKeys.clear(); _selfPublicKey = null; @@ -1064,6 +1094,7 @@ class MeshCoreConnector extends ChangeNotifier { await requestBatteryStatus(force: true); await sendFrame(buildGetRadioSettingsFrame()); await sendFrame(buildGetCustomVarsFrame()); + await sendFrame(buildGetAutoAddFlagsFrame()); _scheduleSelfInfoRetry(); } @@ -1074,7 +1105,7 @@ class MeshCoreConnector extends ChangeNotifier { await sendFrame(buildAppStartFrame()); await sendFrame(buildGetCustomVarsFrame()); await requestBatteryStatus(); - + await sendFrame(buildGetAutoAddFlagsFrame()); _scheduleSelfInfoRetry(); } @@ -1903,8 +1934,8 @@ class MeshCoreConnector extends ChangeNotifier { case respCodeChannelInfo: _handleChannelInfo(frame); break; - case respCodeRadioSettings: - _handleRadioSettings(frame); + case respCodeAutoAddConfig: + _handleAutoAddConfig(frame); break; case respCodeBattAndStorage: _handleBatteryAndStorage(frame); @@ -1985,6 +2016,10 @@ class MeshCoreConnector extends ChangeNotifier { _selfLatitude = readInt32LE(frame, 36) / 1000000.0; _selfLongitude = readInt32LE(frame, 40) / 1000000.0; + if (frame.length >= 47 && frame[47] == 0x00) { + sendFrame(buildSetOtherParamsFrame(0, 0, 0)); + } + // Radio settings (if frame is long enough) if (frame.length >= 58) { _currentFreqHz = readUint32LE(frame, 48); @@ -1992,7 +2027,6 @@ class MeshCoreConnector extends ChangeNotifier { _currentSf = frame[56]; _currentCr = frame[57]; } - // Node name starts at offset 58 if frame is long enough if (frame.length > 58) { _selfName = readCString(frame, 58, frame.length - 58); @@ -2056,25 +2090,6 @@ class MeshCoreConnector extends ChangeNotifier { unawaited(_requestNextQueuedMessage()); } - void _handleRadioSettings(Uint8List frame) { - // Frame format from C++: - // [0] = RESP_CODE_RADIO_SETTINGS - // [1-4] = freq (uint32 LE, in Hz) - // [5-8] = bw (uint32 LE, in Hz) - // [9] = sf - // [10] = cr - if (frame.length >= 11) { - _currentFreqHz = readUint32LE(frame, 1); - _currentBwHz = readUint32LE(frame, 5); - _currentSf = frame[9]; - _currentCr = frame[10]; - debugPrint( - 'Radio settings: freq=$_currentFreqHz bw=$_currentBwHz sf=$_currentSf cr=$_currentCr', - ); - notifyListeners(); - } - } - void _handleBatteryAndStorage(Uint8List frame) { // Frame format from C++: // [0] = RESP_CODE_BATT_AND_STORAGE @@ -2275,6 +2290,10 @@ class MeshCoreConnector extends ChangeNotifier { await _contactStore.saveContacts(_contacts); } + Future _persistDiscoveredContacts() async { + await _discoveryContactStore.saveContacts(_discoveredContacts); + } + int _latestContactLastmod() { if (_contacts.isEmpty) return 0; var latest = 0; @@ -3739,6 +3758,7 @@ class MeshCoreConnector extends ChangeNotifier { return; } + //We ignore our own adverts if (listEquals(publicKey, _selfPublicKey)) { return; } @@ -3759,7 +3779,14 @@ class MeshCoreConnector extends ChangeNotifier { longitude: longitude, lastSeen: DateTime.fromMillisecondsSinceEpoch(timestamp * 1000), ); - _handleContactAdvert(newContact); + if ((_autoAddUsers && type == advTypeChat) || + (_autoAddRepeaters && type == advTypeRepeater) || + (_autoAddRoomServers && type == advTypeRoom) || + (_autoAddSensors && type == advTypeSensor)) { + _handleContactAdvert(newContact); + } else { + _handleDiscovery(newContact); + } _updateDirectRepeater(newContact, snr, path); return; } @@ -3847,6 +3874,50 @@ class MeshCoreConnector extends ChangeNotifier { } notifyListeners(); } + + void _handleAutoAddConfig(Uint8List frame) { + final reader = BufferReader(frame); + try { + reader.skipBytes(1); // Skip the response code byte + final flags = reader.readByte(); + _autoAddUsers = flags & autoAddChatFlag != 0; + _autoAddRepeaters = flags & autoAddRepeaterFlag != 0; + _autoAddRoomServers = flags & autoAddRoomServerFlag != 0; + _autoAddSensors = flags & autoAddSensorFlag != 0; + _overwriteOldest = flags & autoAddOverwriteOldestFlag != 0; + } catch (e) { + appLogger.error('Failed to parse auto-add config: $e', tag: 'Connector'); + } + } + + void _handleDiscovery(Contact contact) { + debugPrint('Discovered new contact: ${contact.name}'); + final disContact = DiscoveryContact( + publicKey: contact.publicKey, + name: contact.name, + type: contact.type, + pathLength: contact.pathLength, + path: contact.path, + latitude: contact.latitude, + longitude: contact.longitude, + lastSeen: contact.lastSeen, + ); + _discoveredContacts.add(disContact); + + unawaited(_persistDiscoveredContacts()); + + // Show notification for new contact (advertisement) + if (_appSettingsService != null) { + final settings = _appSettingsService!.settings; + if (settings.notificationsEnabled && settings.notifyOnNewAdvert) { + _notificationService.showAdvertNotification( + contactName: contact.name, + contactType: contact.typeLabel, + contactId: contact.publicKeyHex, + ); + } + } + } } const int _phRouteMask = 0x03; diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index d5ce9ee..36c13e2 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -167,6 +167,8 @@ const int cmdGetTelemetryReq = 39; const int cmdGetCustomVar = 40; const int cmdSetCustomVar = 41; const int cmdSendBinaryReq = 50; +const int cmdSetAutoAddConfig = 58; +const int cmdGetAutoAddConfig = 59; // Text message types const int txtTypePlain = 0; @@ -200,8 +202,8 @@ const int respCodeDeviceInfo = 13; const int respCodeContactMsgRecvV3 = 16; const int respCodeChannelMsgRecvV3 = 17; const int respCodeChannelInfo = 18; -const int respCodeRadioSettings = 25; const int respCodeCustomVars = 21; +const int respCodeAutoAddConfig = 25; // Push codes (async from device) const int pushCodeAdvert = 0x80; @@ -247,6 +249,18 @@ const int payloadTypeCONTROL = 0x0B; // a control/discovery packet const int payloadTypeRawCustom = 0x0F; // custom packet as raw bytes, for applications with custom encryption, payloads, etc +//auto-add flags +const int autoAddOverwriteOldestFlag = + 1 << 0; // 0x01 - overwrite oldest non-favourite when full +const int autoAddChatFlag = + 1 << 1; // 0x02 - auto-add Chat (Companion) (ADV_TYPE_CHAT) +const int autoAddRepeaterFlag = + 1 << 2; // 0x04 - auto-add Repeater (ADV_TYPE_REPEATER) +const int autoAddRoomServerFlag = + 1 << 3; // 0x08 - auto-add Room Server (ADV_TYPE_ROOM) +const int autoAddSensorFlag = + 1 << 4; // 0x10 - auto-add Sensor (ADV_TYPE_SENSOR) + // Sizes const int pubKeySize = 32; const int maxPathSize = 64; @@ -297,7 +311,7 @@ const int contactNameOffset = 100; const int contactTimestampOffset = 132; const int contactLatOffset = 136; const int contactLonOffset = 140; -const int contactLastmodOffset = 144; +const int contactLastModOffset = 144; const int contactFrameSize = 148; // Message frame offsets @@ -685,6 +699,10 @@ Uint8List buildGetCustomVarsFrame() { return Uint8List.fromList([cmdGetCustomVar]); } +Uint8List buildGetAutoAddFlagsFrame() { + return Uint8List.fromList([cmdGetAutoAddConfig]); +} + // Calculate LoRa airtime for a packet // Based on Semtech SX127x datasheet formula // Returns airtime in milliseconds @@ -826,20 +844,40 @@ Uint8List buildZeroHopContact(Uint8List pubKey) { } // Build CMD_SET_OTHER_PARAMS frame -// Format: [cmd][allowAutoAddContacts][allowTelemetryFlags][advertLocationPolicy][multiAcks] +// Format: [cmd][allowTelemetryFlags][advertLocationPolicy][multiAcks] Uint8List buildSetOtherParamsFrame( - bool allowAutoAddContacts, int allowTelemetryFlags, int advertLocationPolicy, int multiAcks, ) { final writer = BufferWriter(); writer.writeByte(cmdSetOtherParams); - writer.writeByte( - allowAutoAddContacts ? 0x00 : 0x01, - ); // Allow Auto Add Contacts + //Going forward the app will just set Auto Add Contacts to disabled, and use the filter flags + //Allow Auto Add Contacts use inverted logic (0x01 = disabled, 0x00 = enabled). + writer.writeByte(0x01); writer.writeByte(allowTelemetryFlags); // Allow Telemetry Flags writer.writeByte(advertLocationPolicy); // Advertisement Location Policy writer.writeByte(multiAcks); // Multi Acknowledgements return writer.toBytes(); } + +// Build CMD_SET_AUTO_ADD_CONFIG frame +// Format: [cmd][flags] +Uint8List buildSetAutoAddConfigFrame({ + required bool autoAddChat, + required bool autoAddRepeater, + required bool autoAddRoomServer, + required bool autoAddSensor, + required bool overwriteOldest, +}) { + final writer = BufferWriter(); + writer.writeByte(cmdSetAutoAddConfig); + int flags = 0; + if (autoAddChat) flags |= autoAddChatFlag; + if (autoAddRepeater) flags |= autoAddRepeaterFlag; + if (autoAddRoomServer) flags |= autoAddRoomServerFlag; + if (autoAddSensor) flags |= autoAddSensorFlag; + if (overwriteOldest) flags |= autoAddOverwriteOldestFlag; + writer.writeByte(flags); + return writer.toBytes(); +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 175c346..3f92d0e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -98,6 +98,8 @@ "settings_locationIntervalInvalid": "Interval must be at least 60 seconds, and less than 86400 seconds.", "settings_latitude": "Latitude", "settings_longitude": "Longitude", + "settings_contactSettings": "Contact Settings", + "settings_contactSettingsSubtitle": "Settings for how contacts are added.", "settings_privacyMode": "Privacy Mode", "settings_privacyModeSubtitle": "Hide name/location in advertisements", "settings_privacyModeToggle": "Toggle privacy mode to hide your name and location in advertisements.", @@ -1837,5 +1839,21 @@ "settings_gpxExportShareText": "Map data exported from meshcore-open", "settings_gpxExportShareSubject": "meshcore-open GPX map data export", "snrIndicator_nearByRepeaters": "Nearby Repeaters", - "snrIndicator_lastSeen": "Last seen" -} + "snrIndicator_lastSeen": "Last seen", + "contactsSettings_title": "Contacts settings", + "contactsSettings_autoAddTitle": "Automatic Discovery", + "contactsSettings_otherTitle": "Other contact related settings", + "contactsSettings_autoAddUsersTitle": "Auto-add users", + "contactsSettings_autoAddUsersSubtitle": "Allow the companion to automatically add discovered users.", + "contactsSettings_autoAddRepeatersTitle": "Auto-add repeaters", + "contactsSettings_autoAddRepeatersSubtitle": "Allow the companion to automatically add discovered repeaters.", + "contactsSettings_autoAddRoomServersTitle": "Auto-add room servers", + "contactsSettings_autoAddRoomServersSubtitle": "Allow the companion to automatically add discovered room servers.", + "contactsSettings_autoAddSensorsTitle": "Auto-add sensors", + "contactsSettings_autoAddSensorsSubtitle": "Allow the companion to automatically add discovered sensors.", + "contactsSettings_overwriteOldestTitle": "Overwrite Oldest", + "contactsSettings_overwriteOldestSubtitle": "When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.", + "discoveredContacts_Title": "Discovered Contacts", + "discoveredContacts_noMatching": "No matching contacts", + "discoveredContacts_searchHint": "Search discovered contacts" +} \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index ff2c726..333147f 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -544,6 +544,18 @@ abstract class AppLocalizations { /// **'Longitude'** String get settings_longitude; + /// No description provided for @settings_contactSettings. + /// + /// In en, this message translates to: + /// **'Contact Settings'** + String get settings_contactSettings; + + /// No description provided for @settings_contactSettingsSubtitle. + /// + /// In en, this message translates to: + /// **'Settings for how contacts are added.'** + String get settings_contactSettingsSubtitle; + /// No description provided for @settings_privacyMode. /// /// In en, this message translates to: @@ -5380,6 +5392,102 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Last seen'** String get snrIndicator_lastSeen; + + /// No description provided for @contactsSettings_title. + /// + /// In en, this message translates to: + /// **'Contacts settings'** + String get contactsSettings_title; + + /// No description provided for @contactsSettings_autoAddTitle. + /// + /// In en, this message translates to: + /// **'Automatic Discovery'** + String get contactsSettings_autoAddTitle; + + /// No description provided for @contactsSettings_otherTitle. + /// + /// In en, this message translates to: + /// **'Other contact related settings'** + String get contactsSettings_otherTitle; + + /// No description provided for @contactsSettings_autoAddUsersTitle. + /// + /// In en, this message translates to: + /// **'Auto-add users'** + String get contactsSettings_autoAddUsersTitle; + + /// No description provided for @contactsSettings_autoAddUsersSubtitle. + /// + /// In en, this message translates to: + /// **'Allow the companion to automatically add discovered users.'** + String get contactsSettings_autoAddUsersSubtitle; + + /// No description provided for @contactsSettings_autoAddRepeatersTitle. + /// + /// In en, this message translates to: + /// **'Auto-add repeaters'** + String get contactsSettings_autoAddRepeatersTitle; + + /// No description provided for @contactsSettings_autoAddRepeatersSubtitle. + /// + /// In en, this message translates to: + /// **'Allow the companion to automatically add discovered repeaters.'** + String get contactsSettings_autoAddRepeatersSubtitle; + + /// No description provided for @contactsSettings_autoAddRoomServersTitle. + /// + /// In en, this message translates to: + /// **'Auto-add room servers'** + String get contactsSettings_autoAddRoomServersTitle; + + /// No description provided for @contactsSettings_autoAddRoomServersSubtitle. + /// + /// In en, this message translates to: + /// **'Allow the companion to automatically add discovered room servers.'** + String get contactsSettings_autoAddRoomServersSubtitle; + + /// No description provided for @contactsSettings_autoAddSensorsTitle. + /// + /// In en, this message translates to: + /// **'Auto-add sensors'** + String get contactsSettings_autoAddSensorsTitle; + + /// No description provided for @contactsSettings_autoAddSensorsSubtitle. + /// + /// In en, this message translates to: + /// **'Allow the companion to automatically add discovered sensors.'** + String get contactsSettings_autoAddSensorsSubtitle; + + /// No description provided for @contactsSettings_overwriteOldestTitle. + /// + /// In en, this message translates to: + /// **'Overwrite Oldest'** + String get contactsSettings_overwriteOldestTitle; + + /// No description provided for @contactsSettings_overwriteOldestSubtitle. + /// + /// In en, this message translates to: + /// **'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'** + String get contactsSettings_overwriteOldestSubtitle; + + /// No description provided for @discoveredContacts_Title. + /// + /// In en, this message translates to: + /// **'Discovered Contacts'** + String get discoveredContacts_Title; + + /// No description provided for @discoveredContacts_noMatching. + /// + /// In en, this message translates to: + /// **'No matching contacts'** + String get discoveredContacts_noMatching; + + /// No description provided for @discoveredContacts_searchHint. + /// + /// In en, this message translates to: + /// **'Search discovered contacts'** + String get discoveredContacts_searchHint; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index da7ddc9..c26b5b2 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -234,6 +234,13 @@ class AppLocalizationsBg extends AppLocalizations { @override String get settings_longitude => 'Дължина'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Режим на поверителност'; @@ -3112,4 +3119,58 @@ class AppLocalizationsBg extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Последно видян'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 228ffe7..6d36471 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -233,6 +233,13 @@ class AppLocalizationsDe extends AppLocalizations { @override String get settings_longitude => 'Längengrad'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Privatsphäreeinstellung'; @@ -3121,4 +3128,58 @@ class AppLocalizationsDe extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Zuletzt gesehen'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 70b3393..c40b7df 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -232,6 +232,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settings_longitude => 'Longitude'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Privacy Mode'; @@ -3065,4 +3072,58 @@ class AppLocalizationsEn extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Last seen'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 876666b..203916b 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -233,6 +233,13 @@ class AppLocalizationsEs extends AppLocalizations { @override String get settings_longitude => 'Longitud'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Modo Privacidad'; @@ -3113,4 +3120,58 @@ class AppLocalizationsEs extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Visto por última vez'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 0c11eac..7ae1b25 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -234,6 +234,13 @@ class AppLocalizationsFr extends AppLocalizations { @override String get settings_longitude => 'Longitude'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Mode de confidentialité'; @@ -3135,4 +3142,58 @@ class AppLocalizationsFr extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Dernière fois vu'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 8a8fe71..be88ecb 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -233,6 +233,13 @@ class AppLocalizationsIt extends AppLocalizations { @override String get settings_longitude => 'Longitudine'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Modalità Privacy'; @@ -3116,4 +3123,58 @@ class AppLocalizationsIt extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Ultimo accesso'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 8b4eee5..ad1f624 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -233,6 +233,13 @@ class AppLocalizationsNl extends AppLocalizations { @override String get settings_longitude => 'Lengtegraad'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Privacy Mode'; @@ -3103,4 +3110,58 @@ class AppLocalizationsNl extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Laatst gezien'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index cff6010..a97599c 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -235,6 +235,13 @@ class AppLocalizationsPl extends AppLocalizations { @override String get settings_longitude => 'Długość'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Tryb Prywatny'; @@ -3116,4 +3123,58 @@ class AppLocalizationsPl extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Ostatnio widziany'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 831d47a..e1f89e2 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -234,6 +234,13 @@ class AppLocalizationsPt extends AppLocalizations { @override String get settings_longitude => 'Longitude'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Modo de Privacidade'; @@ -3111,4 +3118,58 @@ class AppLocalizationsPt extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Visto pela última vez'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 5c73e3e..b2f3718 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -232,6 +232,13 @@ class AppLocalizationsRu extends AppLocalizations { @override String get settings_longitude => 'Долгота'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Режим конфиденциальности'; @@ -3123,4 +3130,58 @@ class AppLocalizationsRu extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Последний раз видели'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index b4f28fb..773b338 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -233,6 +233,13 @@ class AppLocalizationsSk extends AppLocalizations { @override String get settings_longitude => 'Dĺžka'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Režim ochrany súkromia'; @@ -3098,4 +3105,58 @@ class AppLocalizationsSk extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Naposledy videný'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index e015e45..0f38b94 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -233,6 +233,13 @@ class AppLocalizationsSl extends AppLocalizations { @override String get settings_longitude => 'Dolžina'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Zasebnost'; @@ -3103,4 +3110,58 @@ class AppLocalizationsSl extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Zadnjič videno'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 3a25c3c..4e67267 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -232,6 +232,13 @@ class AppLocalizationsSv extends AppLocalizations { @override String get settings_longitude => 'Längdgrad'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Privatläge'; @@ -3081,4 +3088,58 @@ class AppLocalizationsSv extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Senast sedd'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index cd820cf..40a52ca 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -232,6 +232,13 @@ class AppLocalizationsUk extends AppLocalizations { @override String get settings_longitude => 'Довгота'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => 'Режим приватності'; @@ -3130,4 +3137,58 @@ class AppLocalizationsUk extends AppLocalizations { @override String get snrIndicator_lastSeen => 'Останній раз бачили'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index b63f714..4aec80b 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -226,6 +226,13 @@ class AppLocalizationsZh extends AppLocalizations { @override String get settings_longitude => '经度'; + @override + String get settings_contactSettings => 'Contact Settings'; + + @override + String get settings_contactSettingsSubtitle => + 'Settings for how contacts are added.'; + @override String get settings_privacyMode => '隐私模式'; @@ -2890,4 +2897,58 @@ class AppLocalizationsZh extends AppLocalizations { @override String get snrIndicator_lastSeen => '最近访问'; + + @override + String get contactsSettings_title => 'Contacts settings'; + + @override + String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + + @override + String get contactsSettings_otherTitle => 'Other contact related settings'; + + @override + String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + + @override + String get contactsSettings_autoAddUsersSubtitle => + 'Allow the companion to automatically add discovered users.'; + + @override + String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + + @override + String get contactsSettings_autoAddRepeatersSubtitle => + 'Allow the companion to automatically add discovered repeaters.'; + + @override + String get contactsSettings_autoAddRoomServersTitle => + 'Auto-add room servers'; + + @override + String get contactsSettings_autoAddRoomServersSubtitle => + 'Allow the companion to automatically add discovered room servers.'; + + @override + String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + + @override + String get contactsSettings_autoAddSensorsSubtitle => + 'Allow the companion to automatically add discovered sensors.'; + + @override + String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + + @override + String get contactsSettings_overwriteOldestSubtitle => + 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + + @override + String get discoveredContacts_Title => 'Discovered Contacts'; + + @override + String get discoveredContacts_noMatching => 'No matching contacts'; + + @override + String get discoveredContacts_searchHint => 'Search discovered contacts'; } diff --git a/lib/models/contact.dart b/lib/models/contact.dart index 5e532e6..7d8e011 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -183,7 +183,7 @@ class Contact { ) : Uint8List(0); final name = readCString(data, contactNameOffset, maxNameSize); - final lastmod = readUint32LE(data, contactLastmodOffset); + final lastmod = readUint32LE(data, contactLastModOffset); double? lat, lon; final latRaw = readInt32LE(data, contactLatOffset); diff --git a/lib/models/discovery_contact.dart b/lib/models/discovery_contact.dart new file mode 100644 index 0000000..54c2937 --- /dev/null +++ b/lib/models/discovery_contact.dart @@ -0,0 +1,137 @@ +import 'dart:typed_data'; +import '../connector/meshcore_protocol.dart'; + +class DiscoveryContact { + final Uint8List publicKey; + final String name; + final int type; + final int pathLength; // -1 = flood, 0+ = direct hops (from device) + final Uint8List path; // Path bytes from device + final double? latitude; + final double? longitude; + final DateTime lastSeen; + + DiscoveryContact({ + required this.publicKey, + required this.name, + required this.type, + required this.pathLength, + required this.path, + this.latitude, + this.longitude, + required this.lastSeen, + }); + + String get publicKeyHex => pubKeyToHex(publicKey); + + String get typeLabel { + switch (type) { + case advTypeChat: + return 'Chat'; + case advTypeRepeater: + return 'Repeater'; + case advTypeRoom: + return 'Room'; + case advTypeSensor: + return 'Sensor'; + default: + return 'Unknown'; + } + } + + String get pathLabel { + if (pathLength < 0) return 'Flood'; + if (pathLength == 0) return 'Direct'; + return '$pathLength hops'; + } + + bool get hasLocation => latitude != null && longitude != null; + + DiscoveryContact copyWith({ + Uint8List? publicKey, + String? name, + int? type, + int? pathLength, + Uint8List? path, + double? latitude, + double? longitude, + DateTime? lastSeen, + }) { + return DiscoveryContact( + publicKey: publicKey ?? this.publicKey, + name: name ?? this.name, + type: type ?? this.type, + pathLength: pathLength ?? this.pathLength, + path: path ?? this.path, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + lastSeen: lastSeen ?? this.lastSeen, + ); + } + + String get pathIdList { + final pathBytes = path; + if (pathBytes.isEmpty) return ''; + final parts = []; + final groupSize = pathHashSize; + for (int i = 0; i < pathBytes.length; i += groupSize) { + final end = (i + groupSize) <= pathBytes.length + ? (i + groupSize) + : pathBytes.length; + final chunk = pathBytes.sublist(i, end); + parts.add( + chunk + .map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()) + .join(), + ); + } + return parts.join(','); + } + + String get shortPubKeyHex { + return "<${publicKeyHex.substring(0, 8)}...${publicKeyHex.substring(publicKeyHex.length - 8)}>"; + } + + Uint8List? get traceRouteBytes { + final pathBytes = path; + Uint8List? traceBytes; + + if (pathBytes.isEmpty) { + traceBytes = Uint8List(1); + traceBytes[0] = publicKey[0]; + return traceBytes; + } + + if (type == advTypeRepeater || type == advTypeRoom) { + final len = (pathBytes.length + pathBytes.length + 1); + traceBytes = Uint8List(len); + traceBytes[pathBytes.length] = publicKey[0]; + for (int i = 0; i < pathBytes.length; i++) { + traceBytes[i] = pathBytes[i]; + if (i < pathBytes.length) { + traceBytes[len - 1 - i] = pathBytes[i]; + } + } + } else { + if (pathBytes.length < 2) { + return pathBytes[0] == 0 ? null : pathBytes; + } + final len = (pathBytes.length + pathBytes.length - 1); + traceBytes = Uint8List(len); + for (int i = 0; i < pathBytes.length; i++) { + traceBytes[i] = pathBytes[i]; + if (i < pathBytes.length - 1) { + traceBytes[len - 1 - i] = pathBytes[i]; + } + } + } + return traceBytes; + } + + @override + bool operator ==(Object other) => + other is DiscoveryContact && publicKeyHex == other.publicKeyHex; + + @override + int get hashCode => publicKeyHex.hashCode; +} diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index eeecfb9..6e9f841 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -26,6 +26,7 @@ import '../widgets/room_login_dialog.dart'; import '../widgets/unread_badge.dart'; import 'channels_screen.dart'; import 'chat_screen.dart'; +import 'discovery_screen.dart'; import 'map_screen.dart'; import 'repeater_hub_screen.dart'; import 'settings_screen.dart'; @@ -318,6 +319,21 @@ class _ContactsScreenState extends State ), onTap: () => _disconnect(context, connector), ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.person_add_rounded), + const SizedBox(width: 8), + Text("Discovered Contacts"), + ], + ), + onTap: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DiscoveryScreen(), + ), + ), + ), PopupMenuItem( child: Row( children: [ diff --git a/lib/screens/discovery_screen.dart b/lib/screens/discovery_screen.dart new file mode 100644 index 0000000..b8f49fa --- /dev/null +++ b/lib/screens/discovery_screen.dart @@ -0,0 +1,347 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:meshcore_open/models/contact.dart'; +import 'package:provider/provider.dart'; + +import '../connector/meshcore_connector.dart'; +import '../connector/meshcore_protocol.dart'; +import '../l10n/l10n.dart'; +import '../models/discovery_contact.dart'; +import '../utils/contact_search.dart'; +import '../widgets/app_bar.dart'; +import '../widgets/list_filter_widget.dart'; + +enum DiscoverySortOption { lastSeen, name, type } + +class DiscoveryScreen extends StatefulWidget { + const DiscoveryScreen({super.key}); + + @override + State createState() => _DiscoveryScreenState(); +} + +class _DiscoveryScreenState extends State { + final TextEditingController _searchController = TextEditingController(); + String searchQuery = ''; + ContactSortOption sortOption = ContactSortOption.lastSeen; + bool showUnreadOnly = false; + ContactTypeFilter typeFilter = ContactTypeFilter.all; + DiscoverySortOption discoverySortOption = DiscoverySortOption.lastSeen; + Timer? _searchDebounce; + + @override + void dispose() { + _searchController.dispose(); + _searchDebounce?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + final connector = context.watch(); + + final discoveredContacts = connector.discoveredContacts; + final filteredAndSorted = _filterAndSortContacts( + discoveredContacts, + connector, + ); + + return Scaffold( + appBar: AppBar( + title: AppBarTitle( + l10n.discoveredContacts_Title, + indicators: false, + subtitle: false, + ), + centerTitle: true, + ), + body: Column( + children: [ + _buildFilters(filteredAndSorted, connector), + Expanded( + child: discoveredContacts.isEmpty + ? Center(child: Text(l10n.contacts_noContacts)) + : filteredAndSorted.isEmpty + ? Center(child: Text(l10n.discoveredContacts_noMatching)) + : ListView.builder( + itemCount: filteredAndSorted.length, + itemBuilder: (context, index) { + final contact = filteredAndSorted[index]; + return ListTile( + leading: CircleAvatar( + backgroundColor: _getTypeColor(contact.type), + child: Icon( + _getTypeIcon(contact.type), + color: Colors.white, + size: 20, + ), + ), + title: Text( + contact.name, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + subtitle: Text( + contact.shortPubKeyHex, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + trailing: Text( + _formatLastSeen(context, contact.lastSeen), + style: TextStyle( + fontSize: 12, + color: Colors.grey[600], + ), + ), + ); + }, + ), + ), + ], + ), + ); + } + + Widget _buildFilters(filteredAndSorted, connector) { + final l10n = context.l10n; + + String hintText = ""; + switch (typeFilter) { + case ContactTypeFilter.all: + hintText = context.l10n.contacts_searchContacts( + filteredAndSorted.length, + showUnreadOnly ? " ${context.l10n.contacts_unread}" : "", + ); + break; + case ContactTypeFilter.users: + hintText = context.l10n.contacts_searchUsers( + filteredAndSorted.length, + showUnreadOnly ? " ${context.l10n.contacts_unread}" : "", + ); + break; + case ContactTypeFilter.repeaters: + hintText = context.l10n.contacts_searchRepeaters( + filteredAndSorted.length, + showUnreadOnly ? " ${context.l10n.contacts_unread}" : "", + ); + break; + case ContactTypeFilter.rooms: + hintText = context.l10n.contacts_searchRoomServers( + filteredAndSorted.length, + showUnreadOnly ? " ${context.l10n.contacts_unread}" : "", + ); + break; + case ContactTypeFilter.favorites: + hintText = context.l10n.contacts_searchFavorites( + filteredAndSorted.length, + showUnreadOnly ? " ${context.l10n.contacts_unread}" : "", + ); + break; + } + + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: TextField( + controller: _searchController, + decoration: InputDecoration( + hintText: hintText, + prefixIcon: const Icon(Icons.search), + suffixIcon: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (searchQuery.isNotEmpty) + IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _searchController.clear(); + setState(() { + searchQuery = ''; + }); + }, + ), + _buildFilterButton(context, connector), + ], + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 12, + ), + ), + onChanged: (value) { + _searchDebounce?.cancel(); + _searchDebounce = Timer(const Duration(milliseconds: 300), () { + if (!mounted) return; + setState(() { + searchQuery = value.toLowerCase(); + }); + }); + }, + ), + ), + ], + ); + } + + Widget _buildFilterButton(BuildContext context, MeshCoreConnector connector) { + return DiscoveryContactsFilterMenu( + sortOption: sortOption, + typeFilter: typeFilter, + onSortChanged: (value) { + setState(() { + sortOption = value; + }); + }, + onTypeFilterChanged: (value) { + setState(() { + typeFilter = value; + }); + }, + ); + } + + List _filterAndSortContacts( + List contacts, + MeshCoreConnector connector, + ) { + var filtered = contacts.where((contact) { + if (searchQuery.isEmpty) return true; + return matchesContactQuery( + Contact( + publicKey: contact.publicKey, + name: contact.name, + type: contact.type, + pathLength: contact.pathLength, + path: contact.path, + lastSeen: contact.lastSeen, + ), + searchQuery, + ); + }).toList(); + + // Filter out own node from the list + if (connector.selfPublicKey != null) { + final selfPubKeyHex = pubKeyToHex(connector.selfPublicKey!); + filtered = filtered.where((contact) { + return contact.publicKeyHex != selfPubKeyHex; + }).toList(); + } + + if (typeFilter != ContactTypeFilter.all) { + filtered = filtered.where(_matchesTypeFilter).toList(); + } + + if (showUnreadOnly) { + filtered = filtered.where((contact) { + return connector.getUnreadCountForContact( + Contact( + publicKey: contact.publicKey, + name: contact.name, + type: contact.type, + pathLength: contact.pathLength, + path: contact.path, + lastSeen: contact.lastSeen, + ), + ) > + 0; + }).toList(); + } + + switch (sortOption) { + case ContactSortOption.lastSeen: + filtered.sort( + (a, b) => _resolveLastSeen(b).compareTo(_resolveLastSeen(a)), + ); + break; + case ContactSortOption.name: + filtered.sort( + (a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()), + ); + break; + default: + break; + } + + return filtered; + } + + bool _matchesTypeFilter(DiscoveryContact contact) { + switch (typeFilter) { + case ContactTypeFilter.all: + return true; + case ContactTypeFilter.users: + return contact.type == advTypeChat; + case ContactTypeFilter.repeaters: + return contact.type == advTypeRepeater; + case ContactTypeFilter.rooms: + return contact.type == advTypeRoom; + default: + return false; + } + } + + DateTime _resolveLastSeen(DiscoveryContact contact) { + if (contact.type != advTypeChat) return contact.lastSeen; + return contact.lastSeen.isAfter(contact.lastSeen) + ? contact.lastSeen + : contact.lastSeen; + } + + IconData _getTypeIcon(int type) { + switch (type) { + case advTypeChat: + return Icons.chat; + case advTypeRepeater: + return Icons.cell_tower; + case advTypeRoom: + return Icons.group; + case advTypeSensor: + return Icons.sensors; + default: + return Icons.device_unknown; + } + } + + Color _getTypeColor(int type) { + switch (type) { + case advTypeChat: + return Colors.blue; + case advTypeRepeater: + return Colors.orange; + case advTypeRoom: + return Colors.purple; + case advTypeSensor: + return Colors.green; + default: + return Colors.grey; + } + } + + String _formatLastSeen(BuildContext context, DateTime lastSeen) { + final now = DateTime.now(); + final diff = now.difference(lastSeen); + + if (diff.isNegative || diff.inMinutes < 5) { + return context.l10n.contacts_lastSeenNow; + } + if (diff.inMinutes < 60) { + return context.l10n.contacts_lastSeenMinsAgo(diff.inMinutes); + } + if (diff.inHours < 24) { + final hours = diff.inHours; + return hours == 1 + ? context.l10n.contacts_lastSeenHourAgo + : context.l10n.contacts_lastSeenHoursAgo(hours); + } + final days = diff.inDays; + return days == 1 + ? context.l10n.contacts_lastSeenDayAgo + : context.l10n.contacts_lastSeenDaysAgo(days); + } +} diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index a198f99..fe893f8 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -9,6 +9,7 @@ import '../connector/meshcore_protocol.dart'; import '../l10n/l10n.dart'; import '../models/radio_settings.dart'; import '../widgets/adaptive_app_bar_title.dart'; +import '../widgets/app_bar.dart'; import 'app_settings_screen.dart'; import 'app_debug_log_screen.dart'; import 'ble_debug_log_screen.dart'; @@ -43,8 +44,11 @@ class _SettingsScreenState extends State { final l10n = context.l10n; return Scaffold( appBar: AppBar( - title: AdaptiveAppBarTitle(l10n.settings_title), - centerTitle: true, + title: AppBarTitle( + l10n.settings_title, + indicators: false, + subtitle: false, + ), ), body: SafeArea( top: false, @@ -274,6 +278,14 @@ class _SettingsScreenState extends State { onTap: () => _editLocation(context, connector), ), const Divider(height: 1), + ListTile( + leading: const Icon(Icons.group_add_outlined), + title: Text(l10n.settings_contactSettings), + subtitle: Text(l10n.settings_contactSettingsSubtitle), + trailing: const Icon(Icons.chevron_right), + onTap: () => _editAutoAddConfig(context, connector), + ), + const Divider(height: 1), ListTile( leading: const Icon(Icons.visibility_off_outlined), title: Text(l10n.settings_privacyMode), @@ -849,6 +861,103 @@ class _SettingsScreenState extends State { ), ); } + + void _editAutoAddConfig(BuildContext context, MeshCoreConnector connector) { + final l10n = context.l10n; + bool autoAddChat = false; + bool autoAddRepeater = false; + bool autoAddRoomServer = false; + bool autoAddSensor = false; + bool overwriteOldest = false; + + final connector = context.read(); + autoAddChat = connector.autoAddUsers ?? false; + autoAddRepeater = connector.autoAddRepeaters ?? false; + autoAddRoomServer = connector.autoAddRoomServers ?? false; + autoAddSensor = connector.autoAddSensors ?? false; + overwriteOldest = connector.autoAddOverwriteOldest ?? false; + + showDialog( + context: context, + builder: (dialogContext) => StatefulBuilder( + builder: (context, setDialogState) => AlertDialog( + title: Text(l10n.contactsSettings_autoAddTitle), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FeatureToggleRow( + title: l10n.contactsSettings_autoAddUsersTitle, + subtitle: l10n.contactsSettings_autoAddUsersSubtitle, + value: autoAddChat, + onChanged: (value) { + setDialogState(() => autoAddChat = value); + }, + ), + SizedBox(height: 8), + FeatureToggleRow( + title: l10n.contactsSettings_autoAddRepeatersTitle, + subtitle: l10n.contactsSettings_autoAddRepeatersSubtitle, + value: autoAddRepeater, + onChanged: (value) { + setDialogState(() => autoAddRepeater = value); + }, + ), + SizedBox(height: 8), + FeatureToggleRow( + title: l10n.contactsSettings_autoAddRoomServersTitle, + subtitle: l10n.contactsSettings_autoAddRoomServersSubtitle, + value: autoAddRoomServer, + onChanged: (value) { + setDialogState(() => autoAddRoomServer = value); + }, + ), + SizedBox(height: 8), + FeatureToggleRow( + title: l10n.contactsSettings_autoAddSensorsTitle, + subtitle: l10n.contactsSettings_autoAddSensorsSubtitle, + value: autoAddSensor, + onChanged: (value) { + setDialogState(() => autoAddSensor = value); + }, + ), + Divider(height: 4), + FeatureToggleRow( + title: l10n.contactsSettings_overwriteOldestTitle, + subtitle: l10n.contactsSettings_overwriteOldestSubtitle, + value: overwriteOldest, + onChanged: (value) { + setDialogState(() => overwriteOldest = value); + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(l10n.common_cancel), + ), + TextButton( + onPressed: () async { + final frame = buildSetAutoAddConfigFrame( + autoAddChat: autoAddChat, + autoAddRepeater: autoAddRepeater, + autoAddRoomServer: autoAddRoomServer, + autoAddSensor: autoAddSensor, + overwriteOldest: overwriteOldest, + ); + await connector.sendFrame(frame); + await connector.sendFrame(buildGetAutoAddFlagsFrame()); + Navigator.pop(context); + }, + child: Text(l10n.common_save), + ), + ], + ), + ), + ); + } } class _RadioSettingsDialog extends StatefulWidget { diff --git a/lib/services/ble_debug_log_service.dart b/lib/services/ble_debug_log_service.dart index bc46b59..d923d6b 100644 --- a/lib/services/ble_debug_log_service.dart +++ b/lib/services/ble_debug_log_service.dart @@ -215,8 +215,8 @@ class BleDebugLogService extends ChangeNotifier { return 'RESP_CODE_CHANNEL_MSG_RECV_V3'; case respCodeChannelInfo: return 'RESP_CODE_CHANNEL_INFO'; - case respCodeRadioSettings: - return 'RESP_CODE_RADIO_SETTINGS'; + case respCodeAutoAddConfig: + return 'RESP_CODE_AUTO_ADD_CONFIG'; case pushCodeTraceData: return 'PUSH_CODE_TRACE_DATA'; default: diff --git a/lib/storage/contact_discovery_store.dart b/lib/storage/contact_discovery_store.dart new file mode 100644 index 0000000..84f7807 --- /dev/null +++ b/lib/storage/contact_discovery_store.dart @@ -0,0 +1,59 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import '../models/discovery_contact.dart'; +import 'prefs_manager.dart'; + +class ContactDiscoveryStore { + static const String _key = 'discovered_contacts'; + + Future> loadContacts() async { + final prefs = PrefsManager.instance; + final jsonStr = prefs.getString(_key); + if (jsonStr == null) return []; + + try { + final jsonList = jsonDecode(jsonStr) as List; + return jsonList + .map((entry) => _fromJson(entry as Map)) + .toList(); + } catch (_) { + return []; + } + } + + Future saveContacts(List contacts) async { + final prefs = PrefsManager.instance; + final jsonList = contacts.map(_toJson).toList(); + await prefs.setString(_key, jsonEncode(jsonList)); + } + + Map _toJson(DiscoveryContact contact) { + return { + 'publicKey': base64Encode(contact.publicKey), + 'name': contact.name, + 'type': contact.type, + 'pathLength': contact.pathLength, + 'path': base64Encode(contact.path), + 'latitude': contact.latitude, + 'longitude': contact.longitude, + 'lastSeen': contact.lastSeen.millisecondsSinceEpoch, + }; + } + + DiscoveryContact _fromJson(Map json) { + final lastSeenMs = json['lastSeen'] as int? ?? 0; + return DiscoveryContact( + publicKey: Uint8List.fromList(base64Decode(json['publicKey'] as String)), + name: json['name'] as String? ?? 'Unknown', + type: json['type'] as int? ?? 0, + pathLength: json['pathLength'] as int? ?? -1, + path: json['path'] != null + ? Uint8List.fromList(base64Decode(json['path'] as String)) + : Uint8List(0), + latitude: (json['latitude'] as num?)?.toDouble(), + longitude: (json['longitude'] as num?)?.toDouble(), + lastSeen: DateTime.fromMillisecondsSinceEpoch(lastSeenMs), + ); + } +} diff --git a/lib/widgets/app_bar.dart b/lib/widgets/app_bar.dart index e1cda77..7324481 100644 --- a/lib/widgets/app_bar.dart +++ b/lib/widgets/app_bar.dart @@ -9,7 +9,16 @@ class AppBarTitle extends StatelessWidget { final String title; final Widget? leading; final Widget? trailing; - const AppBarTitle(this.title, {this.leading, this.trailing, super.key}); + final bool indicators; + final bool subtitle; + const AppBarTitle( + this.title, { + this.leading, + this.trailing, + this.indicators = true, + this.subtitle = true, + super.key, + }); @override Widget build(BuildContext context) { @@ -23,10 +32,10 @@ class AppBarTitle extends StatelessWidget { : MediaQuery.sizeOf(context).width; final compact = availableWidth < 240; final showSubtitle = - !compact && connector.isConnected && selfName != null; + !compact && connector.isConnected && selfName != null && subtitle; final showBattery = availableWidth >= 60; final showSnr = availableWidth >= 110; - final showIndicators = showBattery || showSnr; + final showIndicators = (showBattery || showSnr) && indicators; return Row( mainAxisAlignment: MainAxisAlignment.start, diff --git a/lib/widgets/list_filter_widget.dart b/lib/widgets/list_filter_widget.dart index 473a3df..ee6fcd4 100644 --- a/lib/widgets/list_filter_widget.dart +++ b/lib/widgets/list_filter_widget.dart @@ -224,3 +224,93 @@ class ContactsFilterMenu extends StatelessWidget { ); } } + +class DiscoveryContactsFilterMenu extends StatelessWidget { + final ContactSortOption sortOption; + final ContactTypeFilter typeFilter; + final ValueChanged onSortChanged; + final ValueChanged onTypeFilterChanged; + + const DiscoveryContactsFilterMenu({ + super.key, + required this.sortOption, + required this.typeFilter, + required this.onSortChanged, + required this.onTypeFilterChanged, + }); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return SortFilterMenu( + tooltip: l10n.listFilter_tooltip, + sections: [ + SortFilterMenuSection( + title: l10n.listFilter_sortBy, + options: [ + SortFilterMenuOption( + value: _actionSortLastSeen, + label: l10n.listFilter_heardRecently, + checked: sortOption == ContactSortOption.lastSeen, + ), + SortFilterMenuOption( + value: _actionSortName, + label: l10n.listFilter_az, + checked: sortOption == ContactSortOption.name, + ), + ], + ), + SortFilterMenuSection( + title: l10n.listFilter_filters, + options: [ + SortFilterMenuOption( + value: _actionFilterAll, + label: l10n.listFilter_all, + checked: typeFilter == ContactTypeFilter.all, + ), + SortFilterMenuOption( + value: _actionFilterUsers, + label: l10n.listFilter_users, + checked: typeFilter == ContactTypeFilter.users, + ), + SortFilterMenuOption( + value: _actionFilterRepeaters, + label: l10n.listFilter_repeaters, + checked: typeFilter == ContactTypeFilter.repeaters, + ), + SortFilterMenuOption( + value: _actionFilterRooms, + label: l10n.listFilter_roomServers, + checked: typeFilter == ContactTypeFilter.rooms, + ), + ], + ), + ], + onSelected: (action) { + switch (action) { + case _actionSortName: + onSortChanged(ContactSortOption.name); + break; + case _actionSortLastSeen: + onSortChanged(ContactSortOption.lastSeen); + break; + case _actionFilterAll: + onTypeFilterChanged(ContactTypeFilter.all); + break; + case _actionFilterUsers: + onTypeFilterChanged(ContactTypeFilter.users); + break; + case _actionFilterFavorites: + onTypeFilterChanged(ContactTypeFilter.favorites); + break; + case _actionFilterRepeaters: + onTypeFilterChanged(ContactTypeFilter.repeaters); + break; + case _actionFilterRooms: + onTypeFilterChanged(ContactTypeFilter.rooms); + break; + } + }, + ); + } +} From 92d8e7cd0b282f4627c8d7dc8d3974004937cb7f Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sat, 28 Feb 2026 19:14:22 -0800 Subject: [PATCH 02/12] Refactor contact search functionality to use DiscoveryContact model and simplify query matching --- lib/screens/discovery_screen.dart | 29 ++--------------------------- lib/utils/contact_search.dart | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/lib/screens/discovery_screen.dart b/lib/screens/discovery_screen.dart index b8f49fa..10dc016 100644 --- a/lib/screens/discovery_screen.dart +++ b/lib/screens/discovery_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:meshcore_open/models/contact.dart'; @@ -212,17 +213,7 @@ class _DiscoveryScreenState extends State { ) { var filtered = contacts.where((contact) { if (searchQuery.isEmpty) return true; - return matchesContactQuery( - Contact( - publicKey: contact.publicKey, - name: contact.name, - type: contact.type, - pathLength: contact.pathLength, - path: contact.path, - lastSeen: contact.lastSeen, - ), - searchQuery, - ); + return matchesDiscoveryContactQuery(contact, searchQuery); }).toList(); // Filter out own node from the list @@ -237,22 +228,6 @@ class _DiscoveryScreenState extends State { filtered = filtered.where(_matchesTypeFilter).toList(); } - if (showUnreadOnly) { - filtered = filtered.where((contact) { - return connector.getUnreadCountForContact( - Contact( - publicKey: contact.publicKey, - name: contact.name, - type: contact.type, - pathLength: contact.pathLength, - path: contact.path, - lastSeen: contact.lastSeen, - ), - ) > - 0; - }).toList(); - } - switch (sortOption) { case ContactSortOption.lastSeen: filtered.sort( diff --git a/lib/utils/contact_search.dart b/lib/utils/contact_search.dart index 31def4e..6cbd0b2 100644 --- a/lib/utils/contact_search.dart +++ b/lib/utils/contact_search.dart @@ -1,3 +1,5 @@ +import 'package:meshcore_open/models/discovery_contact.dart'; + import '../models/contact.dart'; bool matchesContactQuery(Contact contact, String query) { @@ -14,6 +16,20 @@ bool matchesContactQuery(Contact contact, String query) { return contact.publicKeyHex.toLowerCase().startsWith(hexPrefix); } +bool matchesDiscoveryContactQuery(DiscoveryContact contact, String query) { + final normalizedQuery = query.trim().toLowerCase(); + if (normalizedQuery.isEmpty) return true; + + if (contact.name.toLowerCase().contains(normalizedQuery)) { + return true; + } + + final hexPrefix = _extractHexPrefix(normalizedQuery); + if (hexPrefix == null) return false; + + return contact.publicKeyHex.toLowerCase().startsWith(hexPrefix); +} + String? _extractHexPrefix(String query) { var cleaned = query; if (cleaned.startsWith('0x')) { From 12bf46bba15cf7b9ce06e6a65b4faa67b2d200c9 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 10:13:17 -0800 Subject: [PATCH 03/12] feat(localization): update contact settings translations for multiple languages - Translated contact settings and related strings in Slovenian, Swedish, Ukrainian, Chinese, Dutch, Polish, Portuguese, Russian, and Slovak. - Added new strings for discovered contacts actions such as adding, copying, and deleting contacts. - Enhanced the DiscoveryContact model to include a rawPacket field for better data handling. - Updated the contacts screen to support new actions in the context menu for discovered contacts. - Improved the contact discovery store to handle the serialization of the new rawPacket field. --- lib/connector/meshcore_connector.dart | 97 ++++++++++++++++++++++-- lib/connector/meshcore_protocol.dart | 38 +++++----- lib/l10n/app_bg.arb | 24 +++++- lib/l10n/app_de.arb | 24 +++++- lib/l10n/app_en.arb | 6 +- lib/l10n/app_es.arb | 24 +++++- lib/l10n/app_fr.arb | 24 +++++- lib/l10n/app_it.arb | 24 +++++- lib/l10n/app_localizations.dart | 24 ++++++ lib/l10n/app_localizations_bg.dart | 52 ++++++++----- lib/l10n/app_localizations_de.dart | 54 ++++++++----- lib/l10n/app_localizations_en.dart | 12 +++ lib/l10n/app_localizations_es.dart | 55 +++++++++----- lib/l10n/app_localizations_fr.dart | 54 ++++++++----- lib/l10n/app_localizations_it.dart | 53 ++++++++----- lib/l10n/app_localizations_nl.dart | 52 ++++++++----- lib/l10n/app_localizations_pl.dart | 52 ++++++++----- lib/l10n/app_localizations_pt.dart | 54 ++++++++----- lib/l10n/app_localizations_ru.dart | 54 ++++++++----- lib/l10n/app_localizations_sk.dart | 52 ++++++++----- lib/l10n/app_localizations_sl.dart | 51 ++++++++----- lib/l10n/app_localizations_sv.dart | 52 ++++++++----- lib/l10n/app_localizations_uk.dart | 54 ++++++++----- lib/l10n/app_localizations_zh.dart | 54 +++++++------ lib/l10n/app_nl.arb | 24 +++++- lib/l10n/app_pl.arb | 24 +++++- lib/l10n/app_pt.arb | 24 +++++- lib/l10n/app_ru.arb | 24 +++++- lib/l10n/app_sk.arb | 24 +++++- lib/l10n/app_sl.arb | 24 +++++- lib/l10n/app_sv.arb | 24 +++++- lib/l10n/app_uk.arb | 24 +++++- lib/l10n/app_zh.arb | 24 +++++- lib/models/discovery_contact.dart | 40 +--------- lib/screens/contacts_screen.dart | 3 +- lib/screens/discovery_screen.dart | 71 ++++++++++++++++- lib/storage/contact_discovery_store.dart | 2 + 37 files changed, 1034 insertions(+), 338 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index c142f84..c7ebdaf 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -283,6 +283,7 @@ class MeshCoreConnector extends ChangeNotifier { int? get batteryMillivolts => _batteryMillivolts; int get maxContacts => _maxContacts; int get maxChannels => _maxChannels; + Set get knownContactKeys => Set.unmodifiable(_knownContactKeys); bool get isSyncingQueuedMessages => _isSyncingQueuedMessages; bool get isSyncingChannels => _isSyncingChannels; int get channelSyncProgress => @@ -1534,6 +1535,50 @@ class MeshCoreConnector extends ChangeNotifier { notifyListeners(); } + Future removeDiscoveredContact(DiscoveryContact contact) async { + if (!isConnected) return; + _discoveredContacts.removeWhere( + (c) => c.publicKeyHex == contact.publicKeyHex, + ); + unawaited(_persistDiscoveredContacts()); + notifyListeners(); + } + + Future importDiscoveredContact(DiscoveryContact contact) async { + if (!isConnected) return; + await sendFrame( + buildSetAutoAddConfigFrame( + autoAddChat: true, + autoAddRepeater: true, + autoAddRoomServer: true, + autoAddSensor: true, + overwriteOldest: _overwriteOldest, + ), + ); + await sendFrame(buildImportContactFrame(contact.rawPacket)); + await sendFrame( + buildSetAutoAddConfigFrame( + autoAddChat: _autoAddUsers, + autoAddRepeater: _autoAddRepeaters, + autoAddRoomServer: _autoAddRoomServers, + autoAddSensor: _autoAddSensors, + overwriteOldest: _overwriteOldest, + ), + ); + + _handleContactAdvert( + Contact( + publicKey: contact.publicKey, + name: contact.name, + type: contact.type, + pathLength: contact.pathLength, + path: contact.path, + lastSeen: DateTime.now(), + ), + ); + notifyListeners(); + } + Future clearContactPath(Contact contact) async { if (!isConnected) return; @@ -3705,22 +3750,29 @@ class MeshCoreConnector extends ChangeNotifier { appLogger.warn('Malformed RX frame: $e', tag: 'Connector'); return; } - + final rawPacket = frame.sublist(3); switch (payloadType) { case payloadTypeADVERT: - _handlePayloadAdvertReceived(payload, pathBytes, routeType, snr); + _handlePayloadAdvertReceived( + rawPacket, + payload, + pathBytes, + routeType, + snr, + ); break; default: } } void _handlePayloadAdvertReceived( - Uint8List frame, + Uint8List rawPacket, + Uint8List payload, Uint8List path, int routeType, double snr, ) { - final advert = BufferReader(frame); + final advert = BufferReader(payload); double latitude = 0.0; double longitude = 0.0; String name = ''; @@ -3785,7 +3837,7 @@ class MeshCoreConnector extends ChangeNotifier { (_autoAddSensors && type == advTypeSensor)) { _handleContactAdvert(newContact); } else { - _handleDiscovery(newContact); + _handleDiscovery(newContact, rawPacket); } _updateDirectRepeater(newContact, snr, path); return; @@ -3890,9 +3942,42 @@ class MeshCoreConnector extends ChangeNotifier { } } - void _handleDiscovery(Contact contact) { + void _handleDiscovery(Contact contact, Uint8List rawPacket) { debugPrint('Discovered new contact: ${contact.name}'); + + final existingIndex = _discoveredContacts.indexWhere( + (c) => c.publicKeyHex == contact.publicKeyHex, + ); + final existingContactsIndex = _contacts.indexWhere( + (c) => c.publicKeyHex == contact.publicKeyHex, + ); + + if (existingContactsIndex >= 0) { + if (existingIndex >= 0) { + removeDiscoveredContact(_discoveredContacts[existingIndex]); + unawaited(_persistDiscoveredContacts()); + } + return; + } + + // Update existing contact + if (existingIndex >= 0) { + _discoveredContacts[existingIndex] = _discoveredContacts[existingIndex] + .copyWith( + rawPacket: rawPacket, + name: contact.name, + type: contact.type, + pathLength: contact.pathLength, + path: contact.path, + latitude: contact.latitude, + longitude: contact.longitude, + lastSeen: contact.lastSeen, + ); + return; + } + final disContact = DiscoveryContact( + rawPacket: rawPacket, publicKey: contact.publicKey, name: contact.name, type: contact.type, diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index 36c13e2..4f50ec3 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -114,25 +114,27 @@ class BufferWriter { } void writeHex(String hex) { - // Validate hex string length is even and not empty - if (hex.isEmpty || hex.length % 2 != 0) { - throw FormatException('Invalid hex string length: ${hex.length}'); - } - List result = []; - for (int i = 0; i < hex.length ~/ 2; i++) { - final hexByte = hex.substring(i * 2, i * 2 + 2); - final byte = int.tryParse(hexByte, radix: 16); - if (byte == null) { - throw FormatException( - 'Invalid hex characters at position $i: $hexByte', - ); - } - result.add(byte); - } - writeBytes(Uint8List.fromList(result)); + writeBytes(hex2Uint8List(hex)); } } +Uint8List hex2Uint8List(String hex) { + // Validate hex string length is even and not empty + if (hex.isEmpty || hex.length % 2 != 0) { + throw FormatException('Invalid hex string length: ${hex.length}'); + } + List result = []; + for (int i = 0; i < hex.length ~/ 2; i++) { + final hexByte = hex.substring(i * 2, i * 2 + 2); + final byte = int.tryParse(hexByte, radix: 16); + if (byte == null) { + throw FormatException('Invalid hex characters at position $i: $hexByte'); + } + result.add(byte); + } + return Uint8List.fromList(result); +} + // Command codes (to device) const int cmdAppStart = 1; const int cmdSendTxtMsg = 2; @@ -827,10 +829,10 @@ Uint8List buildExportContactFrame(Uint8List pubKey) { // Build a import contact frame // [cmd][contact_frame x98+] -Uint8List buildImportContactFrame(String contactFrame) { +Uint8List buildImportContactFrame(Uint8List contactFrame) { final writer = BufferWriter(); writer.writeByte(cmdImportContact); - writer.writeHex(contactFrame); + writer.writeBytes(contactFrame); return writer.toBytes(); } diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index 975e067..eed1897 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1799,5 +1799,27 @@ "contacts_unread": "Непрочетено", "contacts_searchRepeaters": "Търсене на {number}{str} повтарящи се...", "contacts_searchContactsNoNumber": "Търси контакти...", - "contacts_searchUsers": "Търсене на {number}{str} потребители..." + "contacts_searchUsers": "Търсене на {number}{str} потребители...", + "contactsSettings_title": "Настройки на контактите", + "contactsSettings_autoAddTitle": "Автоматично откриване", + "contactsSettings_autoAddUsersTitle": "Автоматично добавяне на потребители", + "contactsSettings_otherTitle": "Други настройки свързани с контакти", + "settings_contactSettingsSubtitle": "Настройки за добавяне на контакти.", + "settings_contactSettings": "Настройки за контакти", + "contactsSettings_autoAddSensorsTitle": "Автоматично добавяне на датчици", + "contactsSettings_autoAddRoomServersTitle": "Автоматично добавяне на сървъри на стаите", + "contactsSettings_autoAddRoomServersSubtitle": "Позволи на спътника да добавя автоматично откритите сървъри на стаите.", + "contactsSettings_autoAddRepeatersTitle": "Автоматично добавяне на повтарящи се елементи", + "contactsSettings_autoAddUsersSubtitle": "Позволи на спътника да добавя автоматично откритите потребители.", + "contactsSettings_autoAddRepeatersSubtitle": "Позволи на спътника да добавя автоматично откритите повтарящи се устройства.", + "contactsSettings_autoAddSensorsSubtitle": "Позволи на спътника да добавя автоматично откритите датчици.", + "contactsSettings_overwriteOldestTitle": "Премахни най-старото", + "discoveredContacts_Title": "Открити контакти", + "discoveredContacts_searchHint": "Търсене на открити контакти", + "discoveredContacts_noMatching": "Няма съвпадащи контакти", + "contactsSettings_overwriteOldestSubtitle": "Когато е активиран, компаньонът ще презапише най-стария контакт, който не е отбелязан като любим, когато списъкът с контакти е пълен.", + "discoveredContacts_contactAdded": "Контакт добавен", + "discoveredContacts_copyContact": "Копирай контакт в клипборда", + "discoveredContacts_deleteContact": "Изтрий контакт", + "discoveredContacts_addContact": "Добави контакт" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 74b6c05..4fe662f 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1827,5 +1827,27 @@ "contacts_searchRepeaters": "Suche {number}{str} Repeater...", "contacts_searchFavorites": "Suche {number}{str} Favoriten...", "contacts_searchUsers": "Suche {number}{str} Benutzer...", - "contacts_searchRoomServers": "Suche {number}{str} Raumserver..." + "contacts_searchRoomServers": "Suche {number}{str} Raumserver...", + "settings_contactSettings": "Kontakteinstellungen", + "contactsSettings_otherTitle": "Weitere Einstellungen zu Kontakten", + "contactsSettings_title": "Kontakteinstellungen", + "contactsSettings_autoAddTitle": "Automatische Erkennung", + "contactsSettings_autoAddUsersTitle": "Automatische Hinzufügung von Benutzern", + "settings_contactSettingsSubtitle": "Einstellungen für das Hinzufügen von Kontakten", + "contactsSettings_autoAddSensorsTitle": "Automatisch Sensoren hinzufügen", + "contactsSettings_autoAddUsersSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Benutzer hinzuzufügen", + "contactsSettings_autoAddRoomServersTitle": "Automatisch Raumservers hinzufügen", + "contactsSettings_autoAddRoomServersSubtitle": "Ermöglichen Sie dem Begleiter, entdeckte Raumserver automatisch hinzuzufügen", + "contactsSettings_autoAddRepeatersTitle": "Automatisch Repeater hinzufügen", + "contactsSettings_autoAddRepeatersSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Repeater hinzuzufügen.", + "discoveredContacts_noMatching": "Keine passenden Kontakte", + "discoveredContacts_searchHint": "Entdeckte Kontakte suchen", + "discoveredContacts_addContact": "Kontakt hinzufügen", + "discoveredContacts_contactAdded": "Kontakt hinzugefügt", + "discoveredContacts_deleteContact": "Kontakt löschen", + "discoveredContacts_Title": "Entdeckte Kontakte", + "discoveredContacts_copyContact": "Kontakt in die Zwischenablage kopieren", + "contactsSettings_overwriteOldestTitle": "Überschreiben des Ältesten", + "contactsSettings_overwriteOldestSubtitle": "Wenn aktiviert, überschreibt der Begleiter den ältesten nicht favorisierten Kontakt, wenn die Kontaktliste voll ist.", + "contactsSettings_autoAddSensorsSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Sensoren hinzuzufügen" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 3f92d0e..8d5e528 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1855,5 +1855,9 @@ "contactsSettings_overwriteOldestSubtitle": "When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.", "discoveredContacts_Title": "Discovered Contacts", "discoveredContacts_noMatching": "No matching contacts", - "discoveredContacts_searchHint": "Search discovered contacts" + "discoveredContacts_searchHint": "Search discovered contacts", + "discoveredContacts_contactAdded": "Contact added", + "discoveredContacts_addContact": "Add Contact", + "discoveredContacts_copyContact": "Copy Contact to clipboard", + "discoveredContacts_deleteContact": "Delete Contact" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 74339ff..5a2e1c8 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1827,5 +1827,27 @@ "contacts_searchFavorites": "Buscar {number}{str} Favoritos...", "contacts_searchUsers": "Buscar {number}{str} Usuarios...", "contacts_searchRepeaters": "Buscar {number}{str} Repetidores...", - "contacts_searchRoomServers": "Buscar {number}{str} servidores de sala..." + "contacts_searchRoomServers": "Buscar {number}{str} servidores de sala...", + "contactsSettings_autoAddTitle": "Detección automática", + "settings_contactSettings": "Configuración de contacto", + "contactsSettings_autoAddUsersTitle": "Agregar usuarios automáticamente", + "contactsSettings_otherTitle": "Otras configuraciones relacionadas con el contacto", + "contactsSettings_autoAddUsersSubtitle": "Permitir que el compañero agregue automáticamente a los usuarios descubiertos.", + "contactsSettings_autoAddRepeatersSubtitle": "Permitir que el compañero agregue automáticamente los repetidores descubiertos.", + "contactsSettings_autoAddRoomServersSubtitle": "Permitir que el compañero agregue automáticamente los servidores de salas descubiertos.", + "contactsSettings_autoAddSensorsTitle": "Agregar sensores automáticamente", + "contactsSettings_title": "Configuración de contactos", + "settings_contactSettingsSubtitle": "Configuración de cómo se agregan los contactos.", + "contactsSettings_autoAddSensorsSubtitle": "Permitir que el compañero agregue automáticamente los sensores descubiertos.", + "contactsSettings_autoAddRepeatersTitle": "Agregar repetidores automáticamente", + "contactsSettings_overwriteOldestTitle": "Sobreescribir el más antiguo", + "contactsSettings_autoAddRoomServersTitle": "Agregar automáticamente servidores de sala", + "discoveredContacts_noMatching": "No se encontraron contactos coincidentes", + "discoveredContacts_contactAdded": "Contacto agregado", + "discoveredContacts_copyContact": "Copiar contacto al portapapeles", + "discoveredContacts_deleteContact": "Eliminar contacto", + "discoveredContacts_Title": "Contactos descubiertos", + "contactsSettings_overwriteOldestSubtitle": "Cuando se habilita, el compañero sobrescribirá el contacto más antiguo no favorito cuando la lista de contactos esté llena.", + "discoveredContacts_searchHint": "Buscar contactos descubiertos", + "discoveredContacts_addContact": "Agregar contacto" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 0697aee..e222f53 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1799,5 +1799,27 @@ "contacts_searchUsers": "Rechercher {number}{str} utilisateurs...", "contacts_searchRoomServers": "Rechercher {number}{str} serveurs de salle...", "contacts_searchRepeaters": "Rechercher {number}{str} Répéteurs...", - "contacts_searchContactsNoNumber": "Rechercher des contacts..." + "contacts_searchContactsNoNumber": "Rechercher des contacts...", + "settings_contactSettings": "Paramètres de contact", + "settings_contactSettingsSubtitle": "Paramètres pour l'ajout de contacts", + "contactsSettings_autoAddRepeatersTitle": "Ajouter automatiquement les répéteurs", + "contactsSettings_autoAddRepeatersSubtitle": "Autoriser le compagnon à ajouter automatiquement les répéteurs découverts", + "contactsSettings_autoAddRoomServersTitle": "Ajouter automatiquement les serveurs de salle", + "contactsSettings_autoAddRoomServersSubtitle": "Autoriser le compagnon à ajouter automatiquement les serveurs de salles découverts", + "contactsSettings_otherTitle": "Autres paramètres liés aux contacts", + "contactsSettings_title": "Paramètres des contacts", + "contactsSettings_autoAddUsersTitle": "Ajouter automatiquement les utilisateurs", + "contactsSettings_autoAddTitle": "Découverte automatique", + "contactsSettings_autoAddSensorsTitle": "Ajouter automatiquement les capteurs", + "contactsSettings_autoAddUsersSubtitle": "Autoriser le compagnon à ajouter automatiquement les utilisateurs découverts", + "discoveredContacts_noMatching": "Aucun contact correspondant", + "discoveredContacts_contactAdded": "Contact ajouté", + "discoveredContacts_addContact": "Ajouter un contact", + "discoveredContacts_copyContact": "Copier le contact dans le presse-papiers", + "discoveredContacts_deleteContact": "Supprimer le contact", + "contactsSettings_overwriteOldestTitle": "Écraser le plus ancien", + "contactsSettings_autoAddSensorsSubtitle": "Autoriser le compagnon à ajouter automatiquement les capteurs découverts.", + "contactsSettings_overwriteOldestSubtitle": "Lorsqu'il est activé, le compagnon écrasera l'ancien contact non favori lorsque la liste de contacts est pleine.", + "discoveredContacts_Title": "Contacts découverts", + "discoveredContacts_searchHint": "Rechercher des contacts découverts" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 4798d26..53c3737 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1799,5 +1799,27 @@ "contacts_searchFavorites": "Cerca {number}{str} Preferiti...", "contacts_unread": "Non letti", "contacts_searchRepeaters": "Cerca {number}{str} Ripetitori...", - "contacts_searchRoomServers": "Cerca {number}{str} server Room..." + "contacts_searchRoomServers": "Cerca {number}{str} server Room...", + "contactsSettings_title": "Impostazioni dei contatti", + "settings_contactSettings": "Impostazioni di contatto", + "contactsSettings_otherTitle": "Altre impostazioni relative ai contatti", + "contactsSettings_autoAddUsersSubtitle": "Consenti al compagno di aggiungere automaticamente gli utenti scoperti.", + "contactsSettings_autoAddRepeatersTitle": "Aggiungere ripetitori automaticamente", + "contactsSettings_autoAddRoomServersSubtitle": "Consenti al compagno di aggiungere automaticamente i server delle stanze scoperte.", + "contactsSettings_autoAddSensorsTitle": "Aggiungere automaticamente i sensori", + "settings_contactSettingsSubtitle": "Impostazioni per l'aggiunta dei contatti", + "contactsSettings_autoAddUsersTitle": "Aggiungere utenti automaticamente", + "contactsSettings_autoAddTitle": "Scoperta automatica", + "contactsSettings_autoAddSensorsSubtitle": "Consenti al compagno di aggiungere automaticamente i sensori scoperti", + "discoveredContacts_noMatching": "Nessun contatto corrispondente", + "contactsSettings_autoAddRepeatersSubtitle": "Consenti al compagno di aggiungere automaticamente i ripetitori scoperti.", + "discoveredContacts_searchHint": "Cerca contatti scoperti", + "contactsSettings_autoAddRoomServersTitle": "Aggiungere automaticamente i server delle stanze", + "discoveredContacts_addContact": "Aggiungi contatto", + "contactsSettings_overwriteOldestTitle": "Sostituisci il più vecchio", + "contactsSettings_overwriteOldestSubtitle": "Quando abilitato, il companion sovrascriverà il contatto più vecchio non preferito quando l'elenco dei contatti è pieno.", + "discoveredContacts_Title": "Contatti scoperti", + "discoveredContacts_contactAdded": "Contatto aggiunto", + "discoveredContacts_deleteContact": "Elimina Contatto", + "discoveredContacts_copyContact": "Copia contatto negli appunti" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 333147f..a7c458f 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -5488,6 +5488,30 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Search discovered contacts'** String get discoveredContacts_searchHint; + + /// No description provided for @discoveredContacts_contactAdded. + /// + /// In en, this message translates to: + /// **'Contact added'** + String get discoveredContacts_contactAdded; + + /// No description provided for @discoveredContacts_addContact. + /// + /// In en, this message translates to: + /// **'Add Contact'** + String get discoveredContacts_addContact; + + /// No description provided for @discoveredContacts_copyContact. + /// + /// In en, this message translates to: + /// **'Copy Contact to clipboard'** + String get discoveredContacts_copyContact; + + /// No description provided for @discoveredContacts_deleteContact. + /// + /// In en, this message translates to: + /// **'Delete Contact'** + String get discoveredContacts_deleteContact; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index c26b5b2..f9a858f 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -235,11 +235,11 @@ class AppLocalizationsBg extends AppLocalizations { String get settings_longitude => 'Дължина'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Настройки за контакти'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Настройки за добавяне на контакти.'; @override String get settings_privacyMode => 'Режим на поверителност'; @@ -3121,56 +3121,72 @@ class AppLocalizationsBg extends AppLocalizations { String get snrIndicator_lastSeen => 'Последно видян'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Настройки на контактите'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Автоматично откриване'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Други настройки свързани с контакти'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Автоматично добавяне на потребители'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Позволи на спътника да добавя автоматично откритите потребители.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Автоматично добавяне на повтарящи се елементи'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Позволи на спътника да добавя автоматично откритите повтарящи се устройства.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Автоматично добавяне на сървъри на стаите'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Позволи на спътника да добавя автоматично откритите сървъри на стаите.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Автоматично добавяне на датчици'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Позволи на спътника да добавя автоматично откритите датчици.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Премахни най-старото'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Когато е активиран, компаньонът ще презапише най-стария контакт, който не е отбелязан като любим, когато списъкът с контакти е пълен.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Открити контакти'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Няма съвпадащи контакти'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Търсене на открити контакти'; + + @override + String get discoveredContacts_contactAdded => 'Контакт добавен'; + + @override + String get discoveredContacts_addContact => 'Добави контакт'; + + @override + String get discoveredContacts_copyContact => 'Копирай контакт в клипборда'; + + @override + String get discoveredContacts_deleteContact => 'Изтрий контакт'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 6d36471..77b2a4b 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -234,11 +234,11 @@ class AppLocalizationsDe extends AppLocalizations { String get settings_longitude => 'Längengrad'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Kontakteinstellungen'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Einstellungen für das Hinzufügen von Kontakten'; @override String get settings_privacyMode => 'Privatsphäreeinstellung'; @@ -3130,56 +3130,74 @@ class AppLocalizationsDe extends AppLocalizations { String get snrIndicator_lastSeen => 'Zuletzt gesehen'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Kontakteinstellungen'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Automatische Erkennung'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Weitere Einstellungen zu Kontakten'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Automatische Hinzufügung von Benutzern'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Ermöglichen Sie dem Begleiter, automatisch entdeckte Benutzer hinzuzufügen'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Automatisch Repeater hinzufügen'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Ermöglichen Sie dem Begleiter, automatisch entdeckte Repeater hinzuzufügen.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Automatisch Raumservers hinzufügen'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Ermöglichen Sie dem Begleiter, entdeckte Raumserver automatisch hinzuzufügen'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Automatisch Sensoren hinzufügen'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Ermöglichen Sie dem Begleiter, automatisch entdeckte Sensoren hinzuzufügen'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => + 'Überschreiben des Ältesten'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Wenn aktiviert, überschreibt der Begleiter den ältesten nicht favorisierten Kontakt, wenn die Kontaktliste voll ist.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Entdeckte Kontakte'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Keine passenden Kontakte'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Entdeckte Kontakte suchen'; + + @override + String get discoveredContacts_contactAdded => 'Kontakt hinzugefügt'; + + @override + String get discoveredContacts_addContact => 'Kontakt hinzufügen'; + + @override + String get discoveredContacts_copyContact => + 'Kontakt in die Zwischenablage kopieren'; + + @override + String get discoveredContacts_deleteContact => 'Kontakt löschen'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index c40b7df..08132ac 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -3126,4 +3126,16 @@ class AppLocalizationsEn extends AppLocalizations { @override String get discoveredContacts_searchHint => 'Search discovered contacts'; + + @override + String get discoveredContacts_contactAdded => 'Contact added'; + + @override + String get discoveredContacts_addContact => 'Add Contact'; + + @override + String get discoveredContacts_copyContact => 'Copy Contact to clipboard'; + + @override + String get discoveredContacts_deleteContact => 'Delete Contact'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 203916b..0d2167f 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -234,11 +234,11 @@ class AppLocalizationsEs extends AppLocalizations { String get settings_longitude => 'Longitud'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Configuración de contacto'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Configuración de cómo se agregan los contactos.'; @override String get settings_privacyMode => 'Modo Privacidad'; @@ -3122,56 +3122,75 @@ class AppLocalizationsEs extends AppLocalizations { String get snrIndicator_lastSeen => 'Visto por última vez'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Configuración de contactos'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Detección automática'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Otras configuraciones relacionadas con el contacto'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Agregar usuarios automáticamente'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Permitir que el compañero agregue automáticamente a los usuarios descubiertos.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Agregar repetidores automáticamente'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Permitir que el compañero agregue automáticamente los repetidores descubiertos.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Agregar automáticamente servidores de sala'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Permitir que el compañero agregue automáticamente los servidores de salas descubiertos.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Agregar sensores automáticamente'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Permitir que el compañero agregue automáticamente los sensores descubiertos.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => + 'Sobreescribir el más antiguo'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Cuando se habilita, el compañero sobrescribirá el contacto más antiguo no favorito cuando la lista de contactos esté llena.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Contactos descubiertos'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => + 'No se encontraron contactos coincidentes'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Buscar contactos descubiertos'; + + @override + String get discoveredContacts_contactAdded => 'Contacto agregado'; + + @override + String get discoveredContacts_addContact => 'Agregar contacto'; + + @override + String get discoveredContacts_copyContact => + 'Copiar contacto al portapapeles'; + + @override + String get discoveredContacts_deleteContact => 'Eliminar contacto'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 7ae1b25..29f3af8 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -235,11 +235,11 @@ class AppLocalizationsFr extends AppLocalizations { String get settings_longitude => 'Longitude'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Paramètres de contact'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Paramètres pour l\'ajout de contacts'; @override String get settings_privacyMode => 'Mode de confidentialité'; @@ -3144,56 +3144,74 @@ class AppLocalizationsFr extends AppLocalizations { String get snrIndicator_lastSeen => 'Dernière fois vu'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Paramètres des contacts'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Découverte automatique'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Autres paramètres liés aux contacts'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Ajouter automatiquement les utilisateurs'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Autoriser le compagnon à ajouter automatiquement les utilisateurs découverts'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Ajouter automatiquement les répéteurs'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Autoriser le compagnon à ajouter automatiquement les répéteurs découverts'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Ajouter automatiquement les serveurs de salle'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Autoriser le compagnon à ajouter automatiquement les serveurs de salles découverts'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Ajouter automatiquement les capteurs'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Autoriser le compagnon à ajouter automatiquement les capteurs découverts.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Écraser le plus ancien'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Lorsqu\'il est activé, le compagnon écrasera l\'ancien contact non favori lorsque la liste de contacts est pleine.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Contacts découverts'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Aucun contact correspondant'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => + 'Rechercher des contacts découverts'; + + @override + String get discoveredContacts_contactAdded => 'Contact ajouté'; + + @override + String get discoveredContacts_addContact => 'Ajouter un contact'; + + @override + String get discoveredContacts_copyContact => + 'Copier le contact dans le presse-papiers'; + + @override + String get discoveredContacts_deleteContact => 'Supprimer le contact'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index be88ecb..1fb4eb1 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -234,11 +234,11 @@ class AppLocalizationsIt extends AppLocalizations { String get settings_longitude => 'Longitudine'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Impostazioni di contatto'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Impostazioni per l\'aggiunta dei contatti'; @override String get settings_privacyMode => 'Modalità Privacy'; @@ -3125,56 +3125,73 @@ class AppLocalizationsIt extends AppLocalizations { String get snrIndicator_lastSeen => 'Ultimo accesso'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Impostazioni dei contatti'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Scoperta automatica'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Altre impostazioni relative ai contatti'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Aggiungere utenti automaticamente'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Consenti al compagno di aggiungere automaticamente gli utenti scoperti.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Aggiungere ripetitori automaticamente'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Consenti al compagno di aggiungere automaticamente i ripetitori scoperti.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Aggiungere automaticamente i server delle stanze'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Consenti al compagno di aggiungere automaticamente i server delle stanze scoperte.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Aggiungere automaticamente i sensori'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Consenti al compagno di aggiungere automaticamente i sensori scoperti'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => + 'Sostituisci il più vecchio'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Quando abilitato, il companion sovrascriverà il contatto più vecchio non preferito quando l\'elenco dei contatti è pieno.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Contatti scoperti'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Nessun contatto corrispondente'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Cerca contatti scoperti'; + + @override + String get discoveredContacts_contactAdded => 'Contatto aggiunto'; + + @override + String get discoveredContacts_addContact => 'Aggiungi contatto'; + + @override + String get discoveredContacts_copyContact => 'Copia contatto negli appunti'; + + @override + String get discoveredContacts_deleteContact => 'Elimina Contatto'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index ad1f624..6ed3a84 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -234,11 +234,11 @@ class AppLocalizationsNl extends AppLocalizations { String get settings_longitude => 'Lengtegraad'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Contactinstellingen'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Instellingen voor het toevoegen van contacten'; @override String get settings_privacyMode => 'Privacy Mode'; @@ -3112,56 +3112,72 @@ class AppLocalizationsNl extends AppLocalizations { String get snrIndicator_lastSeen => 'Laatst gezien'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Instellingen voor contacten'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Automatische detectie'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Andere instellingen voor contactgerelateerde zaken'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Gebruikers automatisch toevoegen'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Sta toe dat de companion automatisch ontdekte gebruikers toevoegt'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Automatisch herhalingstoestellen toevoegen'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Sta toe dat de companion automatisch ontdekte repeaters toevoegt'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Automatisch kamerservers toevoegen'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Sta toe dat de companion automatisch ontdekte kamer servers toevoegt.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Automatisch sensoren toevoegen'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Sta toe dat de companion automatisch ontdekte sensoren toevoegt'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Overschrijf Oudste'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Wanneer ingeschakeld, overschrijft de companion het oudste contact dat niet is gemarkeerd als favoriet wanneer de contactenlijst vol is.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Ontdekte contacten'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Geen overeenkomende contacten'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Ontdekte contacten zoeken'; + + @override + String get discoveredContacts_contactAdded => 'Contact toegevoegd'; + + @override + String get discoveredContacts_addContact => 'Contact toevoegen'; + + @override + String get discoveredContacts_copyContact => 'Kopieer contact naar klembord'; + + @override + String get discoveredContacts_deleteContact => 'Contact verwijderen'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index a97599c..703e281 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -236,11 +236,11 @@ class AppLocalizationsPl extends AppLocalizations { String get settings_longitude => 'Długość'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Ustawienia kontaktowe'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Ustawienia dotyczące sposobu dodawania kontaktów'; @override String get settings_privacyMode => 'Tryb Prywatny'; @@ -3125,56 +3125,72 @@ class AppLocalizationsPl extends AppLocalizations { String get snrIndicator_lastSeen => 'Ostatnio widziany'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Ustawienia kontaktów'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Automatyczne odnajdywanie'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Inne ustawienia związane z kontaktami'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Automatycznie dodaj użytkowników'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Pozwól towarzyszowi automatycznie dodawać znalezione użytkowników.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Automatyczne dodawanie powtarzalników'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Zezwól na automatyczne dodawanie odkrytych repeaterów przez towarzysza.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Automatycznie dodaj serwery pokojowe'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Zezwól towarzyszowi na automatyczne dodawanie znalezionych serwerów pokojowych.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Automatycznie dodaj czujniki'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Zezwól towarzyszowi na automatyczne dodawanie wykrytych czujników.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Nadpisz najstarszy'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Gdy jest włączone, companion zastępuje najstarszy kontakt nie ulubiony, gdy lista kontaktów jest pełna.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Odkryte Kontakty'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Brak pasujących kontaktów'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Wyszukaj odkryte kontakty'; + + @override + String get discoveredContacts_contactAdded => 'Kontakt dodany'; + + @override + String get discoveredContacts_addContact => 'Dodaj kontakt'; + + @override + String get discoveredContacts_copyContact => 'Kopiuj kontakt do schowka'; + + @override + String get discoveredContacts_deleteContact => 'Usuń kontakt'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index e1f89e2..442b41e 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -235,11 +235,11 @@ class AppLocalizationsPt extends AppLocalizations { String get settings_longitude => 'Longitude'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Configurações de Contato'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Configurações para como os contatos são adicionados'; @override String get settings_privacyMode => 'Modo de Privacidade'; @@ -3120,56 +3120,74 @@ class AppLocalizationsPt extends AppLocalizations { String get snrIndicator_lastSeen => 'Visto pela última vez'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Configurações de contatos'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Descoberta Automática'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Outras configurações relacionadas a contatos'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Adicionar usuários automaticamente'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Permitir que o companheiro adicione automaticamente os usuários descobertos.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Adicionar repetidores automaticamente'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Permitir que o companheiro adicione automaticamente os repetidores descobertos.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Adicionar automaticamente servidores de sala'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Permitir que o companheiro adicione automaticamente os servidores de salas descobertos.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Adicionar sensores automaticamente'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Permitir que o companheiro adicione automaticamente sensores descobertos.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => + 'Sobrescrever o Mais Antigo'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Quando ativado, o acompanhante substituirá o contato mais antigo não favoritado quando a lista de contatos estiver cheia.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Contatos Descobertos'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Nenhum contato correspondente'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Pesquisar contatos descobertos'; + + @override + String get discoveredContacts_contactAdded => 'Contato adicionado'; + + @override + String get discoveredContacts_addContact => 'Adicionar Contato'; + + @override + String get discoveredContacts_copyContact => + 'Copiar Contato para a área de transferência'; + + @override + String get discoveredContacts_deleteContact => 'Excluir Contato'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index b2f3718..90f8ed6 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -233,11 +233,11 @@ class AppLocalizationsRu extends AppLocalizations { String get settings_longitude => 'Долгота'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Настройки контактов'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Настройки добавления контактов'; @override String get settings_privacyMode => 'Режим конфиденциальности'; @@ -3132,56 +3132,74 @@ class AppLocalizationsRu extends AppLocalizations { String get snrIndicator_lastSeen => 'Последний раз видели'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Настройки контактов'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Автоматическое обнаружение'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Другие настройки, связанные с контактами'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Автоматически добавлять пользователей'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Разрешить компаньону автоматически добавлять обнаруженных пользователей'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Автоматически добавлять ретрансляторы'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Разрешить спутнику автоматически добавлять обнаруженные ретрансляторы'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Автоматически добавлять серверы комнат'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Разрешить компаньону автоматически добавлять обнаруженные сервера комнат.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Автоматически добавлять датчики'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Разрешить компаньону автоматически добавлять обнаруженные датчики'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => + 'Перезаписать самое старое'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'При включении компаньон будет перезаписывать самый старый контакт, не отмеченный как любимый, когда список контактов полон.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Обнаруженные контакты'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Нет совпадающих контактов'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Найденные контакты поиска'; + + @override + String get discoveredContacts_contactAdded => 'Контакт добавлен'; + + @override + String get discoveredContacts_addContact => 'Добавить контакт'; + + @override + String get discoveredContacts_copyContact => + 'Копировать контакт в буфер обмена'; + + @override + String get discoveredContacts_deleteContact => 'Удалить контакт'; } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index 773b338..944bc6c 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -234,11 +234,11 @@ class AppLocalizationsSk extends AppLocalizations { String get settings_longitude => 'Dĺžka'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Nastavenia kontaktov'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Nastavenia pre pridávanie kontaktov.'; @override String get settings_privacyMode => 'Režim ochrany súkromia'; @@ -3107,56 +3107,72 @@ class AppLocalizationsSk extends AppLocalizations { String get snrIndicator_lastSeen => 'Naposledy videný'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Nastavenia kontaktov'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Automatické zisťovanie'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Ďalšie nastavenia súvisiace s kontaktami'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Automaticky pridávať užívateľov'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Povoliť spoločníkovi automaticky pridávať objavených užívateľov.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Automaticky pridávať opakovače'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Povoliť spoločníkovi automaticky pridávať objavené repeater.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Automaticky pridávať server miestnosti'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Povoliť spoločníkovi automaticky pridať objavené serverové miestnosti.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Automaticky pridávať senzory'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Povoliť spoločníkovi automaticky pridávať objavené senzory.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Prepísať najstaršie'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Keď je povolené, spoločník prepíše najstarší kontakt, ktorý nie je označený ako obľúbený, keď je zoznam kontaktov plný.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Objavené kontakty'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Žiadne zhodné kontakty'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Vyhľadať objavené kontakty'; + + @override + String get discoveredContacts_contactAdded => 'Kontakt bol pridaný'; + + @override + String get discoveredContacts_addContact => 'Pridať kontakt'; + + @override + String get discoveredContacts_copyContact => 'Kopírovať kontakt do schránky'; + + @override + String get discoveredContacts_deleteContact => 'Zmazať kontakt'; } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 0f38b94..0fd67ce 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -234,11 +234,11 @@ class AppLocalizationsSl extends AppLocalizations { String get settings_longitude => 'Dolžina'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Nastavitve stika'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Nastavitve za dodajanje stikov.'; @override String get settings_privacyMode => 'Zasebnost'; @@ -3112,56 +3112,71 @@ class AppLocalizationsSl extends AppLocalizations { String get snrIndicator_lastSeen => 'Zadnjič videno'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Nastavitve stikov'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Avtomatsko odkrivanje'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => 'Druge nastavitve v zvezi s stiki'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Avtomatsko dodaj uporabnike'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Dovoli spremljevalcu, da samodejno doda odkrite uporabnike.'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Avtomatsko dodaj ponovitelje'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Dovoli spremljevalcu, da samodejno doda odkrite ponovitelje.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Avtomatsko dodaj strežnike sob'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Dovoli spremljevalcu, da samodejno doda odkrite strežnike sob.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Avtomatsko dodaj senzorje'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Dovoli spremljevalcu, da samodejno doda odkrite senzorje.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Prepiši najstarejše'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Ko je omogočen, bo spremljevalec prepisal najstarejši stik, ki ni označen kot najljubši, ko je seznam stikov poln.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Odkriti stiki'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Ni ujemajočih stikov'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Najdeni stiki po iskanju'; + + @override + String get discoveredContacts_contactAdded => 'Kontakt dodan'; + + @override + String get discoveredContacts_addContact => 'Dodaj stik'; + + @override + String get discoveredContacts_copyContact => 'Kopiraj stik v odložišče'; + + @override + String get discoveredContacts_deleteContact => 'Izbriši stik'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 4e67267..86ba9fd 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -233,11 +233,11 @@ class AppLocalizationsSv extends AppLocalizations { String get settings_longitude => 'Längdgrad'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Kontaktinställningar'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Inställningar för hur kontakter läggs till.'; @override String get settings_privacyMode => 'Privatläge'; @@ -3090,56 +3090,72 @@ class AppLocalizationsSv extends AppLocalizations { String get snrIndicator_lastSeen => 'Senast sedd'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Kontaktinställningar'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Automatisk upptäckt'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Andra inställningar relaterade till kontakt'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Lägg till användare automatiskt'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Tillåt kompanjonen att automatiskt lägga till upptäckta användare'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Lägg till upprepande enheter automatiskt'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Tillåt kompanjonen att automatiskt lägga till upptäckta repeater.'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Lägg automatiskt till rumsservrar'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Tillåt kompanjonen att automatiskt lägga till upptäckta rumsservrar.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Lägg till sensorer automatiskt'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Tillåt kompanjonen att automatiskt lägga till upptäckta sensorer.'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Skriv över äldst'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'När den är aktiverad kommer medhjälparen att skriva över den äldsta kontakten som inte är favoritmarkerad när kontaktnamnslistan är full'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Upptäckta kontakter'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => 'Inga matchande kontakter'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Sök uppfunna kontakter'; + + @override + String get discoveredContacts_contactAdded => 'Kontakt tillagd'; + + @override + String get discoveredContacts_addContact => 'Lägg till kontakt'; + + @override + String get discoveredContacts_copyContact => 'Kopiera kontakt till urklipp'; + + @override + String get discoveredContacts_deleteContact => 'Ta bort kontakt'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 40a52ca..abeb6c6 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -233,11 +233,11 @@ class AppLocalizationsUk extends AppLocalizations { String get settings_longitude => 'Довгота'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => 'Налаштування контактів'; @override String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + 'Налаштування для додавання контактів'; @override String get settings_privacyMode => 'Режим приватності'; @@ -3139,56 +3139,74 @@ class AppLocalizationsUk extends AppLocalizations { String get snrIndicator_lastSeen => 'Останній раз бачили'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => 'Налаштування контактів'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => 'Автоматичне виявлення'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => + 'Інші налаштування, пов\'язані з контактами'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => + 'Автоматично додавати користувачів'; @override String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + 'Дозволити супутникові автоматично додавати виявлених користувачів'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => + 'Автоматично додавати повторювачі'; @override String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + 'Дозволити супутнику автоматично додавати виявлені ретранслятори'; @override String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + 'Автоматично додавати сервери кімнат'; @override String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + 'Дозволити супровіднику автоматично додавати виявлені сервери кімнат.'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => + 'Автоматично додавати датчики'; @override String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + 'Дозволити супровіднику автоматично додавати виявлені сенсори'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => 'Перезаписати найстаріше'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'Коли увімкнено, супровід переганяє найстарший контакт, який не доданий до улюблених, коли список контактів повний.'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => 'Виявлені контакти'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => + 'Відповідних контактів не знайдено'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => 'Знайти виявлені контакти'; + + @override + String get discoveredContacts_contactAdded => 'Контакт додано'; + + @override + String get discoveredContacts_addContact => 'Додати контакт'; + + @override + String get discoveredContacts_copyContact => + 'Копіювати контакт у буфер обміну'; + + @override + String get discoveredContacts_deleteContact => 'Видалити контакт'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 4aec80b..72babcc 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -227,11 +227,10 @@ class AppLocalizationsZh extends AppLocalizations { String get settings_longitude => '经度'; @override - String get settings_contactSettings => 'Contact Settings'; + String get settings_contactSettings => '联系人设置'; @override - String get settings_contactSettingsSubtitle => - 'Settings for how contacts are added.'; + String get settings_contactSettingsSubtitle => '添加联系人的设置'; @override String get settings_privacyMode => '隐私模式'; @@ -2899,56 +2898,63 @@ class AppLocalizationsZh extends AppLocalizations { String get snrIndicator_lastSeen => '最近访问'; @override - String get contactsSettings_title => 'Contacts settings'; + String get contactsSettings_title => '联系人设置'; @override - String get contactsSettings_autoAddTitle => 'Automatic Discovery'; + String get contactsSettings_autoAddTitle => '自动发现'; @override - String get contactsSettings_otherTitle => 'Other contact related settings'; + String get contactsSettings_otherTitle => '其他联系人相关设置'; @override - String get contactsSettings_autoAddUsersTitle => 'Auto-add users'; + String get contactsSettings_autoAddUsersTitle => '自动添加用户'; @override - String get contactsSettings_autoAddUsersSubtitle => - 'Allow the companion to automatically add discovered users.'; + String get contactsSettings_autoAddUsersSubtitle => '允许伴侣自动添加发现的用户'; @override - String get contactsSettings_autoAddRepeatersTitle => 'Auto-add repeaters'; + String get contactsSettings_autoAddRepeatersTitle => '自动添加重复器'; @override - String get contactsSettings_autoAddRepeatersSubtitle => - 'Allow the companion to automatically add discovered repeaters.'; + String get contactsSettings_autoAddRepeatersSubtitle => '允许伴侣自动添加发现的重复器'; @override - String get contactsSettings_autoAddRoomServersTitle => - 'Auto-add room servers'; + String get contactsSettings_autoAddRoomServersTitle => '自动添加房间服务器'; @override - String get contactsSettings_autoAddRoomServersSubtitle => - 'Allow the companion to automatically add discovered room servers.'; + String get contactsSettings_autoAddRoomServersSubtitle => '允许伴侣自动添加发现的房间服务器'; @override - String get contactsSettings_autoAddSensorsTitle => 'Auto-add sensors'; + String get contactsSettings_autoAddSensorsTitle => '自动添加传感器'; @override - String get contactsSettings_autoAddSensorsSubtitle => - 'Allow the companion to automatically add discovered sensors.'; + String get contactsSettings_autoAddSensorsSubtitle => '允许伴侣自动添加发现的传感器'; @override - String get contactsSettings_overwriteOldestTitle => 'Overwrite Oldest'; + String get contactsSettings_overwriteOldestTitle => '覆盖最旧的'; @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + '启用时,伴侣将在联系人列表满时覆盖最老的未收藏的联系人。'; @override - String get discoveredContacts_Title => 'Discovered Contacts'; + String get discoveredContacts_Title => '已发现的联系人'; @override - String get discoveredContacts_noMatching => 'No matching contacts'; + String get discoveredContacts_noMatching => '没有匹配的联系人'; @override - String get discoveredContacts_searchHint => 'Search discovered contacts'; + String get discoveredContacts_searchHint => '搜索已发现的联系人'; + + @override + String get discoveredContacts_contactAdded => '联系人已添加'; + + @override + String get discoveredContacts_addContact => '添加联系人'; + + @override + String get discoveredContacts_copyContact => '复制联系人到剪贴板'; + + @override + String get discoveredContacts_deleteContact => '删除联系人'; } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 69ebecc..7d57cb8 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1799,5 +1799,27 @@ "contacts_searchContactsNoNumber": "Zoek contacten...", "contacts_searchUsers": "Zoek {number}{str} gebruikers...", "contacts_searchFavorites": "Zoek {number}{str} favorieten...", - "contacts_searchRoomServers": "Zoek {number}{str} Room servers..." + "contacts_searchRoomServers": "Zoek {number}{str} Room servers...", + "contactsSettings_autoAddUsersTitle": "Gebruikers automatisch toevoegen", + "contactsSettings_title": "Instellingen voor contacten", + "settings_contactSettings": "Contactinstellingen", + "contactsSettings_otherTitle": "Andere instellingen voor contactgerelateerde zaken", + "contactsSettings_autoAddRepeatersSubtitle": "Sta toe dat de companion automatisch ontdekte repeaters toevoegt", + "contactsSettings_autoAddRoomServersTitle": "Automatisch kamerservers toevoegen", + "contactsSettings_autoAddRoomServersSubtitle": "Sta toe dat de companion automatisch ontdekte kamer servers toevoegt.", + "contactsSettings_autoAddSensorsTitle": "Automatisch sensoren toevoegen", + "settings_contactSettingsSubtitle": "Instellingen voor het toevoegen van contacten", + "contactsSettings_autoAddTitle": "Automatische detectie", + "contactsSettings_autoAddSensorsSubtitle": "Sta toe dat de companion automatisch ontdekte sensoren toevoegt", + "contactsSettings_autoAddUsersSubtitle": "Sta toe dat de companion automatisch ontdekte gebruikers toevoegt", + "contactsSettings_autoAddRepeatersTitle": "Automatisch herhalingstoestellen toevoegen", + "contactsSettings_overwriteOldestTitle": "Overschrijf Oudste", + "discoveredContacts_noMatching": "Geen overeenkomende contacten", + "discoveredContacts_addContact": "Contact toevoegen", + "discoveredContacts_copyContact": "Kopieer contact naar klembord", + "discoveredContacts_deleteContact": "Contact verwijderen", + "discoveredContacts_Title": "Ontdekte contacten", + "contactsSettings_overwriteOldestSubtitle": "Wanneer ingeschakeld, overschrijft de companion het oudste contact dat niet is gemarkeerd als favoriet wanneer de contactenlijst vol is.", + "discoveredContacts_contactAdded": "Contact toegevoegd", + "discoveredContacts_searchHint": "Ontdekte contacten zoeken" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 75e1d34..d20ffee 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1799,5 +1799,27 @@ "contacts_searchFavorites": "Wyszukaj {number}{str} ulubione...", "contacts_searchRoomServers": "Wyszukaj {number}{str} serwerów Room...", "contacts_searchUsers": "Wyszukaj {number}{str} Użytkowników...", - "contacts_searchRepeaters": "Wyszukaj {number}{str} powtórników..." + "contacts_searchRepeaters": "Wyszukaj {number}{str} powtórników...", + "contactsSettings_title": "Ustawienia kontaktów", + "settings_contactSettingsSubtitle": "Ustawienia dotyczące sposobu dodawania kontaktów", + "contactsSettings_autoAddUsersSubtitle": "Pozwól towarzyszowi automatycznie dodawać znalezione użytkowników.", + "contactsSettings_autoAddRepeatersTitle": "Automatyczne dodawanie powtarzalników", + "contactsSettings_autoAddRepeatersSubtitle": "Zezwól na automatyczne dodawanie odkrytych repeaterów przez towarzysza.", + "contactsSettings_autoAddRoomServersTitle": "Automatycznie dodaj serwery pokojowe", + "contactsSettings_autoAddUsersTitle": "Automatycznie dodaj użytkowników", + "settings_contactSettings": "Ustawienia kontaktowe", + "contactsSettings_otherTitle": "Inne ustawienia związane z kontaktami", + "contactsSettings_autoAddTitle": "Automatyczne odnajdywanie", + "contactsSettings_autoAddRoomServersSubtitle": "Zezwól towarzyszowi na automatyczne dodawanie znalezionych serwerów pokojowych.", + "contactsSettings_autoAddSensorsTitle": "Automatycznie dodaj czujniki", + "discoveredContacts_searchHint": "Wyszukaj odkryte kontakty", + "discoveredContacts_contactAdded": "Kontakt dodany", + "discoveredContacts_addContact": "Dodaj kontakt", + "discoveredContacts_copyContact": "Kopiuj kontakt do schowka", + "contactsSettings_overwriteOldestTitle": "Nadpisz najstarszy", + "discoveredContacts_Title": "Odkryte Kontakty", + "contactsSettings_overwriteOldestSubtitle": "Gdy jest włączone, companion zastępuje najstarszy kontakt nie ulubiony, gdy lista kontaktów jest pełna.", + "contactsSettings_autoAddSensorsSubtitle": "Zezwól towarzyszowi na automatyczne dodawanie wykrytych czujników.", + "discoveredContacts_noMatching": "Brak pasujących kontaktów", + "discoveredContacts_deleteContact": "Usuń kontakt" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index f6ada19..421ddd3 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1799,5 +1799,27 @@ "contacts_searchUsers": "Pesquisar {number}{str} Usuários...", "contacts_searchContactsNoNumber": "Pesquisar Contatos...", "contacts_unread": "Não lido", - "contacts_searchRoomServers": "Pesquisar {number}{str} servidores de sala..." + "contacts_searchRoomServers": "Pesquisar {number}{str} servidores de sala...", + "settings_contactSettings": "Configurações de Contato", + "contactsSettings_otherTitle": "Outras configurações relacionadas a contatos", + "contactsSettings_title": "Configurações de contatos", + "contactsSettings_autoAddTitle": "Descoberta Automática", + "settings_contactSettingsSubtitle": "Configurações para como os contatos são adicionados", + "contactsSettings_autoAddUsersTitle": "Adicionar usuários automaticamente", + "contactsSettings_autoAddRepeatersSubtitle": "Permitir que o companheiro adicione automaticamente os repetidores descobertos.", + "contactsSettings_autoAddRoomServersTitle": "Adicionar automaticamente servidores de sala", + "contactsSettings_overwriteOldestTitle": "Sobrescrever o Mais Antigo", + "contactsSettings_autoAddSensorsTitle": "Adicionar sensores automaticamente", + "contactsSettings_overwriteOldestSubtitle": "Quando ativado, o acompanhante substituirá o contato mais antigo não favoritado quando a lista de contatos estiver cheia.", + "discoveredContacts_Title": "Contatos Descobertos", + "contactsSettings_autoAddUsersSubtitle": "Permitir que o companheiro adicione automaticamente os usuários descobertos.", + "contactsSettings_autoAddRepeatersTitle": "Adicionar repetidores automaticamente", + "discoveredContacts_noMatching": "Nenhum contato correspondente", + "contactsSettings_autoAddRoomServersSubtitle": "Permitir que o companheiro adicione automaticamente os servidores de salas descobertos.", + "discoveredContacts_searchHint": "Pesquisar contatos descobertos", + "contactsSettings_autoAddSensorsSubtitle": "Permitir que o companheiro adicione automaticamente sensores descobertos.", + "discoveredContacts_copyContact": "Copiar Contato para a área de transferência", + "discoveredContacts_deleteContact": "Excluir Contato", + "discoveredContacts_contactAdded": "Contato adicionado", + "discoveredContacts_addContact": "Adicionar Contato" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 9aef298..b5910b7 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -1039,5 +1039,27 @@ "contacts_unread": "Непрочитанное", "contacts_searchRoomServers": "Поиск {number}{str} серверов комнат...", "contacts_searchFavorites": "Поиск {number}{str} избранного...", - "contacts_searchUsers": "Поиск {number}{str} пользователей..." + "contacts_searchUsers": "Поиск {number}{str} пользователей...", + "settings_contactSettings": "Настройки контактов", + "settings_contactSettingsSubtitle": "Настройки добавления контактов", + "contactsSettings_autoAddTitle": "Автоматическое обнаружение", + "contactsSettings_title": "Настройки контактов", + "contactsSettings_otherTitle": "Другие настройки, связанные с контактами", + "contactsSettings_autoAddUsersSubtitle": "Разрешить компаньону автоматически добавлять обнаруженных пользователей", + "contactsSettings_autoAddRoomServersTitle": "Автоматически добавлять серверы комнат", + "contactsSettings_autoAddSensorsTitle": "Автоматически добавлять датчики", + "contactsSettings_autoAddSensorsSubtitle": "Разрешить компаньону автоматически добавлять обнаруженные датчики", + "contactsSettings_autoAddUsersTitle": "Автоматически добавлять пользователей", + "contactsSettings_overwriteOldestTitle": "Перезаписать самое старое", + "contactsSettings_autoAddRepeatersTitle": "Автоматически добавлять ретрансляторы", + "contactsSettings_autoAddRepeatersSubtitle": "Разрешить спутнику автоматически добавлять обнаруженные ретрансляторы", + "contactsSettings_overwriteOldestSubtitle": "При включении компаньон будет перезаписывать самый старый контакт, не отмеченный как любимый, когда список контактов полон.", + "contactsSettings_autoAddRoomServersSubtitle": "Разрешить компаньону автоматически добавлять обнаруженные сервера комнат.", + "discoveredContacts_noMatching": "Нет совпадающих контактов", + "discoveredContacts_searchHint": "Найденные контакты поиска", + "discoveredContacts_contactAdded": "Контакт добавлен", + "discoveredContacts_copyContact": "Копировать контакт в буфер обмена", + "discoveredContacts_addContact": "Добавить контакт", + "discoveredContacts_Title": "Обнаруженные контакты", + "discoveredContacts_deleteContact": "Удалить контакт" } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 672b7d7..4fb52ce 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1799,5 +1799,27 @@ "contacts_searchRepeaters": "Hľadať {number}{str} opakovače...", "contacts_searchUsers": "Hľadať {number}{str} používateľov...", "contacts_searchContactsNoNumber": "Hľadať kontakty...", - "contacts_unread": "Neprečítané" + "contacts_unread": "Neprečítané", + "settings_contactSettingsSubtitle": "Nastavenia pre pridávanie kontaktov.", + "contactsSettings_autoAddUsersTitle": "Automaticky pridávať užívateľov", + "contactsSettings_autoAddUsersSubtitle": "Povoliť spoločníkovi automaticky pridávať objavených užívateľov.", + "contactsSettings_autoAddRepeatersTitle": "Automaticky pridávať opakovače", + "contactsSettings_autoAddRoomServersTitle": "Automaticky pridávať server miestnosti", + "contactsSettings_autoAddRoomServersSubtitle": "Povoliť spoločníkovi automaticky pridať objavené serverové miestnosti.", + "contactsSettings_autoAddTitle": "Automatické zisťovanie", + "contactsSettings_title": "Nastavenia kontaktov", + "contactsSettings_otherTitle": "Ďalšie nastavenia súvisiace s kontaktami", + "settings_contactSettings": "Nastavenia kontaktov", + "contactsSettings_autoAddSensorsTitle": "Automaticky pridávať senzory", + "discoveredContacts_noMatching": "Žiadne zhodné kontakty", + "discoveredContacts_searchHint": "Vyhľadať objavené kontakty", + "contactsSettings_autoAddRepeatersSubtitle": "Povoliť spoločníkovi automaticky pridávať objavené repeater.", + "discoveredContacts_contactAdded": "Kontakt bol pridaný", + "discoveredContacts_copyContact": "Kopírovať kontakt do schránky", + "discoveredContacts_deleteContact": "Zmazať kontakt", + "contactsSettings_overwriteOldestSubtitle": "Keď je povolené, spoločník prepíše najstarší kontakt, ktorý nie je označený ako obľúbený, keď je zoznam kontaktov plný.", + "contactsSettings_autoAddSensorsSubtitle": "Povoliť spoločníkovi automaticky pridávať objavené senzory.", + "discoveredContacts_Title": "Objavené kontakty", + "contactsSettings_overwriteOldestTitle": "Prepísať najstaršie", + "discoveredContacts_addContact": "Pridať kontakt" } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index 09359a1..ea75b76 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -1799,5 +1799,27 @@ "contacts_searchRoomServers": "Išči {number}{str} strežnikov sob...", "contacts_searchContactsNoNumber": "Iskanje stikov...", "contacts_searchRepeaters": "Išči {number}{str} ponavljalnike...", - "contacts_searchUsers": "Išči {number}{str} uporabnikov..." + "contacts_searchUsers": "Išči {number}{str} uporabnikov...", + "settings_contactSettings": "Nastavitve stika", + "contactsSettings_autoAddTitle": "Avtomatsko odkrivanje", + "contactsSettings_autoAddUsersTitle": "Avtomatsko dodaj uporabnike", + "contactsSettings_autoAddRepeatersTitle": "Avtomatsko dodaj ponovitelje", + "contactsSettings_autoAddRepeatersSubtitle": "Dovoli spremljevalcu, da samodejno doda odkrite ponovitelje.", + "contactsSettings_autoAddRoomServersTitle": "Avtomatsko dodaj strežnike sob", + "contactsSettings_autoAddRoomServersSubtitle": "Dovoli spremljevalcu, da samodejno doda odkrite strežnike sob.", + "contactsSettings_otherTitle": "Druge nastavitve v zvezi s stiki", + "settings_contactSettingsSubtitle": "Nastavitve za dodajanje stikov.", + "contactsSettings_title": "Nastavitve stikov", + "contactsSettings_autoAddSensorsTitle": "Avtomatsko dodaj senzorje", + "contactsSettings_autoAddUsersSubtitle": "Dovoli spremljevalcu, da samodejno doda odkrite uporabnike.", + "discoveredContacts_noMatching": "Ni ujemajočih stikov", + "contactsSettings_autoAddSensorsSubtitle": "Dovoli spremljevalcu, da samodejno doda odkrite senzorje.", + "discoveredContacts_addContact": "Dodaj stik", + "discoveredContacts_contactAdded": "Kontakt dodan", + "discoveredContacts_copyContact": "Kopiraj stik v odložišče", + "contactsSettings_overwriteOldestTitle": "Prepiši najstarejše", + "contactsSettings_overwriteOldestSubtitle": "Ko je omogočen, bo spremljevalec prepisal najstarejši stik, ki ni označen kot najljubši, ko je seznam stikov poln.", + "discoveredContacts_Title": "Odkriti stiki", + "discoveredContacts_searchHint": "Najdeni stiki po iskanju", + "discoveredContacts_deleteContact": "Izbriši stik" } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index a923cc9..b4bcfb5 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1799,5 +1799,27 @@ "contacts_searchRepeaters": "Sök {number}{str} upprepningsenheter...", "contacts_searchFavorites": "Sök {number}{str} Favoriter...", "contacts_searchUsers": "Sök {number}{str} användare...", - "contacts_searchRoomServers": "Sök {number}{str} Room-servrar..." + "contacts_searchRoomServers": "Sök {number}{str} Room-servrar...", + "settings_contactSettingsSubtitle": "Inställningar för hur kontakter läggs till.", + "settings_contactSettings": "Kontaktinställningar", + "contactsSettings_autoAddTitle": "Automatisk upptäckt", + "contactsSettings_otherTitle": "Andra inställningar relaterade till kontakt", + "contactsSettings_autoAddUsersSubtitle": "Tillåt kompanjonen att automatiskt lägga till upptäckta användare", + "contactsSettings_autoAddRepeatersTitle": "Lägg till upprepande enheter automatiskt", + "contactsSettings_autoAddRoomServersSubtitle": "Tillåt kompanjonen att automatiskt lägga till upptäckta rumsservrar.", + "contactsSettings_autoAddSensorsTitle": "Lägg till sensorer automatiskt", + "contactsSettings_autoAddUsersTitle": "Lägg till användare automatiskt", + "contactsSettings_title": "Kontaktinställningar", + "contactsSettings_autoAddSensorsSubtitle": "Tillåt kompanjonen att automatiskt lägga till upptäckta sensorer.", + "contactsSettings_overwriteOldestTitle": "Skriv över äldst", + "contactsSettings_autoAddRepeatersSubtitle": "Tillåt kompanjonen att automatiskt lägga till upptäckta repeater.", + "contactsSettings_autoAddRoomServersTitle": "Lägg automatiskt till rumsservrar", + "discoveredContacts_noMatching": "Inga matchande kontakter", + "discoveredContacts_searchHint": "Sök uppfunna kontakter", + "discoveredContacts_deleteContact": "Ta bort kontakt", + "discoveredContacts_Title": "Upptäckta kontakter", + "contactsSettings_overwriteOldestSubtitle": "När den är aktiverad kommer medhjälparen att skriva över den äldsta kontakten som inte är favoritmarkerad när kontaktnamnslistan är full", + "discoveredContacts_contactAdded": "Kontakt tillagd", + "discoveredContacts_addContact": "Lägg till kontakt", + "discoveredContacts_copyContact": "Kopiera kontakt till urklipp" } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index c86f11c..733e4e5 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1799,5 +1799,27 @@ "contacts_searchFavorites": "Пошук {number}{str} улюблених...", "contacts_searchContactsNoNumber": "Пошук контактів...", "contacts_searchRepeaters": "Пошук {number}{str} ретрансляторів...", - "contacts_unread": "Непрочитане" + "contacts_unread": "Непрочитане", + "settings_contactSettingsSubtitle": "Налаштування для додавання контактів", + "settings_contactSettings": "Налаштування контактів", + "contactsSettings_autoAddUsersSubtitle": "Дозволити супутникові автоматично додавати виявлених користувачів", + "contactsSettings_autoAddRepeatersTitle": "Автоматично додавати повторювачі", + "contactsSettings_autoAddRepeatersSubtitle": "Дозволити супутнику автоматично додавати виявлені ретранслятори", + "contactsSettings_autoAddRoomServersTitle": "Автоматично додавати сервери кімнат", + "contactsSettings_otherTitle": "Інші налаштування, пов'язані з контактами", + "contactsSettings_autoAddTitle": "Автоматичне виявлення", + "contactsSettings_autoAddUsersTitle": "Автоматично додавати користувачів", + "contactsSettings_title": "Налаштування контактів", + "contactsSettings_autoAddRoomServersSubtitle": "Дозволити супровіднику автоматично додавати виявлені сервери кімнат.", + "contactsSettings_autoAddSensorsTitle": "Автоматично додавати датчики", + "discoveredContacts_searchHint": "Знайти виявлені контакти", + "discoveredContacts_contactAdded": "Контакт додано", + "contactsSettings_autoAddSensorsSubtitle": "Дозволити супровіднику автоматично додавати виявлені сенсори", + "contactsSettings_overwriteOldestTitle": "Перезаписати найстаріше", + "contactsSettings_overwriteOldestSubtitle": "Коли увімкнено, супровід переганяє найстарший контакт, який не доданий до улюблених, коли список контактів повний.", + "discoveredContacts_Title": "Виявлені контакти", + "discoveredContacts_noMatching": "Відповідних контактів не знайдено", + "discoveredContacts_deleteContact": "Видалити контакт", + "discoveredContacts_copyContact": "Копіювати контакт у буфер обміну", + "discoveredContacts_addContact": "Додати контакт" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 63c02a5..d0abb87 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1804,5 +1804,27 @@ "contacts_searchRepeaters": "搜索 {number}{str} 重复器...", "contacts_searchContactsNoNumber": "搜索联系人...", "contacts_searchRoomServers": "搜索 {number}{str} 房间服务器...", - "contacts_searchFavorites": "搜索 {number}{str} 收藏..." + "contacts_searchFavorites": "搜索 {number}{str} 收藏...", + "settings_contactSettings": "联系人设置", + "contactsSettings_title": "联系人设置", + "contactsSettings_autoAddUsersTitle": "自动添加用户", + "contactsSettings_otherTitle": "其他联系人相关设置", + "contactsSettings_autoAddUsersSubtitle": "允许伴侣自动添加发现的用户", + "contactsSettings_autoAddRepeatersSubtitle": "允许伴侣自动添加发现的重复器", + "contactsSettings_autoAddSensorsTitle": "自动添加传感器", + "contactsSettings_autoAddRoomServersSubtitle": "允许伴侣自动添加发现的房间服务器", + "contactsSettings_autoAddRepeatersTitle": "自动添加重复器", + "contactsSettings_autoAddTitle": "自动发现", + "settings_contactSettingsSubtitle": "添加联系人的设置", + "contactsSettings_overwriteOldestTitle": "覆盖最旧的", + "contactsSettings_autoAddSensorsSubtitle": "允许伴侣自动添加发现的传感器", + "discoveredContacts_searchHint": "搜索已发现的联系人", + "contactsSettings_autoAddRoomServersTitle": "自动添加房间服务器", + "discoveredContacts_contactAdded": "联系人已添加", + "discoveredContacts_deleteContact": "删除联系人", + "discoveredContacts_addContact": "添加联系人", + "discoveredContacts_noMatching": "没有匹配的联系人", + "discoveredContacts_Title": "已发现的联系人", + "contactsSettings_overwriteOldestSubtitle": "启用时,伴侣将在联系人列表满时覆盖最老的未收藏的联系人。", + "discoveredContacts_copyContact": "复制联系人到剪贴板" } diff --git a/lib/models/discovery_contact.dart b/lib/models/discovery_contact.dart index 54c2937..f6c6a52 100644 --- a/lib/models/discovery_contact.dart +++ b/lib/models/discovery_contact.dart @@ -2,6 +2,7 @@ import 'dart:typed_data'; import '../connector/meshcore_protocol.dart'; class DiscoveryContact { + final Uint8List rawPacket; final Uint8List publicKey; final String name; final int type; @@ -12,6 +13,7 @@ class DiscoveryContact { final DateTime lastSeen; DiscoveryContact({ + required this.rawPacket, required this.publicKey, required this.name, required this.type, @@ -48,6 +50,7 @@ class DiscoveryContact { bool get hasLocation => latitude != null && longitude != null; DiscoveryContact copyWith({ + Uint8List? rawPacket, Uint8List? publicKey, String? name, int? type, @@ -58,6 +61,7 @@ class DiscoveryContact { DateTime? lastSeen, }) { return DiscoveryContact( + rawPacket: rawPacket ?? this.rawPacket, publicKey: publicKey ?? this.publicKey, name: name ?? this.name, type: type ?? this.type, @@ -92,42 +96,6 @@ class DiscoveryContact { return "<${publicKeyHex.substring(0, 8)}...${publicKeyHex.substring(publicKeyHex.length - 8)}>"; } - Uint8List? get traceRouteBytes { - final pathBytes = path; - Uint8List? traceBytes; - - if (pathBytes.isEmpty) { - traceBytes = Uint8List(1); - traceBytes[0] = publicKey[0]; - return traceBytes; - } - - if (type == advTypeRepeater || type == advTypeRoom) { - final len = (pathBytes.length + pathBytes.length + 1); - traceBytes = Uint8List(len); - traceBytes[pathBytes.length] = publicKey[0]; - for (int i = 0; i < pathBytes.length; i++) { - traceBytes[i] = pathBytes[i]; - if (i < pathBytes.length) { - traceBytes[len - 1 - i] = pathBytes[i]; - } - } - } else { - if (pathBytes.length < 2) { - return pathBytes[0] == 0 ? null : pathBytes; - } - final len = (pathBytes.length + pathBytes.length - 1); - traceBytes = Uint8List(len); - for (int i = 0; i < pathBytes.length; i++) { - traceBytes[i] = pathBytes[i]; - if (i < pathBytes.length - 1) { - traceBytes[len - 1 - i] = pathBytes[i]; - } - } - } - return traceBytes; - } - @override bool operator ==(Object other) => other is DiscoveryContact && publicKeyHex == other.publicKeyHex; diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 6e9f841..5753785 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -219,7 +219,8 @@ class _ContactsScreenState extends State } final hexString = text.substring('meshcore://'.length); try { - final importContactFrame = buildImportContactFrame(hexString); + final bytes = hex2Uint8List(hexString); + final importContactFrame = buildImportContactFrame(bytes); _pendingOperations.add(ContactOperationType.import); await connector.sendFrame(importContactFrame, expectsGenericAck: true); } catch (e) { diff --git a/lib/screens/discovery_screen.dart b/lib/screens/discovery_screen.dart index 10dc016..5cc9fa8 100644 --- a/lib/screens/discovery_screen.dart +++ b/lib/screens/discovery_screen.dart @@ -1,8 +1,7 @@ import 'dart:async'; -import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:meshcore_open/models/contact.dart'; +import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import '../connector/meshcore_connector.dart'; @@ -96,6 +95,11 @@ class _DiscoveryScreenState extends State { color: Colors.grey[600], ), ), + onTap: () { + connector.importDiscoveredContact(contact); + }, + onLongPress: () => + _showContactContextMenu(contact, connector), ); }, ), @@ -105,9 +109,64 @@ class _DiscoveryScreenState extends State { ); } - Widget _buildFilters(filteredAndSorted, connector) { - final l10n = context.l10n; + Future _showContactContextMenu( + DiscoveryContact contact, + MeshCoreConnector connector, + ) async { + final action = await showModalBottomSheet( + context: context, + showDragHandle: true, + builder: (sheetContext) { + final l10n = context.l10n; + return SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.add_reaction_sharp), + title: Text(l10n.discoveredContacts_addContact), + onTap: () => Navigator.of(sheetContext).pop('import_contact'), + ), + ListTile( + leading: const Icon(Icons.copy), + title: Text(l10n.discoveredContacts_copyContact), + onTap: () => Navigator.of(sheetContext).pop('copy_contact'), + ), + ListTile( + leading: const Icon(Icons.delete), + title: Text(l10n.discoveredContacts_deleteContact), + onTap: () => Navigator.of(sheetContext).pop('delete_contact'), + ), + ], + ), + ); + }, + ); + if (!mounted || action == null) return; + + switch (action) { + case 'import_contact': + connector.importDiscoveredContact(contact); + break; + case 'copy_contact': + final hexString = pubKeyToHex(contact.rawPacket); + Clipboard.setData(ClipboardData(text: "meshcore://$hexString")); + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(context.l10n.contacts_contactAdvertCopied)), + ); + break; + case 'delete_contact': + connector.removeDiscoveredContact(contact); + break; + } + } + + Widget _buildFilters( + List filteredAndSorted, + MeshCoreConnector connector, + ) { String hintText = ""; switch (typeFilter) { case ContactTypeFilter.all: @@ -216,6 +275,10 @@ class _DiscoveryScreenState extends State { return matchesDiscoveryContactQuery(contact, searchQuery); }).toList(); + filtered = filtered.where((contact) { + return !connector.knownContactKeys.contains(contact.publicKeyHex); + }).toList(); + // Filter out own node from the list if (connector.selfPublicKey != null) { final selfPubKeyHex = pubKeyToHex(connector.selfPublicKey!); diff --git a/lib/storage/contact_discovery_store.dart b/lib/storage/contact_discovery_store.dart index 84f7807..37bfbb4 100644 --- a/lib/storage/contact_discovery_store.dart +++ b/lib/storage/contact_discovery_store.dart @@ -30,6 +30,7 @@ class ContactDiscoveryStore { Map _toJson(DiscoveryContact contact) { return { + 'rawPacket': base64Encode(contact.rawPacket), 'publicKey': base64Encode(contact.publicKey), 'name': contact.name, 'type': contact.type, @@ -44,6 +45,7 @@ class ContactDiscoveryStore { DiscoveryContact _fromJson(Map json) { final lastSeenMs = json['lastSeen'] as int? ?? 0; return DiscoveryContact( + rawPacket: Uint8List.fromList(base64Decode(json['rawPacket'] as String)), publicKey: Uint8List.fromList(base64Decode(json['publicKey'] as String)), name: json['name'] as String? ?? 'Unknown', type: json['type'] as int? ?? 0, From 128e99e3e7cd6cab5e0e4b5161ece27e96afb810 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 10:35:32 -0800 Subject: [PATCH 04/12] refactor(settings): remove unused import for adaptive_app_bar_title --- lib/screens/settings_screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index fe893f8..0d429f3 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -8,7 +8,6 @@ import '../connector/meshcore_connector.dart'; import '../connector/meshcore_protocol.dart'; import '../l10n/l10n.dart'; import '../models/radio_settings.dart'; -import '../widgets/adaptive_app_bar_title.dart'; import '../widgets/app_bar.dart'; import 'app_settings_screen.dart'; import 'app_debug_log_screen.dart'; From b02225c02e4a8ad0ea1cfb756e38b30a78013f79 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 10:41:31 -0800 Subject: [PATCH 05/12] refactor(connector): remove unused radio settings frame and update command constant --- lib/connector/meshcore_connector.dart | 1 - lib/connector/meshcore_protocol.dart | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index c7ebdaf..52f2a77 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -1093,7 +1093,6 @@ class MeshCoreConnector extends ChangeNotifier { await sendFrame(buildDeviceQueryFrame()); await sendFrame(buildAppStartFrame()); await requestBatteryStatus(force: true); - await sendFrame(buildGetRadioSettingsFrame()); await sendFrame(buildGetCustomVarsFrame()); await sendFrame(buildGetAutoAddFlagsFrame()); _scheduleSelfInfoRetry(); diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index 4f50ec3..db7e02a 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -164,7 +164,7 @@ const int cmdGetChannel = 31; const int cmdSetChannel = 32; const int cmdSendTracePath = 36; const int cmdSetOtherParams = 38; -const int cmdGetRadioSettings = 57; +const int cmdSendAnonReq = 57; const int cmdGetTelemetryReq = 39; const int cmdGetCustomVar = 40; const int cmdSetCustomVar = 41; @@ -691,11 +691,6 @@ Uint8List buildGetContactByKeyFrame(Uint8List pubKey) { return writer.toBytes(); } -// Build CMD_GET_RADIO_SETTINGS frame -Uint8List buildGetRadioSettingsFrame() { - return Uint8List.fromList([cmdGetRadioSettings]); -} - //Build CMD_GET_CUSTOM_VARS frame Uint8List buildGetCustomVarsFrame() { return Uint8List.fromList([cmdGetCustomVar]); From d2640e12940d7e9a13174428dda33d07dda9333a Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 10:52:19 -0800 Subject: [PATCH 06/12] feat(localization): update 'overwrite oldest contact' subtitle for multiple languages --- lib/l10n/app_bg.arb | 4 ++-- lib/l10n/app_de.arb | 4 ++-- lib/l10n/app_en.arb | 2 +- lib/l10n/app_es.arb | 4 ++-- lib/l10n/app_fr.arb | 4 ++-- lib/l10n/app_it.arb | 4 ++-- lib/l10n/app_localizations.dart | 2 +- lib/l10n/app_localizations_bg.dart | 2 +- lib/l10n/app_localizations_de.dart | 2 +- lib/l10n/app_localizations_en.dart | 2 +- lib/l10n/app_localizations_es.dart | 2 +- lib/l10n/app_localizations_fr.dart | 2 +- lib/l10n/app_localizations_it.dart | 2 +- lib/l10n/app_localizations_nl.dart | 2 +- lib/l10n/app_localizations_pl.dart | 2 +- lib/l10n/app_localizations_pt.dart | 2 +- lib/l10n/app_localizations_ru.dart | 2 +- lib/l10n/app_localizations_sk.dart | 2 +- lib/l10n/app_localizations_sl.dart | 2 +- lib/l10n/app_localizations_sv.dart | 2 +- lib/l10n/app_localizations_uk.dart | 2 +- lib/l10n/app_localizations_zh.dart | 2 +- lib/l10n/app_nl.arb | 4 ++-- lib/l10n/app_pl.arb | 4 ++-- lib/l10n/app_pt.arb | 4 ++-- lib/l10n/app_ru.arb | 4 ++-- lib/l10n/app_sk.arb | 4 ++-- lib/l10n/app_sl.arb | 4 ++-- lib/l10n/app_sv.arb | 4 ++-- lib/l10n/app_uk.arb | 4 ++-- lib/l10n/app_zh.arb | 4 ++-- 31 files changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index eed1897..cf33d3d 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1817,9 +1817,9 @@ "discoveredContacts_Title": "Открити контакти", "discoveredContacts_searchHint": "Търсене на открити контакти", "discoveredContacts_noMatching": "Няма съвпадащи контакти", - "contactsSettings_overwriteOldestSubtitle": "Когато е активиран, компаньонът ще презапише най-стария контакт, който не е отбелязан като любим, когато списъкът с контакти е пълен.", "discoveredContacts_contactAdded": "Контакт добавен", "discoveredContacts_copyContact": "Копирай контакт в клипборда", "discoveredContacts_deleteContact": "Изтрий контакт", - "discoveredContacts_addContact": "Добави контакт" + "discoveredContacts_addContact": "Добави контакт", + "contactsSettings_overwriteOldestSubtitle": "Когато списъкът с контакти е пълен, най-старият неключов контакт ще бъде заменен." } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 4fe662f..0029f4c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1848,6 +1848,6 @@ "discoveredContacts_Title": "Entdeckte Kontakte", "discoveredContacts_copyContact": "Kontakt in die Zwischenablage kopieren", "contactsSettings_overwriteOldestTitle": "Überschreiben des Ältesten", - "contactsSettings_overwriteOldestSubtitle": "Wenn aktiviert, überschreibt der Begleiter den ältesten nicht favorisierten Kontakt, wenn die Kontaktliste voll ist.", - "contactsSettings_autoAddSensorsSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Sensoren hinzuzufügen" + "contactsSettings_autoAddSensorsSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Sensoren hinzuzufügen", + "contactsSettings_overwriteOldestSubtitle": "Wenn die Kontaktliste voll ist, wird der älteste nicht favorisierte Kontakt ersetzt." } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8d5e528..66cf2a2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1852,7 +1852,7 @@ "contactsSettings_autoAddSensorsTitle": "Auto-add sensors", "contactsSettings_autoAddSensorsSubtitle": "Allow the companion to automatically add discovered sensors.", "contactsSettings_overwriteOldestTitle": "Overwrite Oldest", - "contactsSettings_overwriteOldestSubtitle": "When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.", + "contactsSettings_overwriteOldestSubtitle": "When the contact list is full, the oldest non-favorited contact will be replaced.", "discoveredContacts_Title": "Discovered Contacts", "discoveredContacts_noMatching": "No matching contacts", "discoveredContacts_searchHint": "Search discovered contacts", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 5a2e1c8..54b9c4d 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1847,7 +1847,7 @@ "discoveredContacts_copyContact": "Copiar contacto al portapapeles", "discoveredContacts_deleteContact": "Eliminar contacto", "discoveredContacts_Title": "Contactos descubiertos", - "contactsSettings_overwriteOldestSubtitle": "Cuando se habilita, el compañero sobrescribirá el contacto más antiguo no favorito cuando la lista de contactos esté llena.", "discoveredContacts_searchHint": "Buscar contactos descubiertos", - "discoveredContacts_addContact": "Agregar contacto" + "discoveredContacts_addContact": "Agregar contacto", + "contactsSettings_overwriteOldestSubtitle": "Cuando la lista de contactos esté llena, se reemplazará el contacto no favorito más antiguo." } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index e222f53..bdfc3e6 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1819,7 +1819,7 @@ "discoveredContacts_deleteContact": "Supprimer le contact", "contactsSettings_overwriteOldestTitle": "Écraser le plus ancien", "contactsSettings_autoAddSensorsSubtitle": "Autoriser le compagnon à ajouter automatiquement les capteurs découverts.", - "contactsSettings_overwriteOldestSubtitle": "Lorsqu'il est activé, le compagnon écrasera l'ancien contact non favori lorsque la liste de contacts est pleine.", "discoveredContacts_Title": "Contacts découverts", - "discoveredContacts_searchHint": "Rechercher des contacts découverts" + "discoveredContacts_searchHint": "Rechercher des contacts découverts", + "contactsSettings_overwriteOldestSubtitle": "Lorsque la liste de contacts est pleine, le contact le plus ancien non favori sera remplacé." } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 53c3737..ad4a80b 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1817,9 +1817,9 @@ "contactsSettings_autoAddRoomServersTitle": "Aggiungere automaticamente i server delle stanze", "discoveredContacts_addContact": "Aggiungi contatto", "contactsSettings_overwriteOldestTitle": "Sostituisci il più vecchio", - "contactsSettings_overwriteOldestSubtitle": "Quando abilitato, il companion sovrascriverà il contatto più vecchio non preferito quando l'elenco dei contatti è pieno.", "discoveredContacts_Title": "Contatti scoperti", "discoveredContacts_contactAdded": "Contatto aggiunto", "discoveredContacts_deleteContact": "Elimina Contatto", - "discoveredContacts_copyContact": "Copia contatto negli appunti" + "discoveredContacts_copyContact": "Copia contatto negli appunti", + "contactsSettings_overwriteOldestSubtitle": "Quando l'elenco dei contatti è pieno, il contatto più vecchio non tra i preferiti verrà sostituito." } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index a7c458f..8b73b19 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -5468,7 +5468,7 @@ abstract class AppLocalizations { /// No description provided for @contactsSettings_overwriteOldestSubtitle. /// /// In en, this message translates to: - /// **'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'** + /// **'When the contact list is full, the oldest non-favorited contact will be replaced.'** String get contactsSettings_overwriteOldestSubtitle; /// No description provided for @discoveredContacts_Title. diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index f9a858f..16712d2 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -3167,7 +3167,7 @@ class AppLocalizationsBg extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Когато е активиран, компаньонът ще презапише най-стария контакт, който не е отбелязан като любим, когато списъкът с контакти е пълен.'; + 'Когато списъкът с контакти е пълен, най-старият неключов контакт ще бъде заменен.'; @override String get discoveredContacts_Title => 'Открити контакти'; diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 77b2a4b..64c75cb 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -3177,7 +3177,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Wenn aktiviert, überschreibt der Begleiter den ältesten nicht favorisierten Kontakt, wenn die Kontaktliste voll ist.'; + 'Wenn die Kontaktliste voll ist, wird der älteste nicht favorisierte Kontakt ersetzt.'; @override String get discoveredContacts_Title => 'Entdeckte Kontakte'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 08132ac..031dd44 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -3116,7 +3116,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'When enabled, the companion will overwrite the oldest contact not favoriteited when the contact list is full.'; + 'When the contact list is full, the oldest non-favorited contact will be replaced.'; @override String get discoveredContacts_Title => 'Discovered Contacts'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 0d2167f..c516d96 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -3169,7 +3169,7 @@ class AppLocalizationsEs extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Cuando se habilita, el compañero sobrescribirá el contacto más antiguo no favorito cuando la lista de contactos esté llena.'; + 'Cuando la lista de contactos esté llena, se reemplazará el contacto no favorito más antiguo.'; @override String get discoveredContacts_Title => 'Contactos descubiertos'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 29f3af8..1ff8aca 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -3190,7 +3190,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Lorsqu\'il est activé, le compagnon écrasera l\'ancien contact non favori lorsque la liste de contacts est pleine.'; + 'Lorsque la liste de contacts est pleine, le contact le plus ancien non favori sera remplacé.'; @override String get discoveredContacts_Title => 'Contacts découverts'; diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index 1fb4eb1..a4e6057 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -3172,7 +3172,7 @@ class AppLocalizationsIt extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Quando abilitato, il companion sovrascriverà il contatto più vecchio non preferito quando l\'elenco dei contatti è pieno.'; + 'Quando l\'elenco dei contatti è pieno, il contatto più vecchio non tra i preferiti verrà sostituito.'; @override String get discoveredContacts_Title => 'Contatti scoperti'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 6ed3a84..3deb4c7 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -3158,7 +3158,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Wanneer ingeschakeld, overschrijft de companion het oudste contact dat niet is gemarkeerd als favoriet wanneer de contactenlijst vol is.'; + 'Wanneer de contactenlijst vol is, wordt de oudste niet-favoriete contactpersoon vervangen.'; @override String get discoveredContacts_Title => 'Ontdekte contacten'; diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 703e281..78c1f8a 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -3171,7 +3171,7 @@ class AppLocalizationsPl extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Gdy jest włączone, companion zastępuje najstarszy kontakt nie ulubiony, gdy lista kontaktów jest pełna.'; + 'Gdy lista kontaktów jest pełna, najstarszy nieulubiony kontakt zostanie zastąpiony.'; @override String get discoveredContacts_Title => 'Odkryte Kontakty'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 442b41e..58f2284 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -3167,7 +3167,7 @@ class AppLocalizationsPt extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Quando ativado, o acompanhante substituirá o contato mais antigo não favoritado quando a lista de contatos estiver cheia.'; + 'Quando a lista de contatos estiver cheia, o contato mais antigo não favoritado será substituído.'; @override String get discoveredContacts_Title => 'Contatos Descobertos'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 90f8ed6..0d5dea5 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -3179,7 +3179,7 @@ class AppLocalizationsRu extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'При включении компаньон будет перезаписывать самый старый контакт, не отмеченный как любимый, когда список контактов полон.'; + 'Когда список контактов заполнен, будет заменен самый старый контакт, который не находится в избранном.'; @override String get discoveredContacts_Title => 'Обнаруженные контакты'; diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index 944bc6c..fd4db23 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -3153,7 +3153,7 @@ class AppLocalizationsSk extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Keď je povolené, spoločník prepíše najstarší kontakt, ktorý nie je označený ako obľúbený, keď je zoznam kontaktov plný.'; + 'Keď je zoznam kontaktov plný, bude nahradený najstarší neoznačený kontakt.'; @override String get discoveredContacts_Title => 'Objavené kontakty'; diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 0fd67ce..339f30a 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -3157,7 +3157,7 @@ class AppLocalizationsSl extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Ko je omogočen, bo spremljevalec prepisal najstarejši stik, ki ni označen kot najljubši, ko je seznam stikov poln.'; + 'Ko je seznam stikov poln, bo najstarejši nestarševski stik zamenjan.'; @override String get discoveredContacts_Title => 'Odkriti stiki'; diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 86ba9fd..9e32ec8 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -3136,7 +3136,7 @@ class AppLocalizationsSv extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'När den är aktiverad kommer medhjälparen att skriva över den äldsta kontakten som inte är favoritmarkerad när kontaktnamnslistan är full'; + 'När kontaktlistan är full ersätts den äldsta icke-favoriterade kontakten.'; @override String get discoveredContacts_Title => 'Upptäckta kontakter'; diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index abeb6c6..fae7e99 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -3185,7 +3185,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - 'Коли увімкнено, супровід переганяє найстарший контакт, який не доданий до улюблених, коли список контактів повний.'; + 'Коли список контактів заповнений, найстарший контакт без позначки улюбленого буде замінений.'; @override String get discoveredContacts_Title => 'Виявлені контакти'; diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 72babcc..8a3a3a3 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -2935,7 +2935,7 @@ class AppLocalizationsZh extends AppLocalizations { @override String get contactsSettings_overwriteOldestSubtitle => - '启用时,伴侣将在联系人列表满时覆盖最老的未收藏的联系人。'; + '当联系人列表已满时,将替换最老的非收藏联系人。'; @override String get discoveredContacts_Title => '已发现的联系人'; diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 7d57cb8..68e6fc6 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1819,7 +1819,7 @@ "discoveredContacts_copyContact": "Kopieer contact naar klembord", "discoveredContacts_deleteContact": "Contact verwijderen", "discoveredContacts_Title": "Ontdekte contacten", - "contactsSettings_overwriteOldestSubtitle": "Wanneer ingeschakeld, overschrijft de companion het oudste contact dat niet is gemarkeerd als favoriet wanneer de contactenlijst vol is.", "discoveredContacts_contactAdded": "Contact toegevoegd", - "discoveredContacts_searchHint": "Ontdekte contacten zoeken" + "discoveredContacts_searchHint": "Ontdekte contacten zoeken", + "contactsSettings_overwriteOldestSubtitle": "Wanneer de contactenlijst vol is, wordt de oudste niet-favoriete contactpersoon vervangen." } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index d20ffee..66d55aa 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1818,8 +1818,8 @@ "discoveredContacts_copyContact": "Kopiuj kontakt do schowka", "contactsSettings_overwriteOldestTitle": "Nadpisz najstarszy", "discoveredContacts_Title": "Odkryte Kontakty", - "contactsSettings_overwriteOldestSubtitle": "Gdy jest włączone, companion zastępuje najstarszy kontakt nie ulubiony, gdy lista kontaktów jest pełna.", "contactsSettings_autoAddSensorsSubtitle": "Zezwól towarzyszowi na automatyczne dodawanie wykrytych czujników.", "discoveredContacts_noMatching": "Brak pasujących kontaktów", - "discoveredContacts_deleteContact": "Usuń kontakt" + "discoveredContacts_deleteContact": "Usuń kontakt", + "contactsSettings_overwriteOldestSubtitle": "Gdy lista kontaktów jest pełna, najstarszy nieulubiony kontakt zostanie zastąpiony." } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 421ddd3..bbf067b 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1810,7 +1810,6 @@ "contactsSettings_autoAddRoomServersTitle": "Adicionar automaticamente servidores de sala", "contactsSettings_overwriteOldestTitle": "Sobrescrever o Mais Antigo", "contactsSettings_autoAddSensorsTitle": "Adicionar sensores automaticamente", - "contactsSettings_overwriteOldestSubtitle": "Quando ativado, o acompanhante substituirá o contato mais antigo não favoritado quando a lista de contatos estiver cheia.", "discoveredContacts_Title": "Contatos Descobertos", "contactsSettings_autoAddUsersSubtitle": "Permitir que o companheiro adicione automaticamente os usuários descobertos.", "contactsSettings_autoAddRepeatersTitle": "Adicionar repetidores automaticamente", @@ -1821,5 +1820,6 @@ "discoveredContacts_copyContact": "Copiar Contato para a área de transferência", "discoveredContacts_deleteContact": "Excluir Contato", "discoveredContacts_contactAdded": "Contato adicionado", - "discoveredContacts_addContact": "Adicionar Contato" + "discoveredContacts_addContact": "Adicionar Contato", + "contactsSettings_overwriteOldestSubtitle": "Quando a lista de contatos estiver cheia, o contato mais antigo não favoritado será substituído." } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index b5910b7..21a9cda 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -1053,7 +1053,6 @@ "contactsSettings_overwriteOldestTitle": "Перезаписать самое старое", "contactsSettings_autoAddRepeatersTitle": "Автоматически добавлять ретрансляторы", "contactsSettings_autoAddRepeatersSubtitle": "Разрешить спутнику автоматически добавлять обнаруженные ретрансляторы", - "contactsSettings_overwriteOldestSubtitle": "При включении компаньон будет перезаписывать самый старый контакт, не отмеченный как любимый, когда список контактов полон.", "contactsSettings_autoAddRoomServersSubtitle": "Разрешить компаньону автоматически добавлять обнаруженные сервера комнат.", "discoveredContacts_noMatching": "Нет совпадающих контактов", "discoveredContacts_searchHint": "Найденные контакты поиска", @@ -1061,5 +1060,6 @@ "discoveredContacts_copyContact": "Копировать контакт в буфер обмена", "discoveredContacts_addContact": "Добавить контакт", "discoveredContacts_Title": "Обнаруженные контакты", - "discoveredContacts_deleteContact": "Удалить контакт" + "discoveredContacts_deleteContact": "Удалить контакт", + "contactsSettings_overwriteOldestSubtitle": "Когда список контактов заполнен, будет заменен самый старый контакт, который не находится в избранном." } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 4fb52ce..19b217e 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1817,9 +1817,9 @@ "discoveredContacts_contactAdded": "Kontakt bol pridaný", "discoveredContacts_copyContact": "Kopírovať kontakt do schránky", "discoveredContacts_deleteContact": "Zmazať kontakt", - "contactsSettings_overwriteOldestSubtitle": "Keď je povolené, spoločník prepíše najstarší kontakt, ktorý nie je označený ako obľúbený, keď je zoznam kontaktov plný.", "contactsSettings_autoAddSensorsSubtitle": "Povoliť spoločníkovi automaticky pridávať objavené senzory.", "discoveredContacts_Title": "Objavené kontakty", "contactsSettings_overwriteOldestTitle": "Prepísať najstaršie", - "discoveredContacts_addContact": "Pridať kontakt" + "discoveredContacts_addContact": "Pridať kontakt", + "contactsSettings_overwriteOldestSubtitle": "Keď je zoznam kontaktov plný, bude nahradený najstarší neoznačený kontakt." } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index ea75b76..aefa817 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -1818,8 +1818,8 @@ "discoveredContacts_contactAdded": "Kontakt dodan", "discoveredContacts_copyContact": "Kopiraj stik v odložišče", "contactsSettings_overwriteOldestTitle": "Prepiši najstarejše", - "contactsSettings_overwriteOldestSubtitle": "Ko je omogočen, bo spremljevalec prepisal najstarejši stik, ki ni označen kot najljubši, ko je seznam stikov poln.", "discoveredContacts_Title": "Odkriti stiki", "discoveredContacts_searchHint": "Najdeni stiki po iskanju", - "discoveredContacts_deleteContact": "Izbriši stik" + "discoveredContacts_deleteContact": "Izbriši stik", + "contactsSettings_overwriteOldestSubtitle": "Ko je seznam stikov poln, bo najstarejši nestarševski stik zamenjan." } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index b4bcfb5..b8f29d7 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1818,8 +1818,8 @@ "discoveredContacts_searchHint": "Sök uppfunna kontakter", "discoveredContacts_deleteContact": "Ta bort kontakt", "discoveredContacts_Title": "Upptäckta kontakter", - "contactsSettings_overwriteOldestSubtitle": "När den är aktiverad kommer medhjälparen att skriva över den äldsta kontakten som inte är favoritmarkerad när kontaktnamnslistan är full", "discoveredContacts_contactAdded": "Kontakt tillagd", "discoveredContacts_addContact": "Lägg till kontakt", - "discoveredContacts_copyContact": "Kopiera kontakt till urklipp" + "discoveredContacts_copyContact": "Kopiera kontakt till urklipp", + "contactsSettings_overwriteOldestSubtitle": "När kontaktlistan är full ersätts den äldsta icke-favoriterade kontakten." } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 733e4e5..275cb13 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1816,10 +1816,10 @@ "discoveredContacts_contactAdded": "Контакт додано", "contactsSettings_autoAddSensorsSubtitle": "Дозволити супровіднику автоматично додавати виявлені сенсори", "contactsSettings_overwriteOldestTitle": "Перезаписати найстаріше", - "contactsSettings_overwriteOldestSubtitle": "Коли увімкнено, супровід переганяє найстарший контакт, який не доданий до улюблених, коли список контактів повний.", "discoveredContacts_Title": "Виявлені контакти", "discoveredContacts_noMatching": "Відповідних контактів не знайдено", "discoveredContacts_deleteContact": "Видалити контакт", "discoveredContacts_copyContact": "Копіювати контакт у буфер обміну", - "discoveredContacts_addContact": "Додати контакт" + "discoveredContacts_addContact": "Додати контакт", + "contactsSettings_overwriteOldestSubtitle": "Коли список контактів заповнений, найстарший контакт без позначки улюбленого буде замінений." } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index d0abb87..11bbd67 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1825,6 +1825,6 @@ "discoveredContacts_addContact": "添加联系人", "discoveredContacts_noMatching": "没有匹配的联系人", "discoveredContacts_Title": "已发现的联系人", - "contactsSettings_overwriteOldestSubtitle": "启用时,伴侣将在联系人列表满时覆盖最老的未收藏的联系人。", - "discoveredContacts_copyContact": "复制联系人到剪贴板" + "discoveredContacts_copyContact": "复制联系人到剪贴板", + "contactsSettings_overwriteOldestSubtitle": "当联系人列表已满时,将替换最老的非收藏联系人。" } From fcab69f9f088bea3a68f4d38387e53ef302a451d Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 13:05:57 -0800 Subject: [PATCH 07/12] refactor(connector): adjust frame length check and simplify contact handling logic refactor(settings): extract settings sending logic into a separate method refactor(ble_debug_log_service): remove unused command case for radio settings refactor(app_bar): update compact width threshold for app bar display --- lib/connector/meshcore_connector.dart | 14 ++-------- lib/screens/settings_screen.dart | 36 ++++++++++++++++++------- lib/services/ble_debug_log_service.dart | 2 -- lib/widgets/app_bar.dart | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 52f2a77..ad2a074 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -2060,7 +2060,7 @@ class MeshCoreConnector extends ChangeNotifier { _selfLatitude = readInt32LE(frame, 36) / 1000000.0; _selfLongitude = readInt32LE(frame, 40) / 1000000.0; - if (frame.length >= 47 && frame[47] == 0x00) { + if (frame.length >= 48 && frame[47] == 0x00) { sendFrame(buildSetOtherParamsFrame(0, 0, 0)); } @@ -3947,17 +3947,6 @@ class MeshCoreConnector extends ChangeNotifier { final existingIndex = _discoveredContacts.indexWhere( (c) => c.publicKeyHex == contact.publicKeyHex, ); - final existingContactsIndex = _contacts.indexWhere( - (c) => c.publicKeyHex == contact.publicKeyHex, - ); - - if (existingContactsIndex >= 0) { - if (existingIndex >= 0) { - removeDiscoveredContact(_discoveredContacts[existingIndex]); - unawaited(_persistDiscoveredContacts()); - } - return; - } // Update existing contact if (existingIndex >= 0) { @@ -3972,6 +3961,7 @@ class MeshCoreConnector extends ChangeNotifier { longitude: contact.longitude, lastSeen: contact.lastSeen, ); + notifyListeners(); return; } diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 0d429f3..0423517 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -938,16 +938,15 @@ class _SettingsScreenState extends State { child: Text(l10n.common_cancel), ), TextButton( - onPressed: () async { - final frame = buildSetAutoAddConfigFrame( - autoAddChat: autoAddChat, - autoAddRepeater: autoAddRepeater, - autoAddRoomServer: autoAddRoomServer, - autoAddSensor: autoAddSensor, - overwriteOldest: overwriteOldest, + onPressed: () { + _sendSettings( + connector, + autoAddChat, + autoAddRepeater, + autoAddRoomServer, + autoAddSensor, + overwriteOldest, ); - await connector.sendFrame(frame); - await connector.sendFrame(buildGetAutoAddFlagsFrame()); Navigator.pop(context); }, child: Text(l10n.common_save), @@ -957,6 +956,25 @@ class _SettingsScreenState extends State { ), ); } + + void _sendSettings( + MeshCoreConnector connector, + autoAddChat, + autoAddRepeater, + autoAddRoomServer, + autoAddSensor, + overwriteOldest, + ) async { + final frame = buildSetAutoAddConfigFrame( + autoAddChat: autoAddChat, + autoAddRepeater: autoAddRepeater, + autoAddRoomServer: autoAddRoomServer, + autoAddSensor: autoAddSensor, + overwriteOldest: overwriteOldest, + ); + await connector.sendFrame(frame); + await connector.sendFrame(buildGetAutoAddFlagsFrame()); + } } class _RadioSettingsDialog extends StatefulWidget { diff --git a/lib/services/ble_debug_log_service.dart b/lib/services/ble_debug_log_service.dart index d923d6b..df2822b 100644 --- a/lib/services/ble_debug_log_service.dart +++ b/lib/services/ble_debug_log_service.dart @@ -172,8 +172,6 @@ class BleDebugLogService extends ChangeNotifier { return 'CMD_GET_CHANNEL'; case cmdSetChannel: return 'CMD_SET_CHANNEL'; - case cmdGetRadioSettings: - return 'CMD_GET_RADIO_SETTINGS'; case cmdSetCustomVar: return 'CMD_SET_CUSTOM_VAR'; case cmdSendTracePath: diff --git a/lib/widgets/app_bar.dart b/lib/widgets/app_bar.dart index 7324481..9f2494e 100644 --- a/lib/widgets/app_bar.dart +++ b/lib/widgets/app_bar.dart @@ -30,7 +30,7 @@ class AppBarTitle extends StatelessWidget { final availableWidth = constraints.hasBoundedWidth ? constraints.maxWidth : MediaQuery.sizeOf(context).width; - final compact = availableWidth < 240; + final compact = availableWidth < 170; final showSubtitle = !compact && connector.isConnected && selfName != null && subtitle; final showBattery = availableWidth >= 60; From 8d736025099de6a08b16ca528a8d613b5f7bba94 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 14:36:04 -0800 Subject: [PATCH 08/12] add flags for manual contact addition and telemetry mode handling --- lib/connector/meshcore_connector.dart | 79 ++++++++++++++++++++------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index ad2a074..14d62dd 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -163,6 +163,12 @@ class MeshCoreConnector extends ChangeNotifier { bool _autoAddRoomServers = false; bool _autoAddSensors = false; bool _overwriteOldest = false; + bool _manualAddContacts = false; + int _telemetryModeBase = 0; + int _telemetryModeLoc = 0; + int _telemetryModeEnv = 0; + int _advertLocPolicy = 0; + int _multiAcks = 0; static const int _defaultMaxContacts = 32; static const int _defaultMaxChannels = 8; @@ -1095,6 +1101,7 @@ class MeshCoreConnector extends ChangeNotifier { await requestBatteryStatus(force: true); await sendFrame(buildGetCustomVarsFrame()); await sendFrame(buildGetAutoAddFlagsFrame()); + _scheduleSelfInfoRetry(); } @@ -1980,6 +1987,7 @@ class MeshCoreConnector extends ChangeNotifier { break; case respCodeAutoAddConfig: _handleAutoAddConfig(frame); + _checkManualAddContacts(); break; case respCodeBattAndStorage: _handleBatteryAndStorage(frame); @@ -2052,28 +2060,35 @@ class MeshCoreConnector extends ChangeNotifier { // [56] = sf // [57] = cr // [58+] = node_name - if (frame.length < 4 + pubKeySize) return; + final reader = BufferReader(frame); + try { + reader.skipBytes(2); + _currentTxPower = reader.readByte(); + _maxTxPower = reader.readByte(); + _selfPublicKey = reader.readBytes(pubKeySize); + _selfLatitude = reader.readInt32LE() / 1000000.0; + _selfLongitude = reader.readInt32LE() / 1000000.0; + _multiAcks = reader.readByte(); + _advertLocPolicy = reader.readByte(); - _currentTxPower = frame[2]; - _maxTxPower = frame[3]; - _selfPublicKey = Uint8List.fromList(frame.sublist(4, 4 + pubKeySize)); - _selfLatitude = readInt32LE(frame, 36) / 1000000.0; - _selfLongitude = readInt32LE(frame, 40) / 1000000.0; + final telemetryFlag = reader.readByte(); + _telemetryModeBase = telemetryFlag & 0x03; + _telemetryModeEnv = telemetryFlag >> 2 & 0x03; + _telemetryModeLoc = telemetryFlag >> 4 & 0x03; - if (frame.length >= 48 && frame[47] == 0x00) { - sendFrame(buildSetOtherParamsFrame(0, 0, 0)); - } + _manualAddContacts = reader.readByte() & 0x01 == 0x00; - // Radio settings (if frame is long enough) - if (frame.length >= 58) { - _currentFreqHz = readUint32LE(frame, 48); - _currentBwHz = readUint32LE(frame, 52); - _currentSf = frame[56]; - _currentCr = frame[57]; - } - // Node name starts at offset 58 if frame is long enough - if (frame.length > 58) { - _selfName = readCString(frame, 58, frame.length - 58); + _currentFreqHz = reader.readUInt32LE(); + _currentBwHz = reader.readUInt32LE(); + _currentSf = reader.readByte(); + _currentCr = reader.readByte(); + + _selfName = reader.readString(); + } catch (e) { + _appDebugLogService?.error( + 'Error parsing SELF_INFO frame: $e', + tag: 'Connector', + ); } _awaitingSelfInfo = false; _selfInfoRetryTimer?.cancel(); @@ -2151,6 +2166,32 @@ class MeshCoreConnector extends ChangeNotifier { } } + void _checkManualAddContacts() async { + // If manual add contacts is enabled, set auto add config and other params. + // and disable it after + if (_manualAddContacts) { + await sendFrame( + buildSetAutoAddConfigFrame( + autoAddChat: true, + autoAddRepeater: true, + autoAddRoomServer: true, + autoAddSensor: true, + overwriteOldest: _overwriteOldest, + ), + ); + await sendFrame( + buildSetOtherParamsFrame( + (_telemetryModeEnv << 4) | + (_telemetryModeLoc << 2) | + (_telemetryModeBase), + _advertLocPolicy, + _multiAcks, + ), + ); + _manualAddContacts = false; + } + } + /// Calculate timeout for a message based on radio settings and path length /// Returns timeout in milliseconds, considering number of hops int calculateTimeout({required int pathLength, int messageBytes = 100}) { From ddeb1edc2e27b277e25389bc09e0c2616f6115d8 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Sun, 1 Mar 2026 14:40:26 -0800 Subject: [PATCH 09/12] refactor(discovery): simplify sorting logic for last seen contacts --- lib/screens/discovery_screen.dart | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lib/screens/discovery_screen.dart b/lib/screens/discovery_screen.dart index 5cc9fa8..dadf632 100644 --- a/lib/screens/discovery_screen.dart +++ b/lib/screens/discovery_screen.dart @@ -293,9 +293,7 @@ class _DiscoveryScreenState extends State { switch (sortOption) { case ContactSortOption.lastSeen: - filtered.sort( - (a, b) => _resolveLastSeen(b).compareTo(_resolveLastSeen(a)), - ); + filtered.sort((a, b) => b.lastSeen.compareTo(a.lastSeen)); break; case ContactSortOption.name: filtered.sort( @@ -324,13 +322,6 @@ class _DiscoveryScreenState extends State { } } - DateTime _resolveLastSeen(DiscoveryContact contact) { - if (contact.type != advTypeChat) return contact.lastSeen; - return contact.lastSeen.isAfter(contact.lastSeen) - ? contact.lastSeen - : contact.lastSeen; - } - IconData _getTypeIcon(int type) { switch (type) { case advTypeChat: From 38856c67e5a9acee38c8013bfadc426259f7a290 Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Mon, 2 Mar 2026 10:23:14 -0800 Subject: [PATCH 10/12] feat: Add functionality to delete all discovered contacts - Implemented a new method to remove all discovered contacts from the list. - Added confirmation dialog for deleting all discovered contacts in the discovery screen. - Updated localization files to include new strings for deleting all discovered contacts. - Refactored contact import logic to streamline the process. - Enhanced the discovery handling to notify users appropriately based on settings. --- lib/connector/meshcore_connector.dart | 109 +++++++++++++++++++++----- lib/l10n/app_bg.arb | 5 +- lib/l10n/app_de.arb | 5 +- lib/l10n/app_en.arb | 5 +- lib/l10n/app_es.arb | 5 +- lib/l10n/app_fr.arb | 5 +- lib/l10n/app_it.arb | 5 +- lib/l10n/app_localizations.dart | 20 ++++- lib/l10n/app_localizations_bg.dart | 11 +++ lib/l10n/app_localizations_de.dart | 11 +++ lib/l10n/app_localizations_en.dart | 13 ++- lib/l10n/app_localizations_es.dart | 11 +++ lib/l10n/app_localizations_fr.dart | 11 +++ lib/l10n/app_localizations_it.dart | 11 +++ lib/l10n/app_localizations_nl.dart | 11 +++ lib/l10n/app_localizations_pl.dart | 11 +++ lib/l10n/app_localizations_pt.dart | 11 +++ lib/l10n/app_localizations_ru.dart | 11 +++ lib/l10n/app_localizations_sk.dart | 11 +++ lib/l10n/app_localizations_sl.dart | 11 +++ lib/l10n/app_localizations_sv.dart | 11 +++ lib/l10n/app_localizations_uk.dart | 11 +++ lib/l10n/app_localizations_zh.dart | 9 +++ lib/l10n/app_nl.arb | 5 +- lib/l10n/app_pl.arb | 5 +- lib/l10n/app_pt.arb | 5 +- lib/l10n/app_ru.arb | 5 +- lib/l10n/app_sk.arb | 5 +- lib/l10n/app_sl.arb | 5 +- lib/l10n/app_sv.arb | 5 +- lib/l10n/app_uk.arb | 5 +- lib/l10n/app_zh.arb | 5 +- lib/screens/contacts_screen.dart | 2 +- lib/screens/discovery_screen.dart | 43 ++++++++++ 34 files changed, 378 insertions(+), 36 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 14d62dd..d71cc75 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -1527,6 +1527,8 @@ class MeshCoreConnector extends ChangeNotifier { Future removeContact(Contact contact) async { if (!isConnected) return; + _handleDiscovery(contact, Uint8List(0), noNotify: true); + await sendFrame(buildRemoveContactFrame(contact.publicKey)); _contacts.removeWhere((c) => c.publicKeyHex == contact.publicKeyHex); _knownContactKeys.remove(contact.publicKeyHex); @@ -1552,23 +1554,15 @@ class MeshCoreConnector extends ChangeNotifier { Future importDiscoveredContact(DiscoveryContact contact) async { if (!isConnected) return; + await sendFrame( - buildSetAutoAddConfigFrame( - autoAddChat: true, - autoAddRepeater: true, - autoAddRoomServer: true, - autoAddSensor: true, - overwriteOldest: _overwriteOldest, - ), - ); - await sendFrame(buildImportContactFrame(contact.rawPacket)); - await sendFrame( - buildSetAutoAddConfigFrame( - autoAddChat: _autoAddUsers, - autoAddRepeater: _autoAddRepeaters, - autoAddRoomServer: _autoAddRoomServers, - autoAddSensor: _autoAddSensors, - overwriteOldest: _overwriteOldest, + buildUpdateContactPathFrame( + contact.publicKey, + contact.path, + contact.pathLength, + type: contact.type, + flags: 0, + name: contact.name, ), ); @@ -3805,6 +3799,76 @@ class MeshCoreConnector extends ChangeNotifier { } } + void importContact(Uint8List frame) { + final packet = BufferReader(frame); + int payloadType = 0; + Uint8List pathBytes = Uint8List(0); + try { + packet.skipBytes(1); // Skip frame type byte + packet.skipBytes(1); // Skip SNR byte + packet.skipBytes(1); // Skip RSSI byte + final header = packet.readByte(); + payloadType = (header >> 2) & 0x0F; + //final payloadVer = (header >> 6) & 0x03; + final pathLen = packet.readByte(); + pathBytes = packet.readBytes(pathLen); + } catch (e) { + appLogger.warn('Malformed RX frame: $e', tag: 'Connector'); + return; + } + double latitude = 0.0; + double longitude = 0.0; + String name = ''; + Uint8List publicKey = Uint8List(0); + int type = 0; + int timestamp = 0; + bool hasLocation = false; + bool hasName = false; + if (payloadType != payloadTypeADVERT) { + appLogger.warn('Unexpected payload type: $payloadType', tag: 'Connector'); + return; + } + try { + publicKey = packet.readBytes(32); + timestamp = packet.readInt32LE(); + //TODO add signature verification + packet.skipBytes(64); // Skip signature for now + final flags = packet.readByte(); + type = flags & 0x0F; + hasLocation = (flags & 0x10) != 0; + // For future use: + //final hasFeature1 = (flags & 0x20) != 0; + //final hasFeature2 = (flags & 0x40) != 0; + hasName = (flags & 0x80) != 0; + if (hasLocation && packet.remaining >= 8) { + latitude = packet.readInt32LE() / 1e6; + longitude = packet.readInt32LE() / 1e6; + } + if (hasName && packet.remaining > 0) { + name = packet.readString(); + } + } catch (e) { + appLogger.warn('Malformed advert frame: $e', tag: 'Connector'); + return; + } + + importDiscoveredContact( + DiscoveryContact( + rawPacket: frame, + publicKey: publicKey, + name: name, + type: type, + pathLength: pathBytes.length, + path: Uint8List.fromList( + pathBytes.reversed.toList(), + ), // Store path in reverse for easier use in outgoing messages + latitude: latitude, + longitude: longitude, + lastSeen: DateTime.fromMillisecondsSinceEpoch(timestamp * 1000), + ), + ); + } + void _handlePayloadAdvertReceived( Uint8List rawPacket, Uint8List payload, @@ -3982,7 +4046,11 @@ class MeshCoreConnector extends ChangeNotifier { } } - void _handleDiscovery(Contact contact, Uint8List rawPacket) { + void _handleDiscovery( + Contact contact, + Uint8List rawPacket, { + bool noNotify = false, + }) { debugPrint('Discovered new contact: ${contact.name}'); final existingIndex = _discoveredContacts.indexWhere( @@ -4022,7 +4090,7 @@ class MeshCoreConnector extends ChangeNotifier { unawaited(_persistDiscoveredContacts()); // Show notification for new contact (advertisement) - if (_appSettingsService != null) { + if (_appSettingsService != null && !noNotify) { final settings = _appSettingsService!.settings; if (settings.notificationsEnabled && settings.notifyOnNewAdvert) { _notificationService.showAdvertNotification( @@ -4033,6 +4101,11 @@ class MeshCoreConnector extends ChangeNotifier { } } } + + void removeAllDiscoveredContacts() { + _discoveredContacts.clear(); + notifyListeners(); + } } const int _phRouteMask = 0x03; diff --git a/lib/l10n/app_bg.arb b/lib/l10n/app_bg.arb index cf33d3d..d8c6821 100644 --- a/lib/l10n/app_bg.arb +++ b/lib/l10n/app_bg.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_copyContact": "Копирай контакт в клипборда", "discoveredContacts_deleteContact": "Изтрий контакт", "discoveredContacts_addContact": "Добави контакт", - "contactsSettings_overwriteOldestSubtitle": "Когато списъкът с контакти е пълен, най-старият неключов контакт ще бъде заменен." + "contactsSettings_overwriteOldestSubtitle": "Когато списъкът с контакти е пълен, най-старият неключов контакт ще бъде заменен.", + "discoveredContacts_deleteContactAll": "Изтриване на Всички Открити Контакти", + "discoveredContacts_deleteContactAllContent": "Сигурни ли сте, че искате да изтриете всички открити контакти?", + "common_deleteAll": "Изтрий всичко" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 0029f4c..690dc6c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1849,5 +1849,8 @@ "discoveredContacts_copyContact": "Kontakt in die Zwischenablage kopieren", "contactsSettings_overwriteOldestTitle": "Überschreiben des Ältesten", "contactsSettings_autoAddSensorsSubtitle": "Ermöglichen Sie dem Begleiter, automatisch entdeckte Sensoren hinzuzufügen", - "contactsSettings_overwriteOldestSubtitle": "Wenn die Kontaktliste voll ist, wird der älteste nicht favorisierte Kontakt ersetzt." + "contactsSettings_overwriteOldestSubtitle": "Wenn die Kontaktliste voll ist, wird der älteste nicht favorisierte Kontakt ersetzt.", + "common_deleteAll": "Alles löschen", + "discoveredContacts_deleteContactAllContent": "Sind Sie sicher, dass Sie alle gefundenen Kontakte löschen möchten?", + "discoveredContacts_deleteContactAll": "Alle entdeckten Kontakte löschen" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 66cf2a2..0eb6173 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -10,6 +10,7 @@ "common_unknownDevice": "Unknown Device", "common_save": "Save", "common_delete": "Delete", + "common_deleteAll": "Delete All", "common_close": "Close", "common_edit": "Edit", "common_add": "Add", @@ -1859,5 +1860,7 @@ "discoveredContacts_contactAdded": "Contact added", "discoveredContacts_addContact": "Add Contact", "discoveredContacts_copyContact": "Copy Contact to clipboard", - "discoveredContacts_deleteContact": "Delete Contact" + "discoveredContacts_deleteContact": "Delete Discovered Contact", + "discoveredContacts_deleteContactAll": "Delete All Discovered Contacts", + "discoveredContacts_deleteContactAllContent": "Are you sure you want to delete all discovered contacts?" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 54b9c4d..3eb91d9 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1849,5 +1849,8 @@ "discoveredContacts_Title": "Contactos descubiertos", "discoveredContacts_searchHint": "Buscar contactos descubiertos", "discoveredContacts_addContact": "Agregar contacto", - "contactsSettings_overwriteOldestSubtitle": "Cuando la lista de contactos esté llena, se reemplazará el contacto no favorito más antiguo." + "contactsSettings_overwriteOldestSubtitle": "Cuando la lista de contactos esté llena, se reemplazará el contacto no favorito más antiguo.", + "common_deleteAll": "Eliminar todo", + "discoveredContacts_deleteContactAll": "Eliminar Todos los Contactos Descubiertos", + "discoveredContacts_deleteContactAllContent": "¿Está seguro de que desea eliminar todos los contactos descubiertos!" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index bdfc3e6..faf8b8b 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1821,5 +1821,8 @@ "contactsSettings_autoAddSensorsSubtitle": "Autoriser le compagnon à ajouter automatiquement les capteurs découverts.", "discoveredContacts_Title": "Contacts découverts", "discoveredContacts_searchHint": "Rechercher des contacts découverts", - "contactsSettings_overwriteOldestSubtitle": "Lorsque la liste de contacts est pleine, le contact le plus ancien non favori sera remplacé." + "contactsSettings_overwriteOldestSubtitle": "Lorsque la liste de contacts est pleine, le contact le plus ancien non favori sera remplacé.", + "common_deleteAll": "Supprimer tout", + "discoveredContacts_deleteContactAll": "Supprimer tous les contacts découverts", + "discoveredContacts_deleteContactAllContent": "Êtes-vous sûr de vouloir supprimer tous les contacts découverts ?" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index ad4a80b..11de963 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_contactAdded": "Contatto aggiunto", "discoveredContacts_deleteContact": "Elimina Contatto", "discoveredContacts_copyContact": "Copia contatto negli appunti", - "contactsSettings_overwriteOldestSubtitle": "Quando l'elenco dei contatti è pieno, il contatto più vecchio non tra i preferiti verrà sostituito." + "contactsSettings_overwriteOldestSubtitle": "Quando l'elenco dei contatti è pieno, il contatto più vecchio non tra i preferiti verrà sostituito.", + "common_deleteAll": "Elimina tutto", + "discoveredContacts_deleteContactAllContent": "Sei sicuro di voler eliminare tutti i contatti scoperti?", + "discoveredContacts_deleteContactAll": "Eliminare tutti i contatti scoperti" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 8b73b19..f44ef17 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -184,6 +184,12 @@ abstract class AppLocalizations { /// **'Delete'** String get common_delete; + /// No description provided for @common_deleteAll. + /// + /// In en, this message translates to: + /// **'Delete All'** + String get common_deleteAll; + /// No description provided for @common_close. /// /// In en, this message translates to: @@ -5510,8 +5516,20 @@ abstract class AppLocalizations { /// No description provided for @discoveredContacts_deleteContact. /// /// In en, this message translates to: - /// **'Delete Contact'** + /// **'Delete Discovered Contact'** String get discoveredContacts_deleteContact; + + /// No description provided for @discoveredContacts_deleteContactAll. + /// + /// In en, this message translates to: + /// **'Delete All Discovered Contacts'** + String get discoveredContacts_deleteContactAll; + + /// No description provided for @discoveredContacts_deleteContactAllContent. + /// + /// In en, this message translates to: + /// **'Are you sure you want to delete all discovered contacts?'** + String get discoveredContacts_deleteContactAllContent; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index 16712d2..05ce277 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -38,6 +38,9 @@ class AppLocalizationsBg extends AppLocalizations { @override String get common_delete => 'Изтрий'; + @override + String get common_deleteAll => 'Изтрий всичко'; + @override String get common_close => 'Затвори'; @@ -3189,4 +3192,12 @@ class AppLocalizationsBg extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Изтрий контакт'; + + @override + String get discoveredContacts_deleteContactAll => + 'Изтриване на Всички Открити Контакти'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Сигурни ли сте, че искате да изтриете всички открити контакти?'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 64c75cb..47377ee 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -38,6 +38,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get common_delete => 'Löschen'; + @override + String get common_deleteAll => 'Alles löschen'; + @override String get common_close => 'Schließen'; @@ -3200,4 +3203,12 @@ class AppLocalizationsDe extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Kontakt löschen'; + + @override + String get discoveredContacts_deleteContactAll => + 'Alle entdeckten Kontakte löschen'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Sind Sie sicher, dass Sie alle gefundenen Kontakte löschen möchten?'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 031dd44..8f1fa3d 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -38,6 +38,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get common_delete => 'Delete'; + @override + String get common_deleteAll => 'Delete All'; + @override String get common_close => 'Close'; @@ -3137,5 +3140,13 @@ class AppLocalizationsEn extends AppLocalizations { String get discoveredContacts_copyContact => 'Copy Contact to clipboard'; @override - String get discoveredContacts_deleteContact => 'Delete Contact'; + String get discoveredContacts_deleteContact => 'Delete Discovered Contact'; + + @override + String get discoveredContacts_deleteContactAll => + 'Delete All Discovered Contacts'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Are you sure you want to delete all discovered contacts?'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index c516d96..ddd9ff9 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -38,6 +38,9 @@ class AppLocalizationsEs extends AppLocalizations { @override String get common_delete => 'Eliminar'; + @override + String get common_deleteAll => 'Eliminar todo'; + @override String get common_close => 'Cerrar'; @@ -3193,4 +3196,12 @@ class AppLocalizationsEs extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Eliminar contacto'; + + @override + String get discoveredContacts_deleteContactAll => + 'Eliminar Todos los Contactos Descubiertos'; + + @override + String get discoveredContacts_deleteContactAllContent => + '¿Está seguro de que desea eliminar todos los contactos descubiertos!'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 1ff8aca..52bf0a3 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -38,6 +38,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get common_delete => 'Supprimer'; + @override + String get common_deleteAll => 'Supprimer tout'; + @override String get common_close => 'Fermer'; @@ -3214,4 +3217,12 @@ class AppLocalizationsFr extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Supprimer le contact'; + + @override + String get discoveredContacts_deleteContactAll => + 'Supprimer tous les contacts découverts'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Êtes-vous sûr de vouloir supprimer tous les contacts découverts ?'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index a4e6057..8730115 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -38,6 +38,9 @@ class AppLocalizationsIt extends AppLocalizations { @override String get common_delete => 'Elimina'; + @override + String get common_deleteAll => 'Elimina tutto'; + @override String get common_close => 'Chiudi'; @@ -3194,4 +3197,12 @@ class AppLocalizationsIt extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Elimina Contatto'; + + @override + String get discoveredContacts_deleteContactAll => + 'Eliminare tutti i contatti scoperti'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Sei sicuro di voler eliminare tutti i contatti scoperti?'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 3deb4c7..93d7f97 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -38,6 +38,9 @@ class AppLocalizationsNl extends AppLocalizations { @override String get common_delete => 'Verwijderen'; + @override + String get common_deleteAll => 'Alles verwijderen'; + @override String get common_close => 'Sluiten'; @@ -3180,4 +3183,12 @@ class AppLocalizationsNl extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Contact verwijderen'; + + @override + String get discoveredContacts_deleteContactAll => + 'Verwijder alle ontdekte contacten'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Weet u zeker dat u alle ontdekte contacten wilt verwijderen?'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index 78c1f8a..3d5bf54 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -38,6 +38,9 @@ class AppLocalizationsPl extends AppLocalizations { @override String get common_delete => 'Usuń'; + @override + String get common_deleteAll => 'Usuń wszystko'; + @override String get common_close => 'Zamknąć'; @@ -3193,4 +3196,12 @@ class AppLocalizationsPl extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Usuń kontakt'; + + @override + String get discoveredContacts_deleteContactAll => + 'Usuń wszystkie odkryte kontakty'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Czy na pewno chcesz usunąć wszystkie znalezione kontakty?'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 58f2284..393f369 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -38,6 +38,9 @@ class AppLocalizationsPt extends AppLocalizations { @override String get common_delete => 'Excluir'; + @override + String get common_deleteAll => 'Excluir Tudo'; + @override String get common_close => 'Fechar'; @@ -3190,4 +3193,12 @@ class AppLocalizationsPt extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Excluir Contato'; + + @override + String get discoveredContacts_deleteContactAll => + 'Excluir Todos os Contatos Descobertos'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Tem certeza de que deseja excluir todos os contatos descobertos?'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 0d5dea5..192cb7f 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -38,6 +38,9 @@ class AppLocalizationsRu extends AppLocalizations { @override String get common_delete => 'Удалить'; + @override + String get common_deleteAll => 'Удалить все'; + @override String get common_close => 'Закрыть'; @@ -3202,4 +3205,12 @@ class AppLocalizationsRu extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Удалить контакт'; + + @override + String get discoveredContacts_deleteContactAll => + 'Удалить Все Обнаруженные Контакты'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Вы уверены, что хотите удалить все обнаруженные контакты?'; } diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index fd4db23..f1076b8 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -38,6 +38,9 @@ class AppLocalizationsSk extends AppLocalizations { @override String get common_delete => 'Odstrániť'; + @override + String get common_deleteAll => 'Zmazať všetko'; + @override String get common_close => 'Zavrieť'; @@ -3175,4 +3178,12 @@ class AppLocalizationsSk extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Zmazať kontakt'; + + @override + String get discoveredContacts_deleteContactAll => + 'Zmazať všetky objavené kontakty'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Ste si istí, že chcete zmazať všetky objavené kontakty?'; } diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 339f30a..469abdb 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -38,6 +38,9 @@ class AppLocalizationsSl extends AppLocalizations { @override String get common_delete => 'Izbrisati'; + @override + String get common_deleteAll => 'Izbriši vse'; + @override String get common_close => 'Zapri'; @@ -3179,4 +3182,12 @@ class AppLocalizationsSl extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Izbriši stik'; + + @override + String get discoveredContacts_deleteContactAll => + 'Izbriši vse odkrite kontakte'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Ste prepričani, da želite izbrisati vse odkrite kontakte?'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 9e32ec8..718d7ad 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -38,6 +38,9 @@ class AppLocalizationsSv extends AppLocalizations { @override String get common_delete => 'Radera'; + @override + String get common_deleteAll => 'Ta bort alla'; + @override String get common_close => 'Stänga'; @@ -3158,4 +3161,12 @@ class AppLocalizationsSv extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Ta bort kontakt'; + + @override + String get discoveredContacts_deleteContactAll => + 'Ta bort alla upptäckta kontakter'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Är du säker på att du vill ta bort alla upptäckta kontakter?'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index fae7e99..9541219 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -38,6 +38,9 @@ class AppLocalizationsUk extends AppLocalizations { @override String get common_delete => 'Видалити'; + @override + String get common_deleteAll => 'Видалити все'; + @override String get common_close => 'Закрити'; @@ -3209,4 +3212,12 @@ class AppLocalizationsUk extends AppLocalizations { @override String get discoveredContacts_deleteContact => 'Видалити контакт'; + + @override + String get discoveredContacts_deleteContactAll => + 'Видалити всі виявлені контакти'; + + @override + String get discoveredContacts_deleteContactAllContent => + 'Ви впевнені, що хочете видалити всі виявлені контакти?'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 8a3a3a3..17f84ce 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -38,6 +38,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get common_delete => '删除'; + @override + String get common_deleteAll => '删除全部'; + @override String get common_close => '关闭'; @@ -2957,4 +2960,10 @@ class AppLocalizationsZh extends AppLocalizations { @override String get discoveredContacts_deleteContact => '删除联系人'; + + @override + String get discoveredContacts_deleteContactAll => '删除所有发现的联系人'; + + @override + String get discoveredContacts_deleteContactAllContent => '您确定要删除所有发现的联系人吗?'; } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 68e6fc6..67ef891 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_Title": "Ontdekte contacten", "discoveredContacts_contactAdded": "Contact toegevoegd", "discoveredContacts_searchHint": "Ontdekte contacten zoeken", - "contactsSettings_overwriteOldestSubtitle": "Wanneer de contactenlijst vol is, wordt de oudste niet-favoriete contactpersoon vervangen." + "contactsSettings_overwriteOldestSubtitle": "Wanneer de contactenlijst vol is, wordt de oudste niet-favoriete contactpersoon vervangen.", + "common_deleteAll": "Alles verwijderen", + "discoveredContacts_deleteContactAll": "Verwijder alle ontdekte contacten", + "discoveredContacts_deleteContactAllContent": "Weet u zeker dat u alle ontdekte contacten wilt verwijderen?" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 66d55aa..d090cb5 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1821,5 +1821,8 @@ "contactsSettings_autoAddSensorsSubtitle": "Zezwól towarzyszowi na automatyczne dodawanie wykrytych czujników.", "discoveredContacts_noMatching": "Brak pasujących kontaktów", "discoveredContacts_deleteContact": "Usuń kontakt", - "contactsSettings_overwriteOldestSubtitle": "Gdy lista kontaktów jest pełna, najstarszy nieulubiony kontakt zostanie zastąpiony." + "contactsSettings_overwriteOldestSubtitle": "Gdy lista kontaktów jest pełna, najstarszy nieulubiony kontakt zostanie zastąpiony.", + "common_deleteAll": "Usuń wszystko", + "discoveredContacts_deleteContactAllContent": "Czy na pewno chcesz usunąć wszystkie znalezione kontakty?", + "discoveredContacts_deleteContactAll": "Usuń wszystkie odkryte kontakty" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index bbf067b..ceecc40 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_deleteContact": "Excluir Contato", "discoveredContacts_contactAdded": "Contato adicionado", "discoveredContacts_addContact": "Adicionar Contato", - "contactsSettings_overwriteOldestSubtitle": "Quando a lista de contatos estiver cheia, o contato mais antigo não favoritado será substituído." + "contactsSettings_overwriteOldestSubtitle": "Quando a lista de contatos estiver cheia, o contato mais antigo não favoritado será substituído.", + "common_deleteAll": "Excluir Tudo", + "discoveredContacts_deleteContactAll": "Excluir Todos os Contatos Descobertos", + "discoveredContacts_deleteContactAllContent": "Tem certeza de que deseja excluir todos os contatos descobertos?" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index 21a9cda..fbed74e 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -1061,5 +1061,8 @@ "discoveredContacts_addContact": "Добавить контакт", "discoveredContacts_Title": "Обнаруженные контакты", "discoveredContacts_deleteContact": "Удалить контакт", - "contactsSettings_overwriteOldestSubtitle": "Когда список контактов заполнен, будет заменен самый старый контакт, который не находится в избранном." + "contactsSettings_overwriteOldestSubtitle": "Когда список контактов заполнен, будет заменен самый старый контакт, который не находится в избранном.", + "common_deleteAll": "Удалить все", + "discoveredContacts_deleteContactAllContent": "Вы уверены, что хотите удалить все обнаруженные контакты?", + "discoveredContacts_deleteContactAll": "Удалить Все Обнаруженные Контакты" } diff --git a/lib/l10n/app_sk.arb b/lib/l10n/app_sk.arb index 19b217e..85d7bec 100644 --- a/lib/l10n/app_sk.arb +++ b/lib/l10n/app_sk.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_Title": "Objavené kontakty", "contactsSettings_overwriteOldestTitle": "Prepísať najstaršie", "discoveredContacts_addContact": "Pridať kontakt", - "contactsSettings_overwriteOldestSubtitle": "Keď je zoznam kontaktov plný, bude nahradený najstarší neoznačený kontakt." + "contactsSettings_overwriteOldestSubtitle": "Keď je zoznam kontaktov plný, bude nahradený najstarší neoznačený kontakt.", + "discoveredContacts_deleteContactAll": "Zmazať všetky objavené kontakty", + "common_deleteAll": "Zmazať všetko", + "discoveredContacts_deleteContactAllContent": "Ste si istí, že chcete zmazať všetky objavené kontakty?" } diff --git a/lib/l10n/app_sl.arb b/lib/l10n/app_sl.arb index aefa817..83bbfa2 100644 --- a/lib/l10n/app_sl.arb +++ b/lib/l10n/app_sl.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_Title": "Odkriti stiki", "discoveredContacts_searchHint": "Najdeni stiki po iskanju", "discoveredContacts_deleteContact": "Izbriši stik", - "contactsSettings_overwriteOldestSubtitle": "Ko je seznam stikov poln, bo najstarejši nestarševski stik zamenjan." + "contactsSettings_overwriteOldestSubtitle": "Ko je seznam stikov poln, bo najstarejši nestarševski stik zamenjan.", + "common_deleteAll": "Izbriši vse", + "discoveredContacts_deleteContactAllContent": "Ste prepričani, da želite izbrisati vse odkrite kontakte?", + "discoveredContacts_deleteContactAll": "Izbriši vse odkrite kontakte" } diff --git a/lib/l10n/app_sv.arb b/lib/l10n/app_sv.arb index b8f29d7..12996e4 100644 --- a/lib/l10n/app_sv.arb +++ b/lib/l10n/app_sv.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_contactAdded": "Kontakt tillagd", "discoveredContacts_addContact": "Lägg till kontakt", "discoveredContacts_copyContact": "Kopiera kontakt till urklipp", - "contactsSettings_overwriteOldestSubtitle": "När kontaktlistan är full ersätts den äldsta icke-favoriterade kontakten." + "contactsSettings_overwriteOldestSubtitle": "När kontaktlistan är full ersätts den äldsta icke-favoriterade kontakten.", + "common_deleteAll": "Ta bort alla", + "discoveredContacts_deleteContactAllContent": "Är du säker på att du vill ta bort alla upptäckta kontakter?", + "discoveredContacts_deleteContactAll": "Ta bort alla upptäckta kontakter" } diff --git a/lib/l10n/app_uk.arb b/lib/l10n/app_uk.arb index 275cb13..4b74e37 100644 --- a/lib/l10n/app_uk.arb +++ b/lib/l10n/app_uk.arb @@ -1821,5 +1821,8 @@ "discoveredContacts_deleteContact": "Видалити контакт", "discoveredContacts_copyContact": "Копіювати контакт у буфер обміну", "discoveredContacts_addContact": "Додати контакт", - "contactsSettings_overwriteOldestSubtitle": "Коли список контактів заповнений, найстарший контакт без позначки улюбленого буде замінений." + "contactsSettings_overwriteOldestSubtitle": "Коли список контактів заповнений, найстарший контакт без позначки улюбленого буде замінений.", + "common_deleteAll": "Видалити все", + "discoveredContacts_deleteContactAll": "Видалити всі виявлені контакти", + "discoveredContacts_deleteContactAllContent": "Ви впевнені, що хочете видалити всі виявлені контакти?" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 11bbd67..be178bc 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1826,5 +1826,8 @@ "discoveredContacts_noMatching": "没有匹配的联系人", "discoveredContacts_Title": "已发现的联系人", "discoveredContacts_copyContact": "复制联系人到剪贴板", - "contactsSettings_overwriteOldestSubtitle": "当联系人列表已满时,将替换最老的非收藏联系人。" + "contactsSettings_overwriteOldestSubtitle": "当联系人列表已满时,将替换最老的非收藏联系人。", + "common_deleteAll": "删除全部", + "discoveredContacts_deleteContactAllContent": "您确定要删除所有发现的联系人吗?", + "discoveredContacts_deleteContactAll": "删除所有发现的联系人" } diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index 5753785..47bac9c 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -222,7 +222,7 @@ class _ContactsScreenState extends State final bytes = hex2Uint8List(hexString); final importContactFrame = buildImportContactFrame(bytes); _pendingOperations.add(ContactOperationType.import); - await connector.sendFrame(importContactFrame, expectsGenericAck: true); + connector.importContact(importContactFrame); } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/screens/discovery_screen.dart b/lib/screens/discovery_screen.dart index dadf632..f122654 100644 --- a/lib/screens/discovery_screen.dart +++ b/lib/screens/discovery_screen.dart @@ -56,6 +56,25 @@ class _DiscoveryScreenState extends State { subtitle: false, ), centerTitle: true, + actions: [ + PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.delete, color: Colors.red), + const SizedBox(width: 8), + Text(context.l10n.discoveredContacts_deleteContactAll), + ], + ), + onTap: () { + _deleteContacts(context, connector); + }, + ), + ], + icon: const Icon(Icons.more_vert), + ), + ], ), body: Column( children: [ @@ -163,6 +182,30 @@ class _DiscoveryScreenState extends State { } } + void _deleteContacts(BuildContext context, MeshCoreConnector connector) { + final l10n = context.l10n; + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(l10n.common_deleteAll), + content: Text(l10n.discoveredContacts_deleteContactAllContent), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(l10n.common_cancel), + ), + TextButton( + onPressed: () async { + Navigator.pop(context); + connector.removeAllDiscoveredContacts(); + }, + child: Text(l10n.common_deleteAll), + ), + ], + ), + ); + } + Widget _buildFilters( List filteredAndSorted, MeshCoreConnector connector, From a0efbbe4bd7446e0eb2fa6c6b66269300c039a8d Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Tue, 3 Mar 2026 17:44:28 -0800 Subject: [PATCH 11/12] Persist Discovered Contacts when updated --- lib/connector/meshcore_connector.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index d71cc75..bc5e654 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -4051,7 +4051,7 @@ class MeshCoreConnector extends ChangeNotifier { Uint8List rawPacket, { bool noNotify = false, }) { - debugPrint('Discovered new contact: ${contact.name}'); + appLogger.info('Discovered new contact: ${contact.name}', tag: 'Connector'); final existingIndex = _discoveredContacts.indexWhere( (c) => c.publicKeyHex == contact.publicKeyHex, @@ -4071,6 +4071,7 @@ class MeshCoreConnector extends ChangeNotifier { lastSeen: contact.lastSeen, ); notifyListeners(); + unawaited(_persistDiscoveredContacts()); return; } From d53465d13b5b6cfe9d2ae489a2d54e1f2042292e Mon Sep 17 00:00:00 2001 From: Winston Lowe Date: Tue, 3 Mar 2026 17:57:56 -0800 Subject: [PATCH 12/12] persist discovered contacts when all are removed --- lib/connector/meshcore_connector.dart | 1 + lib/screens/settings_screen.dart | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index bc5e654..76496a8 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -4105,6 +4105,7 @@ class MeshCoreConnector extends ChangeNotifier { void removeAllDiscoveredContacts() { _discoveredContacts.clear(); + unawaited(_persistDiscoveredContacts()); notifyListeners(); } } diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 0423517..d6118f5 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -959,11 +959,11 @@ class _SettingsScreenState extends State { void _sendSettings( MeshCoreConnector connector, - autoAddChat, - autoAddRepeater, - autoAddRoomServer, - autoAddSensor, - overwriteOldest, + bool autoAddChat, + bool autoAddRepeater, + bool autoAddRoomServer, + bool autoAddSensor, + bool overwriteOldest, ) async { final frame = buildSetAutoAddConfigFrame( autoAddChat: autoAddChat,