diff --git a/lib/screens/ble_debug_log_screen.dart b/lib/screens/ble_debug_log_screen.dart index 54a2c68a..fc8fe2d0 100644 --- a/lib/screens/ble_debug_log_screen.dart +++ b/lib/screens/ble_debug_log_screen.dart @@ -125,7 +125,9 @@ class _BleDebugLogScreenState extends State { if (context.mounted) { showDismissibleSnackBar( context, - content: Text(context.l10n.debugLog_bleCopied), + content: Text( + context.l10n.debugLog_bleCopied, + ), ); } } diff --git a/lib/screens/channels_screen.dart b/lib/screens/channels_screen.dart index 8a6b990a..745445ee 100644 --- a/lib/screens/channels_screen.dart +++ b/lib/screens/channels_screen.dart @@ -438,133 +438,133 @@ class _ChannelsScreenState extends State ) : null, child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // Leading avatar with optional community badge - Stack( - clipBehavior: Clip.none, - children: [ - AvatarCircle( - name: channelLabel, - size: 42, - color: iconColor, - icon: icon, - ), - if (isCommunityChannel) - Positioned( - right: -2, - bottom: -2, - child: Container( - width: 16, - height: 16, - decoration: BoxDecoration( - color: MeshPalette.magenta, - shape: BoxShape.circle, - border: Border.all( - color: Theme.of( - context, - ).colorScheme.surfaceContainerLow, - width: 2, - ), - ), - child: const Icon( - Icons.people, - size: 8, - color: Colors.white, - ), - ), - ), - ], - ), - const SizedBox(width: 12), - // Title + subtitle + ch chip - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Text( - channelLabel, - style: Theme.of(context).textTheme.bodyMedium - ?.copyWith(fontWeight: FontWeight.w500), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - const SizedBox(width: 6), - StatusChip( - label: 'CH ${channel.index}', - color: MeshPalette.blue, - fontSize: 10, - ), - ], - ), - if (lastPreview.isNotEmpty) ...[ - const SizedBox(height: 2), - Text( - lastPreview, - style: MeshTheme.mono( - fontSize: 11.5, - color: scheme.onSurfaceVariant, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ], + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Leading avatar with optional community badge + Stack( + clipBehavior: Clip.none, + children: [ + AvatarCircle( + name: channelLabel, + size: 42, + color: iconColor, + icon: icon, ), - ), - const SizedBox(width: 8), - // Right side: time + unread badge + muted + drag handle - Column( - crossAxisAlignment: CrossAxisAlignment.end, + if (isCommunityChannel) + Positioned( + right: -2, + bottom: -2, + child: Container( + width: 16, + height: 16, + decoration: BoxDecoration( + color: MeshPalette.magenta, + shape: BoxShape.circle, + border: Border.all( + color: Theme.of( + context, + ).colorScheme.surfaceContainerLow, + width: 2, + ), + ), + child: const Icon( + Icons.people, + size: 8, + color: Colors.white, + ), + ), + ), + ], + ), + const SizedBox(width: 12), + // Title + subtitle + ch chip + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (lastTime != null) - Text( - _relativeTime(lastTime), - style: MeshTheme.mono( - fontSize: 11, - color: scheme.onSurfaceVariant, - ), - ), - const SizedBox(height: 4), Row( - mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (isMuted) ...[ - Icon( - Icons.notifications_off, - size: 14, - color: scheme.onSurfaceVariant, + Expanded( + child: Text( + channelLabel, + style: Theme.of(context).textTheme.bodyMedium + ?.copyWith(fontWeight: FontWeight.w500), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), - const SizedBox(width: 4), - ], - if (unreadCount > 0) UnreadBadge(count: unreadCount), + ), + const SizedBox(width: 6), + StatusChip( + label: 'CH ${channel.index}', + color: MeshPalette.blue, + fontSize: 10, + ), ], ), + if (lastPreview.isNotEmpty) ...[ + const SizedBox(height: 2), + Text( + lastPreview, + style: MeshTheme.mono( + fontSize: 11.5, + color: scheme.onSurfaceVariant, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], ], ), - if (showDragHandle && dragIndex != null) ...[ - const SizedBox(width: 4), - ReorderableDragStartListener( - index: dragIndex, - child: Padding( - padding: const EdgeInsets.all(8), - child: Icon( - Icons.drag_handle, + ), + const SizedBox(width: 8), + // Right side: time + unread badge + muted + drag handle + Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + if (lastTime != null) + Text( + _relativeTime(lastTime), + style: MeshTheme.mono( + fontSize: 11, color: scheme.onSurfaceVariant, ), ), + const SizedBox(height: 4), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isMuted) ...[ + Icon( + Icons.notifications_off, + size: 14, + color: scheme.onSurfaceVariant, + ), + const SizedBox(width: 4), + ], + if (unreadCount > 0) UnreadBadge(count: unreadCount), + ], ), ], + ), + if (showDragHandle && dragIndex != null) ...[ + const SizedBox(width: 4), + ReorderableDragStartListener( + index: dragIndex, + child: Padding( + padding: const EdgeInsets.all(8), + child: Icon( + Icons.drag_handle, + color: scheme.onSurfaceVariant, + ), + ), + ), ], - ), + ], ), + ), ); } diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 0bc28674..18e3ba9d 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -285,7 +285,11 @@ class _MapScreenState extends State { ); } - void _handleMapContextPress(BuildContext context, MeshCoreConnector connector, LatLng latLng) { + void _handleMapContextPress( + BuildContext context, + MeshCoreConnector connector, + LatLng latLng, + ) { if (_isSelectingPoi) { setState(() { _isSelectingPoi = false; diff --git a/lib/widgets/routing_sheet.dart b/lib/widgets/routing_sheet.dart index 78036a70..2cc55b8a 100644 --- a/lib/widgets/routing_sheet.dart +++ b/lib/widgets/routing_sheet.dart @@ -538,57 +538,62 @@ class _RoutingSheetBodyState extends State<_RoutingSheetBody> { return GestureDetector( behavior: HitTestBehavior.opaque, onSecondaryTapUp: PlatformInfo.isDesktop && hasBytes - ? (_) => _showPathDetail(context, connector, contact, record.pathBytes) + ? (_) => + _showPathDetail(context, connector, contact, record.pathBytes) : null, child: Card( margin: const EdgeInsets.symmetric(vertical: 4), child: ListTile( enabled: hasBytes, leading: CircleAvatar( - radius: 18, - backgroundColor: bg, - child: Icon( - _qualityIcon(quality), - size: 18, - color: fg, - semanticLabel: _qualityLabel(context, quality), + radius: 18, + backgroundColor: bg, + child: Icon( + _qualityIcon(quality), + size: 18, + color: fg, + semanticLabel: _qualityLabel(context, quality), + ), ), - ), - title: Text(title, maxLines: 1, overflow: TextOverflow.ellipsis), - subtitle: Text( - '$line1\n${line2Parts.join(' • ')}', - style: const TextStyle(fontSize: 11), - ), - isThreeLine: true, - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (inUse) - Tooltip( - message: l10n.routing_inUse, - child: Icon( - Icons.check_circle, - color: scheme.primary, - semanticLabel: l10n.routing_inUse, + title: Text(title, maxLines: 1, overflow: TextOverflow.ellipsis), + subtitle: Text( + '$line1\n${line2Parts.join(' • ')}', + style: const TextStyle(fontSize: 11), + ), + isThreeLine: true, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (inUse) + Tooltip( + message: l10n.routing_inUse, + child: Icon( + Icons.check_circle, + color: scheme.primary, + semanticLabel: l10n.routing_inUse, + ), + ), + IconButton( + icon: const Icon(Icons.delete_outline, size: 20), + tooltip: l10n.chat_removePath, + constraints: const BoxConstraints(minWidth: 44, minHeight: 44), + onPressed: () => pathService.removePathRecord( + contact.publicKeyHex, + record.pathBytes, ), ), - IconButton( - icon: const Icon(Icons.delete_outline, size: 20), - tooltip: l10n.chat_removePath, - constraints: const BoxConstraints(minWidth: 44, minHeight: 44), - onPressed: () => pathService.removePathRecord( - contact.publicKeyHex, - record.pathBytes, - ), - ), - ], - ), + ], + ), onTap: hasBytes && !inUse ? () => _applyHistoryPath(connector, contact, record) : null, onLongPress: hasBytes - ? () => - _showPathDetail(context, connector, contact, record.pathBytes) + ? () => _showPathDetail( + context, + connector, + contact, + record.pathBytes, + ) : null, ), ),