mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-22 10:34:32 +00:00
commit
df15461a81
13 changed files with 443 additions and 286 deletions
|
@ -49,7 +49,7 @@ class CoinControlView extends ConsumerStatefulWidget {
|
|||
|
||||
final String walletId;
|
||||
final CoinControlViewType type;
|
||||
final int? requestedTotal;
|
||||
final Amount? requestedTotal;
|
||||
final Set<UTXO>? selectedUTXOs;
|
||||
|
||||
@override
|
||||
|
@ -673,7 +673,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
|
|||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
int selectedSum =
|
||||
final int selectedSumInt =
|
||||
_selectedAvailable.isEmpty
|
||||
? 0
|
||||
: _selectedAvailable
|
||||
|
@ -682,15 +682,19 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
|
|||
(value, element) =>
|
||||
value += element,
|
||||
);
|
||||
final selectedSum =
|
||||
selectedSumInt.toAmountAsRaw(
|
||||
fractionDigits: coin.decimals,
|
||||
);
|
||||
return Text(
|
||||
"${selectedSum.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed(
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select(
|
||||
(value) => value.locale,
|
||||
),
|
||||
),
|
||||
)} ${coin.ticker}",
|
||||
"${selectedSum.localizedStringAsFixed(
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select(
|
||||
(value) => value.locale,
|
||||
),
|
||||
),
|
||||
)} ${coin.ticker}",
|
||||
style: widget.requestedTotal == null
|
||||
? STextStyles.w600_14(context)
|
||||
: STextStyles.w600_14(context).copyWith(
|
||||
|
@ -731,14 +735,14 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
|
|||
style: STextStyles.w600_14(context),
|
||||
),
|
||||
Text(
|
||||
"${widget.requestedTotal!.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed(
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select(
|
||||
(value) => value.locale,
|
||||
),
|
||||
),
|
||||
)} ${coin.ticker}",
|
||||
"${widget.requestedTotal!.localizedStringAsFixed(
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider
|
||||
.select(
|
||||
(value) => value.locale,
|
||||
),
|
||||
),
|
||||
)} ${coin.ticker}",
|
||||
style: STextStyles.w600_14(context),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -124,13 +124,15 @@ class _UtxoCardState extends ConsumerState<UtxoCard> {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"${utxo.value.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed(
|
||||
"${utxo.value.toAmountAsRaw(
|
||||
fractionDigits: coin.decimals,
|
||||
).localizedStringAsFixed(
|
||||
locale: ref.watch(
|
||||
localeServiceChangeNotifierProvider.select(
|
||||
(value) => value.locale,
|
||||
),
|
||||
),
|
||||
)}} ${coin.ticker}",
|
||||
)} ${coin.ticker}",
|
||||
style: STextStyles.w600_14(context),
|
||||
),
|
||||
const SizedBox(
|
||||
|
|
|
@ -320,14 +320,7 @@ class _ExchangeCurrencySelectionViewState
|
|||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
"Popular coins",
|
||||
style: STextStyles.smallMed12(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
height: 20,
|
||||
),
|
||||
Flexible(
|
||||
child: Builder(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
|
||||
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
||||
|
@ -109,7 +110,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
_sendFieldOnChangedTimer?.cancel();
|
||||
|
||||
_sendFieldOnChangedTimer = Timer(_valueCheckInterval, () async {
|
||||
final newFromAmount = Decimal.tryParse(value);
|
||||
final newFromAmount = _localizedStringToNum(value);
|
||||
|
||||
await ref
|
||||
.read(exchangeFormStateProvider)
|
||||
|
@ -123,7 +124,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
_receiveFieldOnChangedTimer?.cancel();
|
||||
|
||||
_receiveFieldOnChangedTimer = Timer(_valueCheckInterval, () async {
|
||||
final newToAmount = Decimal.tryParse(value);
|
||||
final newToAmount = _localizedStringToNum(value);
|
||||
|
||||
await ref
|
||||
.read(exchangeFormStateProvider)
|
||||
|
@ -131,6 +132,20 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
|||
});
|
||||
}
|
||||
|
||||
Decimal? _localizedStringToNum(String? value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final numFromLocalised = NumberFormat.decimalPattern(
|
||||
ref.read(localeServiceChangeNotifierProvider).locale)
|
||||
.parse(value);
|
||||
return Decimal.tryParse(numFromLocalised.toString());
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<AggregateCurrency> _getAggregateCurrency(Currency currency) async {
|
||||
final rateType = ref.read(exchangeFormStateProvider).exchangeRateType;
|
||||
final currencies = await ExchangeDataLoadingService.instance.isar.currencies
|
||||
|
|
|
@ -15,18 +15,22 @@ import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dia
|
|||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/route_generator.dart';
|
||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/background.dart';
|
||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||
import 'package:stackwallet/widgets/rounded_container.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class Step4View extends ConsumerStatefulWidget {
|
||||
const Step4View({
|
||||
|
@ -120,6 +124,213 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<bool?> _showSendFromFiroBalanceSelectSheet(String walletId) async {
|
||||
final firoWallet = ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(walletId)
|
||||
.wallet as FiroWallet;
|
||||
final locale = ref.read(localeServiceChangeNotifierProvider).locale;
|
||||
|
||||
return await showModalBottomSheet<bool?>(
|
||||
context: context,
|
||||
backgroundColor:
|
||||
Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(
|
||||
Constants.size.circularBorderRadius * 3,
|
||||
),
|
||||
),
|
||||
),
|
||||
builder: (context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
Text(
|
||||
"Select Firo balance",
|
||||
style: STextStyles.pageTitleH2(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
SecondaryButton(
|
||||
label:
|
||||
"${firoWallet.balancePrivate.spendable.localizedStringAsFixed(
|
||||
locale: locale,
|
||||
)} (private)",
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
SecondaryButton(
|
||||
label: "${firoWallet.balance.spendable.localizedStringAsFixed(
|
||||
locale: locale,
|
||||
)} (public)",
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _confirmSend(Tuple2<String, Coin> tuple) async {
|
||||
final bool firoPublicSend;
|
||||
if (tuple.item2 == Coin.firo) {
|
||||
final result = await _showSendFromFiroBalanceSelectSheet(tuple.item1);
|
||||
if (result == null) {
|
||||
return;
|
||||
} else {
|
||||
firoPublicSend = result;
|
||||
}
|
||||
} else {
|
||||
firoPublicSend = false;
|
||||
}
|
||||
|
||||
final manager =
|
||||
ref.read(walletsChangeNotifierProvider).getManager(tuple.item1);
|
||||
|
||||
final Amount amount = model.sendAmount.toAmount(
|
||||
fractionDigits: manager.coin.decimals,
|
||||
);
|
||||
final address = model.trade!.payInAddress;
|
||||
|
||||
bool wasCancelled = false;
|
||||
try {
|
||||
if (!mounted) return;
|
||||
|
||||
unawaited(
|
||||
showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: false,
|
||||
builder: (context) {
|
||||
return BuildingTransactionDialog(
|
||||
coin: manager.coin,
|
||||
onCancel: () {
|
||||
wasCancelled = true;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
final time = Future<dynamic>.delayed(
|
||||
const Duration(
|
||||
milliseconds: 2500,
|
||||
),
|
||||
);
|
||||
|
||||
Future<Map<String, dynamic>> txDataFuture;
|
||||
|
||||
if (firoPublicSend) {
|
||||
txDataFuture = (manager.wallet as FiroWallet).prepareSendPublic(
|
||||
address: address,
|
||||
amount: amount,
|
||||
args: {
|
||||
"feeRate": FeeRateType.average,
|
||||
// ref.read(feeRateTypeStateProvider)
|
||||
},
|
||||
);
|
||||
} else {
|
||||
txDataFuture = manager.prepareSend(
|
||||
address: address,
|
||||
amount: amount,
|
||||
args: {
|
||||
"feeRate": FeeRateType.average,
|
||||
// ref.read(feeRateTypeStateProvider)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final results = await Future.wait([
|
||||
txDataFuture,
|
||||
time,
|
||||
]);
|
||||
|
||||
final txData = results.first as Map<String, dynamic>;
|
||||
|
||||
if (!wasCancelled) {
|
||||
// pop building dialog
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
txData["note"] =
|
||||
"${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange";
|
||||
txData["address"] = address;
|
||||
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
Navigator.of(context).push(
|
||||
RouteGenerator.getRoute(
|
||||
shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
|
||||
builder: (_) => ConfirmChangeNowSendView(
|
||||
transactionInfo: txData,
|
||||
walletId: tuple.item1,
|
||||
routeOnSuccessName: HomeView.routeName,
|
||||
trade: model.trade!,
|
||||
),
|
||||
settings: const RouteSettings(
|
||||
name: ConfirmChangeNowSendView.routeName,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted && !wasCancelled) {
|
||||
// pop building dialog
|
||||
Navigator.of(context).pop();
|
||||
|
||||
unawaited(
|
||||
showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return StackDialog(
|
||||
title: "Transaction failed",
|
||||
message: e.toString(),
|
||||
rightButton: TextButton(
|
||||
style: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.getSecondaryEnabledButtonStyle(context),
|
||||
child: Text(
|
||||
"Ok",
|
||||
style: STextStyles.button(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.buttonTextSecondary,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bool isWalletCoin =
|
||||
|
@ -244,11 +455,15 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
text:
|
||||
model.sendAmount.toString());
|
||||
await clipboard.setData(data);
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
));
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
|
@ -302,11 +517,15 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
final data = ClipboardData(
|
||||
text: model.trade!.payInAddress);
|
||||
await clipboard.setData(data);
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
));
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
|
@ -365,11 +584,15 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
final data = ClipboardData(
|
||||
text: model.trade!.tradeId);
|
||||
await clipboard.setData(data);
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
));
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.svg.copy,
|
||||
|
@ -521,147 +744,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
model.sendTicker.toLowerCase() ==
|
||||
tuple.item2.ticker.toLowerCase()
|
||||
? () async {
|
||||
final manager = ref
|
||||
.read(
|
||||
walletsChangeNotifierProvider)
|
||||
.getManager(tuple.item1);
|
||||
|
||||
final Amount amount =
|
||||
model.sendAmount.toAmount(
|
||||
fractionDigits:
|
||||
manager.coin.decimals,
|
||||
);
|
||||
final address =
|
||||
model.trade!.payInAddress;
|
||||
|
||||
try {
|
||||
bool wasCancelled = false;
|
||||
|
||||
unawaited(
|
||||
showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: false,
|
||||
builder: (context) {
|
||||
return BuildingTransactionDialog(
|
||||
coin: manager.coin,
|
||||
onCancel: () {
|
||||
wasCancelled = true;
|
||||
|
||||
Navigator.of(context)
|
||||
.pop();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
final time =
|
||||
Future<dynamic>.delayed(
|
||||
const Duration(
|
||||
milliseconds: 2500,
|
||||
),
|
||||
);
|
||||
|
||||
final txDataFuture =
|
||||
manager.prepareSend(
|
||||
address: address,
|
||||
amount: amount,
|
||||
args: {
|
||||
"feeRate":
|
||||
FeeRateType.average,
|
||||
// ref.read(feeRateTypeStateProvider)
|
||||
},
|
||||
);
|
||||
|
||||
final results =
|
||||
await Future.wait([
|
||||
txDataFuture,
|
||||
time,
|
||||
]);
|
||||
|
||||
final txData = results.first
|
||||
as Map<String, dynamic>;
|
||||
|
||||
if (!wasCancelled) {
|
||||
// pop building dialog
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
txData["note"] =
|
||||
"${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange";
|
||||
txData["address"] = address;
|
||||
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
RouteGenerator.getRoute(
|
||||
shouldUseMaterialRoute:
|
||||
RouteGenerator
|
||||
.useMaterialPageRoute,
|
||||
builder: (_) =>
|
||||
ConfirmChangeNowSendView(
|
||||
transactionInfo: txData,
|
||||
walletId: tuple.item1,
|
||||
routeOnSuccessName:
|
||||
HomeView.routeName,
|
||||
trade: model.trade!,
|
||||
),
|
||||
settings:
|
||||
const RouteSettings(
|
||||
name:
|
||||
ConfirmChangeNowSendView
|
||||
.routeName,
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// if (mounted) {
|
||||
// pop building dialog
|
||||
Navigator.of(context).pop();
|
||||
|
||||
unawaited(showDialog<dynamic>(
|
||||
context: context,
|
||||
useSafeArea: false,
|
||||
barrierDismissible: true,
|
||||
builder: (context) {
|
||||
return StackDialog(
|
||||
title: "Transaction failed",
|
||||
message: e.toString(),
|
||||
rightButton: TextButton(
|
||||
style: Theme.of(context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.getSecondaryEnabledButtonStyle(
|
||||
context),
|
||||
child: Text(
|
||||
"Ok",
|
||||
style:
|
||||
STextStyles.button(
|
||||
context)
|
||||
.copyWith(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.extension<
|
||||
StackColors>()!
|
||||
.buttonTextSecondary,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.pop();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
// }
|
||||
}
|
||||
await _confirmSend(tuple);
|
||||
}
|
||||
: () {
|
||||
Navigator.of(context).push(
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/amount/amount.dart';
|
|||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/show_loading.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
|
@ -94,11 +95,17 @@ class _ExchangeProviderOptionsState
|
|||
onTap: () {
|
||||
if (ref.read(exchangeFormStateProvider).exchange.name !=
|
||||
ChangeNowExchange.exchangeName) {
|
||||
ref.read(exchangeFormStateProvider).updateExchange(
|
||||
exchange: ChangeNowExchange.instance,
|
||||
shouldUpdateData: true,
|
||||
shouldNotifyListeners: true,
|
||||
);
|
||||
showLoading(
|
||||
whileFuture:
|
||||
ref.read(exchangeFormStateProvider).updateExchange(
|
||||
exchange: ChangeNowExchange.instance,
|
||||
shouldUpdateData: true,
|
||||
shouldNotifyListeners: true,
|
||||
),
|
||||
context: context,
|
||||
message: "Updating rates",
|
||||
isDesktop: isDesktop,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
|
@ -333,11 +340,17 @@ class _ExchangeProviderOptionsState
|
|||
onTap: () {
|
||||
if (ref.read(exchangeFormStateProvider).exchange.name !=
|
||||
MajesticBankExchange.exchangeName) {
|
||||
ref.read(exchangeFormStateProvider).updateExchange(
|
||||
exchange: MajesticBankExchange.instance,
|
||||
shouldUpdateData: true,
|
||||
shouldNotifyListeners: true,
|
||||
);
|
||||
showLoading(
|
||||
whileFuture:
|
||||
ref.read(exchangeFormStateProvider).updateExchange(
|
||||
exchange: MajesticBankExchange.instance,
|
||||
shouldUpdateData: true,
|
||||
shouldNotifyListeners: true,
|
||||
),
|
||||
context: context,
|
||||
isDesktop: isDesktop,
|
||||
message: "Updating rates",
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
|
|
|
@ -1391,77 +1391,88 @@ class _TransactionDetailsViewState
|
|||
false &&
|
||||
_transaction.isCancelled == false &&
|
||||
_transaction.type == TransactionType.outgoing)
|
||||
? SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all<Color>(
|
||||
Theme.of(context).extension<StackColors>()!.textError,
|
||||
),
|
||||
? ConditionalParent(
|
||||
condition: isDesktop,
|
||||
builder: (child) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
vertical: 16,
|
||||
),
|
||||
onPressed: () async {
|
||||
final Manager manager = ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(walletId);
|
||||
child: child,
|
||||
),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all<Color>(
|
||||
Theme.of(context).extension<StackColors>()!.textError,
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
final Manager manager = ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(walletId);
|
||||
|
||||
if (manager.wallet is EpicCashWallet) {
|
||||
final String? id = _transaction.slateId;
|
||||
if (id == null) {
|
||||
if (manager.wallet is EpicCashWallet) {
|
||||
final String? id = _transaction.slateId;
|
||||
if (id == null) {
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "Could not find Epic transaction ID",
|
||||
context: context,
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
unawaited(showDialog<dynamic>(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (_) =>
|
||||
const CancellingTransactionProgressDialog(),
|
||||
));
|
||||
|
||||
final result = await (manager.wallet as EpicCashWallet)
|
||||
.cancelPendingTransactionAndPost(id);
|
||||
if (mounted) {
|
||||
// pop progress dialog
|
||||
Navigator.of(context).pop();
|
||||
|
||||
if (result.isEmpty) {
|
||||
await showDialog<dynamic>(
|
||||
context: context,
|
||||
builder: (_) => StackOkDialog(
|
||||
title: "Transaction cancelled",
|
||||
onOkPressed: (_) {
|
||||
manager.refresh();
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(
|
||||
WalletView.routeName));
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await showDialog<dynamic>(
|
||||
context: context,
|
||||
builder: (_) => StackOkDialog(
|
||||
title: "Failed to cancel transaction",
|
||||
message: result,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "Could not find Epic transaction ID",
|
||||
message: "ERROR: Wallet type is not Epic Cash",
|
||||
context: context,
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
unawaited(showDialog<dynamic>(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (_) =>
|
||||
const CancellingTransactionProgressDialog(),
|
||||
));
|
||||
|
||||
final result = await (manager.wallet as EpicCashWallet)
|
||||
.cancelPendingTransactionAndPost(id);
|
||||
if (mounted) {
|
||||
// pop progress dialog
|
||||
Navigator.of(context).pop();
|
||||
|
||||
if (result.isEmpty) {
|
||||
await showDialog<dynamic>(
|
||||
context: context,
|
||||
builder: (_) => StackOkDialog(
|
||||
title: "Transaction cancelled",
|
||||
onOkPressed: (_) {
|
||||
manager.refresh();
|
||||
Navigator.of(context).popUntil(
|
||||
ModalRoute.withName(WalletView.routeName));
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await showDialog<dynamic>(
|
||||
context: context,
|
||||
builder: (_) => StackOkDialog(
|
||||
title: "Failed to cancel transaction",
|
||||
message: result,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unawaited(showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message: "ERROR: Wallet type is not Epic Cash",
|
||||
context: context,
|
||||
));
|
||||
return;
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
"Cancel Transaction",
|
||||
style: STextStyles.button(context),
|
||||
},
|
||||
child: Text(
|
||||
"Cancel Transaction",
|
||||
style: STextStyles.button(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
|
@ -212,7 +214,7 @@ class _DesktopChooseFromStackState
|
|||
],
|
||||
),
|
||||
const Spacer(),
|
||||
BalanceDisplay(
|
||||
_BalanceDisplay(
|
||||
walletId: walletIds[index],
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -265,8 +267,8 @@ class _DesktopChooseFromStackState
|
|||
}
|
||||
}
|
||||
|
||||
class BalanceDisplay extends ConsumerWidget {
|
||||
const BalanceDisplay({
|
||||
class _BalanceDisplay extends ConsumerWidget {
|
||||
const _BalanceDisplay({
|
||||
Key? key,
|
||||
required this.walletId,
|
||||
}) : super(key: key);
|
||||
|
@ -280,8 +282,14 @@ class BalanceDisplay extends ConsumerWidget {
|
|||
final locale = ref.watch(
|
||||
localeServiceChangeNotifierProvider.select((value) => value.locale));
|
||||
|
||||
Amount total = manager.balance.total;
|
||||
if (manager.coin == Coin.firo || manager.coin == Coin.firoTestNet) {
|
||||
final firoWallet = manager.wallet as FiroWallet;
|
||||
total += firoWallet.balancePrivate.total;
|
||||
}
|
||||
|
||||
return Text(
|
||||
"${manager.balance.spendable.localizedStringAsFixed(locale: locale)} "
|
||||
"${total.localizedStringAsFixed(locale: locale)} "
|
||||
"${manager.coin.ticker}",
|
||||
style: STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
|
|
|
@ -994,10 +994,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
CustomTextButton(
|
||||
text: "Send all ${coin.ticker}",
|
||||
onTap: sendAllTapped,
|
||||
),
|
||||
if (coin != Coin.ethereum)
|
||||
CustomTextButton(
|
||||
text: "Send all ${coin.ticker}",
|
||||
onTap: sendAllTapped,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
|
|
|
@ -337,7 +337,7 @@ class RouteGenerator {
|
|||
),
|
||||
);
|
||||
} else if (args
|
||||
is Tuple4<String, CoinControlViewType, int?, Set<UTXO>?>) {
|
||||
is Tuple4<String, CoinControlViewType, Amount?, Set<UTXO>?>) {
|
||||
return getRoute(
|
||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||
builder: (_) => CoinControlView(
|
||||
|
|
|
@ -479,7 +479,7 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
"minimumConfirmations": MINIMUM_CONFIRMATIONS,
|
||||
"message": "",
|
||||
"amount": (txData['recipientAmt'] as Amount).raw.toInt(),
|
||||
"address": (txData['addresss'] as Amount).raw.toInt(),
|
||||
"address": txData['addresss'] as String,
|
||||
}, name: walletName);
|
||||
|
||||
message = await receivePort.first;
|
||||
|
@ -497,7 +497,7 @@ class EpicCashWallet extends CoinServiceAPI
|
|||
"function": "createTransaction",
|
||||
"wallet": wallet!,
|
||||
"amount": (txData['recipientAmt'] as Amount).raw.toInt(),
|
||||
"address": (txData['addresss'] as Amount).raw.toInt(),
|
||||
"address": txData['addresss'] as String,
|
||||
"secretKeyIndex": 0,
|
||||
"epicboxConfig": epicboxConfig.toString(),
|
||||
"minimumConfirmations": MINIMUM_CONFIRMATIONS,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lottie/lottie.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/theme/color_theme.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
|
||||
class LoadingIndicator extends StatelessWidget {
|
||||
const LoadingIndicator({
|
||||
|
@ -14,17 +16,28 @@ class LoadingIndicator extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isChan = Theme.of(context).extension<StackColors>()!.themeType ==
|
||||
ThemeType.chan ||
|
||||
Theme.of(context).extension<StackColors>()!.themeType ==
|
||||
ThemeType.darkChans;
|
||||
|
||||
return Container(
|
||||
color: Colors.transparent,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: Lottie.asset(
|
||||
Assets.lottie.test2,
|
||||
animate: true,
|
||||
repeat: true,
|
||||
),
|
||||
child: isChan
|
||||
? Image(
|
||||
image: AssetImage(
|
||||
Assets.gif.stacyPlain,
|
||||
),
|
||||
)
|
||||
: Lottie.asset(
|
||||
Assets.lottie.test2,
|
||||
animate: true,
|
||||
repeat: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||
import 'package:stackwallet/pages/token_view/token_view.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart';
|
||||
|
@ -10,6 +11,7 @@ import 'package:stackwallet/providers/db/main_db_provider.dart';
|
|||
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||
import 'package:stackwallet/providers/providers.dart';
|
||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
||||
import 'package:stackwallet/services/coins/manager.dart';
|
||||
import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
|
||||
import 'package:stackwallet/services/transaction_notification_tracker.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
|
@ -35,6 +37,24 @@ class SimpleWalletCard extends ConsumerWidget {
|
|||
final bool popPrevious;
|
||||
final NavigatorState? desktopNavigatorState;
|
||||
|
||||
Future<void> _loadTokenWallet(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
Manager manager,
|
||||
EthContract contract,
|
||||
) async {
|
||||
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
|
||||
token: contract,
|
||||
secureStore: ref.read(secureStoreProvider),
|
||||
ethWallet: manager.wallet as EthereumWallet,
|
||||
tracker: TransactionNotificationTracker(
|
||||
walletId: walletId,
|
||||
),
|
||||
);
|
||||
|
||||
await ref.read(tokenServiceProvider)!.initialize();
|
||||
}
|
||||
|
||||
void _openWallet(BuildContext context, WidgetRef ref) async {
|
||||
final nav = Navigator.of(context);
|
||||
|
||||
|
@ -70,24 +90,18 @@ class SimpleWalletCard extends ConsumerWidget {
|
|||
if (contractAddress != null) {
|
||||
final contract =
|
||||
ref.read(mainDBProvider).getEthContractSync(contractAddress!)!;
|
||||
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
|
||||
token: contract,
|
||||
secureStore: ref.read(secureStoreProvider),
|
||||
ethWallet: manager.wallet as EthereumWallet,
|
||||
tracker: TransactionNotificationTracker(
|
||||
walletId: walletId,
|
||||
),
|
||||
);
|
||||
|
||||
await showLoading<void>(
|
||||
whileFuture: ref.read(tokenServiceProvider)!.initialize(),
|
||||
whileFuture: _loadTokenWallet(context, ref, manager, contract),
|
||||
context: context,
|
||||
opaqueBG: true,
|
||||
message: "Loading ${contract.name}",
|
||||
);
|
||||
|
||||
// pop loading
|
||||
nav.pop();
|
||||
if (desktopNavigatorState == null) {
|
||||
// pop loading
|
||||
nav.pop();
|
||||
}
|
||||
|
||||
if (desktopNavigatorState != null) {
|
||||
await desktopNavigatorState!.pushNamed(
|
||||
|
|
Loading…
Reference in a new issue