ab: sync all recent peers if option enabled
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
29c661d919
commit
553a3798a1
@ -1,9 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/common/widgets/dialog.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/models/ab_model.dart';
|
||||
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -707,6 +709,11 @@ abstract class BasePeerCard extends StatelessWidget {
|
||||
case PeerTabIndex.ab:
|
||||
gFFI.abModel.deletePeer(id);
|
||||
await gFFI.abModel.pushAb();
|
||||
if (shouldSyncAb() && await bind.mainPeerExists(id: peer.id)) {
|
||||
BotToast.showText(
|
||||
contentColor: Colors.lightBlue,
|
||||
text: translate('synced_peer_readded_tip'));
|
||||
}
|
||||
break;
|
||||
case PeerTabIndex.group:
|
||||
break;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/common/widgets/address_book.dart';
|
||||
import 'package:flutter_hbb/common/widgets/dialog.dart';
|
||||
@ -7,6 +8,7 @@ import 'package:flutter_hbb/common/widgets/peer_card.dart';
|
||||
import 'package:flutter_hbb/common/widgets/animated_rotation_widget.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/popup_menu.dart';
|
||||
import 'package:flutter_hbb/models/ab_model.dart';
|
||||
|
||||
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
||||
import 'package:get/get.dart';
|
||||
@ -122,12 +124,11 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
borderRadius: BorderRadius.circular(6)),
|
||||
child: Tooltip(
|
||||
message: translate('Toggle Tags'),
|
||||
child: Icon(
|
||||
Icons.tag_rounded,
|
||||
size: 18,
|
||||
))
|
||||
)),
|
||||
message: translate('Toggle Tags'),
|
||||
child: Icon(
|
||||
Icons.tag_rounded,
|
||||
size: 18,
|
||||
)))),
|
||||
onTap: () async {
|
||||
await bind.mainSetLocalOption(
|
||||
key: "hideAbTagsPanel",
|
||||
@ -221,13 +222,12 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
child: RotatedBox(
|
||||
quarterTurns: 2,
|
||||
child: Tooltip(
|
||||
message: translate('Refresh'),
|
||||
child: Icon(
|
||||
Icons.refresh,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
))
|
||||
)),
|
||||
message: translate('Refresh'),
|
||||
child: Icon(
|
||||
Icons.refresh,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
)))),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -243,29 +243,28 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
|
||||
return Obx(
|
||||
() => Container(
|
||||
padding: EdgeInsets.all(4.0),
|
||||
decoration: hover.value ? deco : null,
|
||||
child: InkWell(
|
||||
onHover: (value) => hover.value = value,
|
||||
onTap: () async {
|
||||
final type = types.elementAt(
|
||||
peerCardUiType.value == types.elementAt(0) ? 1 : 0);
|
||||
await bind.setLocalFlutterOption(
|
||||
k: 'peer-card-ui-type', v: type.index.toString());
|
||||
peerCardUiType.value = type;
|
||||
},
|
||||
child: Tooltip(
|
||||
message: peerCardUiType.value == PeerUiType.grid
|
||||
? translate('List View')
|
||||
: translate('Grid View'),
|
||||
child: Icon(
|
||||
peerCardUiType.value == PeerUiType.grid
|
||||
? Icons.view_list_rounded
|
||||
: Icons.grid_view_rounded,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
))
|
||||
)),
|
||||
padding: EdgeInsets.all(4.0),
|
||||
decoration: hover.value ? deco : null,
|
||||
child: InkWell(
|
||||
onHover: (value) => hover.value = value,
|
||||
onTap: () async {
|
||||
final type = types.elementAt(
|
||||
peerCardUiType.value == types.elementAt(0) ? 1 : 0);
|
||||
await bind.setLocalFlutterOption(
|
||||
k: 'peer-card-ui-type', v: type.index.toString());
|
||||
peerCardUiType.value = type;
|
||||
},
|
||||
child: Tooltip(
|
||||
message: peerCardUiType.value == PeerUiType.grid
|
||||
? translate('List View')
|
||||
: translate('Grid View'),
|
||||
child: Icon(
|
||||
peerCardUiType.value == PeerUiType.grid
|
||||
? Icons.view_list_rounded
|
||||
: Icons.grid_view_rounded,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
)))),
|
||||
);
|
||||
}
|
||||
|
||||
@ -280,12 +279,12 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
model.setMultiSelectionMode(true);
|
||||
},
|
||||
child: Tooltip(
|
||||
message: translate('Select'),
|
||||
child: Icon(
|
||||
IconFont.checkbox,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
)),
|
||||
message: translate('Select'),
|
||||
child: Icon(
|
||||
IconFont.checkbox,
|
||||
size: 18,
|
||||
color: textColor,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -334,8 +333,25 @@ class _PeerTabPageState extends State<PeerTabPage>
|
||||
await bind.mainLoadLanPeers();
|
||||
break;
|
||||
case 3:
|
||||
gFFI.abModel.deletePeers(peers.map((p) => p.id).toList());
|
||||
await gFFI.abModel.pushAb();
|
||||
{
|
||||
bool hasSynced = false;
|
||||
if (shouldSyncAb()) {
|
||||
for (var p in peers) {
|
||||
if (await bind.mainPeerExists(id: p.id)) {
|
||||
hasSynced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
gFFI.abModel.deletePeers(peers.map((p) => p.id).toList());
|
||||
await gFFI.abModel.pushAb();
|
||||
if (hasSynced) {
|
||||
Future.delayed(Duration(seconds: 2), () {
|
||||
BotToast.showText(
|
||||
contentColor: Colors.lightBlue,
|
||||
text: translate('synced_peer_readded_tip'));
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -483,8 +499,7 @@ class _PeerSearchBarState extends State<PeerSearchBar> {
|
||||
child: Icon(
|
||||
Icons.search_rounded,
|
||||
color: Theme.of(context).hintColor,
|
||||
))
|
||||
);
|
||||
)));
|
||||
}
|
||||
|
||||
Widget _buildSearchBar() {
|
||||
@ -543,22 +558,21 @@ class _PeerSearchBarState extends State<PeerSearchBar> {
|
||||
),
|
||||
// Icon(Icons.close),
|
||||
IconButton(
|
||||
alignment: Alignment.centerRight,
|
||||
padding: const EdgeInsets.only(right: 2),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
peerSearchTextController.clear();
|
||||
peerSearchText.value = "";
|
||||
drawer = false;
|
||||
});
|
||||
},
|
||||
icon: Tooltip(
|
||||
message: translate('Close'),
|
||||
child:
|
||||
Icon(
|
||||
Icons.close,
|
||||
color: Theme.of(context).hintColor,
|
||||
)),
|
||||
alignment: Alignment.centerRight,
|
||||
padding: const EdgeInsets.only(right: 2),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
peerSearchTextController.clear();
|
||||
peerSearchText.value = "";
|
||||
drawer = false;
|
||||
});
|
||||
},
|
||||
icon: Tooltip(
|
||||
message: translate('Close'),
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
color: Theme.of(context).hintColor,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -628,7 +642,7 @@ class _PeerSortDropdownState extends State<PeerSortDropdown> {
|
||||
child: Icon(
|
||||
Icons.sort_rounded,
|
||||
size: 18,
|
||||
)),
|
||||
)),
|
||||
onTapDown: (details) {
|
||||
final x = details.globalPosition.dx;
|
||||
final y = details.globalPosition.dy;
|
||||
|
@ -344,33 +344,28 @@ class AbModel {
|
||||
}
|
||||
|
||||
Future<void> _syncFromRecentWithoutLock({bool push = true}) async {
|
||||
bool shouldSync(Peer a, Peer b) {
|
||||
return a.hash != b.hash ||
|
||||
a.username != b.username ||
|
||||
a.platform != b.platform ||
|
||||
a.hostname != b.hostname ||
|
||||
a.alias != b.alias;
|
||||
bool shouldSync(Peer r, Peer p) {
|
||||
return r.hash != p.hash ||
|
||||
r.username != p.username ||
|
||||
r.platform != p.platform ||
|
||||
r.hostname != p.hostname ||
|
||||
(p.alias.isEmpty && r.alias.isNotEmpty);
|
||||
}
|
||||
|
||||
Future<List<Peer>> getRecentPeers() async {
|
||||
try {
|
||||
if (peers.isEmpty) [];
|
||||
List<String> filteredPeerIDs;
|
||||
if (_syncAllFromRecent) {
|
||||
_syncAllFromRecent = false;
|
||||
filteredPeerIDs = peers.map((e) => e.id).toList();
|
||||
filteredPeerIDs = [];
|
||||
} else {
|
||||
final new_stored_str = await bind.mainGetNewStoredPeers();
|
||||
if (new_stored_str.isEmpty) return [];
|
||||
List<String> new_stores =
|
||||
(jsonDecode(new_stored_str) as List<dynamic>)
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
final abPeerIds = peers.map((e) => e.id).toList();
|
||||
filteredPeerIDs =
|
||||
new_stores.where((e) => abPeerIds.contains(e)).toList();
|
||||
filteredPeerIDs = (jsonDecode(new_stored_str) as List<dynamic>)
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
if (filteredPeerIDs.isEmpty) return [];
|
||||
}
|
||||
if (filteredPeerIDs.isEmpty) return [];
|
||||
final loadStr = await bind.mainLoadRecentPeersForAb(
|
||||
filter: jsonEncode(filteredPeerIDs));
|
||||
if (loadStr.isEmpty) {
|
||||
@ -392,28 +387,32 @@ class AbModel {
|
||||
|
||||
try {
|
||||
if (!shouldSyncAb()) return;
|
||||
final oldPeers = peers.toList();
|
||||
final recents = await getRecentPeers();
|
||||
if (recents.isEmpty) return;
|
||||
for (var i = 0; i < peers.length; i++) {
|
||||
var p = peers[i];
|
||||
var r = recents.firstWhereOrNull((r) => p.id == r.id);
|
||||
if (r != null) {
|
||||
peers[i] = merge(r, p);
|
||||
}
|
||||
}
|
||||
bool changed = false;
|
||||
for (var i = 0; i < peers.length; i++) {
|
||||
final o = oldPeers[i];
|
||||
final p = peers[i];
|
||||
if (shouldSync(o, p)) {
|
||||
changed = true;
|
||||
break;
|
||||
bool syncChanged = false;
|
||||
bool uiChanged = false;
|
||||
for (var i = 0; i < recents.length; i++) {
|
||||
var r = recents[i];
|
||||
var index = peers.indexWhere((e) => e.id == r.id);
|
||||
if (index < 0) {
|
||||
peers.add(r);
|
||||
syncChanged = true;
|
||||
uiChanged = true;
|
||||
} else {
|
||||
if (!r.equal(peers[index])) {
|
||||
uiChanged = true;
|
||||
}
|
||||
if (shouldSync(r, peers[index])) {
|
||||
syncChanged = true;
|
||||
}
|
||||
peers[index] = merge(r, peers[index]);
|
||||
}
|
||||
}
|
||||
// Be careful with loop calls
|
||||
if (changed && push) {
|
||||
if (syncChanged && push) {
|
||||
pushAb();
|
||||
} else if (uiChanged) {
|
||||
peers.refresh();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('syncFromRecent:$e');
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'platform_model.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class Peer {
|
||||
final String id;
|
||||
@ -87,6 +89,18 @@ class Peer {
|
||||
rdpPort: '',
|
||||
rdpUsername: '',
|
||||
);
|
||||
bool equal(Peer other) {
|
||||
return id == other.id &&
|
||||
hash == other.hash &&
|
||||
username == other.username &&
|
||||
hostname == other.hostname &&
|
||||
platform == other.platform &&
|
||||
alias == other.alias &&
|
||||
tags.equals(other.tags) &&
|
||||
forceAlwaysRelay == other.forceAlwaysRelay &&
|
||||
rdpPort == other.rdpPort &&
|
||||
rdpUsername == other.rdpUsername;
|
||||
}
|
||||
}
|
||||
|
||||
enum UpdateEvent { online, load }
|
||||
|
@ -1079,6 +1079,10 @@ impl PeerConfig {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn exists(id: &str) -> bool {
|
||||
Self::path(id).exists()
|
||||
}
|
||||
|
||||
serde_field_string!(
|
||||
default_view_style,
|
||||
deserialize_view_style,
|
||||
|
@ -841,6 +841,10 @@ pub fn main_peer_has_password(id: String) -> bool {
|
||||
peer_has_password(id)
|
||||
}
|
||||
|
||||
pub fn main_peer_exists(id: String) -> bool {
|
||||
peer_exists(&id)
|
||||
}
|
||||
|
||||
pub fn main_load_recent_peers() {
|
||||
if !config::APP_DIR.read().unwrap().is_empty() {
|
||||
let peers: Vec<HashMap<&str, String>> = PeerConfig::peers(None)
|
||||
@ -883,8 +887,13 @@ pub fn main_load_recent_peers_sync() -> SyncReturn<String> {
|
||||
|
||||
pub fn main_load_recent_peers_for_ab(filter: String) -> String {
|
||||
let id_filters = serde_json::from_str::<Vec<String>>(&filter).unwrap_or_default();
|
||||
let id_filters = if id_filters.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(id_filters)
|
||||
};
|
||||
if !config::APP_DIR.read().unwrap().is_empty() {
|
||||
let peers: Vec<HashMap<&str, String>> = PeerConfig::peers(Some(id_filters))
|
||||
let peers: Vec<HashMap<&str, String>> = PeerConfig::peers(id_filters)
|
||||
.drain(..)
|
||||
.map(|(id, _, p)| peer_to_map_ab(id, p))
|
||||
.collect();
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", "未成功获取地址簿"),
|
||||
("push_ab_failed_tip", "未成功上传地址簿"),
|
||||
("synced_peer_readded_tip", "最近会话中存在的设备将会被重新添加到地址簿。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", "Tags umschalten"),
|
||||
("pull_ab_failed_tip", "Aktualisierung des Adressbuchs fehlgeschlagen"),
|
||||
("push_ab_failed_tip", "Synchronisierung des Adressbuchs mit dem Server fehlgeschlagen"),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -76,5 +76,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("exceed_max_devices", "You have reached the maximum number of managed devices."),
|
||||
("pull_ab_failed_tip", "Failed to refresh address book"),
|
||||
("push_ab_failed_tip", "Failed to sync address book to server"),
|
||||
("synced_peer_readded_tip", "The devices present in the recent sessions will be re-added to the address book."),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", "Alternar Etiquetas"),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", "Attiva/disattiva tag"),
|
||||
("pull_ab_failed_tip", "Impossibile aggiornare la rubrica"),
|
||||
("push_ab_failed_tip", "Impossibile sincronizzare la rubrica con il server"),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", "Переключить метки"),
|
||||
("pull_ab_failed_tip", "Невозможно обновить адресную книгу"),
|
||||
("push_ab_failed_tip", "Невозможно синхронизировать адресную книгу с сервером"),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", "未成功獲取地址簿"),
|
||||
("push_ab_failed_tip", "未成功上傳地址簿"),
|
||||
("synced_peer_readded_tip", "最近會話中存在的設備將會被重新添加到地址簿。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -537,5 +537,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Toggle Tags", ""),
|
||||
("pull_ab_failed_tip", ""),
|
||||
("push_ab_failed_tip", ""),
|
||||
("synced_peer_readded_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -648,6 +648,11 @@ pub fn peer_to_map_ab(id: String, p: PeerConfig) -> HashMap<&'static str, String
|
||||
m
|
||||
}
|
||||
|
||||
#[cfg(feature = "flutter")]
|
||||
pub fn peer_exists(id: &str) -> bool {
|
||||
PeerConfig::exists(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_lan_peers() -> Vec<HashMap<&'static str, String>> {
|
||||
config::LanPeers::load()
|
||||
|
Loading…
x
Reference in New Issue
Block a user