137 lines
5.6 KiB
Dart
137 lines
5.6 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,
|
|
required this.darkMode,
|
|
});
|
|
|
|
String wsUrl;
|
|
int packetBufferCapacity;
|
|
int logBufferCapacity;
|
|
Duration decoderBatchInterval;
|
|
Duration reconnectInitialDelay;
|
|
Duration reconnectMaxDelay;
|
|
double reconnectBackoffFactor;
|
|
Set<int> miniLogSeverities;
|
|
int statusLookback;
|
|
bool darkMode;
|
|
|
|
/// 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,
|
|
darkMode:
|
|
p.getBool('settings.darkMode') ?? AppConfig.defaultDarkMode,
|
|
);
|
|
}
|
|
|
|
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);
|
|
await p.setBool('settings.darkMode', darkMode);
|
|
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;
|
|
darkMode = AppConfig.defaultDarkMode;
|
|
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;
|
|
darkMode = other.darkMode;
|
|
notifyListeners();
|
|
}
|
|
|
|
Settings clone() => Settings._(
|
|
wsUrl: wsUrl,
|
|
packetBufferCapacity: packetBufferCapacity,
|
|
logBufferCapacity: logBufferCapacity,
|
|
decoderBatchInterval: decoderBatchInterval,
|
|
reconnectInitialDelay: reconnectInitialDelay,
|
|
reconnectMaxDelay: reconnectMaxDelay,
|
|
reconnectBackoffFactor: reconnectBackoffFactor,
|
|
miniLogSeverities: Set.of(miniLogSeverities),
|
|
statusLookback: statusLookback,
|
|
darkMode: darkMode,
|
|
);
|
|
} |