import 'dart:async'; import 'package:drift/drift.dart'; import 'package:flutter/material.dart'; import '../Entities/dialog_type_enum.dart'; import '../Entities/drift_database.dart'; import '../Pages/Dialog/dialog_action.dart'; import '../Pages/Dialog/dialog_input_field.dart'; import '../Pages/Dialog/dynamic_dialog.dart'; import '../Repositories/account_repository.dart'; /// Steuert die Interaktion mit den Accounts class AccountController { /// Gibt die aktuell gültige Instanz der Klasse zurück factory AccountController() => _instance; /// Erstellt eine neue Instanz dieser Klasse AccountController._internal() { _newAccountDialog = DynamicDialog( title: 'Neues Konto erstellen', icon: Icons.account_balance_wallet, inputFields: [ const DialogInputField(id: 'name', label: 'Name', autoFocus: true), ], actions: [ DialogAction(label: 'Abbruch'), DialogAction( label: 'Speichern', isPrimary: true, onPressed: _saveNewAccount, ), ], ); _errorNameEmptyDialog = DynamicDialog( title: 'Fehler!', icon: Icons.error, content: const Text('Der Name des Kontos darf nicht leer sein!'), dialogType: DialogTypeEnum.error, ); _accountCreatedDialog = DynamicDialog( title: 'Account erstellt!', icon: Icons.check_circle, content: const Text('Das Konto wurde erfolgreich erstellt!'), dialogType: DialogTypeEnum.success, ); } static final AccountController _instance = AccountController._internal(); final AccountRepository _accountRepository = AccountRepository(); DynamicDialog? _newAccountDialog; DynamicDialog? _errorNameEmptyDialog; DynamicDialog? _accountCreatedDialog; final ValueNotifier _selected = ValueNotifier(null); /// Stellt das ausgewählte Konto dar, das angezeigt wird ValueNotifier get selected { if (_selected.value == null) { unawaited( updateAccounts().then((_) { _selected.value = accounts.value.firstOrNull; }), ); } return _selected; } set selected(final Account selected) { _selected.value = selected; } final ValueNotifier> _accounts = ValueNotifier>( [], ); /// Stellt die Liste der Konten dar ValueNotifier> get accounts { if (_accounts.value == []) { unawaited(updateAccounts()); } return _accounts; } set accounts(final List accounts) { _accounts.value = accounts; } /// Gibt die gespeicherten Konten als Liste zurück Future updateAccounts() async { final List accounts = await _accountRepository.findBy( orderBy: 'nameAsc', ); _accounts.value = accounts; } /// Startet den Prozess, um ein neues Konto anzulegen void newAccountHandler() { unawaited(_newAccountDialog?.show()); } /// Startet den Prozess, um ein Konto umzubenennen Future renameAccountHandler(final int accountId) async { final Account? account = await _accountRepository.find(accountId); if (account != null) { final renameAccountDialog = DynamicDialog( title: '${account.name} umbenennen', icon: Icons.edit, inputFields: [ DialogInputField( id: 'name', label: 'Name', initialValue: account.name, autoFocus: true, ), ], actions: [ DialogAction(label: 'Abbruch'), DialogAction( label: 'Speichern', isPrimary: true, onPressed: _renameAccount, ), ], hiddenValues: {'account': account}, ); unawaited(renameAccountDialog.show()); } } /// Startet den Prozess, um ein Konto zu löschen Future deleteAccountHandler(final int accountId) async { final Account? account = await _accountRepository.find(accountId); if (account != null) { final deleteAccountDialog = DynamicDialog( dialogType: DialogTypeEnum.error, title: '${account.name} löschen', content: Text('Willst du ${account.name} wirklich löschen?'), icon: Icons.delete_forever, actions: [ DialogAction(label: 'Abbruch', isPrimary: true), DialogAction(label: 'Account löschen', onPressed: _deleteAccount), ], hiddenValues: {'account': account}, ); unawaited(deleteAccountDialog.show()); } } Future _saveNewAccount(final Map values) async { if (values['name'] == null || values['name'] == '') { await _errorNameEmptyDialog?.show(); } else { final account = AccountsCompanion(name: Value(values['name']!)); await _accountRepository.add(account); await _accountCreatedDialog?.show(); await updateAccounts(); } } Future _renameAccount(final Map values) async { if (values['account'] != null && values['name'] != null) { final Account account = values['account']; final acc = AccountsCompanion( id: Value(account.id), name: Value(values['name']), ); await _accountRepository.update(acc); await updateAccounts(); if (account == selected.value) { selected.value = await _accountRepository.find(account.id); } } } Future _deleteAccount(final Map values) async { if (values['account'] != null) { final Account account = values['account']; await _accountRepository.remove(account); await updateAccounts(); if (account == _selected.value) { _selected.value = _accounts.value.firstOrNull; } } } }