119 lines
3.2 KiB
Dart
119 lines
3.2 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:pshared/models/payment/wallet.dart';
|
|
import 'package:pshared/provider/payment/wallets.dart';
|
|
|
|
|
|
class WalletsController with ChangeNotifier {
|
|
late WalletsProvider _wallets;
|
|
|
|
String? _orgRef;
|
|
|
|
/// UI-only: wallet refs with masked balances
|
|
final Set<String> _maskedBalanceWalletRefs = <String>{};
|
|
Set<String> _knownWalletRefs = <String>{};
|
|
|
|
List<Wallet> _walletsList = <Wallet>[];
|
|
Map<String, Wallet> _walletsById = <String, Wallet>{};
|
|
|
|
String? _selectedWalletRef;
|
|
|
|
bool get isLoading => _wallets.isLoading;
|
|
Exception? get error => _wallets.error;
|
|
|
|
void update(WalletsProvider wallets) {
|
|
_wallets = wallets;
|
|
|
|
final nextOrgRef = wallets.organizationRef;
|
|
final orgChanged = nextOrgRef != _orgRef;
|
|
|
|
if (orgChanged) {
|
|
_orgRef = nextOrgRef;
|
|
_maskedBalanceWalletRefs.clear();
|
|
_knownWalletRefs = <String>{};
|
|
_selectedWalletRef = null;
|
|
}
|
|
|
|
_walletsById = _uniqueWalletsById(wallets.wallets);
|
|
_walletsList = _walletsById.values.toList(growable: false);
|
|
|
|
// Remove ids that no longer exist
|
|
final ids = _walletsById.keys.toSet();
|
|
_maskedBalanceWalletRefs.removeWhere((id) => !ids.contains(id));
|
|
|
|
final newIds = ids.difference(_knownWalletRefs);
|
|
if (newIds.isNotEmpty) {
|
|
_maskedBalanceWalletRefs.addAll(newIds);
|
|
}
|
|
_knownWalletRefs = ids;
|
|
|
|
_selectedWalletRef = _resolveSelectedId(
|
|
currentRef: _selectedWalletRef,
|
|
wallets: _walletsList,
|
|
);
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
List<Wallet> get wallets => _walletsList;
|
|
|
|
bool isBalanceMasked(String walletRef) => _maskedBalanceWalletRefs.contains(walletRef);
|
|
bool isBalanceVisible(String walletRef) => !isBalanceMasked(walletRef);
|
|
|
|
List<Wallet> get unmaskedWallets =>
|
|
wallets.where((w) => !_maskedBalanceWalletRefs.contains(w.id)).toList(growable: false);
|
|
|
|
Wallet? get selectedWallet {
|
|
final id = _selectedWalletRef;
|
|
if (id == null) return null;
|
|
return _walletsById[id];
|
|
}
|
|
|
|
String? get selectedWalletRef => _selectedWalletRef;
|
|
|
|
void selectWallet(Wallet wallet) => selectWalletByRef(wallet.id);
|
|
|
|
void selectWalletByRef(String walletRef) {
|
|
if (_selectedWalletRef == walletRef) return;
|
|
|
|
_selectedWalletRef = walletRef;
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Toggle wallet balance masking
|
|
void toggleBalanceMask(String walletRef) {
|
|
final existed = _maskedBalanceWalletRefs.remove(walletRef);
|
|
if (!existed) _maskedBalanceWalletRefs.add(walletRef);
|
|
notifyListeners();
|
|
}
|
|
|
|
/// Unmask balances for all wallets (bulk action)
|
|
void unmaskAllBalances() {
|
|
_maskedBalanceWalletRefs.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
String? _resolveSelectedId({
|
|
required String? currentRef,
|
|
required List<Wallet> wallets,
|
|
}) {
|
|
if (wallets.isEmpty) return null;
|
|
|
|
// Keep current selection if it still exists
|
|
if (currentRef != null && wallets.any((w) => w.id == currentRef)) {
|
|
return currentRef;
|
|
}
|
|
|
|
// Fallback to the first wallet
|
|
return wallets.first.id;
|
|
}
|
|
|
|
Map<String, Wallet> _uniqueWalletsById(List<Wallet> wallets) {
|
|
final result = <String, Wallet>{};
|
|
for (final wallet in wallets) {
|
|
result.putIfAbsent(wallet.id, () => wallet);
|
|
}
|
|
return result;
|
|
}
|
|
}
|