Updated to last dev

This commit is contained in:
HDDen
2026-06-12 14:44:09 +03:00
parent d06a4c1861
commit 27695d372a
8 changed files with 75 additions and 34 deletions
+5 -9
View File
@@ -3208,10 +3208,7 @@ class MeshCoreConnector extends ChangeNotifier {
if (pathLen != null && if (pathLen != null &&
pathLen >= 0 && pathLen >= 0 &&
!_isPathLenValidForCurrentMode( !_isPathLenValidForCurrentMode(pathLen, pathBytes ?? Uint8List(0))) {
pathLen,
pathBytes ?? Uint8List(0),
)) {
appLogger.warn( appLogger.warn(
'setPathOverride: invalid path for ${contact.name}: ' 'setPathOverride: invalid path for ${contact.name}: '
'pathLen=$pathLen, bytesLen=${pathBytes?.length ?? 0}, ' 'pathLen=$pathLen, bytesLen=${pathBytes?.length ?? 0}, '
@@ -6694,13 +6691,12 @@ class MeshCoreConnector extends ChangeNotifier {
return; return;
} }
final pathStartIndex = path.isNotEmpty ? path.length - hashWidth : 0; 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 final pubkeyPrefix = path.isNotEmpty
? path.sublist(pathStartIndex) ? path.sublist(pathStartIndex)
: contact.publicKey.sublist( : contact.publicKey.sublist(0, publicKeyPrefixEnd);
0,
publicKeyPrefixEnd,
);
final contactKeyHex = _resolveDirectRepeaterContactKeyHex( final contactKeyHex = _resolveDirectRepeaterContactKeyHex(
contact, contact,
pubkeyPrefix, pubkeyPrefix,
+20 -3
View File
@@ -1,4 +1,5 @@
import '../connector/meshcore_protocol.dart'; import '../connector/meshcore_protocol.dart';
import '../helpers/path_helper.dart';
import '../models/contact.dart'; import '../models/contact.dart';
import 'app_localizations.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 != null) {
if (pathOverride! < 0) return l10n.chat_floodForced; if (pathOverride! < 0) return l10n.chat_floodForced;
if (pathOverride == 0) return l10n.chat_directForced; 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.channelPath_floodPath;
if (pathLength == 0) return l10n.chat_direct; if (pathLength == 0) return l10n.chat_direct;
return l10n.chat_hopsCount(pathLength); return l10n.chat_hopsCount(
_displayHopCount(path, pathLength, pathHashByteWidth),
);
}
int _displayHopCount(
List<int>? pathBytes,
int storedHopCount,
int hashWidth,
) {
if (pathBytes == null || pathBytes.isEmpty) return storedHopCount;
return PathHelper.splitPathBytes(pathBytes, hashWidth).length;
} }
} }
+1 -1
View File
@@ -271,7 +271,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
), ),
buildDefaultDragHandles: false, buildDefaultDragHandles: false,
itemCount: filteredChannels.length, itemCount: filteredChannels.length,
onReorder: (oldIndex, newIndex) { onReorderItem: (oldIndex, newIndex) {
final reordered = List<Channel>.from( final reordered = List<Channel>.from(
filteredChannels, filteredChannels,
); );
+25 -3
View File
@@ -12,6 +12,7 @@ import '../utils/platform_info.dart';
import '../connector/meshcore_connector.dart'; import '../connector/meshcore_connector.dart';
import '../connector/meshcore_protocol.dart'; import '../connector/meshcore_protocol.dart';
import '../helpers/cyr2lat.dart'; import '../helpers/cyr2lat.dart';
import '../helpers/path_helper.dart';
import '../helpers/reaction_helper.dart'; import '../helpers/reaction_helper.dart';
import '../widgets/message_status_icon.dart'; import '../widgets/message_status_icon.dart';
import '../widgets/empty_state.dart'; import '../widgets/empty_state.dart';
@@ -727,17 +728,35 @@ class _ChatScreenState extends State<ChatScreen> {
} }
String _currentPathLabel(Contact contact) { String _currentPathLabel(Contact contact) {
final connector = context.read<MeshCoreConnector>();
// Check if user has set a path override // Check if user has set a path override
if (contact.pathOverride != null) { if (contact.pathOverride != null) {
if (contact.pathOverride! < 0) return context.l10n.chat_floodForced; if (contact.pathOverride! < 0) return context.l10n.chat_floodForced;
if (contact.pathOverride == 0) return context.l10n.chat_directForced; 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 // Use device's path
if (contact.pathLength < 0) return context.l10n.chat_floodAuto; if (contact.pathLength < 0) return context.l10n.chat_floodAuto;
if (contact.pathLength == 0) return context.l10n.chat_direct; 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<int> pathBytes, int storedHopCount, int hashWidth) {
if (pathBytes.isEmpty) return storedHopCount;
return PathHelper.splitPathBytes(pathBytes, hashWidth).length;
} }
void _showContactInfo(BuildContext context) { void _showContactInfo(BuildContext context) {
@@ -758,7 +777,10 @@ class _ChatScreenState extends State<ChatScreen> {
), ),
_buildInfoRow( _buildInfoRow(
context.l10n.chat_path, context.l10n.chat_path,
contact.pathLabel(context.l10n), contact.pathLabel(
context.l10n,
pathHashByteWidth: connector.pathHashByteWidth,
),
), ),
_buildInfoRow( _buildInfoRow(
context.l10n.contact_lastSeen, context.l10n.contact_lastSeen,
+4 -1
View File
@@ -911,6 +911,7 @@ class _ContactsScreenState extends State<ContactsScreen>
); );
return _ContactTile( return _ContactTile(
contact: contact, contact: contact,
pathHashByteWidth: connector.pathHashByteWidth,
lastSeen: _resolveLastSeen(contact), lastSeen: _resolveLastSeen(contact),
unreadCount: unreadCount, unreadCount: unreadCount,
isFavorite: contact.isFavorite, isFavorite: contact.isFavorite,
@@ -1553,6 +1554,7 @@ class _ContactsScreenState extends State<ContactsScreen>
class _ContactTile extends StatelessWidget { class _ContactTile extends StatelessWidget {
final Contact contact; final Contact contact;
final int pathHashByteWidth;
final DateTime lastSeen; final DateTime lastSeen;
final int unreadCount; final int unreadCount;
final bool isFavorite; final bool isFavorite;
@@ -1561,6 +1563,7 @@ class _ContactTile extends StatelessWidget {
const _ContactTile({ const _ContactTile({
required this.contact, required this.contact,
required this.pathHashByteWidth,
required this.lastSeen, required this.lastSeen,
required this.unreadCount, required this.unreadCount,
required this.isFavorite, required this.isFavorite,
@@ -1579,7 +1582,7 @@ class _ContactTile extends StatelessWidget {
), ),
title: Text(contact.name, maxLines: 1, overflow: TextOverflow.ellipsis), title: Text(contact.name, maxLines: 1, overflow: TextOverflow.ellipsis),
subtitle: Text( subtitle: Text(
contact.pathLabel(context.l10n), contact.pathLabel(context.l10n, pathHashByteWidth: pathHashByteWidth),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
+1 -7
View File
@@ -2468,10 +2468,7 @@ class _MapScreenState extends State<MapScreen> {
builder: (context) => PathTraceMapScreen( builder: (context) => PathTraceMapScreen(
title: l10n.contacts_pathTrace, title: l10n.contacts_pathTrace,
path: Uint8List.fromList(_pathTrace), path: Uint8List.fromList(_pathTrace),
flipPathAround: true, flipPathAround: false,
targetContact: _pathTraceContacts.isNotEmpty
? _pathTraceContacts.last
: null,
pathHashByteWidth: hashW, pathHashByteWidth: hashW,
pathContacts: _pathTraceContacts, pathContacts: _pathTraceContacts,
), ),
@@ -2494,9 +2491,6 @@ class _MapScreenState extends State<MapScreen> {
title: l10n.contacts_pathTrace, title: l10n.contacts_pathTrace,
path: Uint8List.fromList(_pathTrace), path: Uint8List.fromList(_pathTrace),
flipPathAround: true, flipPathAround: true,
targetContact: _pathTraceContacts.isNotEmpty
? _pathTraceContacts.last
: null,
pathHashByteWidth: context pathHashByteWidth: context
.read<MeshCoreConnector>() .read<MeshCoreConnector>()
.pathHashByteWidth, .pathHashByteWidth,
+12 -9
View File
@@ -97,7 +97,9 @@ class _PathEditorSheetState extends State<PathEditorSheet> {
void _syncHexFromHops() { void _syncHexFromHops() {
_syncingHex = true; _syncingHex = true;
_hexController.text = _hops.map((h) => PathHelper.formatHopHex(h.bytes)).join(','); _hexController.text = _hops
.map((h) => PathHelper.formatHopHex(h.bytes))
.join(',');
_syncingHex = false; _syncingHex = false;
_hexError = null; _hexError = null;
} }
@@ -114,8 +116,7 @@ class _PathEditorSheetState extends State<PathEditorSheet> {
final invalid = tokens final invalid = tokens
.where( .where(
(t) => (t) =>
t.length != expectedChars || t.length != expectedChars || int.tryParse(t, radix: 16) == null,
int.tryParse(t, radix: 16) == null,
) )
.toList(); .toList();
setState(() { setState(() {
@@ -144,10 +145,15 @@ class _PathEditorSheetState extends State<PathEditorSheet> {
void _addHop(Contact contact) { void _addHop(Contact contact) {
if (_hops.length >= _maxHops) return; 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(() { setState(() {
_hops.add( _hops.add(
_Hop(_nextHopId++, Uint8List.fromList(contact.publicKey.sublist(0, width))), _Hop(
_nextHopId++,
Uint8List.fromList(contact.publicKey.sublist(0, width)),
),
); );
_syncHexFromHops(); _syncHexFromHops();
}); });
@@ -173,10 +179,7 @@ class _PathEditorSheetState extends State<PathEditorSheet> {
for (final hop in _hops) { for (final hop in _hops) {
bytes.addAll(hop.bytes); bytes.addAll(hop.bytes);
} }
Navigator.pop( Navigator.pop(context, Uint8List.fromList(bytes));
context,
Uint8List.fromList(bytes),
);
} }
Widget _hopTile(BuildContext context, int index) { Widget _hopTile(BuildContext context, int index) {
+7 -1
View File
@@ -547,9 +547,15 @@ class _RoutingSheetBodyState extends State<_RoutingSheetBody> {
connector.pathHashByteWidth, connector.pathHashByteWidth,
) )
: l10n.chat_hopsCount(record.hopCount); : l10n.chat_hopsCount(record.hopCount);
final displayHopCount = hasBytes
? PathHelper.splitPathBytes(
record.pathBytes,
connector.pathHashByteWidth,
).length
: record.hopCount;
final line1 = final line1 =
'${l10n.chat_hopsCount(record.hopCount)}${_qualityLabel(context, quality)}'; '${l10n.chat_hopsCount(displayHopCount)}${_qualityLabel(context, quality)}';
final line2Parts = <String>[ final line2Parts = <String>[
record.timestamp != null record.timestamp != null
? l10n.routing_lastWorked(_relativeTime(context, record.timestamp!)) ? l10n.routing_lastWorked(_relativeTime(context, record.timestamp!))