Files
TelemetryMonitor/lib/config/settings.dart
2026-04-21 14:40:09 -03:00

129 lines
5.3 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'app_config.dart';
/// Runtime-tunable parameters that affect the data pipeline.
///
/// Persistence: all keys under the `settings.` prefix in shared_preferences.
/// Display labels (channel names, status names) live in LayoutController, not
/// here, because they're conceptually about how the dashboard looks.
class Settings extends ChangeNotifier {
Settings._({
required this.wsUrl,
required this.packetBufferCapacity,
required this.logBufferCapacity,
required this.decoderBatchInterval,
required this.reconnectInitialDelay,
required this.reconnectMaxDelay,
required this.reconnectBackoffFactor,
required this.miniLogSeverities,
required this.statusLookback,
});
String wsUrl;
int packetBufferCapacity;
int logBufferCapacity;
Duration decoderBatchInterval;
Duration reconnectInitialDelay;
Duration reconnectMaxDelay;
double reconnectBackoffFactor;
Set<int> miniLogSeverities;
int statusLookback;
/// Load from shared_preferences with defaults for any missing keys.
static Future<Settings> load({bool isWeb = false}) async {
final p = await SharedPreferences.getInstance();
return Settings._(
wsUrl: p.getString('settings.wsUrl') ?? AppConfig.defaultWsUrl,
packetBufferCapacity: p.getInt('settings.packetBufferCapacity') ??
(isWeb
? AppConfig.defaultPacketBufferCapacityWeb
: AppConfig.defaultPacketBufferCapacityNative),
logBufferCapacity: p.getInt('settings.logBufferCapacity') ??
AppConfig.defaultLogBufferCapacity,
decoderBatchInterval: Duration(
milliseconds: p.getInt('settings.decoderBatchIntervalMs') ??
AppConfig.defaultDecoderBatchInterval.inMilliseconds,
),
reconnectInitialDelay: Duration(
milliseconds: p.getInt('settings.reconnectInitialDelayMs') ??
AppConfig.defaultReconnectInitialDelay.inMilliseconds,
),
reconnectMaxDelay: Duration(
milliseconds: p.getInt('settings.reconnectMaxDelayMs') ??
AppConfig.defaultReconnectMaxDelay.inMilliseconds,
),
reconnectBackoffFactor: p.getDouble('settings.reconnectBackoffFactor') ??
AppConfig.defaultReconnectBackoffFactor,
miniLogSeverities: (p.getStringList('settings.miniLogSeverities') ??
AppConfig.defaultMiniLogSeverities.map((s) => s.toString()).toList())
.map(int.parse)
.toSet(),
statusLookback: p.getInt('settings.statusLookback') ??
AppConfig.defaultStatusLookback,
);
}
Future<void> save() async {
final p = await SharedPreferences.getInstance();
await p.setString('settings.wsUrl', wsUrl);
await p.setInt('settings.packetBufferCapacity', packetBufferCapacity);
await p.setInt('settings.logBufferCapacity', logBufferCapacity);
await p.setInt('settings.decoderBatchIntervalMs',
decoderBatchInterval.inMilliseconds);
await p.setInt('settings.reconnectInitialDelayMs',
reconnectInitialDelay.inMilliseconds);
await p.setInt('settings.reconnectMaxDelayMs',
reconnectMaxDelay.inMilliseconds);
await p.setDouble(
'settings.reconnectBackoffFactor', reconnectBackoffFactor);
await p.setStringList('settings.miniLogSeverities',
miniLogSeverities.map((s) => s.toString()).toList());
await p.setInt('settings.statusLookback', statusLookback);
notifyListeners();
}
/// Reset every field to its compile-time default. Does not persist; call
/// [save] afterward if you want it persisted.
void restoreDefaults({bool isWeb = false}) {
wsUrl = AppConfig.defaultWsUrl;
packetBufferCapacity = isWeb
? AppConfig.defaultPacketBufferCapacityWeb
: AppConfig.defaultPacketBufferCapacityNative;
logBufferCapacity = AppConfig.defaultLogBufferCapacity;
decoderBatchInterval = AppConfig.defaultDecoderBatchInterval;
reconnectInitialDelay = AppConfig.defaultReconnectInitialDelay;
reconnectMaxDelay = AppConfig.defaultReconnectMaxDelay;
reconnectBackoffFactor = AppConfig.defaultReconnectBackoffFactor;
miniLogSeverities = Set.of(AppConfig.defaultMiniLogSeverities);
statusLookback = AppConfig.defaultStatusLookback;
notifyListeners();
}
/// Take values from [other] (used to apply edits from the Settings dialog).
void copyFrom(Settings other) {
wsUrl = other.wsUrl;
packetBufferCapacity = other.packetBufferCapacity;
logBufferCapacity = other.logBufferCapacity;
decoderBatchInterval = other.decoderBatchInterval;
reconnectInitialDelay = other.reconnectInitialDelay;
reconnectMaxDelay = other.reconnectMaxDelay;
reconnectBackoffFactor = other.reconnectBackoffFactor;
miniLogSeverities = Set.of(other.miniLogSeverities);
statusLookback = other.statusLookback;
notifyListeners();
}
Settings clone() => Settings._(
wsUrl: wsUrl,
packetBufferCapacity: packetBufferCapacity,
logBufferCapacity: logBufferCapacity,
decoderBatchInterval: decoderBatchInterval,
reconnectInitialDelay: reconnectInitialDelay,
reconnectMaxDelay: reconnectMaxDelay,
reconnectBackoffFactor: reconnectBackoffFactor,
miniLogSeverities: Set.of(miniLogSeverities),
statusLookback: statusLookback,
);
}