@ -40,16 +40,12 @@ class ChannelMessagePathScreen extends StatelessWidget {
final primaryPath = ! channelMessage & & ! message . isOutgoing
final primaryPath = ! channelMessage & & ! message . isOutgoing
? Uint8List . fromList ( primaryPathTmp . reversed . toList ( ) )
? Uint8List . fromList ( primaryPathTmp . reversed . toList ( ) )
: primaryPathTmp ;
: primaryPathTmp ;
final hops = _buildPathHops (
final hashWidth = connector . pathHashByteWidth ;
primaryPath ,
final hops = _buildPathHops ( primaryPath , connector , l10n , hashWidth ) ;
connector ,
l10n ,
message . pathHashSize ,
) ;
final hasHopDetails = primaryPath . isNotEmpty ;
final hasHopDetails = primaryPath . isNotEmpty ;
final observedLabel = _formatObservedHops (
final observedLabel = _formatObservedHops (
primaryPath . length ~ / message. pathHashSize ,
primaryPath . length ~ / hashWidth ,
message. hopCount ,
realHopCount ( message . hopCount , hashWidth ) ,
l10n ,
l10n ,
) ;
) ;
final extraPaths = _otherPaths ( primaryPath , message . pathVariants ) ;
final extraPaths = _otherPaths ( primaryPath , message . pathVariants ) ;
@ -125,6 +121,7 @@ class ChannelMessagePathScreen extends StatelessWidget {
Widget _buildSummaryCard ( BuildContext context , { String ? observedLabel } ) {
Widget _buildSummaryCard ( BuildContext context , { String ? observedLabel } ) {
final l10n = context . l10n ;
final l10n = context . l10n ;
final hashWidth = context . read < MeshCoreConnector > ( ) . pathHashByteWidth ;
return Card (
return Card (
child: Padding (
child: Padding (
padding: const EdgeInsets . all ( 12 ) ,
padding: const EdgeInsets . all ( 12 ) ,
@ -148,7 +145,7 @@ class ChannelMessagePathScreen extends StatelessWidget {
) ,
) ,
_buildDetailRow (
_buildDetailRow (
l10n . channelPath_pathLabelTitle ,
l10n . channelPath_pathLabelTitle ,
_formatPathLabel ( message. hopCount , l10n ) ,
_formatPathLabel ( realHopCount( message. hopCount , hashWidth ) , l10n ) ,
) ,
) ,
if ( observedLabel ! = null )
if ( observedLabel ! = null )
_buildDetailRow ( l10n . channelPath_observedLabel , observedLabel ) ,
_buildDetailRow ( l10n . channelPath_observedLabel , observedLabel ) ,
@ -160,6 +157,7 @@ class ChannelMessagePathScreen extends StatelessWidget {
Widget _buildPathVariants ( BuildContext context , List < Uint8List > variants ) {
Widget _buildPathVariants ( BuildContext context , List < Uint8List > variants ) {
final l10n = context . l10n ;
final l10n = context . l10n ;
final hashWidth = context . read < MeshCoreConnector > ( ) . pathHashByteWidth ;
return Column (
return Column (
crossAxisAlignment: CrossAxisAlignment . start ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
children: [
@ -171,15 +169,10 @@ class ChannelMessagePathScreen extends StatelessWidget {
title: Text (
title: Text (
l10n . channelPath_observedPathTitle (
l10n . channelPath_observedPathTitle (
i + 1 ,
i + 1 ,
_formatHopCount (
_formatHopCount ( variants [ i ] . length ~ / hashWidth , l10n ) ,
variants [ i ] . length ~ / message . pathHashSize ,
l10n ,
) ,
) ,
) ,
) ,
) ,
subtitle: Text (
subtitle: Text ( _formatPathPrefixes ( variants [ i ] , hashWidth ) ) ,
_formatPathPrefixes ( variants [ i ] , message . pathHashSize ) ,
) ,
trailing: const Icon ( Icons . map_outlined , size: 20 ) ,
trailing: const Icon ( Icons . map_outlined , size: 20 ) ,
onTap: ( ) = > _openPathMap (
onTap: ( ) = > _openPathMap (
context ,
context ,
@ -474,11 +467,12 @@ class _ChannelMessagePathMapScreenState
: selectedPathTmp ;
: selectedPathTmp ;
final selectedIndex = _indexForPath ( selectedPath , observedPaths ) ;
final selectedIndex = _indexForPath ( selectedPath , observedPaths ) ;
final hashWidth = connector . pathHashByteWidth ;
final hops = _buildPathHops (
final hops = _buildPathHops (
selectedPath ,
selectedPath ,
connector ,
connector ,
context . l10n ,
context . l10n ,
widget. message . pathHashSize ,
hashWidth ,
) ;
) ;
final points = < LatLng > [ ] ;
final points = < LatLng > [ ] ;
@ -520,7 +514,7 @@ class _ChannelMessagePathMapScreenState
? LatLngBounds . fromPoints ( points )
? LatLngBounds . fromPoints ( points )
: null ;
: null ;
final mapKey = ValueKey (
final mapKey = ValueKey (
' ${ _formatPathPrefixes ( selectedPath , widget. message . pathHashSize ) } , ${ context . l10n . pathTrace_you } ' ,
' ${ _formatPathPrefixes ( selectedPath , hashWidth ) } , ${ context . l10n . pathTrace_you } ' ,
) ;
) ;
_pathDistance = _getPathDistance ( points ) ;
_pathDistance = _getPathDistance ( points ) ;
@ -633,6 +627,7 @@ class _ChannelMessagePathMapScreenState
ValueChanged < int > onSelected ,
ValueChanged < int > onSelected ,
) {
) {
final l10n = context . l10n ;
final l10n = context . l10n ;
final hashWidth = context . read < MeshCoreConnector > ( ) . pathHashByteWidth ;
final selectedPath = paths [ selectedIndex ] ;
final selectedPath = paths [ selectedIndex ] ;
final label = selectedPath . isPrimary
final label = selectedPath . isPrimary
? l10n . channelPath_primaryPath ( selectedIndex + 1 )
? l10n . channelPath_primaryPath ( selectedIndex + 1 )
@ -663,7 +658,7 @@ class _ChannelMessagePathMapScreenState
value: i ,
value: i ,
child: Text (
child: Text (
' ${ paths [ i ] . isPrimary ? l10n . channelPath_primaryPath ( i + 1 ) : l10n . channelPath_pathLabel ( i + 1 ) } '
' ${ paths [ i ] . isPrimary ? l10n . channelPath_primaryPath ( i + 1 ) : l10n . channelPath_pathLabel ( i + 1 ) } '
' • ${ _formatHopCount ( paths [ i ] . pathBytes . length ~ / widget. message . pathHashSize , l10n ) } ' ,
' • ${ _formatHopCount ( paths [ i ] . pathBytes . length ~ / hashWidth , l10n ) } ' ,
) ,
) ,
) ,
) ,
] ,
] ,
@ -677,10 +672,7 @@ class _ChannelMessagePathMapScreenState
Text (
Text (
l10n . channelPath_selectedPathLabel (
l10n . channelPath_selectedPathLabel (
label ,
label ,
_formatPathPrefixes (
_formatPathPrefixes ( selectedPath . pathBytes , hashWidth ) ,
selectedPath . pathBytes ,
widget . message . pathHashSize ,
) ,
) ,
) ,
style: TextStyle ( color: Colors . grey [ 700 ] , fontSize: 12 ) ,
style: TextStyle ( color: Colors . grey [ 700 ] , fontSize: 12 ) ,
) ,
) ,
@ -936,14 +928,14 @@ List<_PathHop> _buildPathHops(
) {
) {
if ( pathBytes . isEmpty ) return const [ ] ;
if ( pathBytes . isEmpty ) return const [ ] ;
final w = hashWidth < 1 ? 1 : hashWidth ;
final w = hashWidth < 1 ? 1 : hashWidth ;
final candidatesByPrefix = < int , List < Contact > > { } ;
final candidatesByPrefix = < String , List < Contact > > { } ;
final allContacts = connector . allContacts ;
final allContacts = connector . allContacts ;
for ( final contact in allContacts ) {
for ( final contact in allContacts ) {
if ( contact . publicKey . isEmpty ) continue ;
if ( contact . publicKey . length < w ) continue ;
if ( contact . type ! = advTypeRepeater & & contact . type ! = advTypeRoom ) {
if ( contact . type ! = advTypeRepeater & & contact . type ! = advTypeRoom ) {
continue ;
continue ;
}
}
final prefix = contact. publicKey . first ;
final prefix = _formatHash( contact. publicKey . sublist( 0 , w ) ) ;
candidatesByPrefix . putIfAbsent ( prefix , ( ) = > < Contact > [ ] ) . add ( contact ) ;
candidatesByPrefix . putIfAbsent ( prefix , ( ) = > < Contact > [ ] ) . add ( contact ) ;
}
}
for ( final candidates in candidatesByPrefix . values ) {
for ( final candidates in candidatesByPrefix . values ) {
@ -960,7 +952,7 @@ List<_PathHop> _buildPathHops(
final hops = < _PathHop > [ ] ;
final hops = < _PathHop > [ ] ;
for ( var i = 0 ; i + w < = pathBytes . length ; i + = w ) {
for ( var i = 0 ; i + w < = pathBytes . length ; i + = w ) {
final hash = pathBytes . sublist ( i , i + w ) ;
final hash = pathBytes . sublist ( i , i + w ) ;
final prefixKey = hash[ 0 ] ;
final prefixKey = _formatHash( hash ) ;
final searchPoint = i = = 0 ? startPoint : previousPosition ;
final searchPoint = i = = 0 ? startPoint : previousPosition ;
final candidates = candidatesByPrefix [ prefixKey ] ;
final candidates = candidatesByPrefix [ prefixKey ] ;
Contact ? contact ;
Contact ? contact ;