mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
- Implemented radio statistics features in multiple screens including chat, channels, and settings. - Added localization for new strings in Swedish, Ukrainian, and Chinese. - Introduced a setting to jump to the oldest unread message in chat and channels. - Enhanced path management and display for contacts and messages. - Updated app settings to include new boolean for jumping to the oldest unread message. - Improved battery indicator and radio stats display in the app bar. - Removed unused wakelock_plus dependency and updated plugin registrations.
289 lines
12 KiB
Dart
289 lines
12 KiB
Dart
enum UnitSystem { metric, imperial }
|
|
|
|
extension UnitSystemValue on UnitSystem {
|
|
String get value {
|
|
switch (this) {
|
|
case UnitSystem.imperial:
|
|
return 'imperial';
|
|
case UnitSystem.metric:
|
|
return 'metric';
|
|
}
|
|
}
|
|
}
|
|
|
|
class AppSettings {
|
|
static const Object _unset = Object();
|
|
|
|
final bool clearPathOnMaxRetry;
|
|
final bool mapShowRepeaters;
|
|
final bool mapShowChatNodes;
|
|
final bool mapShowOtherNodes;
|
|
final bool mapShowOverlaps;
|
|
final double mapTimeFilterHours; // 0 = all time
|
|
final bool mapKeyPrefixEnabled;
|
|
final String mapKeyPrefix;
|
|
final bool mapShowMarkers;
|
|
final bool mapShowGuessedLocations;
|
|
final bool enableMessageTracing;
|
|
final Map<String, double>? mapCacheBounds;
|
|
final int mapCacheMinZoom;
|
|
final int mapCacheMaxZoom;
|
|
final bool notificationsEnabled;
|
|
final bool notifyOnNewMessage;
|
|
final bool notifyOnNewChannelMessage;
|
|
final bool notifyOnNewAdvert;
|
|
final bool autoRouteRotationEnabled;
|
|
final double maxRouteWeight;
|
|
final double initialRouteWeight;
|
|
final double routeWeightSuccessIncrement;
|
|
final double routeWeightFailureDecrement;
|
|
final int maxMessageRetries;
|
|
final String themeMode;
|
|
final String? languageOverride; // null = system default
|
|
final bool appDebugLogEnabled;
|
|
final Map<String, String> batteryChemistryByDeviceId;
|
|
final Map<String, String> batteryChemistryByRepeaterId;
|
|
final UnitSystem unitSystem;
|
|
final Set<String> mutedChannels;
|
|
final bool mapShowDiscoveryContacts;
|
|
final String tcpServerAddress;
|
|
final int tcpServerPort;
|
|
final bool jumpToOldestUnread;
|
|
|
|
AppSettings({
|
|
this.clearPathOnMaxRetry = false,
|
|
this.mapShowRepeaters = true,
|
|
this.mapShowChatNodes = true,
|
|
this.mapShowOtherNodes = true,
|
|
this.mapShowOverlaps = false,
|
|
this.mapTimeFilterHours = 0, // Default to all time
|
|
this.mapKeyPrefixEnabled = false,
|
|
this.mapKeyPrefix = '',
|
|
this.mapShowMarkers = true,
|
|
this.mapShowGuessedLocations = true,
|
|
this.enableMessageTracing = false,
|
|
this.mapCacheBounds,
|
|
this.mapCacheMinZoom = 10,
|
|
this.mapCacheMaxZoom = 15,
|
|
this.notificationsEnabled = true,
|
|
this.notifyOnNewMessage = true,
|
|
this.notifyOnNewChannelMessage = true,
|
|
this.notifyOnNewAdvert = true,
|
|
this.autoRouteRotationEnabled = false,
|
|
this.maxRouteWeight = 5.0,
|
|
this.initialRouteWeight = 3.0,
|
|
this.routeWeightSuccessIncrement = 0.5,
|
|
this.routeWeightFailureDecrement = 0.2,
|
|
this.maxMessageRetries = 5,
|
|
this.themeMode = 'system',
|
|
this.languageOverride,
|
|
this.appDebugLogEnabled = false,
|
|
Map<String, String>? batteryChemistryByDeviceId,
|
|
Map<String, String>? batteryChemistryByRepeaterId,
|
|
this.unitSystem = UnitSystem.metric,
|
|
Set<String>? mutedChannels,
|
|
this.mapShowDiscoveryContacts = true,
|
|
this.tcpServerAddress = '',
|
|
this.tcpServerPort = 0,
|
|
this.jumpToOldestUnread = false,
|
|
}) : batteryChemistryByDeviceId = batteryChemistryByDeviceId ?? {},
|
|
batteryChemistryByRepeaterId = batteryChemistryByRepeaterId ?? {},
|
|
mutedChannels = mutedChannels ?? {};
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'clear_path_on_max_retry': clearPathOnMaxRetry,
|
|
'map_show_repeaters': mapShowRepeaters,
|
|
'map_show_chat_nodes': mapShowChatNodes,
|
|
'map_show_other_nodes': mapShowOtherNodes,
|
|
'map_show_overlaps': mapShowOverlaps,
|
|
'map_time_filter_hours': mapTimeFilterHours,
|
|
'map_key_prefix_enabled': mapKeyPrefixEnabled,
|
|
'map_key_prefix': mapKeyPrefix,
|
|
'map_show_markers': mapShowMarkers,
|
|
'map_show_guessed_locations': mapShowGuessedLocations,
|
|
'enable_message_tracing': enableMessageTracing,
|
|
'map_cache_bounds': mapCacheBounds,
|
|
'map_cache_min_zoom': mapCacheMinZoom,
|
|
'map_cache_max_zoom': mapCacheMaxZoom,
|
|
'notifications_enabled': notificationsEnabled,
|
|
'notify_on_new_message': notifyOnNewMessage,
|
|
'notify_on_new_channel_message': notifyOnNewChannelMessage,
|
|
'notify_on_new_advert': notifyOnNewAdvert,
|
|
'auto_route_rotation_enabled': autoRouteRotationEnabled,
|
|
'max_route_weight': maxRouteWeight,
|
|
'initial_route_weight': initialRouteWeight,
|
|
'route_weight_success_increment': routeWeightSuccessIncrement,
|
|
'route_weight_failure_decrement': routeWeightFailureDecrement,
|
|
'max_message_retries': maxMessageRetries,
|
|
'theme_mode': themeMode,
|
|
'language_override': languageOverride,
|
|
'app_debug_log_enabled': appDebugLogEnabled,
|
|
'battery_chemistry_by_device_id': batteryChemistryByDeviceId,
|
|
'battery_chemistry_by_repeater_id': batteryChemistryByRepeaterId,
|
|
'unit_system': unitSystem.value,
|
|
'muted_channels': mutedChannels.toList(),
|
|
'map_show_discovery_contacts': mapShowDiscoveryContacts,
|
|
'tcp_server_address': tcpServerAddress,
|
|
'tcp_server_port': tcpServerPort,
|
|
'jump_to_oldest_unread': jumpToOldestUnread,
|
|
};
|
|
}
|
|
|
|
factory AppSettings.fromJson(Map<String, dynamic> json) {
|
|
UnitSystem parseUnitSystem(dynamic value) {
|
|
if (value is String && value.toLowerCase() == 'imperial') {
|
|
return UnitSystem.imperial;
|
|
}
|
|
return UnitSystem.metric;
|
|
}
|
|
|
|
return AppSettings(
|
|
clearPathOnMaxRetry: json['clear_path_on_max_retry'] as bool? ?? false,
|
|
mapShowRepeaters: json['map_show_repeaters'] as bool? ?? true,
|
|
mapShowChatNodes: json['map_show_chat_nodes'] as bool? ?? true,
|
|
mapShowOtherNodes: json['map_show_other_nodes'] as bool? ?? true,
|
|
mapShowOverlaps: json['map_show_overlaps'] as bool? ?? false,
|
|
mapTimeFilterHours:
|
|
(json['map_time_filter_hours'] as num?)?.toDouble() ?? 0,
|
|
mapKeyPrefixEnabled: json['map_key_prefix_enabled'] as bool? ?? false,
|
|
mapKeyPrefix: json['map_key_prefix'] as String? ?? '',
|
|
mapShowMarkers: json['map_show_markers'] as bool? ?? true,
|
|
mapShowGuessedLocations:
|
|
json['map_show_guessed_locations'] as bool? ?? true,
|
|
enableMessageTracing: json['enable_message_tracing'] as bool? ?? false,
|
|
mapCacheBounds: (json['map_cache_bounds'] as Map?)?.map(
|
|
(key, value) => MapEntry(key.toString(), (value as num).toDouble()),
|
|
),
|
|
mapCacheMinZoom: json['map_cache_min_zoom'] as int? ?? 10,
|
|
mapCacheMaxZoom: json['map_cache_max_zoom'] as int? ?? 15,
|
|
notificationsEnabled: json['notifications_enabled'] as bool? ?? true,
|
|
notifyOnNewMessage: json['notify_on_new_message'] as bool? ?? true,
|
|
notifyOnNewChannelMessage:
|
|
json['notify_on_new_channel_message'] as bool? ?? true,
|
|
notifyOnNewAdvert: json['notify_on_new_advert'] as bool? ?? true,
|
|
autoRouteRotationEnabled:
|
|
json['auto_route_rotation_enabled'] as bool? ?? false,
|
|
maxRouteWeight: (json['max_route_weight'] as num?)?.toDouble() ?? 5.0,
|
|
initialRouteWeight:
|
|
(json['initial_route_weight'] as num?)?.toDouble() ?? 3.0,
|
|
routeWeightSuccessIncrement:
|
|
(json['route_weight_success_increment'] as num?)?.toDouble() ?? 0.5,
|
|
routeWeightFailureDecrement:
|
|
(json['route_weight_failure_decrement'] as num?)?.toDouble() ?? 0.2,
|
|
maxMessageRetries: json['max_message_retries'] as int? ?? 5,
|
|
themeMode: json['theme_mode'] as String? ?? 'system',
|
|
languageOverride: json['language_override'] as String?,
|
|
appDebugLogEnabled: json['app_debug_log_enabled'] as bool? ?? false,
|
|
batteryChemistryByDeviceId:
|
|
(json['battery_chemistry_by_device_id'] as Map?)?.map(
|
|
(key, value) => MapEntry(key.toString(), value.toString()),
|
|
) ??
|
|
{},
|
|
batteryChemistryByRepeaterId:
|
|
(json['battery_chemistry_by_repeater_id'] as Map?)?.map(
|
|
(key, value) => MapEntry(key.toString(), value.toString()),
|
|
) ??
|
|
{},
|
|
unitSystem: parseUnitSystem(json['unit_system']),
|
|
mutedChannels:
|
|
((json['muted_channels'] as List?)
|
|
?.map((e) => e.toString())
|
|
.toSet()) ??
|
|
{},
|
|
mapShowDiscoveryContacts:
|
|
json['map_show_discovery_contacts'] as bool? ?? true,
|
|
tcpServerAddress: json['tcp_server_address'] as String? ?? '',
|
|
tcpServerPort: json['tcp_server_port'] as int? ?? 0,
|
|
jumpToOldestUnread: json['jump_to_oldest_unread'] as bool? ?? false,
|
|
);
|
|
}
|
|
|
|
AppSettings copyWith({
|
|
bool? clearPathOnMaxRetry,
|
|
bool? mapShowRepeaters,
|
|
bool? mapShowChatNodes,
|
|
bool? mapShowOtherNodes,
|
|
bool? mapShowOverlaps,
|
|
double? mapTimeFilterHours,
|
|
bool? mapKeyPrefixEnabled,
|
|
String? mapKeyPrefix,
|
|
bool? mapShowMarkers,
|
|
bool? mapShowGuessedLocations,
|
|
bool? enableMessageTracing,
|
|
Object? mapCacheBounds = _unset,
|
|
int? mapCacheMinZoom,
|
|
int? mapCacheMaxZoom,
|
|
bool? notificationsEnabled,
|
|
bool? notifyOnNewMessage,
|
|
bool? notifyOnNewChannelMessage,
|
|
bool? notifyOnNewAdvert,
|
|
bool? autoRouteRotationEnabled,
|
|
double? maxRouteWeight,
|
|
double? initialRouteWeight,
|
|
double? routeWeightSuccessIncrement,
|
|
double? routeWeightFailureDecrement,
|
|
int? maxMessageRetries,
|
|
String? themeMode,
|
|
Object? languageOverride = _unset,
|
|
bool? appDebugLogEnabled,
|
|
Map<String, String>? batteryChemistryByDeviceId,
|
|
Map<String, String>? batteryChemistryByRepeaterId,
|
|
UnitSystem? unitSystem,
|
|
Set<String>? mutedChannels,
|
|
bool? mapShowDiscoveryContacts,
|
|
String? tcpServerAddress,
|
|
int? tcpServerPort,
|
|
bool? jumpToOldestUnread,
|
|
}) {
|
|
return AppSettings(
|
|
clearPathOnMaxRetry: clearPathOnMaxRetry ?? this.clearPathOnMaxRetry,
|
|
mapShowRepeaters: mapShowRepeaters ?? this.mapShowRepeaters,
|
|
mapShowChatNodes: mapShowChatNodes ?? this.mapShowChatNodes,
|
|
mapShowOtherNodes: mapShowOtherNodes ?? this.mapShowOtherNodes,
|
|
mapShowOverlaps: mapShowOverlaps ?? this.mapShowOverlaps,
|
|
mapTimeFilterHours: mapTimeFilterHours ?? this.mapTimeFilterHours,
|
|
mapKeyPrefixEnabled: mapKeyPrefixEnabled ?? this.mapKeyPrefixEnabled,
|
|
mapKeyPrefix: mapKeyPrefix ?? this.mapKeyPrefix,
|
|
mapShowMarkers: mapShowMarkers ?? this.mapShowMarkers,
|
|
mapShowGuessedLocations:
|
|
mapShowGuessedLocations ?? this.mapShowGuessedLocations,
|
|
enableMessageTracing: enableMessageTracing ?? this.enableMessageTracing,
|
|
mapCacheBounds: mapCacheBounds == _unset
|
|
? this.mapCacheBounds
|
|
: mapCacheBounds as Map<String, double>?,
|
|
mapCacheMinZoom: mapCacheMinZoom ?? this.mapCacheMinZoom,
|
|
mapCacheMaxZoom: mapCacheMaxZoom ?? this.mapCacheMaxZoom,
|
|
notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
|
|
notifyOnNewMessage: notifyOnNewMessage ?? this.notifyOnNewMessage,
|
|
notifyOnNewChannelMessage:
|
|
notifyOnNewChannelMessage ?? this.notifyOnNewChannelMessage,
|
|
notifyOnNewAdvert: notifyOnNewAdvert ?? this.notifyOnNewAdvert,
|
|
autoRouteRotationEnabled:
|
|
autoRouteRotationEnabled ?? this.autoRouteRotationEnabled,
|
|
maxRouteWeight: maxRouteWeight ?? this.maxRouteWeight,
|
|
initialRouteWeight: initialRouteWeight ?? this.initialRouteWeight,
|
|
routeWeightSuccessIncrement:
|
|
routeWeightSuccessIncrement ?? this.routeWeightSuccessIncrement,
|
|
routeWeightFailureDecrement:
|
|
routeWeightFailureDecrement ?? this.routeWeightFailureDecrement,
|
|
maxMessageRetries: maxMessageRetries ?? this.maxMessageRetries,
|
|
themeMode: themeMode ?? this.themeMode,
|
|
languageOverride: languageOverride == _unset
|
|
? this.languageOverride
|
|
: languageOverride as String?,
|
|
appDebugLogEnabled: appDebugLogEnabled ?? this.appDebugLogEnabled,
|
|
batteryChemistryByDeviceId:
|
|
batteryChemistryByDeviceId ?? this.batteryChemistryByDeviceId,
|
|
batteryChemistryByRepeaterId:
|
|
batteryChemistryByRepeaterId ?? this.batteryChemistryByRepeaterId,
|
|
unitSystem: unitSystem ?? this.unitSystem,
|
|
mutedChannels: mutedChannels ?? this.mutedChannels,
|
|
mapShowDiscoveryContacts:
|
|
mapShowDiscoveryContacts ?? this.mapShowDiscoveryContacts,
|
|
tcpServerAddress: tcpServerAddress ?? this.tcpServerAddress,
|
|
tcpServerPort: tcpServerPort ?? this.tcpServerPort,
|
|
jumpToOldestUnread: jumpToOldestUnread ?? this.jumpToOldestUnread,
|
|
);
|
|
}
|
|
}
|