relatica/lib/services/timeline_entry_filter_servi...

95 wiersze
2.4 KiB
Dart

import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:result_monad/result_monad.dart';
import '../models/exec_error.dart';
import '../models/filters/timeline_entry_filter.dart';
import '../models/timeline_entry.dart';
import '../utils/filter_runner.dart';
class TimelineEntryFilterService extends ChangeNotifier {
static final _logger = Logger('$TimelineEntryFilterService');
final String filePath;
final _filters = <String, TimelineEntryFilter>{};
final _entryCache = <String, _EntryCacheItem>{};
List<TimelineEntryFilter> get filters =>
UnmodifiableListView(_filters.values);
TimelineEntryFilterService(this.filePath);
void load() {
final file = File(filePath);
if (!file.existsSync()) {
return;
}
try {
final str = file.readAsStringSync();
final json = jsonDecode(str) as List<dynamic>;
final filters = json.map((j) => TimelineEntryFilter.fromJson(j)).toList();
_filters.clear();
_filters.addEntries(filters.map((f) => MapEntry(f.id, f)));
} catch (e) {
_logger.severe('Error parsing filters file $filePath: $e');
}
}
void save() {
try {
final json = _filters.values.map((f) => f.toJson()).toList();
final str = jsonEncode(json);
File(filePath).writeAsStringSync(str);
} catch (e) {
_logger.severe('Error writing filters file $filePath: $e');
}
}
Result<TimelineEntryFilter, ExecError> getForId(String id) {
if (!_filters.containsKey(id)) {
return buildErrorResult(
type: ErrorType.notFound,
message: 'No filter with id: $id',
);
}
return Result.ok(_filters[id]!);
}
void upsertFilter(TimelineEntryFilter filter) {
_filters[filter.id] = filter;
_entryCache.clear();
save();
notifyListeners();
}
void removeById(String id) {
_filters.remove(id);
_entryCache.clear();
save();
notifyListeners();
}
FilterResult checkTimelineEntry(TimelineEntry entry) {
if (entry == _entryCache[entry.id]?.entry) {
return _entryCache[entry.id]!.result;
}
final result = runFilters(entry, _filters.values.toList());
_entryCache[entry.id] = _EntryCacheItem(entry, result);
return result;
}
}
class _EntryCacheItem {
final TimelineEntry entry;
final FilterResult result;
_EntryCacheItem(this.entry, this.result);
}