223 lines
7.6 KiB
Dart
223 lines
7.6 KiB
Dart
import 'dart:async';
|
|
import 'package:bloc/bloc.dart';
|
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
import 'package:get_it/get_it.dart';
|
|
import 'package:okane/database/sqlite.dart';
|
|
import 'package:okane/ui/navigation.dart';
|
|
|
|
part 'core.freezed.dart';
|
|
|
|
@freezed
|
|
abstract class CoreState with _$CoreState {
|
|
const factory CoreState({
|
|
@Default(OkanePage.accounts) OkanePage activePage,
|
|
int? activeAccountIndex,
|
|
@Default(null) TransactionDto? activeTransaction,
|
|
@Default([]) List<Account> accounts,
|
|
@Default([]) List<RecurringTransactionDto> recurringTransactions,
|
|
@Default([]) List<TransactionDto> transactions,
|
|
@Default([]) List<TransactionTemplateDto> transactionTemplates,
|
|
@Default([]) List<Beneficiary> beneficiaries,
|
|
@Default([]) List<ExpenseCategory> expenseCategories,
|
|
@Default([]) List<BudgetsDto> budgets,
|
|
@Default([]) List<BudgetItemDto> budgetItems,
|
|
@Default(null) BudgetsDto? activeBudget,
|
|
@Default([]) List<LoanDto> loans,
|
|
@Default(null) LoanDto? activeLoan,
|
|
@Default(false) bool isDeletingAccount,
|
|
}) = _CoreState;
|
|
}
|
|
|
|
class CoreCubit extends Cubit<CoreState> {
|
|
CoreCubit() : super(CoreState());
|
|
|
|
StreamSubscription<void>? _recurringTransactionStreamSubscription;
|
|
StreamSubscription<void>? _transactionTemplatesStreamSubcription;
|
|
StreamSubscription<void>? _accountsStreamSubscription;
|
|
StreamSubscription<void>? _transactionsStreamSubscription;
|
|
StreamSubscription<void>? _beneficiariesStreamSubscription;
|
|
StreamSubscription<void>? _expenseCategoryStreamSubscription;
|
|
StreamSubscription<void>? _budgetsStreamSubscription;
|
|
StreamSubscription<void>? _budgetItemsStreamSubscription;
|
|
StreamSubscription<void>? _loanStreamSubscription;
|
|
|
|
void setupAccountStream() {
|
|
_accountsStreamSubscription?.cancel();
|
|
_accountsStreamSubscription = GetIt.I
|
|
.get<OkaneDatabase>()
|
|
.accountsDao
|
|
.accountsStream()
|
|
.listen((accounts) {
|
|
emit(
|
|
state.copyWith(
|
|
accounts: accounts,
|
|
activeAccountIndex:
|
|
accounts.isNotEmpty ? state.activeAccountIndex ?? 0 : null,
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
void setupStreams(Account account) {
|
|
final db = GetIt.I.get<OkaneDatabase>();
|
|
setupAccountStream();
|
|
_recurringTransactionStreamSubscription?.cancel();
|
|
_recurringTransactionStreamSubscription = db.recurringTransactionsDao
|
|
.recurringTransactionsStream(account)
|
|
.listen((recurring) async {
|
|
emit(state.copyWith(recurringTransactions: recurring));
|
|
});
|
|
_transactionTemplatesStreamSubcription?.cancel();
|
|
_transactionTemplatesStreamSubcription = db.transactionTemplatesDao
|
|
.transactionTemplatesStream(account)
|
|
.listen((templates) async {
|
|
emit(state.copyWith(transactionTemplates: templates));
|
|
});
|
|
_transactionsStreamSubscription?.cancel();
|
|
_transactionsStreamSubscription = db.transactionsDao
|
|
.transactionsStream(activeAccount!)
|
|
.listen((transactions) async {
|
|
emit(state.copyWith(transactions: transactions));
|
|
});
|
|
_beneficiariesStreamSubscription?.cancel();
|
|
_beneficiariesStreamSubscription = db.beneficiariesDao
|
|
.beneficiariesStream()
|
|
.listen((beneficiaries) async {
|
|
emit(state.copyWith(beneficiaries: beneficiaries));
|
|
});
|
|
_expenseCategoryStreamSubscription?.cancel();
|
|
_expenseCategoryStreamSubscription = db.expenseCategoriesDao
|
|
.expenseCategoriesStream(account)
|
|
.listen((expenseCategories) async {
|
|
emit(state.copyWith(expenseCategories: expenseCategories));
|
|
});
|
|
_budgetsStreamSubscription?.cancel();
|
|
_budgetsStreamSubscription = db.budgetsDao
|
|
.budgetsStream(activeAccount!)
|
|
.listen((budgets) async {
|
|
print("BUDGETS: $budgets");
|
|
emit(state.copyWith(budgets: budgets));
|
|
});
|
|
_loanStreamSubscription?.cancel();
|
|
_loanStreamSubscription = db.loansDao.loansStream(account).listen((
|
|
loans,
|
|
) async {
|
|
emit(state.copyWith(loans: loans));
|
|
});
|
|
}
|
|
|
|
void cancelStreams() {
|
|
_recurringTransactionStreamSubscription?.cancel();
|
|
_accountsStreamSubscription?.cancel();
|
|
_beneficiariesStreamSubscription?.cancel();
|
|
_budgetsStreamSubscription?.cancel();
|
|
_expenseCategoryStreamSubscription?.cancel();
|
|
_transactionsStreamSubscription?.cancel();
|
|
_transactionTemplatesStreamSubcription?.cancel();
|
|
_loanStreamSubscription?.cancel();
|
|
}
|
|
|
|
Future<void> init() async {
|
|
final db = GetIt.I.get<OkaneDatabase>();
|
|
final accounts = await db.accountsDao.getAccounts();
|
|
final account = accounts.isEmpty ? null : accounts[0];
|
|
emit(
|
|
state.copyWith(
|
|
accounts: accounts,
|
|
activeAccountIndex: accounts.isEmpty ? null : 0,
|
|
transactions: await db.transactionsDao.getTransactions(account),
|
|
beneficiaries: await db.beneficiariesDao.getBeneficiaries(),
|
|
transactionTemplates: await db.transactionTemplatesDao
|
|
.getTransactionTemplates(account),
|
|
recurringTransactions: await db.recurringTransactionsDao
|
|
.getRecurringTransactions(account),
|
|
expenseCategories: await db.expenseCategoriesDao.getExpenseCategories(
|
|
account,
|
|
),
|
|
//budgets: await db.budgetsDao.getBudgets(account),
|
|
loans: await db.loansDao.getLoans(account),
|
|
),
|
|
);
|
|
|
|
if (account != null) {
|
|
setupAccountStream();
|
|
setupStreams(account);
|
|
} else {
|
|
setupAccountStream();
|
|
}
|
|
print("Core init done");
|
|
}
|
|
|
|
void setPage(OkanePage page) {
|
|
emit(state.copyWith(activePage: page));
|
|
}
|
|
|
|
Future<void> setActiveAccountIndex(int index) async {
|
|
final db = GetIt.I.get<OkaneDatabase>();
|
|
final account = state.accounts[index];
|
|
emit(
|
|
state.copyWith(
|
|
activeAccountIndex: index,
|
|
transactions: await db.transactionsDao.getTransactions(account),
|
|
beneficiaries: await db.beneficiariesDao.getBeneficiaries(),
|
|
transactionTemplates: await db.transactionTemplatesDao
|
|
.getTransactionTemplates(account),
|
|
recurringTransactions: await db.recurringTransactionsDao
|
|
.getRecurringTransactions(account),
|
|
budgets: await db.budgetsDao.getBudgets(account),
|
|
activeBudget: null,
|
|
activeTransaction: null,
|
|
activeLoan: null,
|
|
),
|
|
);
|
|
setupStreams(account);
|
|
}
|
|
|
|
void setActiveTransaction(TransactionDto? item) {
|
|
emit(state.copyWith(activeTransaction: item));
|
|
}
|
|
|
|
void setAccounts(List<Account> accounts) {
|
|
emit(state.copyWith(accounts: accounts));
|
|
}
|
|
|
|
void setActiveBudget(BudgetsDto? budget) {
|
|
emit(state.copyWith(activeBudget: budget, budgetItems: []));
|
|
_budgetItemsStreamSubscription?.cancel();
|
|
if (budget != null) {
|
|
_budgetItemsStreamSubscription = GetIt.I
|
|
.get<OkaneDatabase>()
|
|
.budgetsDao
|
|
.watchBudgetItems(budget.budget)
|
|
.listen((items) {
|
|
emit(state.copyWith(budgetItems: items));
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> deleteAccount(Account account) async {
|
|
final l = List.of(state.accounts);
|
|
l.removeWhere((a) => a.id == account.id);
|
|
final newIndex = l.isEmpty ? null : 0;
|
|
emit(state.copyWith(activeAccountIndex: newIndex, isDeletingAccount: true));
|
|
|
|
cancelStreams();
|
|
try {
|
|
// TODO
|
|
//await db.deleteAccount(account);
|
|
} finally {
|
|
emit(state.copyWith(isDeletingAccount: false));
|
|
}
|
|
await init();
|
|
}
|
|
|
|
void setActiveLoan(LoanDto loan) {
|
|
emit(state.copyWith(activeLoan: loan));
|
|
}
|
|
|
|
Account? get activeAccount =>
|
|
state.activeAccountIndex == null
|
|
? null
|
|
: state.accounts[state.activeAccountIndex!];
|
|
}
|