use provider to keep logfilter alive

This commit is contained in:
Fabian Freund
2026-01-21 15:18:52 +01:00
parent b573ed5645
commit 9155b9bace
3 changed files with 120 additions and 14 deletions
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024-2025 Fabian Freund.
*
* This file is part of WebLibre
* (see https://weblibre.eu).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:logger/logger.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'log_filter.g.dart';
@Riverpod(keepAlive: true)
class LogFilter extends _$LogFilter {
@override
Level build() {
return Level.all;
}
// ignore: use_setters_to_change_properties
void setFilter(Level level) {
state = level;
}
}
@@ -0,0 +1,61 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'log_filter.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, type=warning
@ProviderFor(LogFilter)
final logFilterProvider = LogFilterProvider._();
final class LogFilterProvider extends $NotifierProvider<LogFilter, Level> {
LogFilterProvider._()
: super(
from: null,
argument: null,
retry: null,
name: r'logFilterProvider',
isAutoDispose: false,
dependencies: null,
$allTransitiveDependencies: null,
);
@override
String debugGetCreateSourceHash() => _$logFilterHash();
@$internal
@override
LogFilter create() => LogFilter();
/// {@macro riverpod.override_with_value}
Override overrideWithValue(Level value) {
return $ProviderOverride(
origin: this,
providerOverride: $SyncValueProvider<Level>(value),
);
}
}
String _$logFilterHash() => r'b2ee125735571998293b0396907938c38a54d0b5';
abstract class _$LogFilter extends $Notifier<Level> {
Level build();
@$mustCallSuper
@override
void runBuild() {
final ref = this.ref as $Ref<Level, Level>;
final element =
ref.element
as $ClassProviderElement<
AnyNotifier<Level, Level>,
Level,
Object?,
Object?
>;
element.handleCreate(ref, build);
}
}
@@ -23,10 +23,12 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:timeago/timeago.dart' as timeago; import 'package:timeago/timeago.dart' as timeago;
import 'package:weblibre/core/logger.dart'; import 'package:weblibre/core/logger.dart';
import 'package:weblibre/features/settings/domain/providers/log_filter.dart';
import 'package:weblibre/utils/ui_helper.dart'; import 'package:weblibre/utils/ui_helper.dart';
IconData _levelIcon(Level level) { IconData _levelIcon(Level level) {
@@ -77,7 +79,7 @@ Color _levelBackgroundColor(Level level, BuildContext context) {
}; };
} }
class ErrorLogsScreen extends HookWidget { class ErrorLogsScreen extends HookConsumerWidget {
const ErrorLogsScreen({super.key}); const ErrorLogsScreen({super.key});
String _logsText() { String _logsText() {
@@ -93,13 +95,14 @@ class ErrorLogsScreen extends HookWidget {
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, WidgetRef ref) {
final minLogLevel = useState(Level.all); final minLogLevel = ref.watch(logFilterProvider);
final allLogs = useMemoized(() => loggerMemory.buffer.toList()); final allLogs = useMemoized(() => loggerMemory.buffer.toList());
final sortedLogs = useMemoized( final sortedLogs = useMemoized(
() => allLogs.reversed () => allLogs.reversed
.where((e) => e.level.value >= minLogLevel.value.value) .where((e) => e.level.value >= minLogLevel.value)
.toList(), .toList(),
[allLogs, minLogLevel.value], [allLogs, minLogLevel.value],
); );
@@ -113,17 +116,22 @@ class ErrorLogsScreen extends HookWidget {
return TextButton.icon( return TextButton.icon(
onPressed: controller.open, onPressed: controller.open,
icon: const Icon(Icons.filter_list), icon: const Icon(Icons.filter_list),
label: Text(minLogLevel.value.name.toUpperCase()), label: Text(minLogLevel.name.toUpperCase()),
); );
}, },
menuChildren: [ menuChildren: [
const Divider(height: 0), const Divider(height: 0),
_buildLevelFilterMenuItem(context, minLogLevel, Level.trace), _buildLevelFilterMenuItem(context, ref, minLogLevel, Level.trace),
_buildLevelFilterMenuItem(context, minLogLevel, Level.debug), _buildLevelFilterMenuItem(context, ref, minLogLevel, Level.debug),
_buildLevelFilterMenuItem(context, minLogLevel, Level.info), _buildLevelFilterMenuItem(context, ref, minLogLevel, Level.info),
_buildLevelFilterMenuItem(context, minLogLevel, Level.warning), _buildLevelFilterMenuItem(
_buildLevelFilterMenuItem(context, minLogLevel, Level.error), context,
_buildLevelFilterMenuItem(context, minLogLevel, Level.fatal), ref,
minLogLevel,
Level.warning,
),
_buildLevelFilterMenuItem(context, ref, minLogLevel, Level.error),
_buildLevelFilterMenuItem(context, ref, minLogLevel, Level.fatal),
], ],
), ),
IconButton( IconButton(
@@ -150,10 +158,11 @@ class ErrorLogsScreen extends HookWidget {
Widget _buildLevelFilterMenuItem( Widget _buildLevelFilterMenuItem(
BuildContext context, BuildContext context,
ValueNotifier<Level> minLogLevel, WidgetRef ref,
Level minLogLevel,
Level level, Level level,
) { ) {
final isSelected = level.value == minLogLevel.value.value; final isSelected = level.value == minLogLevel.value;
final levelColor = _levelColor(level); final levelColor = _levelColor(level);
return CheckboxMenuButton( return CheckboxMenuButton(
@@ -161,7 +170,7 @@ class ErrorLogsScreen extends HookWidget {
value: isSelected, value: isSelected,
onChanged: (value) { onChanged: (value) {
if (value == true) { if (value == true) {
minLogLevel.value = level; ref.read(logFilterProvider.notifier).setFilter(level);
} }
}, },
child: Text(level.name.toUpperCase()), child: Text(level.name.toUpperCase()),