|
|
|
|
@@ -1,7 +1,7 @@
|
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:pshared/models/payment/wallet.dart';
|
|
|
|
|
import 'package:pshared/provider/payment/wallets.dart';
|
|
|
|
|
|
|
|
|
|
@@ -9,57 +9,52 @@ import 'package:pshared/provider/payment/wallets.dart';
|
|
|
|
|
class WalletsController with ChangeNotifier {
|
|
|
|
|
late WalletsProvider _wallets;
|
|
|
|
|
|
|
|
|
|
// If you want per-org isolation, we reset when org changes.
|
|
|
|
|
String? _orgRef;
|
|
|
|
|
|
|
|
|
|
// Visibility is UI-only: store hidden wallet ids here.
|
|
|
|
|
final Set<String> _hiddenWalletIds = <String>{};
|
|
|
|
|
/// UI-only: which wallets are allowed to be visible
|
|
|
|
|
final Set<String> _visibleWalletIds = <String>{};
|
|
|
|
|
|
|
|
|
|
String? _selectedWalletId;
|
|
|
|
|
|
|
|
|
|
bool get isLoading => _wallets.isLoading;
|
|
|
|
|
|
|
|
|
|
Exception? get error => _wallets.error;
|
|
|
|
|
|
|
|
|
|
/// Inject / update dependency (use ProxyProvider).
|
|
|
|
|
void update(WalletsProvider wallets) {
|
|
|
|
|
_wallets = wallets;
|
|
|
|
|
|
|
|
|
|
final nextOrgRef = wallets.organizationId;
|
|
|
|
|
final orgChanged = nextOrgRef != _orgRef;
|
|
|
|
|
|
|
|
|
|
if (orgChanged) {
|
|
|
|
|
_orgRef = nextOrgRef;
|
|
|
|
|
_hiddenWalletIds.clear();
|
|
|
|
|
_visibleWalletIds.clear(); // All wallets hidden on org change
|
|
|
|
|
_selectedWalletId = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prune hidden ids for wallets that no longer exist.
|
|
|
|
|
// Remove ids that no longer exist
|
|
|
|
|
final ids = wallets.wallets.map((w) => w.id).toSet();
|
|
|
|
|
final beforeHiddenLen = _hiddenWalletIds.length;
|
|
|
|
|
_hiddenWalletIds.removeWhere((id) => !ids.contains(id));
|
|
|
|
|
_visibleWalletIds.removeWhere((id) => !ids.contains(id));
|
|
|
|
|
|
|
|
|
|
// Ensure selection is valid.
|
|
|
|
|
final beforeSelected = _selectedWalletId;
|
|
|
|
|
|
|
|
|
|
_selectedWalletId = _resolveSelectedId(
|
|
|
|
|
currentId: _selectedWalletId,
|
|
|
|
|
wallets: wallets.wallets,
|
|
|
|
|
hiddenIds: _hiddenWalletIds,
|
|
|
|
|
visibleIds: _visibleWalletIds,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final selectionChanged = beforeSelected != _selectedWalletId;
|
|
|
|
|
final hiddenChanged = beforeHiddenLen != _hiddenWalletIds.length;
|
|
|
|
|
|
|
|
|
|
if (orgChanged || selectionChanged || hiddenChanged) {
|
|
|
|
|
if (beforeSelected != _selectedWalletId || orgChanged) {
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Wallet> get wallets => _wallets.wallets;
|
|
|
|
|
|
|
|
|
|
bool isHidden(String walletId) => _hiddenWalletIds.contains(walletId);
|
|
|
|
|
bool isVisible(String walletId) => _visibleWalletIds.contains(walletId);
|
|
|
|
|
bool isHidden(String walletId) => !isVisible(walletId);
|
|
|
|
|
|
|
|
|
|
List<Wallet> get visibleWallets =>
|
|
|
|
|
wallets.where((w) => !_hiddenWalletIds.contains(w.id)).toList(growable: false);
|
|
|
|
|
wallets.where((w) => _visibleWalletIds.contains(w.id)).toList(growable: false);
|
|
|
|
|
|
|
|
|
|
Wallet? get selectedWallet {
|
|
|
|
|
final id = _selectedWalletId;
|
|
|
|
|
@@ -74,56 +69,59 @@ class WalletsController with ChangeNotifier {
|
|
|
|
|
void selectWalletId(String walletId) {
|
|
|
|
|
if (_selectedWalletId == walletId) return;
|
|
|
|
|
|
|
|
|
|
// Allow selecting hidden wallet if you want; if not, block it:
|
|
|
|
|
// if (isHidden(walletId)) return;
|
|
|
|
|
// Prevent selecting a hidden wallet
|
|
|
|
|
if (!_visibleWalletIds.contains(walletId)) return;
|
|
|
|
|
|
|
|
|
|
_selectedWalletId = walletId;
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Toggle wallet visibility
|
|
|
|
|
void toggleVisibility(String walletId) {
|
|
|
|
|
final existed = _hiddenWalletIds.remove(walletId);
|
|
|
|
|
if (!existed) _hiddenWalletIds.add(walletId);
|
|
|
|
|
final existed = _visibleWalletIds.remove(walletId);
|
|
|
|
|
if (!existed) _visibleWalletIds.add(walletId);
|
|
|
|
|
|
|
|
|
|
// If we hid the selected wallet, move selection to next visible.
|
|
|
|
|
_selectedWalletId = _resolveSelectedId(
|
|
|
|
|
currentId: _selectedWalletId,
|
|
|
|
|
wallets: wallets,
|
|
|
|
|
hiddenIds: _hiddenWalletIds,
|
|
|
|
|
visibleIds: _visibleWalletIds,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Show all wallets (bulk action)
|
|
|
|
|
void showAll() {
|
|
|
|
|
if (_hiddenWalletIds.isEmpty) return;
|
|
|
|
|
_hiddenWalletIds.clear();
|
|
|
|
|
final allIds = wallets.map((w) => w.id);
|
|
|
|
|
_visibleWalletIds
|
|
|
|
|
..clear()
|
|
|
|
|
..addAll(allIds);
|
|
|
|
|
|
|
|
|
|
_selectedWalletId = _resolveSelectedId(
|
|
|
|
|
currentId: _selectedWalletId,
|
|
|
|
|
wallets: wallets,
|
|
|
|
|
hiddenIds: _hiddenWalletIds,
|
|
|
|
|
visibleIds: _visibleWalletIds,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? _resolveSelectedId({
|
|
|
|
|
required String? currentId,
|
|
|
|
|
required List<Wallet> wallets,
|
|
|
|
|
required Set<String> hiddenIds,
|
|
|
|
|
required Set<String> visibleIds,
|
|
|
|
|
}) {
|
|
|
|
|
if (wallets.isEmpty) return null;
|
|
|
|
|
|
|
|
|
|
// Keep current if exists and is not hidden.
|
|
|
|
|
if (currentId != null) {
|
|
|
|
|
final exists = wallets.any((w) => w.id == currentId);
|
|
|
|
|
if (exists && !hiddenIds.contains(currentId)) return currentId;
|
|
|
|
|
// Keep current selection if it still exists and is visible
|
|
|
|
|
if (currentId != null &&
|
|
|
|
|
visibleIds.contains(currentId) &&
|
|
|
|
|
wallets.any((w) => w.id == currentId)) {
|
|
|
|
|
return currentId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pick first visible.
|
|
|
|
|
final firstVisible = wallets.firstWhereOrNull((w) => !hiddenIds.contains(w.id));
|
|
|
|
|
if (firstVisible != null) return firstVisible.id;
|
|
|
|
|
|
|
|
|
|
// All hidden: fall back to first wallet id (or return null if you prefer).
|
|
|
|
|
return wallets.first.id;
|
|
|
|
|
// Select the first visible wallet
|
|
|
|
|
final firstVisible = wallets.firstWhereOrNull((w) => visibleIds.contains(w.id));
|
|
|
|
|
return firstVisible?.id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|