mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
Merge 7c768994aa into a4bbeffddc
This commit is contained in:
commit
a15feadeb2
42 changed files with 1462 additions and 33 deletions
|
|
@ -356,6 +356,26 @@ class MeshCoreConnector extends ChangeNotifier {
|
|||
return List.unmodifiable(_discoveredContacts);
|
||||
}
|
||||
|
||||
String exportDiscoveredContactsJson() {
|
||||
return _discoveryContactStore.exportContactsJson(_discoveredContacts);
|
||||
}
|
||||
|
||||
Future<int> importDiscoveredContactsJson(String json) async {
|
||||
final newCount = _discoveryContactStore.importContactsJson(
|
||||
json: json,
|
||||
existingContacts: _discoveredContacts,
|
||||
knownContactKeys: _knownContactKeys,
|
||||
);
|
||||
|
||||
if (newCount == 0 && _discoveredContacts.isEmpty) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
await _persistDiscoveredContacts();
|
||||
notifyListeners();
|
||||
return newCount;
|
||||
}
|
||||
|
||||
List<Channel> get channels => List.unmodifiable(_channels);
|
||||
bool get isConnected => _state == MeshCoreConnectionState.connected;
|
||||
bool get isLoadingContacts => _isLoadingContacts;
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_copyContact": "Копирай контакт в клипборда",
|
||||
"discoveredContacts_deleteContact": "Изтрий контакт",
|
||||
"discoveredContacts_addContact": "Добави контакт",
|
||||
"discoveredContacts_export": "Експортирай откритите контакти",
|
||||
"discoveredContacts_import": "Импортирай откритите контакти",
|
||||
"discoveredContacts_exported": "Откритите контакти са експортирани в {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Неуспешно експортиране на откритите контакти: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Импортирани са {count} открити контакта.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Във файла за импортиране не са намерени контакти.",
|
||||
"discoveredContacts_importFailed": "Неуспешно импортиране на откритите контакти: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactsSettings_overwriteOldestSubtitle": "Когато списъкът с контакти е пълен, най-старият неключов контакт ще бъде заменен.",
|
||||
"discoveredContacts_deleteContactAll": "Изтриване на Всички Открити Контакти",
|
||||
"discoveredContacts_deleteContactAllContent": "Сигурни ли сте, че искате да изтриете всички открити контакти?",
|
||||
|
|
|
|||
|
|
@ -1856,6 +1856,41 @@
|
|||
"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",
|
||||
"discoveredContacts_export": "Entdeckte Kontakte exportieren",
|
||||
"discoveredContacts_import": "Entdeckte Kontakte importieren",
|
||||
"discoveredContacts_exported": "Entdeckte Kontakte exportiert nach {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Export von entdeckten Kontakten fehlgeschlagen: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} entdeckte Kontakte importiert.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Keine Kontakte in Importdatei gefunden.",
|
||||
"discoveredContacts_importFailed": "Import von entdeckten Kontakten fehlgeschlagen: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_showGuessedLocations": "Zeige die vermuteten Knotenpositionen",
|
||||
"map_guessedLocation": "Geschätzter Ort",
|
||||
"usbScreenSubtitle": "Wählen Sie ein erkannten serielles Gerät aus und verbinden Sie es direkt mit Ihrem MeshCore-Knoten.",
|
||||
|
|
|
|||
|
|
@ -1922,6 +1922,41 @@
|
|||
"contacts_invalidAdvertFormat": "Invalid contact data",
|
||||
"contacts_contactImported": "Contact has been imported.",
|
||||
"contacts_contactImportFailed": "Failed to import contact.",
|
||||
"discoveredContacts_export": "Export discovered contacts",
|
||||
"discoveredContacts_import": "Import discovered contacts",
|
||||
"discoveredContacts_exported": "Exported discovered contacts to {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Failed to export discovered contacts: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Imported {count} discovered contacts.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "No contacts found in import file.",
|
||||
"discoveredContacts_importFailed": "Failed to import discovered contacts: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contacts_zeroHopAdvert": "Zero Hop Advert",
|
||||
"contacts_floodAdvert": "Flood Advert",
|
||||
"contacts_copyAdvertToClipboard": "Copy Advert to Clipboard",
|
||||
|
|
@ -2068,7 +2103,6 @@
|
|||
"radioStats_stripWaiting": "Fetching radio stats…",
|
||||
"radioStats_settingsTile": "Radio stats",
|
||||
"radioStats_settingsSubtitle": "Noise floor, RSSI, SNR, and airtime",
|
||||
|
||||
"translation_title": "Translation",
|
||||
"translation_enableTitle": "Enable translation",
|
||||
"translation_enableSubtitle": "Translate incoming messages and allow pre-send translation.",
|
||||
|
|
|
|||
|
|
@ -1856,6 +1856,41 @@
|
|||
"common_deleteAll": "Eliminar todo",
|
||||
"discoveredContacts_deleteContactAll": "Eliminar Todos los Contactos Descubiertos",
|
||||
"discoveredContacts_deleteContactAllContent": "¿Está seguro de que desea eliminar todos los contactos descubiertos!",
|
||||
"discoveredContacts_export": "Exportar contactos descubiertos",
|
||||
"discoveredContacts_import": "Importar contactos descubiertos",
|
||||
"discoveredContacts_exported": "Contactos descubiertos exportados a {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Error al exportar contactos descubiertos: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} contactos descubiertos importados.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "No se encontraron contactos en el archivo de importación.",
|
||||
"discoveredContacts_importFailed": "Error al importar contactos descubiertos: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_guessedLocation": "Ubicación estimada",
|
||||
"map_showGuessedLocations": "Mostrar las ubicaciones estimadas de los nodos.",
|
||||
"usbScreenTitle": "Conecte mediante USB",
|
||||
|
|
|
|||
|
|
@ -1828,6 +1828,41 @@
|
|||
"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 ?",
|
||||
"discoveredContacts_export": "Exporter les contacts découverts",
|
||||
"discoveredContacts_import": "Importer les contacts découverts",
|
||||
"discoveredContacts_exported": "Contacts découverts exportés vers {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Impossible d'exporter les contacts découverts: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} contacts découverts importés.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Aucun contact trouvé dans le fichier d'importation.",
|
||||
"discoveredContacts_importFailed": "Impossible d'importer les contacts découverts: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"map_showGuessedLocations": "Afficher les emplacements des nœuds estimés",
|
||||
"map_guessedLocation": "Lieu deviné",
|
||||
"connectionChoiceUsbLabel": "USB",
|
||||
|
|
|
|||
|
|
@ -1949,6 +1949,41 @@
|
|||
"discoveredContacts_deleteContact": "Törölj a feltalált kapcsolatot",
|
||||
"discoveredContacts_deleteContactAll": "Törölj minden megtalált kapcsolatot",
|
||||
"discoveredContacts_deleteContactAllContent": "Biztos, hogy szeretné törölni az összes eddig megtalált kapcsolatot?",
|
||||
"discoveredContacts_export": "Felfedezett kapcsolatok exportálása",
|
||||
"discoveredContacts_import": "Felfedezett kapcsolatok importálása",
|
||||
"discoveredContacts_exported": "A felfedezett kapcsolatok exportálva ide: {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "A felfedezett kapcsolatok exportálása nem sikerült: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} felfedezett kapcsolat importálva.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Az importfájlban nem találhatók kapcsolatok.",
|
||||
"discoveredContacts_importFailed": "A felfedezett kapcsolatok importálása nem sikerült: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_sendCooldown": "Kérjük, várjon egy pillanatot, mielőtt újra elküldené.",
|
||||
"appSettings_jumpToOldestUnread": "Jelentkezzen az legörebb, olvasatlan üzenetre",
|
||||
"appSettings_jumpToOldestUnreadSubtitle": "Amikor egy új csevet indítunk, amelyben vannak olvashatatlan üzenetek, görgessük a listát, hogy a legelső, olvashatatlan üzenet megjelenjen, nem pedig az utolsó.",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_contactAdded": "Contatto aggiunto",
|
||||
"discoveredContacts_deleteContact": "Elimina Contatto",
|
||||
"discoveredContacts_copyContact": "Copia contatto negli appunti",
|
||||
"discoveredContacts_export": "Esporta contatti scoperti",
|
||||
"discoveredContacts_import": "Importa contatti scoperti",
|
||||
"discoveredContacts_exported": "Contatti scoperti esportati in {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Esportazione dei contatti scoperti non riuscita: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Importati {count} contatti scoperti.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Nessun contatto trovato nel file di importazione.",
|
||||
"discoveredContacts_importFailed": "Importazione dei contatti scoperti non riuscita: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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?",
|
||||
|
|
|
|||
|
|
@ -1949,6 +1949,41 @@
|
|||
"discoveredContacts_deleteContact": "発見された連絡先を削除",
|
||||
"discoveredContacts_deleteContactAll": "発見されたすべての連絡先を削除",
|
||||
"discoveredContacts_deleteContactAllContent": "本当に、見つけたすべての連絡先を削除してもよろしいですか?",
|
||||
"discoveredContacts_export": "発見済みの連絡先をエクスポート",
|
||||
"discoveredContacts_import": "発見済みの連絡先をインポート",
|
||||
"discoveredContacts_exported": "発見済みの連絡先を {path} にエクスポートしました。",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "発見済みの連絡先のエクスポートに失敗しました: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} 件の発見済み連絡先をインポートしました。",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "インポートファイルに連絡先が見つかりませんでした。",
|
||||
"discoveredContacts_importFailed": "発見済みの連絡先のインポートに失敗しました: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_sendCooldown": "再度送信する前に、しばらくお待ちください。",
|
||||
"appSettings_jumpToOldestUnread": "最も古い未読のメッセージへ移動",
|
||||
"appSettings_jumpToOldestUnreadSubtitle": "未読メッセージがあるチャットを開く際、「最新のメッセージ」ではなく、最初に未読のメッセージまでスクロールしてください。",
|
||||
|
|
|
|||
|
|
@ -1949,6 +1949,41 @@
|
|||
"discoveredContacts_deleteContact": "발견된 연락처 삭제",
|
||||
"discoveredContacts_deleteContactAll": "발견된 모든 연락처 삭제",
|
||||
"discoveredContacts_deleteContactAllContent": "정말로 모든 검색된 연락처를 삭제하시겠습니까?",
|
||||
"discoveredContacts_export": "발견된 연락처 내보내기",
|
||||
"discoveredContacts_import": "발견된 연락처 가져오기",
|
||||
"discoveredContacts_exported": "발견된 연락처를 {path}(으)로 내보냈습니다.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "발견된 연락처 내보내기에 실패했습니다: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "발견된 연락처 {count}개를 가져왔습니다.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "가져오기 파일에서 연락처를 찾을 수 없습니다.",
|
||||
"discoveredContacts_importFailed": "발견된 연락처 가져오기에 실패했습니다: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chat_sendCooldown": "다시 보내기 전에 잠시 기다려 주시기 바랍니다.",
|
||||
"appSettings_jumpToOldestUnread": "가장 오래된, 아직 읽지 않은 항목으로 이동",
|
||||
"appSettings_jumpToOldestUnreadSubtitle": "새로운 메시지가 없는 채팅을 열 때, 최신 메시지가 아닌 첫 번째 읽지 않은 메시지로 스크롤하세요.",
|
||||
|
|
|
|||
|
|
@ -5741,6 +5741,48 @@ abstract class AppLocalizations {
|
|||
/// **'Failed to import contact.'**
|
||||
String get contacts_contactImportFailed;
|
||||
|
||||
/// No description provided for @discoveredContacts_export.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Export discovered contacts'**
|
||||
String get discoveredContacts_export;
|
||||
|
||||
/// No description provided for @discoveredContacts_import.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Import discovered contacts'**
|
||||
String get discoveredContacts_import;
|
||||
|
||||
/// No description provided for @discoveredContacts_exported.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Exported discovered contacts to {path}.'**
|
||||
String discoveredContacts_exported(String path);
|
||||
|
||||
/// No description provided for @discoveredContacts_exportFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Failed to export discovered contacts: {error}'**
|
||||
String discoveredContacts_exportFailed(String error);
|
||||
|
||||
/// No description provided for @discoveredContacts_imported.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Imported {count} discovered contacts.'**
|
||||
String discoveredContacts_imported(int count);
|
||||
|
||||
/// No description provided for @discoveredContacts_importNoContacts.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No contacts found in import file.'**
|
||||
String get discoveredContacts_importNoContacts;
|
||||
|
||||
/// No description provided for @discoveredContacts_importFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Failed to import discovered contacts: {error}'**
|
||||
String discoveredContacts_importFailed(String error);
|
||||
|
||||
/// No description provided for @contacts_zeroHopAdvert.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -3296,6 +3296,36 @@ class AppLocalizationsBg extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Контактът не е успешно импортиран.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Експортирай откритите контакти';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Импортирай откритите контакти';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Откритите контакти са експортирани в $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Неуспешно експортиране на откритите контакти: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Импортирани са $count открити контакта.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Във файла за импортиране не са намерени контакти.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Неуспешно импортиране на откритите контакти: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Реклама без скок';
|
||||
|
||||
|
|
|
|||
|
|
@ -3301,6 +3301,36 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Kontakt konnte nicht importiert werden';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Entdeckte Kontakte exportieren';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Entdeckte Kontakte importieren';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Entdeckte Kontakte exportiert nach $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Export von entdeckten Kontakten fehlgeschlagen: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count entdeckte Kontakte importiert.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Keine Kontakte in Importdatei gefunden.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Import von entdeckten Kontakten fehlgeschlagen: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Zero-Hop-Ankündigung';
|
||||
|
||||
|
|
|
|||
|
|
@ -3239,6 +3239,36 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Failed to import contact.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Export discovered contacts';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Import discovered contacts';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Exported discovered contacts to $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Failed to export discovered contacts: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Imported $count discovered contacts.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'No contacts found in import file.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Failed to import discovered contacts: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Zero Hop Advert';
|
||||
|
||||
|
|
|
|||
|
|
@ -3296,6 +3296,36 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Contacto no se importó correctamente.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Exportar contactos descubiertos';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importar contactos descubiertos';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Contactos descubiertos exportados a $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Error al exportar contactos descubiertos: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count contactos descubiertos importados.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'No se encontraron contactos en el archivo de importación.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Error al importar contactos descubiertos: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Anuncio de Zero Hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3313,6 +3313,36 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Échec de l\'importation du contact.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Exporter les contacts découverts';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importer les contacts découverts';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Contacts découverts exportés vers $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Impossible d\'exporter les contacts découverts: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count contacts découverts importés.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Aucun contact trouvé dans le fichier d\'importation.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Impossible d\'importer les contacts découverts: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Annonce Zero saut';
|
||||
|
||||
|
|
|
|||
|
|
@ -3310,6 +3310,36 @@ class AppLocalizationsHu extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Nem sikerült a kapcsolatot importálni.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Felfedezett kapcsolatok exportálása';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Felfedezett kapcsolatok importálása';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'A felfedezett kapcsolatok exportálva ide: $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'A felfedezett kapcsolatok exportálása nem sikerült: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count felfedezett kapcsolat importálva.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Az importfájlban nem találhatók kapcsolatok.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'A felfedezett kapcsolatok importálása nem sikerült: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Zero Hop reklám';
|
||||
|
||||
|
|
|
|||
|
|
@ -3299,6 +3299,36 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Contatto non importato con successo.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Esporta contatti scoperti';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importa contatti scoperti';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Contatti scoperti esportati in $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Esportazione dei contatti scoperti non riuscita: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Importati $count contatti scoperti.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Nessun contatto trovato nel file di importazione.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Importazione dei contatti scoperti non riuscita: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Annuncio Zero Hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3149,6 +3149,35 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => '連絡先のインポートに失敗しました。';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => '発見済みの連絡先をエクスポート';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => '発見済みの連絡先をインポート';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return '発見済みの連絡先を $path にエクスポートしました。';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return '発見済みの連絡先のエクスポートに失敗しました: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count 件の発見済み連絡先をインポートしました。';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts => 'インポートファイルに連絡先が見つかりませんでした。';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return '発見済みの連絡先のインポートに失敗しました: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'ゼロホップ広告';
|
||||
|
||||
|
|
|
|||
|
|
@ -3149,6 +3149,35 @@ class AppLocalizationsKo extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => '연락처를 가져오지 못했습니다.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => '발견된 연락처 내보내기';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => '발견된 연락처 가져오기';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return '발견된 연락처를 $path(으)로 내보냈습니다.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return '발견된 연락처 내보내기에 실패했습니다: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '발견된 연락처 $count개를 가져왔습니다.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts => '가져오기 파일에서 연락처를 찾을 수 없습니다.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return '발견된 연락처 가져오기에 실패했습니다: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => '제로 홉 광고';
|
||||
|
||||
|
|
|
|||
|
|
@ -3280,6 +3280,36 @@ class AppLocalizationsNl extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Contact kon niet geïmporteerd worden.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Ontdekte contacten exporteren';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Ontdekte contacten importeren';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Ontdekte contacten geëxporteerd naar $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Exporteren van ontdekte contacten mislukt: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count ontdekte contacten geïmporteerd.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Geen contacten gevonden in het importbestand.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Importeren van ontdekte contacten mislukt: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Zero Hop Reclame';
|
||||
|
||||
|
|
|
|||
|
|
@ -3306,6 +3306,36 @@ class AppLocalizationsPl extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Kontakt nie został zaimportowany.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Eksportuj odkryte kontakty';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importuj odkryte kontakty';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Wyeksportowano odkryte kontakty do $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Nie udało się wyeksportować odkrytych kontaktów: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Zaimportowano $count odkrytych kontaktów.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Nie znaleziono kontaktów w pliku importu.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Nie udało się zaimportować odkrytych kontaktów: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Rozgłoszenie zero-hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3293,6 +3293,36 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Contato falhou ao ser importado.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Exportar contatos descobertos';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importar contatos descobertos';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Contatos descobertos exportados para $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Falha ao exportar contatos descobertos: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '$count contatos descobertos importados.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Nenhum contato encontrado no arquivo de importação.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Falha ao importar contatos descobertos: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Anúncio Zero Hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3299,6 +3299,37 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Контакт не удалось импортировать';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export =>
|
||||
'Экспортировать обнаруженные контакты';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Импортировать обнаруженные контакты';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Обнаруженные контакты экспортированы в $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Не удалось экспортировать обнаруженные контакты: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Импортировано $count обнаруженных контактов.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'В файле импорта не найдены контакты.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Не удалось импортировать обнаруженные контакты: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Реклама Zero Hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3274,6 +3274,36 @@ class AppLocalizationsSk extends AppLocalizations {
|
|||
String get contacts_contactImportFailed =>
|
||||
'Kontakt sa nepodarilo importovať.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Exportovať objavené kontakty';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importovať objavené kontakty';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Objavené kontakty boli exportované do $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Export objavených kontaktov zlyhal: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Bolo importovaných $count objavených kontaktov.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'V importovanom súbore sa nenašli žiadne kontakty.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Import objavených kontaktov zlyhal: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Inzerát Zero Hop';
|
||||
|
||||
|
|
|
|||
|
|
@ -3274,6 +3274,36 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Kontakt ni bil uspešno uvožen.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Izvozi odkrite stike';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Uvozi odkrite stike';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Odkriti stiki so izvoženi v $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Izvoz odkritih stikov ni uspel: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Uvoženih je bilo $count odkritih stikov.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'V uvozni datoteki ni bilo najdenih stikov.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Uvoz odkritih stikov ni uspel: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Reklama brez posrednikov';
|
||||
|
||||
|
|
|
|||
|
|
@ -3256,6 +3256,36 @@ class AppLocalizationsSv extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Kontakt kunde inte importeras.';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Exportera upptäckta kontakter';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Importera upptäckta kontakter';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Upptäckta kontakter exporterades till $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Det gick inte att exportera upptäckta kontakter: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Importerade $count upptäckta kontakter.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'Inga kontakter hittades i importfilen.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Det gick inte att importera upptäckta kontakter: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Reklam med nollhopp';
|
||||
|
||||
|
|
|
|||
|
|
@ -3301,6 +3301,36 @@ class AppLocalizationsUk extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => 'Контакт не вдалося імпортувати';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => 'Експортувати виявлені контакти';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => 'Імпортувати виявлені контакти';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return 'Виявлені контакти експортовано до $path.';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return 'Не вдалося експортувати виявлені контакти: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return 'Імпортовано $count виявлених контактів.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts =>
|
||||
'У файлі імпорту не знайдено контактів.';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return 'Не вдалося імпортувати виявлені контакти: $error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => 'Реклама без перехоплення';
|
||||
|
||||
|
|
|
|||
|
|
@ -3073,6 +3073,35 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get contacts_contactImportFailed => '导入联系人失败。';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_export => '导出已发现的联系人';
|
||||
|
||||
@override
|
||||
String get discoveredContacts_import => '导入已发现的联系人';
|
||||
|
||||
@override
|
||||
String discoveredContacts_exported(String path) {
|
||||
return '已将已发现的联系人导出到$path。';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_exportFailed(String error) {
|
||||
return '导出已发现的联系人失败:$error';
|
||||
}
|
||||
|
||||
@override
|
||||
String discoveredContacts_imported(int count) {
|
||||
return '已导入$count个已发现的联系人。';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discoveredContacts_importNoContacts => '在导入文件中未找到联系人。';
|
||||
|
||||
@override
|
||||
String discoveredContacts_importFailed(String error) {
|
||||
return '导入已发现的联系人失败:$error';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contacts_zeroHopAdvert => '发送零跳广播';
|
||||
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_Title": "Ontdekte contacten",
|
||||
"discoveredContacts_contactAdded": "Contact toegevoegd",
|
||||
"discoveredContacts_searchHint": "Ontdekte contacten zoeken",
|
||||
"discoveredContacts_export": "Ontdekte contacten exporteren",
|
||||
"discoveredContacts_import": "Ontdekte contacten importeren",
|
||||
"discoveredContacts_exported": "Ontdekte contacten geëxporteerd naar {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Exporteren van ontdekte contacten mislukt: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} ontdekte contacten geïmporteerd.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Geen contacten gevonden in het importbestand.",
|
||||
"discoveredContacts_importFailed": "Importeren van ontdekte contacten mislukt: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactsSettings_overwriteOldestSubtitle": "Wanneer de contactenlijst vol is, wordt de oudste niet-favoriete contactpersoon vervangen.",
|
||||
"common_deleteAll": "Alles verwijderen",
|
||||
"discoveredContacts_deleteContactAll": "Verwijder alle ontdekte contacten",
|
||||
|
|
|
|||
|
|
@ -1862,6 +1862,41 @@
|
|||
"contactsSettings_autoAddSensorsSubtitle": "Zezwól towarzyszowi na automatyczne dodawanie wykrytych czujników.",
|
||||
"discoveredContacts_noMatching": "Brak pasujących kontaktów",
|
||||
"discoveredContacts_deleteContact": "Usuń kontakt",
|
||||
"discoveredContacts_export": "Eksportuj odkryte kontakty",
|
||||
"discoveredContacts_import": "Importuj odkryte kontakty",
|
||||
"discoveredContacts_exported": "Wyeksportowano odkryte kontakty do {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Nie udało się wyeksportować odkrytych kontaktów: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Zaimportowano {count} odkrytych kontaktów.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Nie znaleziono kontaktów w pliku importu.",
|
||||
"discoveredContacts_importFailed": "Nie udało się zaimportować odkrytych kontaktów: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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?",
|
||||
|
|
@ -2100,12 +2135,6 @@
|
|||
"scanner_linuxPairingPinTitle": "Kod PIN parowania Bluetooth",
|
||||
"repeater_cliQuickClockSync": "Synchronizacja zegara",
|
||||
"repeater_cliQuickDiscovery": "Odkryj Sąsiadów",
|
||||
"@repeater_clockSyncAfterLogin": {
|
||||
"description": "Repeater setting: auto sync device clock after successful login"
|
||||
},
|
||||
"@repeater_clockSyncAfterLoginSubtitle": {
|
||||
"description": "Repeater setting subtitle: describes the clock sync after login behavior"
|
||||
},
|
||||
"repeater_clockSyncAfterLogin": "Synchronizacja zegara po zalogowaniu",
|
||||
"repeater_clockSyncAfterLoginSubtitle": "Automatycznie wysyłaj powiadomienie \"synchronizacja zegara\" po pomyślnym zalogowaniu.",
|
||||
"chat_sendMessage": "Wyślij wiadomość",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_deleteContact": "Excluir Contato",
|
||||
"discoveredContacts_contactAdded": "Contato adicionado",
|
||||
"discoveredContacts_addContact": "Adicionar Contato",
|
||||
"discoveredContacts_export": "Exportar contatos descobertos",
|
||||
"discoveredContacts_import": "Importar contatos descobertos",
|
||||
"discoveredContacts_exported": "Contatos descobertos exportados para {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Falha ao exportar contatos descobertos: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "{count} contatos descobertos importados.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Nenhum contato encontrado no arquivo de importação.",
|
||||
"discoveredContacts_importFailed": "Falha ao importar contatos descobertos: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -1064,6 +1064,41 @@
|
|||
"discoveredContacts_addContact": "Добавить контакт",
|
||||
"discoveredContacts_Title": "Обнаруженные контакты",
|
||||
"discoveredContacts_deleteContact": "Удалить контакт",
|
||||
"discoveredContacts_export": "Экспортировать обнаруженные контакты",
|
||||
"discoveredContacts_import": "Импортировать обнаруженные контакты",
|
||||
"discoveredContacts_exported": "Обнаруженные контакты экспортированы в {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Не удалось экспортировать обнаруженные контакты: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Импортировано {count} обнаруженных контактов.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "В файле импорта не найдены контакты.",
|
||||
"discoveredContacts_importFailed": "Не удалось импортировать обнаруженные контакты: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactsSettings_overwriteOldestSubtitle": "Когда список контактов заполнен, будет заменен самый старый контакт, который не находится в избранном.",
|
||||
"common_deleteAll": "Удалить все",
|
||||
"discoveredContacts_deleteContactAllContent": "Вы уверены, что хотите удалить все обнаруженные контакты?",
|
||||
|
|
@ -1302,12 +1337,6 @@
|
|||
"scanner_linuxPairingPinTitle": "PIN‑код сопряжения Bluetooth",
|
||||
"repeater_cliQuickDiscovery": "Обнаружить Соседей",
|
||||
"repeater_cliQuickClockSync": "Синхронизация часов",
|
||||
"@repeater_clockSyncAfterLogin": {
|
||||
"description": "Repeater setting: auto sync device clock after successful login"
|
||||
},
|
||||
"@repeater_clockSyncAfterLoginSubtitle": {
|
||||
"description": "Repeater setting subtitle: describes the clock sync after login behavior"
|
||||
},
|
||||
"repeater_clockSyncAfterLogin": "Синхронизация часов после входа в систему",
|
||||
"repeater_clockSyncAfterLoginSubtitle": "Автоматически отправлять сообщение \"синхронизация времени\" после успешной авторизации.",
|
||||
"chat_sendMessage": "Отправить сообщение",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_Title": "Objavené kontakty",
|
||||
"contactsSettings_overwriteOldestTitle": "Prepísať najstaršie",
|
||||
"discoveredContacts_addContact": "Pridať kontakt",
|
||||
"discoveredContacts_export": "Exportovať objavené kontakty",
|
||||
"discoveredContacts_import": "Importovať objavené kontakty",
|
||||
"discoveredContacts_exported": "Objavené kontakty boli exportované do {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Export objavených kontaktov zlyhal: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Bolo importovaných {count} objavených kontaktov.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "V importovanom súbore sa nenašli žiadne kontakty.",
|
||||
"discoveredContacts_importFailed": "Import objavených kontaktov zlyhal: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_Title": "Odkriti stiki",
|
||||
"discoveredContacts_searchHint": "Najdeni stiki po iskanju",
|
||||
"discoveredContacts_deleteContact": "Izbriši stik",
|
||||
"discoveredContacts_export": "Izvozi odkrite stike",
|
||||
"discoveredContacts_import": "Uvozi odkrite stike",
|
||||
"discoveredContacts_exported": "Odkriti stiki so izvoženi v {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Izvoz odkritih stikov ni uspel: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Uvoženih je bilo {count} odkritih stikov.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "V uvozni datoteki ni bilo najdenih stikov.",
|
||||
"discoveredContacts_importFailed": "Uvoz odkritih stikov ni uspel: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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?",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_contactAdded": "Kontakt tillagd",
|
||||
"discoveredContacts_addContact": "Lägg till kontakt",
|
||||
"discoveredContacts_copyContact": "Kopiera kontakt till urklipp",
|
||||
"discoveredContacts_export": "Exportera upptäckta kontakter",
|
||||
"discoveredContacts_import": "Importera upptäckta kontakter",
|
||||
"discoveredContacts_exported": "Upptäckta kontakter exporterades till {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Det gick inte att exportera upptäckta kontakter: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Importerade {count} upptäckta kontakter.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "Inga kontakter hittades i importfilen.",
|
||||
"discoveredContacts_importFailed": "Det gick inte att importera upptäckta kontakter: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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?",
|
||||
|
|
@ -2062,12 +2097,6 @@
|
|||
"scanner_linuxPairingHidePin": "Dölj PIN",
|
||||
"repeater_cliQuickDiscovery": "Upptäck grannar",
|
||||
"repeater_cliQuickClockSync": "Synkronisera klocka",
|
||||
"@repeater_clockSyncAfterLogin": {
|
||||
"description": "Repeater setting: auto sync device clock after successful login"
|
||||
},
|
||||
"@repeater_clockSyncAfterLoginSubtitle": {
|
||||
"description": "Repeater setting subtitle: describes the clock sync after login behavior"
|
||||
},
|
||||
"repeater_clockSyncAfterLoginSubtitle": "Automatiskt skicka \"klocksynkronisering\" efter en lyckad inloggning.",
|
||||
"repeater_clockSyncAfterLogin": "Synkronisera klockan efter inloggning",
|
||||
"repeater_guest": "Information om repetorer",
|
||||
|
|
|
|||
|
|
@ -1824,6 +1824,41 @@
|
|||
"discoveredContacts_deleteContact": "Видалити контакт",
|
||||
"discoveredContacts_copyContact": "Копіювати контакт у буфер обміну",
|
||||
"discoveredContacts_addContact": "Додати контакт",
|
||||
"discoveredContacts_export": "Експортувати виявлені контакти",
|
||||
"discoveredContacts_import": "Імпортувати виявлені контакти",
|
||||
"discoveredContacts_exported": "Виявлені контакти експортовано до {path}.",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "Не вдалося експортувати виявлені контакти: {error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "Імпортовано {count} виявлених контактів.",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "У файлі імпорту не знайдено контактів.",
|
||||
"discoveredContacts_importFailed": "Не вдалося імпортувати виявлені контакти: {error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactsSettings_overwriteOldestSubtitle": "Коли список контактів заповнений, найстарший контакт без позначки улюбленого буде замінений.",
|
||||
"common_deleteAll": "Видалити все",
|
||||
"discoveredContacts_deleteContactAll": "Видалити всі виявлені контакти",
|
||||
|
|
@ -2062,12 +2097,6 @@
|
|||
"scanner_linuxPairingHidePin": "Приховати PIN",
|
||||
"repeater_cliQuickClockSync": "Синхронізація годинника",
|
||||
"repeater_cliQuickDiscovery": "Відкрити сусідів",
|
||||
"@repeater_clockSyncAfterLogin": {
|
||||
"description": "Repeater setting: auto sync device clock after successful login"
|
||||
},
|
||||
"@repeater_clockSyncAfterLoginSubtitle": {
|
||||
"description": "Repeater setting subtitle: describes the clock sync after login behavior"
|
||||
},
|
||||
"repeater_clockSyncAfterLoginSubtitle": "Автоматично надсилати повідомлення \"синхронізація годин\" після успішного входу.",
|
||||
"repeater_clockSyncAfterLogin": "Синхронізація годин після входу",
|
||||
"repeater_guestTools": "Інструменти для гостей",
|
||||
|
|
|
|||
|
|
@ -1829,6 +1829,41 @@
|
|||
"discoveredContacts_noMatching": "没有匹配的联系人",
|
||||
"discoveredContacts_Title": "已发现的联系人",
|
||||
"discoveredContacts_copyContact": "复制联系人到剪贴板",
|
||||
"discoveredContacts_export": "导出已发现的联系人",
|
||||
"discoveredContacts_import": "导入已发现的联系人",
|
||||
"discoveredContacts_exported": "已将已发现的联系人导出到{path}。",
|
||||
"@discoveredContacts_exported": {
|
||||
"placeholders": {
|
||||
"path": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_exportFailed": "导出已发现的联系人失败:{error}",
|
||||
"@discoveredContacts_exportFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_imported": "已导入{count}个已发现的联系人。",
|
||||
"@discoveredContacts_imported": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"discoveredContacts_importNoContacts": "在导入文件中未找到联系人。",
|
||||
"discoveredContacts_importFailed": "导入已发现的联系人失败:{error}",
|
||||
"@discoveredContacts_importFailed": {
|
||||
"placeholders": {
|
||||
"error": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactsSettings_overwriteOldestSubtitle": "当联系人列表已满时,将替换最老的非收藏联系人。",
|
||||
"common_deleteAll": "删除全部",
|
||||
"discoveredContacts_deleteContactAllContent": "您确定要删除所有发现的联系人吗?",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ class Contact {
|
|||
final DateTime lastSeen;
|
||||
final DateTime lastMessageAt;
|
||||
final bool isActive;
|
||||
final bool wasPulled;
|
||||
final Uint8List? rawPacket;
|
||||
|
||||
Contact({
|
||||
|
|
@ -35,7 +34,6 @@ class Contact {
|
|||
required this.lastSeen,
|
||||
DateTime? lastMessageAt,
|
||||
this.isActive = true,
|
||||
this.wasPulled = false,
|
||||
this.rawPacket,
|
||||
}) : lastMessageAt = lastMessageAt ?? lastSeen;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
import '../connector/meshcore_connector.dart';
|
||||
import '../connector/meshcore_protocol.dart';
|
||||
|
|
@ -66,9 +71,44 @@ class _DiscoveryScreenState extends State<DiscoveryScreen> {
|
|||
),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
PopupMenuButton(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) {
|
||||
switch (value) {
|
||||
case 'export':
|
||||
unawaited(_exportDiscoveredContacts(context, connector));
|
||||
break;
|
||||
case 'import':
|
||||
unawaited(_importDiscoveredContacts(context, connector));
|
||||
break;
|
||||
case 'delete_all':
|
||||
_deleteContacts(context, connector);
|
||||
break;
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => <PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'export',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.upload_file),
|
||||
const SizedBox(width: 8),
|
||||
Text(l10n.discoveredContacts_export),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'import',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.download),
|
||||
const SizedBox(width: 8),
|
||||
Text(l10n.discoveredContacts_import),
|
||||
],
|
||||
),
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
PopupMenuItem<String>(
|
||||
value: 'delete_all',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.delete, color: Colors.red),
|
||||
|
|
@ -76,9 +116,6 @@ class _DiscoveryScreenState extends State<DiscoveryScreen> {
|
|||
Text(context.l10n.discoveredContacts_deleteContactAll),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
_deleteContacts(context, connector);
|
||||
},
|
||||
),
|
||||
],
|
||||
icon: const Icon(Icons.more_vert),
|
||||
|
|
@ -270,6 +307,144 @@ class _DiscoveryScreenState extends State<DiscoveryScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _exportDiscoveredContacts(
|
||||
BuildContext context,
|
||||
MeshCoreConnector connector,
|
||||
) async {
|
||||
final l10n = context.l10n;
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final json = connector.exportDiscoveredContactsJson();
|
||||
|
||||
try {
|
||||
const filename = 'meshcore_discovered_contacts.json';
|
||||
final bytes = Uint8List.fromList(utf8.encode(json));
|
||||
|
||||
if (PlatformInfo.isDesktop) {
|
||||
final location = await getSaveLocation(
|
||||
suggestedName: filename,
|
||||
acceptedTypeGroups: [
|
||||
const XTypeGroup(label: 'JSON', extensions: ['json']),
|
||||
],
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (location == null) return;
|
||||
final exportFile = XFile.fromData(
|
||||
bytes,
|
||||
mimeType: 'application/json',
|
||||
name: filename,
|
||||
);
|
||||
await exportFile.saveTo(location.path);
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(l10n.discoveredContacts_exported(location.path)),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final exportPath = '${tempDir.path}/$filename';
|
||||
final exportFile = File(exportPath);
|
||||
await exportFile.writeAsBytes(bytes, flush: true);
|
||||
|
||||
try {
|
||||
final result = await SharePlus.instance.share(
|
||||
ShareParams(subject: filename, files: [XFile(exportPath)]),
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
if (result.status == ShareResultStatus.success) {
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text(l10n.discoveredContacts_exported(filename))),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (await exportFile.exists()) {
|
||||
await exportFile.delete();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(l10n.discoveredContacts_exportFailed(e.toString())),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _importDiscoveredContacts(
|
||||
BuildContext context,
|
||||
MeshCoreConnector connector,
|
||||
) async {
|
||||
final l10n = context.l10n;
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
try {
|
||||
final json = await _resolveImportJson(context);
|
||||
if (json == null) {
|
||||
// User cancelled the file picker — nothing to do.
|
||||
return;
|
||||
}
|
||||
final foundCount = _countContactsInImportJson(json);
|
||||
if (foundCount == 0) {
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text(l10n.discoveredContacts_importNoContacts)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final importedCount = await connector.importDiscoveredContactsJson(json);
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(l10n.discoveredContacts_imported(importedCount)),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
messenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(l10n.discoveredContacts_importFailed(e.toString())),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> _resolveImportJson(BuildContext context) async {
|
||||
final file = await openFile(
|
||||
acceptedTypeGroups: [
|
||||
const XTypeGroup(label: 'JSON', extensions: ['json']),
|
||||
],
|
||||
);
|
||||
if (file == null) return null;
|
||||
final bytes = await file.readAsBytes();
|
||||
|
||||
if (bytes.isEmpty) return '';
|
||||
|
||||
// Try UTF-8 first (handles BOM automatically)
|
||||
try {
|
||||
final text = utf8.decode(bytes, allowMalformed: true);
|
||||
// Remove BOM if present
|
||||
return text.startsWith('\ufeff') ? text.substring(1) : text;
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
int _countContactsInImportJson(String json) {
|
||||
try {
|
||||
final decoded = jsonDecode(json);
|
||||
if (decoded is List) {
|
||||
return decoded.length;
|
||||
}
|
||||
return 0;
|
||||
} catch (_) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildFilters(
|
||||
List<Contact> filteredAndSorted,
|
||||
MeshCoreConnector connector,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,55 @@ class ContactDiscoveryStore {
|
|||
await prefs.setString(_keyPrefix, jsonEncode(jsonList));
|
||||
}
|
||||
|
||||
String exportContactsJson(List<Contact> contacts) {
|
||||
final jsonList = contacts.map(_toJson).toList();
|
||||
return jsonEncode(jsonList);
|
||||
}
|
||||
|
||||
int importContactsJson({
|
||||
required String json,
|
||||
required List<Contact> existingContacts,
|
||||
required Set<String> knownContactKeys,
|
||||
}) {
|
||||
try {
|
||||
final jsonList = jsonDecode(json) as List<dynamic>;
|
||||
final importedContacts = jsonList
|
||||
.map((entry) => _fromJson(entry as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
int newCount = 0;
|
||||
|
||||
// Create a set of existing discovered contact keys for deduplication
|
||||
final existingKeySet = <String>{};
|
||||
for (final contact in existingContacts) {
|
||||
existingKeySet.add(contact.publicKeyHex);
|
||||
}
|
||||
|
||||
// Process imported contacts
|
||||
for (final imported in importedContacts) {
|
||||
final keyHex = imported.publicKeyHex;
|
||||
|
||||
// Skip if already in device's contact list
|
||||
if (knownContactKeys.contains(keyHex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if already in discovered contacts (existing is always fresher)
|
||||
if (existingKeySet.contains(keyHex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add as new discovered contact
|
||||
existingContacts.add(imported);
|
||||
newCount++;
|
||||
}
|
||||
|
||||
return newCount;
|
||||
} catch (_) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _toJson(Contact contact) {
|
||||
return {
|
||||
'publicKey': base64Encode(contact.publicKey),
|
||||
|
|
@ -44,6 +93,7 @@ class ContactDiscoveryStore {
|
|||
'longitude': contact.longitude,
|
||||
'lastSeen': contact.lastSeen.millisecondsSinceEpoch,
|
||||
'lastMessageAt': contact.lastMessageAt.millisecondsSinceEpoch,
|
||||
'isActive': contact.isActive,
|
||||
'rawPacket': contact.rawPacket != null
|
||||
? base64Encode(contact.rawPacket!)
|
||||
: null,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ dependencies:
|
|||
gpx: ^2.3.0
|
||||
path_provider: ^2.1.5
|
||||
share_plus: ^12.0.1
|
||||
file_selector: ^1.0.3
|
||||
build_pipe: ^0.3.1
|
||||
material_symbols_icons: ^4.2906.0
|
||||
web: ^1.1.1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue