new favourites feature

This commit is contained in:
davmar
2026-09-10 16:25:24 +02:00
parent aec89ac41d
commit 83295439d5
22 changed files with 3168 additions and 282 deletions
+6
View File
@@ -51,6 +51,12 @@ abstract final class StorageKeys {
/// How many years ahead Look ahead can navigate (default 5).
static const lookAheadMaxYears = 'look_ahead_max_years_v1';
/// Named Overview chart favourites (JSON list).
static const overviewFavourites = 'overview_favourites_v1';
/// Home screen filter widgets (JSON list).
static const homeFilterWidgets = 'home_filter_widgets_v1';
}
/// Named routes registered on [MaterialApp].
+87
View File
@@ -0,0 +1,87 @@
/// Apply a [TransactionFilterSelection] and compute Home widget metrics.
library;
import '../models/bank.dart';
import '../models/transaction_meta.dart';
import '../providers/tx_meta_provider.dart';
import '../utils/tx_calendar.dart';
import '../widgets/label_filter_dialog.dart';
class TxFilterMetrics {
const TxFilterMetrics({
required this.count,
required this.amountIn,
required this.amountOut,
required this.transactions,
});
final int count;
final double amountIn;
final double amountOut;
final List<BankTransaction> transactions;
double get net => amountIn - amountOut;
}
/// Filter [all] the same way Transactions does (pool → search → flow/amount).
List<BankTransaction> applyTransactionFilter({
required List<BankTransaction> all,
required TxMetaController meta,
required TransactionFilterSelection filter,
DateTime? month,
}) {
final nowMonth = monthStart(month ?? DateTime.now());
final pool = filter.monthOnly
? [
for (final tx in all)
if (_txInMonth(tx, nowMonth)) tx,
]
: all;
return [
for (final tx in meta.search(
pool,
filter.query,
labelIds: filter.labelIds,
))
if (txMatchesFlow(tx, filter.flow) &&
txMatchesAmountRange(tx, filter.amountRange))
tx,
];
}
TxFilterMetrics computeTxFilterMetrics({
required List<BankTransaction> all,
required TxMetaController meta,
required TransactionFilterSelection filter,
DateTime? month,
}) {
final filtered = applyTransactionFilter(
all: all,
meta: meta,
filter: filter,
month: month,
);
var amountIn = 0.0;
var amountOut = 0.0;
for (final tx in filtered) {
if (meta.metaFor(tx).internalTransfer) continue;
if (tx.amount < 0) {
amountOut += tx.amount.abs();
} else if (tx.amount > 0) {
amountIn += tx.amount;
}
}
return TxFilterMetrics(
count: filtered.length,
amountIn: amountIn,
amountOut: amountOut,
transactions: filtered,
);
}
bool _txInMonth(BankTransaction tx, DateTime month) {
final date = DateTime.tryParse(tx.date);
if (date == null) return false;
return isSameMonth(date, month);
}