fix colors; add case sensitive and regex checkboxes

This commit is contained in:
hardliner66 2024-10-06 15:58:31 +02:00
parent ceefe500e9
commit bfd0baf771
3 changed files with 117 additions and 19 deletions

View File

@ -111,6 +111,22 @@ class LogViewerScreenState extends State<LogViewerScreen> {
},
),
),
Checkbox(
value: settingsController.useRegex,
onChanged: (value) {
settingsController.updateUseRegex(value ?? false);
_filterLogs();
},
),
const Text('Use Regex'),
Checkbox(
value: settingsController.caseSensitive,
onChanged: (value) {
settingsController.updateCaseSensitive(value ?? false);
_filterLogs();
},
),
const Text('Case Sensitive'),
DropdownButton<LogLevel>(
underline: Container(height: 0),
alignment: Alignment.center,
@ -235,7 +251,8 @@ class LogViewerScreenState extends State<LogViewerScreen> {
visibleLogs = logs
.where((log) =>
log.level.index >= selectedLogLevel.index &&
log.contains(controller.text))
log.contains(controller.text, settingsController.useRegex,
caseSensitive: settingsController.caseSensitive))
.toList();
});
}
@ -247,14 +264,12 @@ class LogViewerScreenState extends State<LogViewerScreen> {
if (line.isNotEmpty) {
List<String> parts = line.split('\t');
if (parts.length >= 5) {
var component = parts[4];
int i = component.lastIndexOf('@');
parsedLogs.add(LogEntry(
parts[0],
fromString(parts[1]),
parts[2],
parts[3],
Component(component.substring(0, i), component.substring(i + 1)),
parts[4],
parts.sublist(5),
));
} else if (!line.contains('*** NEW LOG FILE ***')) {
@ -327,21 +342,44 @@ class LogEntry {
final LogLevel level;
final String category;
final String threadId;
final Component component;
final String component;
final List<String> message;
LogEntry(this.timestamp, this.level, this.category, this.threadId,
this.component, this.message);
bool contains(String value) {
var v = value.toLowerCase();
return timestamp.toLowerCase().contains(v) ||
level.lowerCaseName.contains(v) ||
category.toLowerCase().contains(v) ||
threadId.toLowerCase().contains(v) ||
component.name.toLowerCase().contains(v) ||
component.address.toLowerCase().contains(v) ||
message.where((value) => value.toLowerCase().contains(v)).isNotEmpty;
bool contains(String value, bool useRegex, {bool caseSensitive = false}) {
if (useRegex) {
try {
var regex =
RegExp(value, caseSensitive: caseSensitive, multiLine: true);
return regex.hasMatch(timestamp) ||
regex.hasMatch(level.lowerCaseName) ||
regex.hasMatch(category) ||
regex.hasMatch(threadId) ||
regex.hasMatch(component) ||
regex.hasMatch(message.join('\n'));
} catch (e) {
return false;
}
} else if (caseSensitive) {
var v = value;
return timestamp.contains(v) ||
level.name.contains(v) ||
category.contains(v) ||
threadId.contains(v) ||
component.contains(v) ||
message.where((value) => value.contains(v)).isNotEmpty;
} else {
var v = value.toLowerCase();
return timestamp.toLowerCase().contains(v) ||
level.lowerCaseName.contains(v) ||
category.toLowerCase().contains(v) ||
threadId.toLowerCase().contains(v) ||
component.toLowerCase().contains(v) ||
message.where((value) => value.toLowerCase().contains(v)).isNotEmpty;
}
}
}
@ -367,7 +405,7 @@ class LogEntryWidget extends StatelessWidget {
),
),
Text(
'Component: ${log.component.name}@${log.component.address}',
'Component: ${log.component}',
style: const TextStyle(
fontStyle: FontStyle.italic,
),
@ -390,7 +428,7 @@ class LogEntryWidget extends StatelessWidget {
case LogLevel.debug:
return Colors.green;
default:
return Colors.black;
return Colors.blueGrey;
}
}
}

View File

@ -16,24 +16,63 @@ class SettingsController with ChangeNotifier {
// Make ThemeMode a private variable so it is not updated directly without
// also persisting the changes with the SettingsService.
late ThemeMode _themeMode;
late bool _useRegex;
late bool _caseSensitive;
// Allow Widgets to read the user's preferred ThemeMode.
ThemeMode get themeMode => _themeMode;
bool get useRegex => _useRegex;
bool get caseSensitive => _caseSensitive;
/// Load the user's settings from the SettingsService. It may load from a
/// local database or the internet. The controller only knows it can load the
/// settings from the service.
Future<void> loadSettings() async {
_themeMode = await _settingsService.themeMode();
_useRegex = await _settingsService.useRegex();
_caseSensitive = await _settingsService.caseSensitive();
// Important! Inform listeners a change has occurred.
notifyListeners();
}
Future<void> updateCaseSensitive(bool? caseSensitive) async {
if (caseSensitive == null) return; // Do nothing if null is passed in.
// Do not perform any work if new and old ThemeMode are identical
if (caseSensitive == _caseSensitive) return;
// Otherwise, store the new ThemeMode in memory
_caseSensitive = caseSensitive;
// Important! Inform listeners a change has occurred.
notifyListeners();
// Persist the changes to a local database or the internet using the
// SettingService.
await _settingsService.updateCaseSensitive(caseSensitive);
}
/// Update and persist the ThemeMode based on the user's selection.
Future<void> updateUseRegex(bool? regex) async {
if (regex == null) return; // Do nothing if null is passed in.
// Do not perform any work if new and old ThemeMode are identical
if (regex == _useRegex) return;
// Otherwise, store the new ThemeMode in memory
_useRegex = regex;
// Important! Inform listeners a change has occurred.
notifyListeners();
// Persist the changes to a local database or the internet using the
// SettingService.
await _settingsService.updateUseRegex(regex);
}
/// Update and persist the ThemeMode based on the user's selection.
Future<void> updateThemeMode(ThemeMode? newThemeMode) async {
if (newThemeMode == null) return;
if (newThemeMode == null) return; // Do nothing if null is passed in.
// Do not perform any work if new and old ThemeMode are identical
if (newThemeMode == _themeMode) return;

View File

@ -17,9 +17,30 @@ class SettingsService {
return ThemeMode.system;
}
Future<bool> useRegex() async {
var prefs = await SharedPreferences.getInstance();
return prefs.getBool("useRegex") ?? false;
}
Future<bool> caseSensitive() async {
var prefs = await SharedPreferences.getInstance();
return prefs.getBool("caseSensitive") ?? false;
}
/// Persists the user's preferred ThemeMode to local or remote storage.
Future<void> updateThemeMode(ThemeMode theme) async {
var prefs = await SharedPreferences.getInstance();
prefs.setInt("theme", theme.index);
}
/// Persists the user's preferred ThemeMode to local or remote storage.
Future<void> updateUseRegex(bool useRegex) async {
var prefs = await SharedPreferences.getInstance();
prefs.setBool("useRegex", useRegex);
}
Future<void> updateCaseSensitive(bool caseSensitive) async {
var prefs = await SharedPreferences.getInstance();
prefs.setBool("caseSensitive", caseSensitive);
}
}