mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
WIP firo redesign
This commit is contained in:
parent
94941dfb94
commit
fbc398bc14
9 changed files with 938 additions and 159 deletions
|
@ -13,7 +13,9 @@ import 'package:stackwallet/pages/send_view/sub_widgets/transaction_fee_selectio
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
|
import 'package:stackwallet/providers/ui/fee_rate_type_state_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart';
|
import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart';
|
||||||
|
import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
|
||||||
import 'package:stackwallet/route_generator.dart';
|
import 'package:stackwallet/route_generator.dart';
|
||||||
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/utilities/address_utils.dart';
|
import 'package:stackwallet/utilities/address_utils.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -37,6 +39,8 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||||
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
||||||
|
|
||||||
|
import 'sub_widgets/firo_balance_selection_sheet.dart';
|
||||||
|
|
||||||
class SendView extends ConsumerStatefulWidget {
|
class SendView extends ConsumerStatefulWidget {
|
||||||
const SendView({
|
const SendView({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -82,6 +86,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
Decimal? _cachedAmountToSend;
|
Decimal? _cachedAmountToSend;
|
||||||
String? _address;
|
String? _address;
|
||||||
|
|
||||||
|
String? _privateBalanceString;
|
||||||
|
String? _publicBalanceString;
|
||||||
|
|
||||||
bool _addressToggleFlag = false;
|
bool _addressToggleFlag = false;
|
||||||
|
|
||||||
bool _cryptoAmountChangeLock = false;
|
bool _cryptoAmountChangeLock = false;
|
||||||
|
@ -196,6 +203,26 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
return cachedFees[amount]!;
|
return cachedFees[amount]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> _firoBalanceFuture(
|
||||||
|
ChangeNotifierProvider<Manager> provider, String locale) async {
|
||||||
|
final wallet = ref.read(provider).wallet as FiroWallet?;
|
||||||
|
|
||||||
|
if (wallet != null) {
|
||||||
|
Decimal? balance;
|
||||||
|
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
|
||||||
|
"Private") {
|
||||||
|
balance = await wallet.availablePrivateBalance();
|
||||||
|
} else {
|
||||||
|
balance = await wallet.availablePublicBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Format.localizedStringAsFixed(
|
||||||
|
value: balance, locale: locale, decimalPlaces: 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
ref.refresh(feeSheetSessionCacheProvider);
|
ref.refresh(feeSheetSessionCacheProvider);
|
||||||
|
@ -334,21 +361,59 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.svg.iconFor(coin: coin),
|
Assets.svg.iconFor(coin: coin),
|
||||||
width: 18,
|
width: 22,
|
||||||
height: 18,
|
height: 22,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 6,
|
width: 6,
|
||||||
),
|
),
|
||||||
Text(
|
if (coin != Coin.firo &&
|
||||||
ref.watch(provider
|
coin != Coin.firoTestNet)
|
||||||
.select((value) => value.walletName)),
|
Text(
|
||||||
style: STextStyles.titleBold12,
|
ref.watch(provider
|
||||||
),
|
.select((value) => value.walletName)),
|
||||||
|
style: STextStyles.titleBold12,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo ||
|
||||||
|
coin == Coin.firoTestNet)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
ref.watch(provider.select(
|
||||||
|
(value) => value.walletName)),
|
||||||
|
style: STextStyles.titleBold12
|
||||||
|
.copyWith(fontSize: 14),
|
||||||
|
),
|
||||||
|
// const SizedBox(
|
||||||
|
// height: 2,
|
||||||
|
// ),
|
||||||
|
Text(
|
||||||
|
"${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
|
||||||
|
style: STextStyles.label
|
||||||
|
.copyWith(fontSize: 10),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: ref.watch(provider.select(
|
future: (coin != Coin.firo &&
|
||||||
(value) => value.availableBalance)),
|
coin != Coin.firoTestNet)
|
||||||
|
? ref.watch(provider.select(
|
||||||
|
(value) => value.availableBalance))
|
||||||
|
: ref
|
||||||
|
.watch(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state ==
|
||||||
|
"Private"
|
||||||
|
? (ref.watch(provider).wallet
|
||||||
|
as FiroWallet)
|
||||||
|
.availablePrivateBalance()
|
||||||
|
: (ref.watch(provider).wallet
|
||||||
|
as FiroWallet)
|
||||||
|
.availablePublicBalance(),
|
||||||
builder:
|
builder:
|
||||||
(_, AsyncSnapshot<Decimal> snapshot) {
|
(_, AsyncSnapshot<Decimal> snapshot) {
|
||||||
if (snapshot.connectionState ==
|
if (snapshot.connectionState ==
|
||||||
|
@ -423,6 +488,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
AnimatedText(
|
AnimatedText(
|
||||||
stringsToLoopThrough: const [
|
stringsToLoopThrough: const [
|
||||||
"Loading balance ",
|
"Loading balance ",
|
||||||
|
@ -730,6 +798,141 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
Text(
|
||||||
|
"Send from",
|
||||||
|
style: STextStyles.smallMed12,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
const TextField(
|
||||||
|
readOnly: true,
|
||||||
|
textInputAction: TextInputAction.none,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12,
|
||||||
|
),
|
||||||
|
child: RawMaterialButton(
|
||||||
|
splashColor: CFColors.splashLight,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet<dynamic>(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
context: context,
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.circular(20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
builder: (_) => FiroBalanceSelectionSheet(
|
||||||
|
walletId: walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"${ref.watch(publicPrivateBalanceStateProvider.state).state} balance",
|
||||||
|
style: STextStyles.itemSubtitle12,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
FutureBuilder(
|
||||||
|
future: _firoBalanceFuture(
|
||||||
|
provider, locale),
|
||||||
|
builder: (context,
|
||||||
|
AsyncSnapshot<String?>
|
||||||
|
snapshot) {
|
||||||
|
if (snapshot.connectionState ==
|
||||||
|
ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
if (ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state ==
|
||||||
|
"Private") {
|
||||||
|
_privateBalanceString =
|
||||||
|
snapshot.data!;
|
||||||
|
} else {
|
||||||
|
_publicBalanceString =
|
||||||
|
snapshot.data!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state ==
|
||||||
|
"Private" &&
|
||||||
|
_privateBalanceString !=
|
||||||
|
null) {
|
||||||
|
return Text(
|
||||||
|
"$_privateBalanceString ${coin.ticker}",
|
||||||
|
style:
|
||||||
|
STextStyles.itemSubtitle,
|
||||||
|
);
|
||||||
|
} else if (ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state ==
|
||||||
|
"Public" &&
|
||||||
|
_publicBalanceString !=
|
||||||
|
null) {
|
||||||
|
return Text(
|
||||||
|
"$_publicBalanceString ${coin.ticker}",
|
||||||
|
style:
|
||||||
|
STextStyles.itemSubtitle,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return AnimatedText(
|
||||||
|
stringsToLoopThrough: const [
|
||||||
|
"Loading balance",
|
||||||
|
"Loading balance.",
|
||||||
|
"Loading balance..",
|
||||||
|
"Loading balance...",
|
||||||
|
],
|
||||||
|
style:
|
||||||
|
STextStyles.itemSubtitle,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.svg.chevronDown,
|
||||||
|
width: 8,
|
||||||
|
height: 4,
|
||||||
|
color: CFColors.gray3,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 12,
|
height: 12,
|
||||||
),
|
),
|
||||||
|
@ -744,10 +947,34 @@ class _SendViewState extends ConsumerState<SendView> {
|
||||||
BlueTextButton(
|
BlueTextButton(
|
||||||
text: "Send all ${coin.ticker}",
|
text: "Send all ${coin.ticker}",
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
cryptoAmountController.text = (await ref
|
if (coin == Coin.firo ||
|
||||||
.read(provider)
|
coin == Coin.firoTestNet) {
|
||||||
.availableBalance)
|
final firoWallet =
|
||||||
.toStringAsFixed(Constants.decimalPlaces);
|
ref.read(provider).wallet as FiroWallet;
|
||||||
|
if (ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state ==
|
||||||
|
"Private") {
|
||||||
|
cryptoAmountController.text =
|
||||||
|
(await firoWallet
|
||||||
|
.availablePrivateBalance())
|
||||||
|
.toStringAsFixed(
|
||||||
|
Constants.decimalPlaces);
|
||||||
|
} else {
|
||||||
|
cryptoAmountController.text =
|
||||||
|
(await firoWallet
|
||||||
|
.availablePublicBalance())
|
||||||
|
.toStringAsFixed(
|
||||||
|
Constants.decimalPlaces);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cryptoAmountController.text = (await ref
|
||||||
|
.read(provider)
|
||||||
|
.availableBalance)
|
||||||
|
.toStringAsFixed(Constants.decimalPlaces);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,287 @@
|
||||||
|
import 'package:decimal/decimal.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
|
||||||
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
|
import 'package:stackwallet/utilities/cfcolors.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/widgets/animated_text.dart';
|
||||||
|
|
||||||
|
class FiroBalanceSelectionSheet extends ConsumerStatefulWidget {
|
||||||
|
const FiroBalanceSelectionSheet({
|
||||||
|
Key? key,
|
||||||
|
required this.walletId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<FiroBalanceSelectionSheet> createState() =>
|
||||||
|
_FiroBalanceSelectionSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FiroBalanceSelectionSheetState
|
||||||
|
extends ConsumerState<FiroBalanceSelectionSheet> {
|
||||||
|
late final String walletId;
|
||||||
|
|
||||||
|
final stringsToLoopThrough = [
|
||||||
|
"Loading balance",
|
||||||
|
"Loading balance.",
|
||||||
|
"Loading balance..",
|
||||||
|
"Loading balance...",
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
walletId = widget.walletId;
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
debugPrint("BUILD: $runtimeType");
|
||||||
|
|
||||||
|
final manager = ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId)));
|
||||||
|
final firoWallet = manager.wallet as FiroWallet;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: CFColors.white,
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: Radius.circular(20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 24,
|
||||||
|
right: 24,
|
||||||
|
top: 10,
|
||||||
|
bottom: 0,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CFColors.fieldGray,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
width: 60,
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 36,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Select balance",
|
||||||
|
style: STextStyles.pageTitleH2,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
final state =
|
||||||
|
ref.read(publicPrivateBalanceStateProvider.state).state;
|
||||||
|
if (state != "Private") {
|
||||||
|
ref.read(publicPrivateBalanceStateProvider.state).state =
|
||||||
|
"Private";
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: Radio(
|
||||||
|
activeColor: CFColors.link2,
|
||||||
|
value: "Private",
|
||||||
|
groupValue: ref
|
||||||
|
.watch(
|
||||||
|
publicPrivateBalanceStateProvider.state)
|
||||||
|
.state,
|
||||||
|
onChanged: (x) {
|
||||||
|
ref
|
||||||
|
.read(publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state = "Private";
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Row(
|
||||||
|
// children: [
|
||||||
|
Text(
|
||||||
|
"Private balance",
|
||||||
|
style: STextStyles.titleBold12.copyWith(
|
||||||
|
color: const Color(0xFF44464E),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
FutureBuilder(
|
||||||
|
future: firoWallet.availablePrivateBalance(),
|
||||||
|
builder:
|
||||||
|
(context, AsyncSnapshot<Decimal> snapshot) {
|
||||||
|
if (snapshot.connectionState ==
|
||||||
|
ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
return Text(
|
||||||
|
"${snapshot.data!} ${manager.coin.ticker}",
|
||||||
|
style: STextStyles.itemSubtitle,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return AnimatedText(
|
||||||
|
stringsToLoopThrough:
|
||||||
|
stringsToLoopThrough,
|
||||||
|
style: STextStyles.itemSubtitle,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
final state =
|
||||||
|
ref.read(publicPrivateBalanceStateProvider.state).state;
|
||||||
|
if (state != "Public") {
|
||||||
|
ref.read(publicPrivateBalanceStateProvider.state).state =
|
||||||
|
"Public";
|
||||||
|
}
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: Radio(
|
||||||
|
activeColor: CFColors.link2,
|
||||||
|
value: "Public",
|
||||||
|
groupValue: ref
|
||||||
|
.watch(
|
||||||
|
publicPrivateBalanceStateProvider.state)
|
||||||
|
.state,
|
||||||
|
onChanged: (x) {
|
||||||
|
ref
|
||||||
|
.read(publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state = "Public";
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Row(
|
||||||
|
// children: [
|
||||||
|
Text(
|
||||||
|
"Public balance",
|
||||||
|
style: STextStyles.titleBold12.copyWith(
|
||||||
|
color: const Color(0xFF44464E),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
FutureBuilder(
|
||||||
|
future: firoWallet.availablePublicBalance(),
|
||||||
|
builder:
|
||||||
|
(context, AsyncSnapshot<Decimal> snapshot) {
|
||||||
|
if (snapshot.connectionState ==
|
||||||
|
ConnectionState.done &&
|
||||||
|
snapshot.hasData) {
|
||||||
|
return Text(
|
||||||
|
"${snapshot.data!} ${manager.coin.ticker}",
|
||||||
|
style: STextStyles.itemSubtitle,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return AnimatedText(
|
||||||
|
stringsToLoopThrough:
|
||||||
|
stringsToLoopThrough,
|
||||||
|
style: STextStyles.itemSubtitle,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
||||||
import 'package:stackwallet/utilities/cfcolors.dart';
|
import 'package:stackwallet/utilities/cfcolors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
|
import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
|
||||||
|
@ -18,6 +20,9 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final maxHeight = MediaQuery.of(context).size.height * 0.60;
|
final maxHeight = MediaQuery.of(context).size.height * 0.60;
|
||||||
|
|
||||||
|
final coin = ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId).coin));
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: CFColors.white,
|
color: CFColors.white,
|
||||||
|
@ -105,25 +110,44 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
Column(
|
if (coin != Coin.firo && coin != Coin.firoTestNet)
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Text(
|
children: [
|
||||||
"Available balance",
|
Text(
|
||||||
style: STextStyles.titleBold12,
|
"Available balance",
|
||||||
),
|
style: STextStyles.titleBold12,
|
||||||
const SizedBox(
|
|
||||||
height: 2,
|
|
||||||
),
|
|
||||||
// TODO need text from design
|
|
||||||
Text(
|
|
||||||
"Current spendable (unlocked) balance",
|
|
||||||
style: STextStyles.itemSubtitle12.copyWith(
|
|
||||||
color: CFColors.neutral60,
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
],
|
height: 2,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"Current spendable (unlocked) balance",
|
||||||
|
style: STextStyles.itemSubtitle12.copyWith(
|
||||||
|
color: CFColors.neutral60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Private balance",
|
||||||
|
style: STextStyles.titleBold12,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Current private spendable (unlocked) balance",
|
||||||
|
style: STextStyles.itemSubtitle12.copyWith(
|
||||||
|
color: CFColors.neutral60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -172,25 +196,44 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
Column(
|
if (coin != Coin.firo && coin != Coin.firoTestNet)
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Text(
|
children: [
|
||||||
"Full balance",
|
Text(
|
||||||
style: STextStyles.titleBold12,
|
"Full balance",
|
||||||
),
|
style: STextStyles.titleBold12,
|
||||||
const SizedBox(
|
|
||||||
height: 2,
|
|
||||||
),
|
|
||||||
// TODO need text from design
|
|
||||||
Text(
|
|
||||||
"Total wallet balance",
|
|
||||||
style: STextStyles.itemSubtitle12.copyWith(
|
|
||||||
color: CFColors.neutral60,
|
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
],
|
height: 2,
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"Total wallet balance",
|
||||||
|
style: STextStyles.itemSubtitle12.copyWith(
|
||||||
|
color: CFColors.neutral60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Public balance",
|
||||||
|
style: STextStyles.titleBold12,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Current public spendable (unlocked) balance",
|
||||||
|
style: STextStyles.itemSubtitle12.copyWith(
|
||||||
|
color: CFColors.neutral60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_balance_toggle_
|
||||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_refresh_button.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
import 'package:stackwallet/providers/wallet/wallet_balance_toggle_state_provider.dart';
|
||||||
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -67,15 +68,25 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Consumer(
|
child: Consumer(
|
||||||
builder: (_, ref, __) {
|
builder: (_, ref, __) {
|
||||||
final totalBalanceFuture = ref
|
|
||||||
.watch(managerProvider.select((value) => value.totalBalance));
|
|
||||||
|
|
||||||
final availableBalanceFuture = ref.watch(
|
|
||||||
managerProvider.select((value) => value.availableBalance));
|
|
||||||
|
|
||||||
final Coin coin =
|
final Coin coin =
|
||||||
ref.watch(managerProvider.select((value) => value.coin));
|
ref.watch(managerProvider.select((value) => value.coin));
|
||||||
|
|
||||||
|
Future<Decimal>? totalBalanceFuture;
|
||||||
|
Future<Decimal>? availableBalanceFuture;
|
||||||
|
if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
||||||
|
final firoWallet =
|
||||||
|
ref.watch(managerProvider.select((value) => value.wallet))
|
||||||
|
as FiroWallet;
|
||||||
|
totalBalanceFuture = firoWallet.availablePublicBalance();
|
||||||
|
availableBalanceFuture = firoWallet.availablePrivateBalance();
|
||||||
|
} else {
|
||||||
|
totalBalanceFuture = ref.watch(
|
||||||
|
managerProvider.select((value) => value.totalBalance));
|
||||||
|
|
||||||
|
availableBalanceFuture = ref.watch(
|
||||||
|
managerProvider.select((value) => value.availableBalance));
|
||||||
|
}
|
||||||
|
|
||||||
final locale = ref.watch(localeServiceChangeNotifierProvider
|
final locale = ref.watch(localeServiceChangeNotifierProvider
|
||||||
.select((value) => value.locale));
|
.select((value) => value.locale));
|
||||||
|
|
||||||
|
@ -114,12 +125,20 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
|
||||||
onTap: showSheet,
|
onTap: showSheet,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
"${_showAvailable ? "Available" : "Full"} Balance",
|
Text(
|
||||||
style: STextStyles.subtitle.copyWith(
|
"${_showAvailable ? "Private" : "Public"} Balance",
|
||||||
fontWeight: FontWeight.w500,
|
style: STextStyles.subtitle.copyWith(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (coin != Coin.firo && coin != Coin.firoTestNet)
|
||||||
|
Text(
|
||||||
|
"${_showAvailable ? "Available" : "Full"} Balance",
|
||||||
|
style: STextStyles.subtitle.copyWith(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 4,
|
width: 4,
|
||||||
),
|
),
|
||||||
|
@ -166,12 +185,20 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
|
||||||
onTap: showSheet,
|
onTap: showSheet,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
if (coin == Coin.firo || coin == Coin.firoTestNet)
|
||||||
"${_showAvailable ? "Available" : "Full"} Balance",
|
Text(
|
||||||
style: STextStyles.subtitle.copyWith(
|
"${_showAvailable ? "Private" : "Public"} Balance",
|
||||||
fontWeight: FontWeight.w500,
|
style: STextStyles.subtitle.copyWith(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (coin != Coin.firo && coin != Coin.firoTestNet)
|
||||||
|
Text(
|
||||||
|
"${_showAvailable ? "Available" : "Full"} Balance",
|
||||||
|
style: STextStyles.subtitle.copyWith(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 4,
|
width: 4,
|
||||||
),
|
),
|
||||||
|
|
|
@ -71,11 +71,11 @@ class _TransactionDetailsViewState
|
||||||
fee = Format.satoshisToAmount(_transaction.fees);
|
fee = Format.satoshisToAmount(_transaction.fees);
|
||||||
amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "- " : "+ ";
|
amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "- " : "+ ";
|
||||||
|
|
||||||
if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
// if (coin == Coin.firo || coin == Coin.firoTestNet) {
|
||||||
showFeePending = true;
|
// showFeePending = true;
|
||||||
} else {
|
// } else {
|
||||||
showFeePending = false;
|
// showFeePending = false;
|
||||||
}
|
// }
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +86,10 @@ class _TransactionDetailsViewState
|
||||||
|
|
||||||
String whatIsIt(String type) {
|
String whatIsIt(String type) {
|
||||||
if (type == "Received") {
|
if (type == "Received") {
|
||||||
if (_transaction.isMinting) {
|
// if (_transaction.isMinting) {
|
||||||
return "Minting";
|
// return "Minting";
|
||||||
} else if (_transaction.confirmedStatus) {
|
// } else
|
||||||
|
if (_transaction.confirmedStatus) {
|
||||||
return "Received";
|
return "Received";
|
||||||
} else {
|
} else {
|
||||||
return "Receiving";
|
return "Receiving";
|
||||||
|
@ -507,83 +508,83 @@ class _TransactionDetailsViewState
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
|
// if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
|
||||||
_transaction.subType == "mint")
|
// _transaction.subType == "mint")
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 12,
|
// height: 12,
|
||||||
),
|
// ),
|
||||||
if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
|
// if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
|
||||||
_transaction.subType == "mint")
|
// _transaction.subType == "mint")
|
||||||
RoundedWhiteContainer(
|
// RoundedWhiteContainer(
|
||||||
child: Column(
|
// child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
// children: [
|
||||||
Row(
|
// Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
// children: [
|
||||||
Text(
|
// Text(
|
||||||
"Mint Transaction ID",
|
// "Mint Transaction ID",
|
||||||
style: STextStyles.itemSubtitle,
|
// style: STextStyles.itemSubtitle,
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 8,
|
// height: 8,
|
||||||
),
|
// ),
|
||||||
// Flexible(
|
// // Flexible(
|
||||||
// child: FittedBox(
|
// // child: FittedBox(
|
||||||
// fit: BoxFit.scaleDown,
|
// // fit: BoxFit.scaleDown,
|
||||||
// child:
|
// // child:
|
||||||
SelectableText(
|
// SelectableText(
|
||||||
_transaction.otherData ?? "Unknown",
|
// _transaction.otherData ?? "Unknown",
|
||||||
style: STextStyles.itemSubtitle12,
|
// style: STextStyles.itemSubtitle12,
|
||||||
),
|
// ),
|
||||||
// ),
|
// // ),
|
||||||
// ),
|
// // ),
|
||||||
const SizedBox(
|
// const SizedBox(
|
||||||
height: 8,
|
// height: 8,
|
||||||
),
|
// ),
|
||||||
BlueTextButton(
|
// BlueTextButton(
|
||||||
text: "Open in block explorer",
|
// text: "Open in block explorer",
|
||||||
onTap: () async {
|
// onTap: () async {
|
||||||
final uri = getBlockExplorerTransactionUrlFor(
|
// final uri = getBlockExplorerTransactionUrlFor(
|
||||||
coin: coin,
|
// coin: coin,
|
||||||
txid: _transaction.otherData ?? "Unknown",
|
// txid: _transaction.otherData ?? "Unknown",
|
||||||
);
|
// );
|
||||||
// ref
|
// // ref
|
||||||
// .read(
|
// // .read(
|
||||||
// shouldShowLockscreenOnResumeStateProvider
|
// // shouldShowLockscreenOnResumeStateProvider
|
||||||
// .state)
|
// // .state)
|
||||||
// .state = false;
|
// // .state = false;
|
||||||
try {
|
// try {
|
||||||
await launchUrl(
|
// await launchUrl(
|
||||||
uri,
|
// uri,
|
||||||
mode: LaunchMode.externalApplication,
|
// mode: LaunchMode.externalApplication,
|
||||||
);
|
// );
|
||||||
} catch (_) {
|
// } catch (_) {
|
||||||
showDialog<void>(
|
// unawaited(showDialog<void>(
|
||||||
context: context,
|
// context: context,
|
||||||
builder: (_) => StackOkDialog(
|
// builder: (_) => StackOkDialog(
|
||||||
title: "Could not open in block explorer",
|
// title: "Could not open in block explorer",
|
||||||
message:
|
// message:
|
||||||
"Failed to open \"${uri.toString()}\"",
|
// "Failed to open \"${uri.toString()}\"",
|
||||||
),
|
// ),
|
||||||
);
|
// ));
|
||||||
} finally {
|
// } finally {
|
||||||
// Future<void>.delayed(
|
// // Future<void>.delayed(
|
||||||
// const Duration(seconds: 1),
|
// // const Duration(seconds: 1),
|
||||||
// () => ref
|
// // () => ref
|
||||||
// .read(
|
// // .read(
|
||||||
// shouldShowLockscreenOnResumeStateProvider
|
// // shouldShowLockscreenOnResumeStateProvider
|
||||||
// .state)
|
// // .state)
|
||||||
// .state = true,
|
// // .state = true,
|
||||||
// );
|
// // );
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
if (coin == Coin.epicCash)
|
if (coin == Coin.epicCash)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 12,
|
height: 12,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
|
import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
|
||||||
import 'package:stackwallet/pages/home_view/home_view.dart';
|
import 'package:stackwallet/pages/home_view/home_view.dart';
|
||||||
|
@ -22,6 +24,7 @@ import 'package:stackwallet/providers/global/auto_swb_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
|
import 'package:stackwallet/providers/ui/transaction_filter_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
|
import 'package:stackwallet/providers/ui/unread_notifications_provider.dart';
|
||||||
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
|
@ -31,12 +34,18 @@ import 'package:stackwallet/utilities/cfcolors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
|
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
|
||||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
import '../../providers/wallet/public_private_balance_state_provider.dart';
|
||||||
|
import '../../providers/wallet/wallet_balance_toggle_state_provider.dart';
|
||||||
|
import '../../utilities/enums/wallet_balance_toggle_state.dart';
|
||||||
|
|
||||||
/// [eventBus] should only be set during testing
|
/// [eventBus] should only be set during testing
|
||||||
class WalletView extends ConsumerStatefulWidget {
|
class WalletView extends ConsumerStatefulWidget {
|
||||||
const WalletView({
|
const WalletView({
|
||||||
|
@ -271,10 +280,78 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> attemptAnonymize() async {
|
||||||
|
bool shouldPop = false;
|
||||||
|
unawaited(
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => WillPopScope(
|
||||||
|
child: const CustomLoadingOverlay(
|
||||||
|
message: "Anonymizing balance",
|
||||||
|
eventBus: null,
|
||||||
|
),
|
||||||
|
onWillPop: () async => shouldPop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final firoWallet = ref.read(managerProvider).wallet as FiroWallet;
|
||||||
|
|
||||||
|
final publicBalance = await firoWallet.availablePublicBalance();
|
||||||
|
if (publicBalance <= Decimal.zero) {
|
||||||
|
shouldPop = true;
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).popUntil(
|
||||||
|
ModalRoute.withName(WalletView.routeName),
|
||||||
|
);
|
||||||
|
unawaited(
|
||||||
|
showFloatingFlushBar(
|
||||||
|
type: FlushBarType.info,
|
||||||
|
message: "No funds available to anonymize!",
|
||||||
|
context: context,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await firoWallet.anonymizeAllPublicFunds();
|
||||||
|
shouldPop = true;
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).popUntil(
|
||||||
|
ModalRoute.withName(WalletView.routeName),
|
||||||
|
);
|
||||||
|
unawaited(
|
||||||
|
showFloatingFlushBar(
|
||||||
|
type: FlushBarType.success,
|
||||||
|
message: "Anonymize transaction submitted",
|
||||||
|
context: context,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
shouldPop = true;
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).popUntil(
|
||||||
|
ModalRoute.withName(WalletView.routeName),
|
||||||
|
);
|
||||||
|
await showDialog<dynamic>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => StackOkDialog(
|
||||||
|
title: "Anonymize all failed",
|
||||||
|
message: "Reason: $e",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
debugPrint("BUILD: $runtimeType");
|
debugPrint("BUILD: $runtimeType");
|
||||||
|
|
||||||
|
final coin = ref.watch(managerProvider.select((value) => value.coin));
|
||||||
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: _onWillPop,
|
onWillPop: _onWillPop,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
@ -283,9 +360,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.svg.iconFor(
|
Assets.svg.iconFor(coin: coin),
|
||||||
coin: ref
|
|
||||||
.watch(managerProvider.select((value) => value.coin))),
|
|
||||||
// color: CFColors.stackAccent,
|
// color: CFColors.stackAccent,
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
|
@ -440,6 +515,69 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
if (coin == Coin.firo)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => StackDialog(
|
||||||
|
title: "Attention!",
|
||||||
|
message:
|
||||||
|
"You're about to anonymize all of your public funds.",
|
||||||
|
leftButton: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"Cancel",
|
||||||
|
style: STextStyles.button.copyWith(
|
||||||
|
color: CFColors.stackAccent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
rightButton: TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
unawaited(attemptAnonymize());
|
||||||
|
},
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textButtonTheme
|
||||||
|
.style
|
||||||
|
?.copyWith(
|
||||||
|
backgroundColor:
|
||||||
|
MaterialStateProperty.all<Color>(
|
||||||
|
CFColors.stackAccent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"Continue",
|
||||||
|
style: STextStyles.button,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
"Anonymize funds",
|
||||||
|
style: STextStyles.button.copyWith(
|
||||||
|
color: CFColors.stackAccent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
|
@ -550,6 +688,25 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
ref.read(managerProvider).walletId;
|
ref.read(managerProvider).walletId;
|
||||||
final coin =
|
final coin =
|
||||||
ref.read(managerProvider).coin;
|
ref.read(managerProvider).coin;
|
||||||
|
switch (ref
|
||||||
|
.read(walletBalanceToggleStateProvider
|
||||||
|
.state)
|
||||||
|
.state) {
|
||||||
|
case WalletBalanceToggleState.full:
|
||||||
|
ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state = "Public";
|
||||||
|
break;
|
||||||
|
case WalletBalanceToggleState.available:
|
||||||
|
ref
|
||||||
|
.read(
|
||||||
|
publicPrivateBalanceStateProvider
|
||||||
|
.state)
|
||||||
|
.state = "Private";
|
||||||
|
break;
|
||||||
|
}
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
SendView.routeName,
|
SendView.routeName,
|
||||||
arguments: Tuple2(
|
arguments: Tuple2(
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
final publicPrivateBalanceStateProvider =
|
||||||
|
StateProvider<String>((_) => "Private");
|
|
@ -1761,7 +1761,12 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
balances.add(
|
balances.add(
|
||||||
(lelantusBalance + utxosValue + _unconfirmedLelantusBalance) * price);
|
(lelantusBalance + utxosValue + _unconfirmedLelantusBalance) * price);
|
||||||
|
|
||||||
balances.add(utxosValue);
|
int availableSats =
|
||||||
|
utxos.satoshiBalance - utxos.satoshiBalanceUnconfirmed;
|
||||||
|
if (availableSats < 0) {
|
||||||
|
availableSats = 0;
|
||||||
|
}
|
||||||
|
balances.add(Format.satoshisToAmount(availableSats));
|
||||||
|
|
||||||
Logging.instance.log("balances $balances", level: LogLevel.Info);
|
Logging.instance.log("balances $balances", level: LogLevel.Info);
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
|
@ -2782,6 +2787,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
Decimal currentPrice = await firoPrice;
|
Decimal currentPrice = await firoPrice;
|
||||||
final List<Map<String, dynamic>> outputArray = [];
|
final List<Map<String, dynamic>> outputArray = [];
|
||||||
int satoshiBalance = 0;
|
int satoshiBalance = 0;
|
||||||
|
int satoshiBalancePending = 0;
|
||||||
|
|
||||||
for (int i = 0; i < utxoData.length; i++) {
|
for (int i = 0; i < utxoData.length; i++) {
|
||||||
for (int j = 0; j < utxoData[i].length; j++) {
|
for (int j = 0; j < utxoData[i].length; j++) {
|
||||||
|
@ -2795,16 +2801,22 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
);
|
);
|
||||||
|
|
||||||
final Map<String, dynamic> tx = {};
|
final Map<String, dynamic> tx = {};
|
||||||
|
final int confirmations = txn["confirmations"] as int? ?? 0;
|
||||||
|
final bool confirmed = confirmations >= MINIMUM_CONFIRMATIONS;
|
||||||
|
if (!confirmed) {
|
||||||
|
satoshiBalancePending += value;
|
||||||
|
}
|
||||||
|
|
||||||
tx["txid"] = txn["txid"];
|
tx["txid"] = txn["txid"];
|
||||||
tx["vout"] = utxoData[i][j]["tx_pos"];
|
tx["vout"] = utxoData[i][j]["tx_pos"];
|
||||||
tx["value"] = value;
|
tx["value"] = value;
|
||||||
|
|
||||||
tx["status"] = <String, dynamic>{};
|
tx["status"] = <String, dynamic>{};
|
||||||
|
tx["status"]["confirmed"] = confirmed;
|
||||||
|
tx["status"]["confirmations"] = confirmations;
|
||||||
tx["status"]["confirmed"] =
|
tx["status"]["confirmed"] =
|
||||||
txn["confirmations"] == null ? false : txn["confirmations"] > 0;
|
txn["confirmations"] == null ? false : txn["confirmations"] > 0;
|
||||||
tx["status"]["confirmations"] =
|
|
||||||
txn["confirmations"] == null ? 0 : txn["confirmations"]!;
|
|
||||||
tx["status"]["block_height"] = txn["height"];
|
tx["status"]["block_height"] = txn["height"];
|
||||||
tx["status"]["block_hash"] = txn["blockhash"];
|
tx["status"]["block_hash"] = txn["blockhash"];
|
||||||
tx["status"]["block_time"] = txn["blocktime"];
|
tx["status"]["block_time"] = txn["blocktime"];
|
||||||
|
@ -2832,6 +2844,7 @@ class FiroWallet extends CoinServiceAPI {
|
||||||
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
.toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces)
|
||||||
.toString(),
|
.toString(),
|
||||||
"outputArray": outputArray,
|
"outputArray": outputArray,
|
||||||
|
"unconfirmed": satoshiBalancePending,
|
||||||
};
|
};
|
||||||
|
|
||||||
final dataModel = UtxoData.fromJson(result);
|
final dataModel = UtxoData.fromJson(result);
|
||||||
|
|
|
@ -37,10 +37,30 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
|
||||||
if (coin == Coin.epicCash && _transaction.slateId == null) {
|
if (coin == Coin.epicCash && _transaction.slateId == null) {
|
||||||
return "Restored Funds";
|
return "Restored Funds";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_transaction.subType == "mint") {
|
||||||
|
// if (type == "Received") {
|
||||||
|
if (_transaction.confirmedStatus) {
|
||||||
|
return "Anonymized";
|
||||||
|
} else {
|
||||||
|
return "Anonymizing";
|
||||||
|
}
|
||||||
|
// } else if (type == "Sent") {
|
||||||
|
// if (_transaction.confirmedStatus) {
|
||||||
|
// return "Sent MINT";
|
||||||
|
// } else {
|
||||||
|
// return "Sending MINT";
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return type;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
if (type == "Received") {
|
if (type == "Received") {
|
||||||
if (_transaction.isMinting) {
|
// if (_transaction.isMinting) {
|
||||||
return "Minting";
|
// return "Minting";
|
||||||
} else if (_transaction.confirmedStatus) {
|
// } else
|
||||||
|
if (_transaction.confirmedStatus) {
|
||||||
return "Received";
|
return "Received";
|
||||||
} else {
|
} else {
|
||||||
return "Receiving";
|
return "Receiving";
|
||||||
|
|
Loading…
Reference in a new issue