update wallet ui to handle new data models

This commit is contained in:
julian 2023-01-11 22:26:38 -06:00
parent eb915a0927
commit f8c6a17fa7
10 changed files with 318 additions and 821 deletions

View file

@ -7,7 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';
import 'package:stackwallet/models/paymint/transactions_model.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/exchange_view/edit_trade_note_view.dart';
import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
@ -23,7 +23,6 @@ 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/flush_bar_type.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';

View file

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/models/paymint/transactions_model.dart' as old;
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart';
import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart';
@ -14,7 +13,6 @@ import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
import 'package:stackwallet/services/coins/manager.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/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
@ -42,20 +40,10 @@ class TransactionsList extends ConsumerStatefulWidget {
class _TransactionsListState extends ConsumerState<TransactionsList> {
//
bool _hasLoaded = false;
Map<String, old.Transaction> _transactions = {};
List<Transaction> _transactions2 = [];
late final ChangeNotifierProvider<Manager> managerProvider;
void updateTransactions(old.TransactionData newData) {
_transactions = {};
final newTransactions =
newData.txChunks.expand((element) => element.transactions);
for (final tx in newTransactions) {
_transactions[tx.txid] = tx;
}
}
BorderRadius get _borderRadiusFirst {
return BorderRadius.only(
topLeft: Radius.circular(
@ -80,14 +68,14 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
Widget itemBuilder(
BuildContext context,
old.Transaction tx,
Transaction tx,
BorderRadius? radius,
) {
final matchingTrades = ref
.read(tradesServiceProvider)
.trades
.where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid);
if (tx.txType == "Sent" && matchingTrades.isNotEmpty) {
if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) {
final trade = matchingTrades.first;
return Container(
decoration: BoxDecoration(
@ -199,127 +187,6 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
}
}
Widget itemBuilder2(
BuildContext context,
Transaction tx,
BorderRadius? radius,
) {
final matchingTrades = ref
.read(tradesServiceProvider)
.trades
.where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid);
if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) {
final trade = matchingTrades.first;
return Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: radius,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TransactionCard2(
// this may mess with combined firo transactions
key: Key(tx.toString()), //
transaction: tx,
walletId: widget.walletId,
),
TradeCard(
// this may mess with combined firo transactions
key: Key(tx.toString() + trade.uuid), //
trade: trade,
onTap: () async {
if (Util.isDesktop) {
// await showDialog<void>(
// context: context,
// builder: (context) => Navigator(
// initialRoute: TradeDetailsView.routeName,
// onGenerateRoute: RouteGenerator.generateRoute,
// onGenerateInitialRoutes: (_, __) {
// return [
// FadePageRoute(
// DesktopDialog(
// maxHeight: null,
// maxWidth: 580,
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// Padding(
// padding: const EdgeInsets.only(
// left: 32,
// bottom: 16,
// ),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// "Trade details",
// style: STextStyles.desktopH3(context),
// ),
// DesktopDialogCloseButton(
// onPressedOverride: Navigator.of(
// context,
// rootNavigator: true,
// ).pop,
// ),
// ],
// ),
// ),
// Flexible(
// child: TradeDetailsView(
// tradeId: trade.tradeId,
// transactionIfSentFromStack: tx,
// walletName:
// ref.read(managerProvider).walletName,
// walletId: widget.walletId,
// ),
// ),
// ],
// ),
// ),
// const RouteSettings(
// name: TradeDetailsView.routeName,
// ),
// ),
// ];
// },
// ),
// );
} else {
unawaited(
Navigator.of(context).pushNamed(
TradeDetailsView.routeName,
arguments: Tuple4(
trade.tradeId,
tx,
widget.walletId,
ref.read(managerProvider).walletName,
),
),
);
}
},
)
],
),
);
} else {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: radius,
),
child: TransactionCard2(
// this may mess with combined firo transactions
key: Key(tx.toString()), //
transaction: tx,
walletId: widget.walletId,
),
);
}
}
void updateHeightProvider(Manager manager) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
ref.read(currentHeightProvider(manager.coin).state).state =
@ -342,186 +209,94 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(widget.walletId)));
if (manager.coin == Coin.dogecoinTestNet) {
updateHeightProvider(manager);
final wallet = manager.wallet as DogecoinWallet;
return FutureBuilder(
future: wallet.isar.transactions.where().findAll(),
builder: (fbContext, AsyncSnapshot<List<Transaction>> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
_transactions2 = snapshot.data!;
_hasLoaded = true;
}
if (!_hasLoaded) {
return Column(
children: const [
Spacer(),
Center(
child: LoadingIndicator(
height: 50,
width: 50,
),
updateHeightProvider(manager);
final wallet = manager.wallet as DogecoinWallet;
return FutureBuilder(
future: wallet.isar.transactions.where().findAll(),
builder: (fbContext, AsyncSnapshot<List<Transaction>> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
_transactions2 = snapshot.data!;
_hasLoaded = true;
}
if (!_hasLoaded) {
return Column(
children: const [
Spacer(),
Center(
child: LoadingIndicator(
height: 50,
width: 50,
),
Spacer(
flex: 4,
),
],
);
}
if (_transactions2.isEmpty) {
return const NoTransActionsFound();
} else {
_transactions2.sort((a, b) => b.timestamp - a.timestamp);
return RefreshIndicator(
onRefresh: () async {
//todo: check if print needed
// debugPrint("pulled down to refresh on transaction list");
final managerProvider = ref
.read(walletsChangeNotifierProvider)
.getManagerProvider(widget.walletId);
if (!ref.read(managerProvider).isRefreshing) {
unawaited(ref.read(managerProvider).refresh());
}
},
child: Util.isDesktop
? ListView.separated(
itemBuilder: (context, index) {
BorderRadius? radius;
if (_transactions2.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
} else if (index == _transactions2.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = _transactions2[index];
return itemBuilder2(context, tx, radius);
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 2,
color: Theme.of(context)
.extension<StackColors>()!
.background,
),
Spacer(
flex: 4,
),
],
);
}
if (_transactions2.isEmpty) {
return const NoTransActionsFound();
} else {
_transactions2.sort((a, b) => b.timestamp - a.timestamp);
return RefreshIndicator(
onRefresh: () async {
//todo: check if print needed
// debugPrint("pulled down to refresh on transaction list");
final managerProvider = ref
.read(walletsChangeNotifierProvider)
.getManagerProvider(widget.walletId);
if (!ref.read(managerProvider).isRefreshing) {
unawaited(ref.read(managerProvider).refresh());
}
},
child: Util.isDesktop
? ListView.separated(
itemBuilder: (context, index) {
BorderRadius? radius;
if (_transactions2.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
},
itemCount: _transactions2.length,
)
: ListView.builder(
itemCount: _transactions2.length,
itemBuilder: (context, index) {
BorderRadius? radius;
if (_transactions2.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
} else if (index == _transactions2.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = _transactions2[index];
return itemBuilder2(context, tx, radius);
},
),
);
}
},
);
} else {
return FutureBuilder(
future:
ref.watch(managerProvider.select((value) => value.transactionData)),
builder: (fbContext, AsyncSnapshot<old.TransactionData> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
updateTransactions(snapshot.data!);
_hasLoaded = true;
}
if (!_hasLoaded) {
return Column(
children: const [
Spacer(),
Center(
child: LoadingIndicator(
height: 50,
width: 50,
),
),
Spacer(
flex: 4,
),
],
);
}
if (_transactions.isEmpty) {
return const NoTransActionsFound();
} else {
final list = _transactions.values.toList(growable: false);
list.sort((a, b) => b.timestamp - a.timestamp);
return RefreshIndicator(
onRefresh: () async {
//todo: check if print needed
// debugPrint("pulled down to refresh on transaction list");
final managerProvider = ref
.read(walletsChangeNotifierProvider)
.getManagerProvider(widget.walletId);
if (!ref.read(managerProvider).isRefreshing) {
unawaited(ref.read(managerProvider).refresh());
}
},
child: Util.isDesktop
? ListView.separated(
itemBuilder: (context, index) {
BorderRadius? radius;
if (list.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
} else if (index == list.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = list[index];
return itemBuilder(context, tx, radius);
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 2,
color: Theme.of(context)
.extension<StackColors>()!
.background,
} else if (index == _transactions2.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = _transactions2[index];
return itemBuilder(context, tx, radius);
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 2,
color: Theme.of(context)
.extension<StackColors>()!
.background,
);
},
itemCount: _transactions2.length,
)
: ListView.builder(
itemCount: _transactions2.length,
itemBuilder: (context, index) {
BorderRadius? radius;
if (_transactions2.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
},
itemCount: list.length,
)
: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
BorderRadius? radius;
if (list.length == 1) {
radius = BorderRadius.circular(
Constants.size.circularBorderRadius,
);
} else if (index == list.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = list[index];
return itemBuilder(context, tx, radius);
},
),
);
}
},
);
}
} else if (index == _transactions2.length - 1) {
radius = _borderRadiusLast;
} else if (index == 0) {
radius = _borderRadiusFirst;
}
final tx = _transactions2[index];
return itemBuilder(context, tx, radius);
},
),
);
}
},
);
}
}

View file

@ -1,79 +1,18 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
import 'package:stackwallet/models/paymint/transactions_model.dart' as old;
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
class TxIcon extends StatelessWidget {
const TxIcon({Key? key, required this.transaction}) : super(key: key);
final old.Transaction transaction;
static const Size size = Size(32, 32);
String _getAssetName(
bool isCancelled, bool isReceived, bool isPending, BuildContext context) {
if (!isReceived && transaction.subType == "mint") {
if (isCancelled) {
return Assets.svg.anonymizeFailed;
}
if (isPending) {
return Assets.svg.anonymizePending;
}
return Assets.svg.anonymize;
}
if (isReceived) {
if (isCancelled) {
return Assets.svg.receiveCancelled(context);
}
if (isPending) {
return Assets.svg.receivePending(context);
}
return Assets.svg.receive(context);
} else {
if (isCancelled) {
return Assets.svg.sendCancelled(context);
}
if (isPending) {
return Assets.svg.sendPending(context);
}
return Assets.svg.send(context);
}
}
@override
Widget build(BuildContext context) {
final txIsReceived = transaction.txType == "Received";
return SizedBox(
width: size.width,
height: size.height,
child: Center(
child: SvgPicture.asset(
_getAssetName(
transaction.isCancelled,
txIsReceived,
!transaction.confirmedStatus,
context,
),
width: size.width,
height: size.height,
),
),
);
}
}
class TxIcon2 extends StatelessWidget {
const TxIcon2({
const TxIcon({
Key? key,
required this.transaction,
required this.currentHeight,
required this.coin,
}) : super(key: key);
final isar_models.Transaction transaction;
final Transaction transaction;
final int currentHeight;
final Coin coin;
@ -81,8 +20,7 @@ class TxIcon2 extends StatelessWidget {
String _getAssetName(
bool isCancelled, bool isReceived, bool isPending, BuildContext context) {
if (!isReceived &&
transaction.subType == isar_models.TransactionSubType.mint) {
if (!isReceived && transaction.subType == TransactionSubType.mint) {
if (isCancelled) {
return Assets.svg.anonymizeFailed;
}
@ -113,8 +51,7 @@ class TxIcon2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
final txIsReceived =
transaction.type == isar_models.TransactionType.incoming;
final txIsReceived = transaction.type == TransactionType.incoming;
return SizedBox(
width: size.width,

View file

@ -32,13 +32,14 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)))
.wallet as FiroWallet;
totalBalanceFuture = firoWallet.availablePublicBalance();
availableBalanceFuture = firoWallet.availablePrivateBalance();
totalBalanceFuture = Future(() => firoWallet.balance.getSpendable());
availableBalanceFuture =
Future(() => firoWallet.balancePrivate.getSpendable());
} else {
final wallet = ref.watch(walletsChangeNotifierProvider
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)));
totalBalanceFuture = wallet.totalBalance;
availableBalanceFuture = wallet.availableBalance;
totalBalanceFuture = Future(() => manager.balance.getTotal());
availableBalanceFuture = Future(() => manager.balance.getSpendable());
}
return Container(

View file

@ -79,14 +79,16 @@ class _WalletSummaryInfoState extends State<WalletSummaryInfo> {
final firoWallet =
ref.watch(managerProvider.select((value) => value.wallet))
as FiroWallet;
totalBalanceFuture = firoWallet.availablePublicBalance();
availableBalanceFuture = firoWallet.availablePrivateBalance();
totalBalanceFuture =
Future(() => firoWallet.balance.getSpendable());
availableBalanceFuture =
Future(() => firoWallet.balancePrivate.getSpendable());
} else {
totalBalanceFuture = ref.watch(
managerProvider.select((value) => value.totalBalance));
availableBalanceFuture = ref.watch(
managerProvider.select((value) => value.availableBalance));
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)));
totalBalanceFuture = Future(() => manager.balance.getTotal());
availableBalanceFuture =
Future(() => manager.balance.getSpendable());
}
final locale = ref.watch(localeServiceChangeNotifierProvider

View file

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/paymint/transactions_model.dart';
import 'package:stackwallet/models/transaction_filter.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
@ -34,6 +33,9 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:stackwallet/widgets/transaction_card.dart';
import 'package:tuple/tuple.dart';
import '../../../models/isar/models/blockchain_data/transaction.dart';
import '../../../providers/blockchain/dogecoin/current_height_provider.dart';
class AllTransactionsView extends ConsumerStatefulWidget {
const AllTransactionsView({
Key? key,
@ -89,11 +91,15 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
return false;
}
if (filter.received && !filter.sent && tx.txType == "Sent") {
if (filter.received &&
!filter.sent &&
tx.type == TransactionType.outgoing) {
return false;
}
if (filter.sent && !filter.received && tx.txType == "Received") {
if (filter.sent &&
!filter.received &&
tx.type == TransactionType.incoming) {
return false;
}
@ -141,11 +147,10 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
contains |= tx.txid.toLowerCase().contains(keyword);
// check if subType contains
contains |=
tx.subType.isNotEmpty && tx.subType.toLowerCase().contains(keyword);
contains |= tx.subType.name.toLowerCase().contains(keyword);
// check if txType contains
contains |= tx.txType.toLowerCase().contains(keyword);
contains |= tx.type.name.toLowerCase().contains(keyword);
// check if date contains
contains |=
@ -454,17 +459,13 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
// debugPrint("Consumer build called");
return FutureBuilder(
future: ref.watch(managerProvider
.select((value) => value.transactionData)),
builder: (_, AsyncSnapshot<TransactionData> snapshot) {
future: ref.watch(
managerProvider.select((value) => value.transactions)),
builder: (_, AsyncSnapshot<List<Transaction>> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final filtered = filter(
transactions: snapshot.data!
.getAllTransactions()
.values
.toList(),
filter: criteria);
transactions: snapshot.data!, filter: criteria);
final searched = search(_searchString, filtered);
@ -787,33 +788,33 @@ class _DesktopTransactionCardRowState
late final Transaction _transaction;
late final String walletId;
String whatIsIt(String type, Coin coin) {
String whatIsIt(TransactionType type, Coin coin, int height) {
if (coin == Coin.epicCash && _transaction.slateId == null) {
return "Restored Funds";
}
if (_transaction.subType == "mint") {
if (_transaction.confirmedStatus) {
if (_transaction.subType == TransactionSubType.mint) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Anonymized";
} else {
return "Anonymizing";
}
}
if (type == "Received") {
if (_transaction.confirmedStatus) {
if (type == TransactionType.incoming) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Received";
} else {
return "Receiving";
}
} else if (type == "Sent") {
if (_transaction.confirmedStatus) {
} else if (type == TransactionType.outgoing) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Sent";
} else {
return "Sending";
}
} else {
return type;
return type.name;
}
}
@ -843,15 +844,17 @@ class _DesktopTransactionCardRowState
late final String prefix;
if (Util.isDesktop) {
if (_transaction.txType == "Sent") {
if (_transaction.type == TransactionType.outgoing) {
prefix = "-";
} else if (_transaction.txType == "Received") {
} else if (_transaction.type == TransactionType.incoming) {
prefix = "+";
}
} else {
prefix = "";
}
final currentHeight = ref.watch(currentHeightProvider(coin).state).state;
return Material(
color: Theme.of(context).extension<StackColors>()!.popupBG,
elevation: 0,
@ -911,7 +914,11 @@ class _DesktopTransactionCardRowState
),
child: Row(
children: [
TxIcon(transaction: _transaction),
TxIcon(
transaction: _transaction,
currentHeight: currentHeight,
coin: coin,
),
const SizedBox(
width: 12,
),
@ -920,7 +927,11 @@ class _DesktopTransactionCardRowState
child: Text(
_transaction.isCancelled
? "Cancelled"
: whatIsIt(_transaction.txType, coin),
: whatIsIt(
_transaction.type,
coin,
currentHeight,
),
style:
STextStyles.desktopTextExtraExtraSmall(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark,

View file

@ -5,12 +5,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/dialogs/cancelling_transaction_progress_dialog.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart';
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
@ -19,7 +20,6 @@ import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/block_explorers.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@ -80,13 +80,13 @@ class _TransactionDetailsViewState
coin = widget.coin;
amount = Format.satoshisToAmount(_transaction.amount, coin: coin);
fee = Format.satoshisToAmount(_transaction.fees, coin: coin);
fee = Format.satoshisToAmount(_transaction.fee, coin: coin);
if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
_transaction.subType == "mint") {
_transaction.subType == TransactionSubType.mint) {
amountPrefix = "";
} else {
amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "-" : "+";
amountPrefix = _transaction.type == TransactionType.outgoing ? "-" : "+";
}
// if (coin == Coin.firo || coin == Coin.firoTestNet) {
@ -102,10 +102,10 @@ class _TransactionDetailsViewState
super.dispose();
}
String whatIsIt(String type) {
String whatIsIt(TransactionType type, int height) {
if (coin == Coin.firo || coin == Coin.firoTestNet) {
if (_transaction.subType == "mint") {
if (_transaction.confirmedStatus) {
if (_transaction.subType == TransactionSubType.mint) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Minted";
} else {
return "Minting";
@ -113,23 +113,23 @@ class _TransactionDetailsViewState
}
}
if (type == "Received") {
if (type == TransactionType.incoming) {
// if (_transaction.isMinting) {
// return "Minting";
// } else
if (_transaction.confirmedStatus) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Received";
} else {
return "Receiving";
}
} else if (type == "Sent") {
if (_transaction.confirmedStatus) {
} else if (type == TransactionType.outgoing) {
if (_transaction.isConfirmed(height, coin.requiredConfirmations)) {
return "Sent";
} else {
return "Sending";
}
} else {
return type;
return type.name;
}
}
@ -298,6 +298,8 @@ class _TransactionDetailsViewState
@override
Widget build(BuildContext context) {
final currentHeight = ref.watch(currentHeightProvider(coin).state).state;
return ConditionalParent(
condition: !isDesktop,
builder: (child) => Background(
@ -403,6 +405,8 @@ class _TransactionDetailsViewState
children: [
TxIcon(
transaction: _transaction,
currentHeight: currentHeight,
coin: coin,
),
const SizedBox(
width: 16,
@ -411,7 +415,9 @@ class _TransactionDetailsViewState
_transaction.isCancelled
? "Cancelled"
: whatIsIt(
_transaction.txType),
_transaction.type,
currentHeight,
),
style:
STextStyles.desktopTextMedium(
context),
@ -489,6 +495,8 @@ class _TransactionDetailsViewState
if (!isDesktop)
TxIcon(
transaction: _transaction,
currentHeight: currentHeight,
coin: coin,
),
],
),
@ -523,13 +531,17 @@ class _TransactionDetailsViewState
SelectableText(
_transaction.isCancelled
? "Cancelled"
: whatIsIt(_transaction.txType),
: whatIsIt(
_transaction.type,
currentHeight,
),
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
context)
.copyWith(
color: _transaction.txType == "Sent"
color: _transaction.type ==
TransactionType.outgoing
? Theme.of(context)
.extension<StackColors>()!
.accentColorOrange
@ -546,11 +558,12 @@ class _TransactionDetailsViewState
),
if (!((coin == Coin.monero ||
coin == Coin.wownero) &&
_transaction.txType.toLowerCase() ==
"sent") &&
_transaction.type ==
TransactionType.outgoing) &&
!((coin == Coin.firo ||
coin == Coin.firoTestNet) &&
_transaction.subType == "mint"))
_transaction.subType ==
TransactionSubType.mint))
isDesktop
? const _Divider()
: const SizedBox(
@ -558,11 +571,12 @@ class _TransactionDetailsViewState
),
if (!((coin == Coin.monero ||
coin == Coin.wownero) &&
_transaction.txType.toLowerCase() ==
"sent") &&
_transaction.type ==
TransactionType.outgoing) &&
!((coin == Coin.firo ||
coin == Coin.firoTestNet) &&
_transaction.subType == "mint"))
_transaction.subType ==
TransactionSubType.mint))
RoundedWhiteContainer(
padding: isDesktop
? const EdgeInsets.all(16)
@ -578,8 +592,8 @@ class _TransactionDetailsViewState
CrossAxisAlignment.start,
children: [
Text(
_transaction.txType.toLowerCase() ==
"sent"
_transaction.type ==
TransactionType.outgoing
? "Sent to"
: "Receiving address",
style: isDesktop
@ -592,8 +606,8 @@ class _TransactionDetailsViewState
const SizedBox(
height: 8,
),
_transaction.txType.toLowerCase() ==
"received"
_transaction.type ==
TransactionType.incoming
? FutureBuilder(
future: fetchContactNameFor(
_transaction.address),
@ -855,7 +869,10 @@ class _TransactionDetailsViewState
: const EdgeInsets.all(12),
child: Builder(builder: (context) {
final feeString = showFeePending
? _transaction.confirmedStatus
? _transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
)
? Format.localizedStringAsFixed(
value: fee,
locale: ref.watch(
@ -947,9 +964,14 @@ class _TransactionDetailsViewState
: const EdgeInsets.all(12),
child: Builder(builder: (context) {
final height = widget.coin != Coin.epicCash &&
_transaction.confirmedStatus
_transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
)
? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
: _transaction.confirmations > 0
: _transaction.getConfirmations(
currentHeight) >
0
? "${_transaction.height}"
: "Pending";
@ -1297,9 +1319,13 @@ class _TransactionDetailsViewState
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: (coin == Coin.epicCash &&
_transaction.confirmedStatus == false &&
_transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
) ==
false &&
_transaction.isCancelled == false &&
_transaction.txType == "Sent")
_transaction.type == TransactionType.outgoing)
? SizedBox(
width: MediaQuery.of(context).size.width - 32,
child: TextButton(

View file

@ -97,73 +97,73 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
final manager =
ref.read(walletsChangeNotifierProvider).getManager(walletId);
// TODO: remove the need for this!!
final bool isOwnAddress = await manager.isOwnAddress(_address!);
if (isOwnAddress) {
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return DesktopDialog(
maxWidth: 400,
maxHeight: double.infinity,
child: Padding(
padding: const EdgeInsets.only(
left: 32,
bottom: 32,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Transaction failed",
style: STextStyles.desktopH3(context),
),
const DesktopDialogCloseButton(),
],
),
const SizedBox(
height: 12,
),
Text(
"Sending to self is currently disabled",
textAlign: TextAlign.left,
style: STextStyles.desktopTextExtraExtraSmall(context)
.copyWith(
fontSize: 18,
),
),
const SizedBox(
height: 40,
),
Row(
children: [
Expanded(
child: SecondaryButton(
buttonHeight: ButtonHeight.l,
label: "Ok",
onPressed: () {
Navigator.of(context).pop();
},
),
),
const SizedBox(
width: 32,
),
],
),
],
),
),
);
},
);
return;
}
// // TODO: remove the need for this!!
// final bool isOwnAddress = await manager.isOwnAddress(_address!);
// if (isOwnAddress) {
// await showDialog<dynamic>(
// context: context,
// useSafeArea: false,
// barrierDismissible: true,
// builder: (context) {
// return DesktopDialog(
// maxWidth: 400,
// maxHeight: double.infinity,
// child: Padding(
// padding: const EdgeInsets.only(
// left: 32,
// bottom: 32,
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// "Transaction failed",
// style: STextStyles.desktopH3(context),
// ),
// const DesktopDialogCloseButton(),
// ],
// ),
// const SizedBox(
// height: 12,
// ),
// Text(
// "Sending to self is currently disabled",
// textAlign: TextAlign.left,
// style: STextStyles.desktopTextExtraExtraSmall(context)
// .copyWith(
// fontSize: 18,
// ),
// ),
// const SizedBox(
// height: 40,
// ),
// Row(
// children: [
// Expanded(
// child: SecondaryButton(
// buttonHeight: ButtonHeight.l,
// label: "Ok",
// onPressed: () {
// Navigator.of(context).pop();
// },
// ),
// ),
// const SizedBox(
// width: 32,
// ),
// ],
// ),
// ],
// ),
// ),
// );
// },
// );
// return;
// }
final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin);
int availableBalance;
@ -171,16 +171,14 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
"Private") {
availableBalance = Format.decimalAmountToSatoshis(
await (manager.wallet as FiroWallet).availablePrivateBalance(),
coin);
(manager.wallet as FiroWallet).availablePrivateBalance(), coin);
} else {
availableBalance = Format.decimalAmountToSatoshis(
await (manager.wallet as FiroWallet).availablePublicBalance(),
coin);
(manager.wallet as FiroWallet).availablePublicBalance(), coin);
}
} else {
availableBalance =
Format.decimalAmountToSatoshis(await manager.availableBalance, coin);
Format.decimalAmountToSatoshis(manager.balance.getSpendable(), coin);
}
// confirm send all
@ -568,9 +566,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
if (wallet != null) {
Decimal? balance;
if (private) {
balance = await wallet.availablePrivateBalance();
balance = wallet.availablePrivateBalance();
} else {
balance = await wallet.availablePublicBalance();
balance = wallet.availablePublicBalance();
}
return Format.localizedStringAsFixed(
@ -757,19 +755,18 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
.wallet as FiroWallet;
if (ref.read(publicPrivateBalanceStateProvider.state).state ==
"Private") {
cryptoAmountController.text =
(await firoWallet.availablePrivateBalance())
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
cryptoAmountController.text = (firoWallet.availablePrivateBalance())
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
} else {
cryptoAmountController.text =
(await firoWallet.availablePublicBalance())
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
cryptoAmountController.text = (firoWallet.availablePublicBalance())
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
}
} else {
cryptoAmountController.text = (await ref
cryptoAmountController.text = (ref
.read(walletsChangeNotifierProvider)
.getManager(walletId)
.availableBalance)
.balance
.getSpendable())
.toStringAsFixed(Constants.decimalPlacesForCoin(coin));
}
}

View file

@ -68,15 +68,17 @@ class _WDesktopWalletSummaryState extends State<DesktopWalletSummary> {
final firoWallet = ref.watch(
managerProvider.select((value) => value.wallet))
as FiroWallet;
totalBalanceFuture = firoWallet.availablePublicBalance();
availableBalanceFuture =
firoWallet.availablePrivateBalance();
totalBalanceFuture =
Future(() => firoWallet.balance.getSpendable());
availableBalanceFuture = Future(
() => firoWallet.balancePrivate.getSpendable());
} else {
totalBalanceFuture = ref.watch(managerProvider
.select((value) => value.totalBalance));
availableBalanceFuture = ref.watch(managerProvider
.select((value) => value.availableBalance));
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)));
totalBalanceFuture =
Future(() => manager.balance.getTotal());
availableBalanceFuture =
Future(() => manager.balance.getSpendable());
}
final locale = ref.watch(localeServiceChangeNotifierProvider

View file

@ -2,11 +2,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
import 'package:stackwallet/models/paymint/transactions_model.dart' as old;
import 'package:stackwallet/models/isar/models/isar_models.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
import 'package:stackwallet/providers/blockchain/dogecoin/current_height_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -17,8 +17,6 @@ import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:tuple/tuple.dart';
import '../providers/blockchain/dogecoin/current_height_provider.dart';
class TransactionCard extends ConsumerStatefulWidget {
const TransactionCard({
Key? key,
@ -26,7 +24,7 @@ class TransactionCard extends ConsumerStatefulWidget {
required this.walletId,
}) : super(key: key);
final old.Transaction transaction;
final Transaction transaction;
final String walletId;
@override
@ -34,17 +32,26 @@ class TransactionCard extends ConsumerStatefulWidget {
}
class _TransactionCardState extends ConsumerState<TransactionCard> {
late final old.Transaction _transaction;
late final Transaction _transaction;
late final String walletId;
String whatIsIt(String type, Coin coin) {
String whatIsIt(
TransactionType type,
Coin coin,
int currentHeight,
) {
if (coin == Coin.epicCash && _transaction.slateId == null) {
return "Restored Funds";
}
if (_transaction.subType == "mint") {
final confirmedStatus = _transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
);
if (_transaction.subType == TransactionSubType.mint) {
// if (type == "Received") {
if (_transaction.confirmedStatus) {
if (confirmedStatus) {
return "Anonymized";
} else {
return "Anonymizing";
@ -60,23 +67,23 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
// }
}
if (type == "Received") {
if (type == TransactionType.incoming) {
// if (_transaction.isMinting) {
// return "Minting";
// } else
if (_transaction.confirmedStatus) {
if (confirmedStatus) {
return "Received";
} else {
return "Receiving";
}
} else if (type == "Sent") {
if (_transaction.confirmedStatus) {
} else if (type == TransactionType.outgoing) {
if (confirmedStatus) {
return "Sent";
} else {
return "Sending";
}
} else {
return type;
return type.name;
}
}
@ -106,13 +113,15 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
String prefix = "";
if (Util.isDesktop) {
if (_transaction.txType == "Sent") {
if (_transaction.type == TransactionType.outgoing) {
prefix = "-";
} else if (_transaction.txType == "Received") {
} else if (_transaction.type == TransactionType.incoming) {
prefix = "+";
}
}
final currentHeight = ref.watch(currentHeightProvider(coin).state).state;
return Material(
color: Theme.of(context).extension<StackColors>()!.popupBG,
elevation: 0,
@ -169,269 +178,7 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
padding: const EdgeInsets.all(8),
child: Row(
children: [
TxIcon(transaction: _transaction),
const SizedBox(
width: 14,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
_transaction.isCancelled
? "Cancelled"
: whatIsIt(_transaction.txType, coin),
style: STextStyles.itemSubtitle12(context),
),
),
),
const SizedBox(
width: 10,
),
Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Builder(
builder: (_) {
final amount = _transaction.amount;
return Text(
"$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}",
style:
STextStyles.itemSubtitle12_600(context),
);
},
),
),
),
],
),
const SizedBox(
height: 4,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
Format.extractDateFrom(_transaction.timestamp),
style: STextStyles.label(context),
),
),
),
if (ref.watch(prefsChangeNotifierProvider
.select((value) => value.externalCalls)))
const SizedBox(
width: 10,
),
if (ref.watch(prefsChangeNotifierProvider
.select((value) => value.externalCalls)))
Flexible(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Builder(
builder: (_) {
int value = _transaction.amount;
return Text(
"$prefix${Format.localizedStringAsFixed(
value: Format.satoshisToAmount(value,
coin: coin) *
price,
locale: locale,
decimalPlaces: 2,
)} $baseCurrency",
style: STextStyles.label(context),
);
},
),
),
),
],
),
],
),
),
],
),
),
),
),
);
}
}
class TransactionCard2 extends ConsumerStatefulWidget {
const TransactionCard2({
Key? key,
required this.transaction,
required this.walletId,
}) : super(key: key);
final isar_models.Transaction transaction;
final String walletId;
@override
ConsumerState<TransactionCard2> createState() => _TransactionCardState2();
}
class _TransactionCardState2 extends ConsumerState<TransactionCard2> {
late final isar_models.Transaction _transaction;
late final String walletId;
String whatIsIt(
isar_models.TransactionType type,
Coin coin,
int currentHeight,
) {
if (coin == Coin.epicCash && _transaction.slateId == null) {
return "Restored Funds";
}
final confirmedStatus = _transaction.isConfirmed(
currentHeight,
coin.requiredConfirmations,
);
if (_transaction.subType == isar_models.TransactionSubType.mint) {
// if (type == "Received") {
if (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 == isar_models.TransactionType.incoming) {
// if (_transaction.isMinting) {
// return "Minting";
// } else
if (confirmedStatus) {
return "Received";
} else {
return "Receiving";
}
} else if (type == isar_models.TransactionType.outgoing) {
if (confirmedStatus) {
return "Sent";
} else {
return "Sending";
}
} else {
return type.name;
}
}
@override
void initState() {
walletId = widget.walletId;
_transaction = widget.transaction;
super.initState();
}
@override
Widget build(BuildContext context) {
final locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale));
final manager = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManager(walletId)));
final baseCurrency = ref
.watch(prefsChangeNotifierProvider.select((value) => value.currency));
final coin = manager.coin;
final price = ref
.watch(priceAnd24hChangeNotifierProvider
.select((value) => value.getPrice(coin)))
.item1;
String prefix = "";
if (Util.isDesktop) {
if (_transaction.type == isar_models.TransactionType.outgoing) {
prefix = "-";
} else if (_transaction.type == isar_models.TransactionType.incoming) {
prefix = "+";
}
}
final currentHeight = ref.watch(currentHeightProvider(coin).state).state;
return Material(
color: Theme.of(context).extension<StackColors>()!.popupBG,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(Constants.size.circularBorderRadius),
),
child: Padding(
padding: const EdgeInsets.all(6),
child: RawMaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
onPressed: () async {
if (coin == Coin.epicCash && _transaction.slateId == null) {
unawaited(showFloatingFlushBar(
context: context,
message:
"Restored Epic funds from your Seed have no Data.\nUse Stack Backup to keep your transaction history.",
type: FlushBarType.warning,
duration: const Duration(seconds: 5),
));
return;
}
if (Util.isDesktop) {
// await showDialog<void>(
// context: context,
// builder: (context) => DesktopDialog(
// maxHeight: MediaQuery.of(context).size.height - 64,
// maxWidth: 580,
// child: TransactionDetailsView(
// transaction: _transaction,
// coin: coin,
// walletId: walletId,
// ),
// ),
// );
} else {
unawaited(
Navigator.of(context).pushNamed(
TransactionDetailsView.routeName,
arguments: Tuple3(
_transaction,
coin,
walletId,
),
),
);
}
},
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
children: [
TxIcon2(
TxIcon(
transaction: _transaction,
coin: ref.watch(walletsChangeNotifierProvider.select(
(value) => value.getManager(widget.walletId).coin)),