Multibyte: fix map

This commit is contained in:
HDDen
2026-05-28 02:20:56 +03:00
parent 6e81fdfd46
commit 2e4f26d7cd
8 changed files with 338 additions and 267 deletions
+1 -2
View File
@@ -301,8 +301,7 @@ class _ChannelsScreenState extends State<ChannelsScreen>
),
buildDefaultDragHandles: false,
itemCount: filteredChannels.length,
onReorder: (oldIndex, newIndex) {
if (newIndex > oldIndex) newIndex -= 1;
onReorderItem: (oldIndex, newIndex) {
final reordered = List<Channel>.from(
filteredChannels,
);
+18 -3
View File
@@ -70,6 +70,7 @@ class _MapScreenState extends State<MapScreen> {
bool _hasInitializedMap = false;
bool _removedMarkersLoaded = false;
final List<int> _pathTrace = [];
final List<int> _pathTraceHopWidths = [];
final List<Contact> _pathTraceContacts = [];
final List<LatLng> _points = [];
final List<Polyline> _polylines = [];
@@ -2302,11 +2303,12 @@ class _MapScreenState extends State<MapScreen> {
final hopWidth = min(
connector.pathHashByteWidth.clamp(1, pubKeySize),
contact.publicKey.length,
);
).toInt();
setState(() {
_pathTrace.addAll(
contact.publicKey.sublist(0, hopWidth),
); // Add the hop-width prefix of the public key to the trace
_pathTraceHopWidths.add(hopWidth);
_pathTraceContacts.add(
contact.copyWith(
latitude: position?.latitude ?? contact.latitude,
@@ -2321,6 +2323,7 @@ class _MapScreenState extends State<MapScreen> {
setState(() {
_isBuildingPathTrace = true;
_pathTrace.clear();
_pathTraceHopWidths.clear();
_pathTraceContacts.clear();
_points.clear();
_polylines.clear();
@@ -2330,8 +2333,19 @@ class _MapScreenState extends State<MapScreen> {
void _removePath() {
setState(() {
final recordedHopWidth = _pathTraceHopWidths.isNotEmpty
? _pathTraceHopWidths.removeLast()
: context.read<MeshCoreConnector>().pathHashByteWidth.clamp(
1,
pubKeySize,
);
final hopByteCount = min(recordedHopWidth, _pathTrace.length).toInt();
_pathTraceContacts.removeLast();
_pathTrace.removeLast(); // Remove last node from path trace
// A path trace hop can be wider than one byte; remove the full hash prefix.
_pathTrace.removeRange(
_pathTrace.length - hopByteCount,
_pathTrace.length,
);
_points.removeLast(); // Remove last point from points list
_polylines.clear(); // Clear polylines
});
@@ -2369,7 +2383,7 @@ class _MapScreenState extends State<MapScreen> {
PathHelper.splitPathBytes(
_pathTrace,
context.read<MeshCoreConnector>().pathHashByteWidth,
).map(PathHelper.formatHopHex).join(',') ,
).map(PathHelper.formatHopHex).join(','),
style: TextStyle(fontSize: 18),
),
// const SizedBox(height: 6),
@@ -2445,6 +2459,7 @@ class _MapScreenState extends State<MapScreen> {
setState(() {
_isBuildingPathTrace = false;
_pathTrace.clear();
_pathTraceHopWidths.clear();
_points.clear();
_polylines.clear();
});
+13 -11
View File
@@ -115,9 +115,10 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
Uint8List? _sentTagBytes;
String _formatPathPrefixes(Uint8List pathBytes) {
return PathHelper.splitPathBytes(pathBytes, widget.pathHashByteWidth)
.map(PathHelper.formatHopHex)
.join(',');
return PathHelper.splitPathBytes(
pathBytes,
widget.pathHashByteWidth,
).map(PathHelper.formatHopHex).join(',');
}
@override
@@ -327,7 +328,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
// Check if it's a binary response
if (frame.length >= 12 &&
code == pushCodeTraceData &&
(listEquals(frame.sublist(4, 8), _sentTagBytes) || listEquals(frame.sublist(4, 8), tagData))) {
(listEquals(frame.sublist(4, 8), _sentTagBytes) ||
listEquals(frame.sublist(4, 8), tagData))) {
_timeoutTimer?.cancel();
if (!mounted) return;
_handleTraceResponse(frame);
@@ -370,10 +372,7 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
buffer.skipBytes(5); // Skip Flag byte and tag data
buffer.skipBytes(4); // Skip auth code
final pathBytes = buffer.readBytes(pathLength);
final pathData = PathHelper.splitPathBytes(
pathBytes,
width,
);
final pathData = PathHelper.splitPathBytes(pathBytes, width);
List<double> snrData = buffer
.readRemainingBytes()
.map((snr) => snr.toSigned(8).toDouble() / 4)
@@ -414,7 +413,10 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
for (final repeaterData in pathData) {
final hopWidth = repeaterData.length;
if (repeater.publicKey.length < hopWidth) continue;
if (listEquals(repeater.publicKey.sublist(0, hopWidth), repeaterData)) {
if (listEquals(
repeater.publicKey.sublist(0, hopWidth),
repeaterData,
)) {
pathContacts[_hopKey(repeaterData)] = repeater;
lastContact = repeater;
}
@@ -434,8 +436,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
(c) =>
c.hasLocation &&
c.path.isNotEmpty &&
_hopKey(_lastHopChunk(c.path, widget.pathHashByteWidth)) ==
hopKey,
_hopKey(_lastHopChunk(c.path, widget.pathHashByteWidth)) ==
hopKey,
)
.toList();
if (peers.isNotEmpty) {