Files
umbrix/lib/features/logs/notifier/logs_notifier.dart

81 lines
2.1 KiB
Dart
Raw Normal View History

2023-07-06 17:18:41 +03:30
import 'dart:async';
import 'package:dartx/dartx.dart';
import 'package:hiddify/data/data_providers.dart';
import 'package:hiddify/domain/clash/clash.dart';
import 'package:hiddify/features/logs/notifier/logs_state.dart';
import 'package:hiddify/utils/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'logs_notifier.g.dart';
// TODO: rewrite
2023-08-19 22:27:23 +03:30
@Riverpod(keepAlive: true)
2023-07-06 17:18:41 +03:30
class LogsNotifier extends _$LogsNotifier with AppLogger {
static const maxLength = 1000;
@override
Stream<LogsState> build() {
state = const AsyncData(LogsState());
2023-08-19 22:27:23 +03:30
return ref.read(coreFacadeProvider).watchLogs().asyncMap(
2023-07-06 17:18:41 +03:30
(event) async {
_logs = [
event.getOrElse((l) => throw l),
..._logs.takeFirst(maxLength - 1),
];
return switch (state) {
// ignore: unused_result
AsyncData(:final value) => value.copyWith(logs: await _computeLogs()),
_ => LogsState(logs: await _computeLogs()),
};
},
);
}
2023-08-19 22:27:23 +03:30
var _logs = <String>[];
2023-07-06 17:18:41 +03:30
final _debouncer = CallbackDebouncer(const Duration(milliseconds: 200));
LogLevel? _levelFilter;
String _filter = "";
2023-08-19 22:27:23 +03:30
Future<List<String>> _computeLogs() async {
2023-07-06 17:18:41 +03:30
if (_levelFilter == null && _filter.isEmpty) return _logs;
return _logs.where((e) {
2023-08-19 22:27:23 +03:30
return _filter.isEmpty || e.contains(_filter);
2023-07-06 17:18:41 +03:30
}).toList();
}
void clear() {
if (state case AsyncData(:final value)) {
state = AsyncData(value.copyWith(logs: [])).copyWithPrevious(state);
}
}
void filterMessage(String? filter) {
_filter = filter ?? '';
_debouncer(
() async {
if (state case AsyncData(:final value)) {
state = AsyncData(
value.copyWith(
filter: _filter,
logs: await _computeLogs(),
),
).copyWithPrevious(state);
}
},
);
}
Future<void> filterLevel(LogLevel? level) async {
_levelFilter = level;
if (state case AsyncData(:final value)) {
state = AsyncData(
value.copyWith(
levelFilter: _levelFilter,
logs: await _computeLogs(),
),
).copyWithPrevious(state);
}
}
}