Refresh button for balance

This commit is contained in:
Arseni
2025-12-30 18:36:29 +03:00
parent 202582626a
commit b157522fdb
8 changed files with 148 additions and 17 deletions

View File

@@ -29,6 +29,8 @@ class WalletsProvider with ChangeNotifier {
bool _isRefreshingBalances = false;
bool get isRefreshingBalances => _isRefreshingBalances;
final Set<String> _refreshingWallets = <String>{};
bool isWalletRefreshing(String walletId) => _refreshingWallets.contains(walletId);
void update(OrganizationsProvider organizations) {
_organizations = organizations;
@@ -81,6 +83,31 @@ class WalletsProvider with ChangeNotifier {
}
}
Future<void> refreshBalance(String walletId) async {
if (_refreshingWallets.contains(walletId)) return;
final wallet = wallets.firstWhereOrNull((w) => w.id == walletId);
if (wallet == null) return;
_refreshingWallets.add(walletId);
notifyListeners();
try {
final balance = await _service.getBalance(_organizations.current.id, walletId);
final updatedWallet = wallet.copyWith(balance: balance);
final next = List<Wallet>.from(wallets);
final idx = next.indexWhere((w) => w.id == walletId);
if (idx >= 0) {
next[idx] = updatedWallet;
_setResource(_resource.copyWith(data: next));
}
} catch (e) {
_setResource(_resource.copyWith(error: toException(e)));
} finally {
_refreshingWallets.remove(walletId);
notifyListeners();
}
}
void toggleVisibility(String walletId) {
final index = wallets.indexWhere((w) => w.id == walletId);
if (index < 0) return;

View File

@@ -383,6 +383,7 @@
"payout": "Payout",
"sendTo": "Send Payout To",
"send": "Send Payout",
"refreshBalance": "Refresh balance",
"recipientPaysFee": "Recipient pays the fee",
"sentAmount": "Sent amount: {amount}",

View File

@@ -383,6 +383,7 @@
"payout": "Выплата",
"sendTo": "Отправить выплату",
"send": "Отправить выплату",
"refreshBalance": "Обновить баланс",
"recipientPaysFee": "Получатель оплачивает комиссию",
"sentAmount": "Отправленная сумма: {amount}",

View File

@@ -8,6 +8,7 @@ import 'package:pweb/pages/dashboard/buttons/balance/amount.dart';
import 'package:pweb/pages/dashboard/buttons/balance/config.dart';
import 'package:pweb/pages/dashboard/buttons/balance/header.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pweb/widgets/wallet_balance_refresh_button.dart';
class WalletCard extends StatelessWidget {
@@ -37,11 +38,18 @@ class WalletCard extends StatelessWidget {
walletNetwork: wallet.network,
tokenSymbol: wallet.tokenSymbol,
),
BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
Row(
children: [
BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
),
WalletBalanceRefreshButton(
walletId: wallet.id,
),
],
),
BalanceAddFunds(
onTopUp: () {

View File

@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pshared/provider/recipient/provider.dart';
import 'package:pweb/pages/payment_methods/payment_page/back_button.dart';
@@ -14,6 +17,7 @@ import 'package:pweb/pages/payment_methods/widgets/recipient_section.dart';
import 'package:pweb/pages/payment_methods/widgets/section_title.dart';
import 'package:pweb/utils/dimensions.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/widgets/wallet_balance_refresh_button.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
@@ -74,7 +78,20 @@ class PaymentPageContent extends StatelessWidget {
SizedBox(height: dimensions.paddingSmall),
PaymentHeader(),
SizedBox(height: dimensions.paddingXXLarge),
SectionTitle(loc.sourceOfFunds),
Row(
children: [
Expanded(child: SectionTitle(loc.sourceOfFunds)),
Consumer<WalletsProvider>(
builder: (context, provider, _) {
final selectedWalletId = provider.selectedWallet?.id;
if (selectedWalletId == null) {
return const SizedBox.shrink();
}
return WalletBalanceRefreshButton(walletId: selectedWalletId);
},
),
],
),
SizedBox(height: dimensions.paddingSmall),
PaymentMethodSelector(
onMethodChanged: onWalletSelected,

View File

@@ -5,8 +5,10 @@ import 'package:provider/provider.dart';
import 'package:pshared/utils/currency.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pweb/models/visibility.dart';
import 'package:pweb/pages/dashboard/buttons/balance/amount.dart';
import 'package:pweb/widgets/wallet_balance_refresh_button.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
@@ -43,11 +45,20 @@ class WalletCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
),
WalletBalanceRefreshButton(
walletId: wallet.id,
iconOnly: VisibilityState.hidden,
),
],
),
Text(
AppLocalizations.of(context)!.paymentTypeCryptoWallet,

View File

@@ -6,6 +6,7 @@ import 'package:provider/provider.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pweb/pages/dashboard/buttons/balance/amount.dart';
import 'package:pweb/widgets/wallet_balance_refresh_button.dart';
class WalletEditFields extends StatelessWidget {
@@ -26,12 +27,15 @@ class WalletEditFields extends StatelessWidget {
children: [
Row(
children: [
BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
Expanded(
child: BalanceAmount(
wallet: wallet,
onToggleVisibility: () {
context.read<WalletsProvider>().toggleVisibility(wallet.id);
},
),
),
WalletBalanceRefreshButton(walletId: wallet.id),
],
),
const SizedBox(height: 8),
@@ -51,4 +55,4 @@ class WalletEditFields extends StatelessWidget {
},
);
}
}
}

View File

@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pweb/models/visibility.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class WalletBalanceRefreshButton extends StatelessWidget {
final String walletId;
final VisibilityState iconOnly;
final double iconSize = 18;
const WalletBalanceRefreshButton({
super.key,
required this.walletId,
this.iconOnly = VisibilityState.visible,
});
@override
Widget build(BuildContext context) {
final walletsProvider = context.watch<WalletsProvider>();
final loc = AppLocalizations.of(context)!;
final isBusy = walletsProvider.isWalletRefreshing(walletId) || walletsProvider.isLoading;
final hasTarget = walletsProvider.wallets.any((w) => w.id == walletId);
void refresh() {
final provider = context.read<WalletsProvider>();
provider.refreshBalance(walletId);
}
if (iconOnly == VisibilityState.hidden) {
return IconButton(
tooltip: loc.refreshBalance,
onPressed: hasTarget && !isBusy ? refresh : null,
icon: isBusy
? SizedBox(
width: iconSize,
height: iconSize,
child: const CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.refresh),
);
}
return TextButton.icon(
onPressed: hasTarget && !isBusy ? refresh : null,
icon: isBusy
? SizedBox(
width: iconSize,
height: iconSize,
child: const CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.refresh),
label: Text(loc.refreshBalance),
style: TextButton.styleFrom(visualDensity: VisualDensity.compact),
);
}
}