mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-04 04:06:38 +00:00
WIP group fusions on wallet home screen activity
This commit is contained in:
parent
79d117d7f1
commit
c6a370e4f5
5 changed files with 392 additions and 130 deletions
|
@ -0,0 +1,176 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||||
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
|
||||||
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
|
||||||
|
class FusionTxGroup {
|
||||||
|
final List<TransactionV2> transactions;
|
||||||
|
FusionTxGroup(this.transactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FusionTxGroupCard extends ConsumerWidget {
|
||||||
|
const FusionTxGroupCard({super.key, required this.group});
|
||||||
|
|
||||||
|
final FusionTxGroup group;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final walletId = group.transactions.first.walletId;
|
||||||
|
|
||||||
|
final coin = ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId).coin));
|
||||||
|
|
||||||
|
final currentHeight = ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(walletId).currentHeight));
|
||||||
|
|
||||||
|
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 (Util.isDesktop) {
|
||||||
|
// await showDialog<void>(
|
||||||
|
// context: context,
|
||||||
|
// builder: (context) => DesktopDialog(
|
||||||
|
// maxHeight: MediaQuery.of(context).size.height - 64,
|
||||||
|
// maxWidth: 580,
|
||||||
|
// child: TransactionV2DetailsView(
|
||||||
|
// transaction: _transaction,
|
||||||
|
// coin: coin,
|
||||||
|
// walletId: walletId,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
} else {
|
||||||
|
// unawaited(
|
||||||
|
// Navigator.of(context).pushNamed(
|
||||||
|
// TransactionV2DetailsView.routeName,
|
||||||
|
// arguments: (
|
||||||
|
// tx: _transaction,
|
||||||
|
// coin: coin,
|
||||||
|
// walletId: walletId,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
TxIcon(
|
||||||
|
transaction: group.transactions.first,
|
||||||
|
coin: coin,
|
||||||
|
currentHeight: currentHeight,
|
||||||
|
),
|
||||||
|
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(
|
||||||
|
"Fusions",
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Builder(
|
||||||
|
builder: (_) {
|
||||||
|
return Text(
|
||||||
|
"${group.transactions.length} fusion transactions",
|
||||||
|
style: STextStyles.itemSubtitle12(context),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
Format.extractDateFrom(
|
||||||
|
group.transactions.last.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: (_) {
|
||||||
|
// return Text(
|
||||||
|
// "$prefix${Amount.fromDecimal(
|
||||||
|
// amount.decimal * price,
|
||||||
|
// fractionDigits: 2,
|
||||||
|
// ).fiatString(
|
||||||
|
// locale: locale,
|
||||||
|
// )} $baseCurrency",
|
||||||
|
// style: STextStyles.label(context),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,8 +13,10 @@ import 'dart:async';
|
||||||
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:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart';
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart';
|
||||||
|
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart';
|
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
|
||||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||||
|
@ -102,6 +104,59 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
|
||||||
return const NoTransActionsFound();
|
return const NoTransActionsFound();
|
||||||
} else {
|
} else {
|
||||||
_transactions.sort((a, b) => b.timestamp - a.timestamp);
|
_transactions.sort((a, b) => b.timestamp - a.timestamp);
|
||||||
|
|
||||||
|
final List<Object> _txns = [];
|
||||||
|
|
||||||
|
List<TransactionV2> fusions = [];
|
||||||
|
|
||||||
|
for (int i = 0; i < _transactions.length; i++) {
|
||||||
|
final tx = _transactions[i];
|
||||||
|
|
||||||
|
if (tx.subType == TransactionSubType.cashFusion) {
|
||||||
|
if (fusions.isNotEmpty) {
|
||||||
|
final prevTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
fusions.last.timestamp * 1000);
|
||||||
|
final thisTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000);
|
||||||
|
|
||||||
|
print(
|
||||||
|
"DIFFERERNCE: ${prevTime.difference(thisTime).inMinutes}");
|
||||||
|
|
||||||
|
if (prevTime.difference(thisTime).inMinutes > 30) {
|
||||||
|
_txns.add(FusionTxGroup(fusions));
|
||||||
|
fusions = [tx];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fusions.add(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1 < _transactions.length) {
|
||||||
|
final nextTx = _transactions[i + 1];
|
||||||
|
if (nextTx.subType != TransactionSubType.cashFusion &&
|
||||||
|
fusions.isNotEmpty) {
|
||||||
|
_txns.add(FusionTxGroup(fusions));
|
||||||
|
fusions = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.subType != TransactionSubType.cashFusion) {
|
||||||
|
_txns.add(tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
int count = 0;
|
||||||
|
for (final e in _txns) {
|
||||||
|
if (e is TransactionV2) {
|
||||||
|
count++;
|
||||||
|
} else if (e is FusionTxGroup) {
|
||||||
|
count += e.transactions.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(count == _transactions.length);
|
||||||
|
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
final managerProvider = ref
|
final managerProvider = ref
|
||||||
|
@ -116,16 +171,16 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
BorderRadius? radius;
|
BorderRadius? radius;
|
||||||
if (_transactions.length == 1) {
|
if (_txns.length == 1) {
|
||||||
radius = BorderRadius.circular(
|
radius = BorderRadius.circular(
|
||||||
Constants.size.circularBorderRadius,
|
Constants.size.circularBorderRadius,
|
||||||
);
|
);
|
||||||
} else if (index == _transactions.length - 1) {
|
} else if (index == _txns.length - 1) {
|
||||||
radius = _borderRadiusLast;
|
radius = _borderRadiusLast;
|
||||||
} else if (index == 0) {
|
} else if (index == 0) {
|
||||||
radius = _borderRadiusFirst;
|
radius = _borderRadiusFirst;
|
||||||
}
|
}
|
||||||
final tx = _transactions[index];
|
final tx = _txns[index];
|
||||||
return TxListItem(
|
return TxListItem(
|
||||||
tx: tx,
|
tx: tx,
|
||||||
coin: manager.coin,
|
coin: manager.coin,
|
||||||
|
@ -141,24 +196,24 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
|
||||||
.background,
|
.background,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemCount: _transactions.length,
|
itemCount: _txns.length,
|
||||||
)
|
)
|
||||||
: ListView.builder(
|
: ListView.builder(
|
||||||
itemCount: _transactions.length,
|
itemCount: _txns.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
BorderRadius? radius;
|
BorderRadius? radius;
|
||||||
bool shouldWrap = false;
|
bool shouldWrap = false;
|
||||||
if (_transactions.length == 1) {
|
if (_txns.length == 1) {
|
||||||
radius = BorderRadius.circular(
|
radius = BorderRadius.circular(
|
||||||
Constants.size.circularBorderRadius,
|
Constants.size.circularBorderRadius,
|
||||||
);
|
);
|
||||||
} else if (index == _transactions.length - 1) {
|
} else if (index == _txns.length - 1) {
|
||||||
radius = _borderRadiusLast;
|
radius = _borderRadiusLast;
|
||||||
shouldWrap = true;
|
shouldWrap = true;
|
||||||
} else if (index == 0) {
|
} else if (index == 0) {
|
||||||
radius = _borderRadiusFirst;
|
radius = _borderRadiusFirst;
|
||||||
}
|
}
|
||||||
final tx = _transactions[index];
|
final tx = _txns[index];
|
||||||
if (shouldWrap) {
|
if (shouldWrap) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
|
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
|
||||||
|
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart';
|
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart';
|
||||||
import 'package:stackwallet/providers/global/trades_service_provider.dart';
|
import 'package:stackwallet/providers/global/trades_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
|
@ -24,137 +25,156 @@ class TxListItem extends ConsumerWidget {
|
||||||
required this.tx,
|
required this.tx,
|
||||||
this.radius,
|
this.radius,
|
||||||
required this.coin,
|
required this.coin,
|
||||||
});
|
}) : assert(tx is TransactionV2 || tx is FusionTxGroup);
|
||||||
|
|
||||||
final TransactionV2 tx;
|
final Object tx;
|
||||||
final BorderRadius? radius;
|
final BorderRadius? radius;
|
||||||
final Coin coin;
|
final Coin coin;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final matchingTrades = ref
|
if (tx is TransactionV2) {
|
||||||
.read(tradesServiceProvider)
|
final _tx = tx as TransactionV2;
|
||||||
.trades
|
|
||||||
.where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid);
|
|
||||||
|
|
||||||
if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) {
|
final matchingTrades = ref
|
||||||
final trade = matchingTrades.first;
|
.read(tradesServiceProvider)
|
||||||
return Container(
|
.trades
|
||||||
decoration: BoxDecoration(
|
.where((e) => e.payInTxid == _tx.txid || e.payOutTxid == _tx.txid);
|
||||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
|
||||||
borderRadius: radius,
|
if (_tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) {
|
||||||
),
|
final trade = matchingTrades.first;
|
||||||
child: Column(
|
return Container(
|
||||||
mainAxisSize: MainAxisSize.min,
|
decoration: BoxDecoration(
|
||||||
children: [
|
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
TransactionCardV2(
|
borderRadius: radius,
|
||||||
key: UniqueKey(),
|
),
|
||||||
transaction: tx,
|
child: Column(
|
||||||
),
|
mainAxisSize: MainAxisSize.min,
|
||||||
TradeCard(
|
children: [
|
||||||
key: Key(tx.txid +
|
TransactionCardV2(
|
||||||
tx.type.name +
|
key: UniqueKey(),
|
||||||
tx.hashCode.toString() +
|
transaction: _tx,
|
||||||
trade.uuid), //
|
),
|
||||||
trade: trade,
|
TradeCard(
|
||||||
onTap: () async {
|
key: Key(_tx.txid +
|
||||||
if (Util.isDesktop) {
|
_tx.type.name +
|
||||||
await showDialog<void>(
|
_tx.hashCode.toString() +
|
||||||
context: context,
|
trade.uuid), //
|
||||||
builder: (context) => Navigator(
|
trade: trade,
|
||||||
initialRoute: TradeDetailsView.routeName,
|
onTap: () async {
|
||||||
onGenerateRoute: RouteGenerator.generateRoute,
|
if (Util.isDesktop) {
|
||||||
onGenerateInitialRoutes: (_, __) {
|
await showDialog<void>(
|
||||||
return [
|
context: context,
|
||||||
FadePageRoute(
|
builder: (context) => Navigator(
|
||||||
DesktopDialog(
|
initialRoute: TradeDetailsView.routeName,
|
||||||
maxHeight: null,
|
onGenerateRoute: RouteGenerator.generateRoute,
|
||||||
maxWidth: 580,
|
onGenerateInitialRoutes: (_, __) {
|
||||||
child: Column(
|
return [
|
||||||
mainAxisSize: MainAxisSize.min,
|
FadePageRoute(
|
||||||
children: [
|
DesktopDialog(
|
||||||
Padding(
|
maxHeight: null,
|
||||||
padding: const EdgeInsets.only(
|
maxWidth: 580,
|
||||||
left: 32,
|
child: Column(
|
||||||
bottom: 16,
|
mainAxisSize: MainAxisSize.min,
|
||||||
),
|
children: [
|
||||||
child: Row(
|
Padding(
|
||||||
mainAxisAlignment:
|
padding: const EdgeInsets.only(
|
||||||
MainAxisAlignment.spaceBetween,
|
left: 32,
|
||||||
children: [
|
bottom: 16,
|
||||||
Text(
|
),
|
||||||
"Trade details",
|
child: Row(
|
||||||
style: STextStyles.desktopH3(context),
|
mainAxisAlignment:
|
||||||
),
|
MainAxisAlignment.spaceBetween,
|
||||||
DesktopDialogCloseButton(
|
children: [
|
||||||
onPressedOverride: Navigator.of(
|
Text(
|
||||||
context,
|
"Trade details",
|
||||||
rootNavigator: true,
|
style:
|
||||||
).pop,
|
STextStyles.desktopH3(context),
|
||||||
),
|
),
|
||||||
],
|
DesktopDialogCloseButton(
|
||||||
),
|
onPressedOverride: Navigator.of(
|
||||||
),
|
context,
|
||||||
Flexible(
|
rootNavigator: true,
|
||||||
child: TradeDetailsView(
|
).pop,
|
||||||
tradeId: trade.tradeId,
|
),
|
||||||
// TODO
|
],
|
||||||
// transactionIfSentFromStack: tx,
|
|
||||||
transactionIfSentFromStack: null,
|
|
||||||
walletName: ref.watch(
|
|
||||||
walletsChangeNotifierProvider.select(
|
|
||||||
(value) => value
|
|
||||||
.getManager(tx.walletId)
|
|
||||||
.walletName,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
walletId: tx.walletId,
|
|
||||||
),
|
),
|
||||||
),
|
Flexible(
|
||||||
],
|
child: TradeDetailsView(
|
||||||
|
tradeId: trade.tradeId,
|
||||||
|
// TODO
|
||||||
|
// transactionIfSentFromStack: tx,
|
||||||
|
transactionIfSentFromStack: null,
|
||||||
|
walletName: ref.watch(
|
||||||
|
walletsChangeNotifierProvider.select(
|
||||||
|
(value) => value
|
||||||
|
.getManager(_tx.walletId)
|
||||||
|
.walletName,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
walletId: _tx.walletId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const RouteSettings(
|
||||||
|
name: TradeDetailsView.routeName,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const RouteSettings(
|
];
|
||||||
name: TradeDetailsView.routeName,
|
},
|
||||||
),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
unawaited(
|
|
||||||
Navigator.of(context).pushNamed(
|
|
||||||
TradeDetailsView.routeName,
|
|
||||||
arguments: Tuple4(
|
|
||||||
trade.tradeId,
|
|
||||||
tx,
|
|
||||||
tx.walletId,
|
|
||||||
ref
|
|
||||||
.read(walletsChangeNotifierProvider)
|
|
||||||
.getManager(tx.walletId)
|
|
||||||
.walletName,
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
} else {
|
||||||
}
|
unawaited(
|
||||||
},
|
Navigator.of(context).pushNamed(
|
||||||
)
|
TradeDetailsView.routeName,
|
||||||
],
|
arguments: Tuple4(
|
||||||
),
|
trade.tradeId,
|
||||||
);
|
_tx,
|
||||||
} else {
|
_tx.walletId,
|
||||||
return Container(
|
ref
|
||||||
decoration: BoxDecoration(
|
.read(walletsChangeNotifierProvider)
|
||||||
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
.getManager(_tx.walletId)
|
||||||
borderRadius: radius,
|
.walletName,
|
||||||
),
|
),
|
||||||
child: TransactionCardV2(
|
),
|
||||||
// this may mess with combined firo transactions
|
);
|
||||||
key: UniqueKey(),
|
}
|
||||||
transaction: tx,
|
},
|
||||||
),
|
)
|
||||||
);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
|
borderRadius: radius,
|
||||||
|
),
|
||||||
|
child: TransactionCardV2(
|
||||||
|
// this may mess with combined firo transactions
|
||||||
|
key: UniqueKey(),
|
||||||
|
transaction: _tx,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final group = tx as FusionTxGroup;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
|
borderRadius: radius,
|
||||||
|
),
|
||||||
|
child: FusionTxGroupCard(
|
||||||
|
// this may mess with combined firo transactions
|
||||||
|
key: UniqueKey(),
|
||||||
|
group: group,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,7 +446,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
.getManager(widget.walletId)
|
.getManager(widget.walletId)
|
||||||
.hasTokenSupport))
|
.hasTokenSupport))
|
||||||
? "Tokens"
|
? "Tokens"
|
||||||
: "Recent transactions",
|
: "Recent activity",
|
||||||
style: STextStyles.desktopTextExtraSmall(context)
|
style: STextStyles.desktopTextExtraSmall(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
|
|
|
@ -50,16 +50,27 @@ abstract class Format {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// format date string from unix timestamp
|
// format date string from unix timestamp
|
||||||
static String extractDateFrom(int timestamp, {bool localized = true}) {
|
static String extractDateFrom(
|
||||||
|
int timestamp, {
|
||||||
|
bool localized = true,
|
||||||
|
bool noTime = false,
|
||||||
|
}) {
|
||||||
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
||||||
|
|
||||||
if (!localized) {
|
if (!localized) {
|
||||||
date = date.toUtc();
|
date = date.toUtc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final dayAndYear =
|
||||||
|
"${date.day} ${Constants.monthMapShort[date.month]} ${date.year}";
|
||||||
|
|
||||||
|
if (noTime) {
|
||||||
|
return dayAndYear;
|
||||||
|
}
|
||||||
|
|
||||||
final minutes =
|
final minutes =
|
||||||
date.minute < 10 ? "0${date.minute}" : date.minute.toString();
|
date.minute < 10 ? "0${date.minute}" : date.minute.toString();
|
||||||
return "${date.day} ${Constants.monthMapShort[date.month]} ${date.year}, ${date.hour}:$minutes";
|
return "$dayAndYear, ${date.hour}:$minutes";
|
||||||
}
|
}
|
||||||
|
|
||||||
// static String localizedStringAsFixed({
|
// static String localizedStringAsFixed({
|
||||||
|
|
Loading…
Reference in a new issue