From 27695d372a548dd5214fffb8a15c7ed5aaa4c37d Mon Sep 17 00:00:00 2001 From: HDDen <62592944+HDDen@users.noreply.github.com> Date: Fri, 12 Jun 2026 14:44:09 +0300 Subject: [PATCH] Updated to last dev --- lib/connector/meshcore_connector.dart | 14 +++++--------- lib/l10n/contact_localization.dart | 23 +++++++++++++++++++--- lib/screens/channels_screen.dart | 2 +- lib/screens/chat_screen.dart | 28 ++++++++++++++++++++++++--- lib/screens/contacts_screen.dart | 5 ++++- lib/screens/map_screen.dart | 8 +------- lib/widgets/path_editor_sheet.dart | 21 +++++++++++--------- lib/widgets/routing_sheet.dart | 8 +++++++- 8 files changed, 75 insertions(+), 34 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index bb9c5370..d9b86cb4 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -3208,10 +3208,7 @@ class MeshCoreConnector extends ChangeNotifier { if (pathLen != null && pathLen >= 0 && - !_isPathLenValidForCurrentMode( - pathLen, - pathBytes ?? Uint8List(0), - )) { + !_isPathLenValidForCurrentMode(pathLen, pathBytes ?? Uint8List(0))) { appLogger.warn( 'setPathOverride: invalid path for ${contact.name}: ' 'pathLen=$pathLen, bytesLen=${pathBytes?.length ?? 0}, ' @@ -6694,13 +6691,12 @@ class MeshCoreConnector extends ChangeNotifier { return; } final pathStartIndex = path.isNotEmpty ? path.length - hashWidth : 0; - final publicKeyPrefixEnd = math.min(hashWidth, contact.publicKey.length).toInt(); + final publicKeyPrefixEnd = math + .min(hashWidth, contact.publicKey.length) + .toInt(); final pubkeyPrefix = path.isNotEmpty ? path.sublist(pathStartIndex) - : contact.publicKey.sublist( - 0, - publicKeyPrefixEnd, - ); + : contact.publicKey.sublist(0, publicKeyPrefixEnd); final contactKeyHex = _resolveDirectRepeaterContactKeyHex( contact, pubkeyPrefix, diff --git a/lib/l10n/contact_localization.dart b/lib/l10n/contact_localization.dart index d8344a32..4f21c585 100644 --- a/lib/l10n/contact_localization.dart +++ b/lib/l10n/contact_localization.dart @@ -1,4 +1,5 @@ import '../connector/meshcore_protocol.dart'; +import '../helpers/path_helper.dart'; import '../models/contact.dart'; import 'app_localizations.dart'; @@ -23,14 +24,30 @@ extension ContactLocalization on Contact { } } - String pathLabel(AppLocalizations l10n) { + String pathLabel( + AppLocalizations l10n, { + int pathHashByteWidth = pathHashSize, + }) { if (pathOverride != null) { if (pathOverride! < 0) return l10n.chat_floodForced; if (pathOverride == 0) return l10n.chat_directForced; - return l10n.chat_hopsForced(pathOverride!); + return l10n.chat_hopsForced( + _displayHopCount(pathOverrideBytes, pathOverride!, pathHashByteWidth), + ); } if (pathLength < 0) return l10n.channelPath_floodPath; if (pathLength == 0) return l10n.chat_direct; - return l10n.chat_hopsCount(pathLength); + return l10n.chat_hopsCount( + _displayHopCount(path, pathLength, pathHashByteWidth), + ); + } + + int _displayHopCount( + List? pathBytes, + int storedHopCount, + int hashWidth, + ) { + if (pathBytes == null || pathBytes.isEmpty) return storedHopCount; + return PathHelper.splitPathBytes(pathBytes, hashWidth).length; } } diff --git a/lib/screens/channels_screen.dart b/lib/screens/channels_screen.dart index cbb3cfaf..96b154ac 100644 --- a/lib/screens/channels_screen.dart +++ b/lib/screens/channels_screen.dart @@ -271,7 +271,7 @@ class _ChannelsScreenState extends State ), buildDefaultDragHandles: false, itemCount: filteredChannels.length, - onReorder: (oldIndex, newIndex) { + onReorderItem: (oldIndex, newIndex) { final reordered = List.from( filteredChannels, ); diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart index 89310bbd..cdb108a8 100644 --- a/lib/screens/chat_screen.dart +++ b/lib/screens/chat_screen.dart @@ -12,6 +12,7 @@ import '../utils/platform_info.dart'; import '../connector/meshcore_connector.dart'; import '../connector/meshcore_protocol.dart'; import '../helpers/cyr2lat.dart'; +import '../helpers/path_helper.dart'; import '../helpers/reaction_helper.dart'; import '../widgets/message_status_icon.dart'; import '../widgets/empty_state.dart'; @@ -727,17 +728,35 @@ class _ChatScreenState extends State { } String _currentPathLabel(Contact contact) { + final connector = context.read(); + // Check if user has set a path override if (contact.pathOverride != null) { if (contact.pathOverride! < 0) return context.l10n.chat_floodForced; if (contact.pathOverride == 0) return context.l10n.chat_directForced; - return context.l10n.chat_hopsForced(contact.pathOverride!); + final bytes = contact.pathOverrideBytes ?? Uint8List(0); + final hopCount = _displayHopCount( + bytes, + contact.pathOverride!, + connector.pathHashByteWidth, + ); + return context.l10n.chat_hopsForced(hopCount); } // Use device's path if (contact.pathLength < 0) return context.l10n.chat_floodAuto; if (contact.pathLength == 0) return context.l10n.chat_direct; - return context.l10n.chat_hopsCount(contact.pathLength); + final hopCount = _displayHopCount( + contact.path, + contact.pathLength, + connector.pathHashByteWidth, + ); + return context.l10n.chat_hopsCount(hopCount); + } + + int _displayHopCount(List pathBytes, int storedHopCount, int hashWidth) { + if (pathBytes.isEmpty) return storedHopCount; + return PathHelper.splitPathBytes(pathBytes, hashWidth).length; } void _showContactInfo(BuildContext context) { @@ -758,7 +777,10 @@ class _ChatScreenState extends State { ), _buildInfoRow( context.l10n.chat_path, - contact.pathLabel(context.l10n), + contact.pathLabel( + context.l10n, + pathHashByteWidth: connector.pathHashByteWidth, + ), ), _buildInfoRow( context.l10n.contact_lastSeen, diff --git a/lib/screens/contacts_screen.dart b/lib/screens/contacts_screen.dart index fedc428a..0431baae 100644 --- a/lib/screens/contacts_screen.dart +++ b/lib/screens/contacts_screen.dart @@ -911,6 +911,7 @@ class _ContactsScreenState extends State ); return _ContactTile( contact: contact, + pathHashByteWidth: connector.pathHashByteWidth, lastSeen: _resolveLastSeen(contact), unreadCount: unreadCount, isFavorite: contact.isFavorite, @@ -1553,6 +1554,7 @@ class _ContactsScreenState extends State class _ContactTile extends StatelessWidget { final Contact contact; + final int pathHashByteWidth; final DateTime lastSeen; final int unreadCount; final bool isFavorite; @@ -1561,6 +1563,7 @@ class _ContactTile extends StatelessWidget { const _ContactTile({ required this.contact, + required this.pathHashByteWidth, required this.lastSeen, required this.unreadCount, required this.isFavorite, @@ -1579,7 +1582,7 @@ class _ContactTile extends StatelessWidget { ), title: Text(contact.name, maxLines: 1, overflow: TextOverflow.ellipsis), subtitle: Text( - contact.pathLabel(context.l10n), + contact.pathLabel(context.l10n, pathHashByteWidth: pathHashByteWidth), maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 044f2183..3c717f94 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -2468,10 +2468,7 @@ class _MapScreenState extends State { builder: (context) => PathTraceMapScreen( title: l10n.contacts_pathTrace, path: Uint8List.fromList(_pathTrace), - flipPathAround: true, - targetContact: _pathTraceContacts.isNotEmpty - ? _pathTraceContacts.last - : null, + flipPathAround: false, pathHashByteWidth: hashW, pathContacts: _pathTraceContacts, ), @@ -2494,9 +2491,6 @@ class _MapScreenState extends State { title: l10n.contacts_pathTrace, path: Uint8List.fromList(_pathTrace), flipPathAround: true, - targetContact: _pathTraceContacts.isNotEmpty - ? _pathTraceContacts.last - : null, pathHashByteWidth: context .read() .pathHashByteWidth, diff --git a/lib/widgets/path_editor_sheet.dart b/lib/widgets/path_editor_sheet.dart index 67d9510c..f20aad1c 100644 --- a/lib/widgets/path_editor_sheet.dart +++ b/lib/widgets/path_editor_sheet.dart @@ -97,7 +97,9 @@ class _PathEditorSheetState extends State { void _syncHexFromHops() { _syncingHex = true; - _hexController.text = _hops.map((h) => PathHelper.formatHopHex(h.bytes)).join(','); + _hexController.text = _hops + .map((h) => PathHelper.formatHopHex(h.bytes)) + .join(','); _syncingHex = false; _hexError = null; } @@ -114,8 +116,7 @@ class _PathEditorSheetState extends State { final invalid = tokens .where( (t) => - t.length != expectedChars || - int.tryParse(t, radix: 16) == null, + t.length != expectedChars || int.tryParse(t, radix: 16) == null, ) .toList(); setState(() { @@ -144,10 +145,15 @@ class _PathEditorSheetState extends State { void _addHop(Contact contact) { if (_hops.length >= _maxHops) return; - final width = widget.pathHashByteWidth.clamp(1, contact.publicKey.length).toInt(); + final width = widget.pathHashByteWidth + .clamp(1, contact.publicKey.length) + .toInt(); setState(() { _hops.add( - _Hop(_nextHopId++, Uint8List.fromList(contact.publicKey.sublist(0, width))), + _Hop( + _nextHopId++, + Uint8List.fromList(contact.publicKey.sublist(0, width)), + ), ); _syncHexFromHops(); }); @@ -173,10 +179,7 @@ class _PathEditorSheetState extends State { for (final hop in _hops) { bytes.addAll(hop.bytes); } - Navigator.pop( - context, - Uint8List.fromList(bytes), - ); + Navigator.pop(context, Uint8List.fromList(bytes)); } Widget _hopTile(BuildContext context, int index) { diff --git a/lib/widgets/routing_sheet.dart b/lib/widgets/routing_sheet.dart index 5859e0c2..1370fb3d 100644 --- a/lib/widgets/routing_sheet.dart +++ b/lib/widgets/routing_sheet.dart @@ -547,9 +547,15 @@ class _RoutingSheetBodyState extends State<_RoutingSheetBody> { connector.pathHashByteWidth, ) : l10n.chat_hopsCount(record.hopCount); + final displayHopCount = hasBytes + ? PathHelper.splitPathBytes( + record.pathBytes, + connector.pathHashByteWidth, + ).length + : record.hopCount; final line1 = - '${l10n.chat_hopsCount(record.hopCount)} • ${_qualityLabel(context, quality)}'; + '${l10n.chat_hopsCount(displayHopCount)} • ${_qualityLabel(context, quality)}'; final line2Parts = [ record.timestamp != null ? l10n.routing_lastWorked(_relativeTime(context, record.timestamp!))