diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index d9e0d20..a0dedac 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1088,6 +1088,7 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { LoRaCodingRate _codingRate = LoRaCodingRate.cr4_5; final _txPowerController = TextEditingController(text: '20'); bool _clientRepeat = false; + int? _selectedPresetIndex; @override void initState() { @@ -1139,6 +1140,7 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { } _clientRepeat = widget.connector.clientRepeat ?? false; + _selectedPresetIndex = _findMatchingPresetIndex(); } @override @@ -1158,6 +1160,55 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { }); } + int? _findMatchingPresetIndex() { + final freqMHz = double.tryParse(_frequencyController.text); + final txPower = int.tryParse(_txPowerController.text); + if (freqMHz == null || txPower == null) return null; + + const epsilon = 0.001; + for (var i = 0; i < RadioSettings.presets.length; i++) { + final preset = RadioSettings.presets[i].$2; + if ((preset.frequencyMHz - freqMHz).abs() < epsilon && + preset.bandwidth == _bandwidth && + preset.spreadingFactor == _spreadingFactor && + preset.codingRate == _codingRate && + preset.txPowerDbm == txPower) { + return i; + } + } + return null; + } + + double _offGridFrequencyForBaseFrequency(double baseFrequencyMHz) { + if (baseFrequencyMHz < 500) return 433.0; + if (baseFrequencyMHz < 900) return 869.0; + return 918.0; + } + + double _normalFrequencyForBand(double frequencyMHz) { + if (frequencyMHz < 500) return 433.650; + if (frequencyMHz < 900) return 869.432; + return 915.8; + } + + void _handleClientRepeatChanged(bool enabled) { + setState(() { + _clientRepeat = enabled; + + final baseFrequencyMHz = _selectedPresetIndex != null + ? RadioSettings.presets[_selectedPresetIndex!].$2.frequencyMHz + : (double.tryParse(_frequencyController.text) ?? 915.0); + + final nextFrequencyMHz = enabled + ? _offGridFrequencyForBaseFrequency(baseFrequencyMHz) + : (_selectedPresetIndex != null + ? RadioSettings.presets[_selectedPresetIndex!].$2.frequencyMHz + : _normalFrequencyForBand(baseFrequencyMHz)); + + _frequencyController.text = nextFrequencyMHz.toStringAsFixed(3); + }); + } + Future _saveSettings() async { final l10n = context.l10n; final freqMHz = double.tryParse(_frequencyController.text); @@ -1250,6 +1301,7 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { crossAxisAlignment: CrossAxisAlignment.start, children: [ DropdownButtonFormField( + initialValue: _selectedPresetIndex, decoration: InputDecoration( labelText: l10n.settings_presets, border: const OutlineInputBorder(), @@ -1263,6 +1315,7 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { ], onChanged: (index) { if (index != null) { + _selectedPresetIndex = index; _applyPreset(RadioSettings.presets[index].$2); } }, @@ -1345,7 +1398,7 @@ class _RadioSettingsDialogState extends State<_RadioSettingsDialog> { title: Text(l10n.settings_clientRepeat), subtitle: Text(l10n.settings_clientRepeatSubtitle), value: _clientRepeat, - onChanged: (value) => setState(() => _clientRepeat = value), + onChanged: _handleClientRepeatChanged, contentPadding: EdgeInsets.zero, ), ],