mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-13 01:10:28 +00:00
feat: Add RX/TX indicators preference with toggle in settings
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import '../providers/connection_provider.dart';
|
import '../providers/connection_provider.dart';
|
||||||
import '../providers/app_provider.dart';
|
import '../providers/app_provider.dart';
|
||||||
import '../providers/messages_provider.dart';
|
import '../providers/messages_provider.dart';
|
||||||
@@ -34,6 +35,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
late TabController _tabController;
|
late TabController _tabController;
|
||||||
int _currentIndex = 0;
|
int _currentIndex = 0;
|
||||||
bool _isMapFullscreen = false;
|
bool _isMapFullscreen = false;
|
||||||
|
bool _showRxTxIndicators = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -48,6 +50,16 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
_loadRxTxPreference();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadRxTxPreference() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_showRxTxIndicators = prefs.getBool('show_rx_tx_indicators') ?? true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -475,8 +487,8 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () async {
|
||||||
Navigator.push(
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => SettingsScreen(
|
builder: (context) => SettingsScreen(
|
||||||
@@ -485,6 +497,8 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// Reload preference when returning from settings
|
||||||
|
_loadRxTxPreference();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -580,34 +594,40 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
color: deviceInfo.signalRssi != null
|
color: deviceInfo.signalRssi != null
|
||||||
? _getSignalColor(deviceInfo.signalRssi!)
|
? _getSignalColor(deviceInfo.signalRssi!)
|
||||||
: Colors.grey,
|
: Colors.grey,
|
||||||
size: 16,
|
size: 14,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 3),
|
||||||
if (deviceInfo.signalRssi != null)
|
if (deviceInfo.signalRssi != null)
|
||||||
Text(
|
Flexible(
|
||||||
'${deviceInfo.signalRssi}dBm',
|
child: Text(
|
||||||
style: TextStyle(
|
'${deviceInfo.signalRssi}',
|
||||||
fontSize: 14,
|
style: TextStyle(
|
||||||
color: _getSignalColor(deviceInfo.signalRssi!),
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w500,
|
color: _getSignalColor(deviceInfo.signalRssi!),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 8),
|
||||||
// Battery indicator
|
// Battery indicator
|
||||||
if (deviceInfo.batteryPercent != null) ...[
|
if (deviceInfo.batteryPercent != null) ...[
|
||||||
Icon(
|
Icon(
|
||||||
_getBatteryIcon(deviceInfo.batteryPercent!),
|
_getBatteryIcon(deviceInfo.batteryPercent!),
|
||||||
color: _getBatteryColor(deviceInfo.batteryPercent!),
|
color: _getBatteryColor(deviceInfo.batteryPercent!),
|
||||||
size: 16,
|
size: 14,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 3),
|
||||||
Text(
|
Flexible(
|
||||||
'${deviceInfo.batteryPercent!.round()}%',
|
child: Text(
|
||||||
style: TextStyle(
|
'${deviceInfo.batteryPercent!.round()}%',
|
||||||
fontSize: 14,
|
style: TextStyle(
|
||||||
color: _getBatteryColor(
|
fontSize: 12,
|
||||||
deviceInfo.batteryPercent!,
|
color: _getBatteryColor(
|
||||||
|
deviceInfo.batteryPercent!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -687,75 +707,77 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
),
|
),
|
||||||
child: const Icon(Icons.campaign, size: 20),
|
child: const Icon(Icons.campaign, size: 20),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
if (_showRxTxIndicators) ...[
|
||||||
// RX/TX indicators with long press to open packet log
|
const SizedBox(width: 8),
|
||||||
GestureDetector(
|
// RX/TX indicators with long press to open packet log
|
||||||
onLongPress: () {
|
GestureDetector(
|
||||||
Navigator.push(
|
onLongPress: () {
|
||||||
context,
|
Navigator.push(
|
||||||
MaterialPageRoute(
|
context,
|
||||||
builder: (context) =>
|
MaterialPageRoute(
|
||||||
PacketLogScreen(bleService: provider.bleService),
|
builder: (context) =>
|
||||||
),
|
PacketLogScreen(bleService: provider.bleService),
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
child: Column(
|
},
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
// RX indicator
|
children: [
|
||||||
Row(
|
// RX indicator
|
||||||
mainAxisSize: MainAxisSize.min,
|
Row(
|
||||||
children: [
|
mainAxisSize: MainAxisSize.min,
|
||||||
Container(
|
children: [
|
||||||
width: 8,
|
Container(
|
||||||
height: 8,
|
width: 8,
|
||||||
decoration: BoxDecoration(
|
height: 8,
|
||||||
shape: BoxShape.circle,
|
decoration: BoxDecoration(
|
||||||
color: provider.rxActivity
|
shape: BoxShape.circle,
|
||||||
? Colors.green
|
color: provider.rxActivity
|
||||||
: Colors.grey.withOpacity(0.3),
|
? Colors.green
|
||||||
|
: Colors.grey.withOpacity(0.3),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 4),
|
||||||
const SizedBox(width: 4),
|
Text(
|
||||||
Text(
|
'RX:${provider.rxPacketCount}',
|
||||||
'RX:${provider.rxPacketCount}',
|
style: const TextStyle(
|
||||||
style: const TextStyle(
|
fontSize: 11,
|
||||||
fontSize: 11,
|
color: Colors.grey,
|
||||||
color: Colors.grey,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
const SizedBox(height: 4),
|
||||||
const SizedBox(height: 4),
|
// TX indicator
|
||||||
// TX indicator
|
Row(
|
||||||
Row(
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
children: [
|
||||||
children: [
|
Container(
|
||||||
Container(
|
width: 8,
|
||||||
width: 8,
|
height: 8,
|
||||||
height: 8,
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
shape: BoxShape.circle,
|
||||||
shape: BoxShape.circle,
|
color: provider.txActivity
|
||||||
color: provider.txActivity
|
? Colors.blue
|
||||||
? Colors.blue
|
: Colors.grey.withOpacity(0.3),
|
||||||
: Colors.grey.withOpacity(0.3),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 4),
|
||||||
const SizedBox(width: 4),
|
Text(
|
||||||
Text(
|
'TX:${provider.txPacketCount}',
|
||||||
'TX:${provider.txPacketCount}',
|
style: const TextStyle(
|
||||||
style: const TextStyle(
|
fontSize: 11,
|
||||||
fontSize: 11,
|
color: Colors.grey,
|
||||||
color: Colors.grey,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(width: 12),
|
||||||
const SizedBox(width: 12),
|
],
|
||||||
// Settings button (tap for device settings, long press for packet logs)
|
// Settings button (tap for device settings, long press for packet logs)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
late AppThemeMode _selectedTheme;
|
late AppThemeMode _selectedTheme;
|
||||||
PackageInfo? _packageInfo;
|
PackageInfo? _packageInfo;
|
||||||
bool _isLoadingSampleData = false;
|
bool _isLoadingSampleData = false;
|
||||||
|
bool _showRxTxIndicators = true;
|
||||||
final LocationTrackingService _locationService = LocationTrackingService();
|
final LocationTrackingService _locationService = LocationTrackingService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -37,6 +38,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
_selectedTheme = widget.currentTheme;
|
_selectedTheme = widget.currentTheme;
|
||||||
_loadPackageInfo();
|
_loadPackageInfo();
|
||||||
_initializeLocationService();
|
_initializeLocationService();
|
||||||
|
_loadRxTxPreference();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadPackageInfo() async {
|
Future<void> _loadPackageInfo() async {
|
||||||
@@ -48,6 +50,20 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _loadRxTxPreference() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_showRxTxIndicators = prefs.getBool('show_rx_tx_indicators') ?? true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _saveRxTxPreference(bool value) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool('show_rx_tx_indicators', value);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _initializeLocationService() async {
|
Future<void> _initializeLocationService() async {
|
||||||
// Initialize location service with BLE service
|
// Initialize location service with BLE service
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
@@ -294,6 +310,18 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
trailing: const Icon(Icons.chevron_right),
|
trailing: const Icon(Icons.chevron_right),
|
||||||
onTap: () => _showThemeDialog(),
|
onTap: () => _showThemeDialog(),
|
||||||
),
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
secondary: const Icon(Icons.radar),
|
||||||
|
title: const Text('Show RX/TX Indicators'),
|
||||||
|
subtitle: const Text('Display packet activity indicators in top bar'),
|
||||||
|
value: _showRxTxIndicators,
|
||||||
|
onChanged: (value) async {
|
||||||
|
setState(() {
|
||||||
|
_showRxTxIndicators = value;
|
||||||
|
});
|
||||||
|
await _saveRxTxPreference(value);
|
||||||
|
},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
|
||||||
// Location Settings Section
|
// Location Settings Section
|
||||||
|
|||||||
Reference in New Issue
Block a user