relatica/lib/utils/filter_runner.dart

114 wiersze
3.0 KiB
Dart

import '../models/filters/string_filter.dart';
import '../models/filters/timeline_entry_filter.dart';
import '../models/timeline_entry.dart';
class FilterResult {
final TimelineEntryFilterAction action;
final bool isFiltered;
const FilterResult(this.isFiltered, this.action);
String toActionString() {
return isFiltered ? action.name : 'show';
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is FilterResult &&
runtimeType == other.runtimeType &&
action == other.action &&
isFiltered == other.isFiltered;
@override
int get hashCode => action.hashCode ^ isFiltered.hashCode;
}
FilterResult runFilters(
TimelineEntry entry,
List<TimelineEntryFilter> filters,
) {
var isFiltered = false;
var action = TimelineEntryFilterAction.warn;
for (final filter in filters) {
if (filter.isFiltered(entry)) {
isFiltered = true;
if (filter.action == TimelineEntryFilterAction.hide) {
action = TimelineEntryFilterAction.hide;
break;
}
}
}
return FilterResult(isFiltered, action);
}
extension StringFilterOps on StringFilter {
bool isFiltered(String value) {
switch (type) {
case ComparisonType.contains:
return value.contains(filterString);
case ComparisonType.containsIgnoreCase:
return value.toLowerCase().contains(filterString.toLowerCase());
case ComparisonType.equals:
return value == filterString;
case ComparisonType.equalsIgnoreCase:
return value.toLowerCase() == filterString.toLowerCase();
case ComparisonType.endsWithIgnoreCase:
return value.toLowerCase().endsWith(filterString.toLowerCase());
}
}
}
extension TimelineEntryFilterOps on TimelineEntryFilter {
bool isFiltered(TimelineEntry entry) {
if (authorFilters.isEmpty &&
domainFilters.isEmpty &&
hashtagFilters.isEmpty &&
keywordFilters.isEmpty) {
return false;
}
var authorFiltered = authorFilters.isEmpty ? true : false;
for (final filter in authorFilters) {
if (filter.isFiltered(entry.authorId)) {
authorFiltered = true;
break;
}
}
var hashtagFiltered = hashtagFilters.isEmpty ? true : false;
for (final filter in hashtagFilters) {
for (final tag in entry.tags) {
if (filter.isFiltered(tag)) {
hashtagFiltered = true;
break;
}
}
}
var domainFiltered = domainFilters.isEmpty ? true : false;
for (final filter in domainFilters) {
final domain =
Uri.tryParse(entry.externalLink)?.host ?? entry.externalLink;
if (filter.isFiltered(domain)) {
domainFiltered = true;
break;
}
}
var contentFiltered = keywordFilters.isEmpty ? true : false;
for (final filter in keywordFilters) {
if (filter.isFiltered(entry.body)) {
contentFiltered = true;
break;
}
}
return authorFiltered &&
domainFiltered &&
hashtagFiltered &&
contentFiltered;
}
}