mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-24 11:15:58 +00:00
utxo details navigation and skeleton view
This commit is contained in:
parent
6465faa4e1
commit
6e547d6f34
5 changed files with 212 additions and 50 deletions
|
@ -182,6 +182,13 @@ class MainDB {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<UTXO?> watchUTXO({
|
||||||
|
required Id id,
|
||||||
|
bool fireImmediately = false,
|
||||||
|
}) {
|
||||||
|
return isar.utxos.watchObject(id, fireImmediately: fireImmediately);
|
||||||
|
}
|
||||||
|
|
||||||
// transaction notes
|
// transaction notes
|
||||||
QueryBuilder<TransactionNote, TransactionNote, QAfterWhereClause>
|
QueryBuilder<TransactionNote, TransactionNote, QAfterWhereClause>
|
||||||
getTransactionNotes(String walletId) =>
|
getTransactionNotes(String walletId) =>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/db/main_db.dart';
|
import 'package:stackwallet/db/main_db.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/pages/coin_control/utxo_card.dart';
|
import 'package:stackwallet/pages/coin_control/utxo_card.dart';
|
||||||
|
import 'package:stackwallet/pages/coin_control/utxo_details_view.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
@ -11,6 +12,7 @@ import 'package:stackwallet/widgets/background.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/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
import 'package:stackwallet/widgets/toggle.dart';
|
import 'package:stackwallet/widgets/toggle.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class CoinControlView extends ConsumerStatefulWidget {
|
class CoinControlView extends ConsumerStatefulWidget {
|
||||||
const CoinControlView({
|
const CoinControlView({
|
||||||
|
@ -40,6 +42,8 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
|
||||||
.idProperty()
|
.idProperty()
|
||||||
.findAllSync();
|
.findAllSync();
|
||||||
|
|
||||||
|
print(ids);
|
||||||
|
|
||||||
return Background(
|
return Background(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
||||||
|
@ -116,6 +120,15 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
|
||||||
key: Key("${utxo.walletId}_${utxo.id}"),
|
key: Key("${utxo.walletId}_${utxo.id}"),
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
utxo: utxo,
|
utxo: utxo,
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
UtxoDetailsView.routeName,
|
||||||
|
arguments: Tuple2(
|
||||||
|
utxo.id,
|
||||||
|
widget.walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,11 +6,13 @@ import 'package:stackwallet/db/main_db.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_container.dart';
|
||||||
|
|
||||||
class UtxoCard extends ConsumerStatefulWidget {
|
class UtxoCard extends ConsumerStatefulWidget {
|
||||||
const UtxoCard({
|
const UtxoCard({
|
||||||
|
@ -18,11 +20,13 @@ class UtxoCard extends ConsumerStatefulWidget {
|
||||||
required this.utxo,
|
required this.utxo,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.selectable = false,
|
this.selectable = false,
|
||||||
|
this.onPressed,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final UTXO utxo;
|
final UTXO utxo;
|
||||||
final bool selectable;
|
final bool selectable;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<UtxoCard> createState() => _UtxoCardState();
|
ConsumerState<UtxoCard> createState() => _UtxoCardState();
|
||||||
|
@ -59,54 +63,76 @@ class _UtxoCardState extends ConsumerState<UtxoCard> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RoundedWhiteContainer(
|
return ConditionalParent(
|
||||||
child: Row(
|
condition: widget.onPressed != null,
|
||||||
children: [
|
builder: (child) => MaterialButton(
|
||||||
SvgPicture.asset(
|
padding: const EdgeInsets.all(0),
|
||||||
_selected
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
? Assets.svg.coinControl.selected
|
color: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
: utxo.isBlocked
|
elevation: 0,
|
||||||
? Assets.svg.coinControl.blocked
|
disabledElevation: 0,
|
||||||
: Assets.svg.coinControl.unBlocked,
|
hoverElevation: 0,
|
||||||
width: 32,
|
focusElevation: 0,
|
||||||
height: 32,
|
highlightElevation: 0,
|
||||||
),
|
shape: RoundedRectangleBorder(
|
||||||
const SizedBox(
|
borderRadius:
|
||||||
width: 10,
|
BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||||
),
|
),
|
||||||
Expanded(
|
onPressed: widget.onPressed,
|
||||||
child: Column(
|
child: child,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
),
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: RoundedContainer(
|
||||||
children: [
|
color: widget.onPressed == null
|
||||||
Text(
|
? Theme.of(context).extension<StackColors>()!.popupBG
|
||||||
"${Format.satoshisToAmount(
|
: Colors.transparent,
|
||||||
utxo.value,
|
child: Row(
|
||||||
coin: coin,
|
children: [
|
||||||
).toStringAsFixed(coin.decimals)} ${coin.ticker}",
|
SvgPicture.asset(
|
||||||
style: STextStyles.w600_14(context),
|
_selected
|
||||||
),
|
? Assets.svg.coinControl.selected
|
||||||
const SizedBox(
|
: utxo.isBlocked
|
||||||
height: 2,
|
? Assets.svg.coinControl.blocked
|
||||||
),
|
: Assets.svg.coinControl.unBlocked,
|
||||||
Row(
|
width: 32,
|
||||||
children: [
|
height: 32,
|
||||||
Flexible(
|
),
|
||||||
child: Text(
|
const SizedBox(
|
||||||
label ?? utxo.address ?? utxo.txid,
|
width: 10,
|
||||||
style: STextStyles.w500_12(context).copyWith(
|
),
|
||||||
color: Theme.of(context)
|
Expanded(
|
||||||
.extension<StackColors>()!
|
child: Column(
|
||||||
.textSubtitle1,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"${Format.satoshisToAmount(
|
||||||
|
utxo.value,
|
||||||
|
coin: coin,
|
||||||
|
).toStringAsFixed(coin.decimals)} ${coin.ticker}",
|
||||||
|
style: STextStyles.w600_14(context),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 2,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
label ?? utxo.address ?? utxo.txid,
|
||||||
|
style: STextStyles.w500_12(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
99
lib/pages/coin_control/utxo_details_view.dart
Normal file
99
lib/pages/coin_control/utxo_details_view.dart
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/main_db.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
|
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
|
class UtxoDetailsView extends ConsumerStatefulWidget {
|
||||||
|
const UtxoDetailsView({
|
||||||
|
Key? key,
|
||||||
|
required this.utxoId,
|
||||||
|
required this.walletId,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
static const routeName = "/utxoDetails";
|
||||||
|
|
||||||
|
final Id utxoId;
|
||||||
|
final String walletId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<UtxoDetailsView> createState() => _UtxoDetailsViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> {
|
||||||
|
late Stream<UTXO?> stream;
|
||||||
|
|
||||||
|
UTXO? utxo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
utxo = MainDB.instance.isar.utxos
|
||||||
|
.where()
|
||||||
|
.idEqualTo(widget.utxoId)
|
||||||
|
.findFirstSync()!;
|
||||||
|
|
||||||
|
stream = MainDB.instance.watchUTXO(id: widget.utxoId);
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final coin = ref.watch(walletsChangeNotifierProvider
|
||||||
|
.select((value) => value.getManager(widget.walletId).coin));
|
||||||
|
return Background(
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: AppBarBackButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16,
|
||||||
|
),
|
||||||
|
child: StreamBuilder<UTXO?>(
|
||||||
|
stream: stream,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
utxo = snapshot.data!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
RoundedWhiteContainer(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"${Format.satoshisToAmount(
|
||||||
|
utxo!.value,
|
||||||
|
coin: coin,
|
||||||
|
).toStringAsFixed(
|
||||||
|
coin.decimals,
|
||||||
|
)} ${coin.ticker}",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.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:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/buy/response_objects/quote.dart';
|
import 'package:stackwallet/models/buy/response_objects/quote.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
import 'package:stackwallet/models/contact_address_entry.dart';
|
||||||
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
||||||
|
@ -28,6 +29,7 @@ import 'package:stackwallet/pages/buy_view/buy_in_wallet_view.dart';
|
||||||
import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart';
|
import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart';
|
||||||
import 'package:stackwallet/pages/buy_view/buy_view.dart';
|
import 'package:stackwallet/pages/buy_view/buy_view.dart';
|
||||||
import 'package:stackwallet/pages/coin_control/coin_control_view.dart';
|
import 'package:stackwallet/pages/coin_control/coin_control_view.dart';
|
||||||
|
import 'package:stackwallet/pages/coin_control/utxo_details_view.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
|
import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/edit_trade_note_view.dart';
|
import 'package:stackwallet/pages/exchange_view/edit_trade_note_view.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_1_view.dart';
|
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_1_view.dart';
|
||||||
|
@ -199,11 +201,11 @@ class RouteGenerator {
|
||||||
builder: (_) => const AddWalletView(),
|
builder: (_) => const AddWalletView(),
|
||||||
settings: RouteSettings(name: settings.name));
|
settings: RouteSettings(name: settings.name));
|
||||||
|
|
||||||
case PaynymClaimView.routeName:
|
case CoinControlView.routeName:
|
||||||
if (args is String) {
|
if (args is String) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => PaynymClaimView(
|
builder: (_) => CoinControlView(
|
||||||
walletId: args,
|
walletId: args,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
|
@ -213,11 +215,26 @@ class RouteGenerator {
|
||||||
}
|
}
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case CoinControlView.routeName:
|
case UtxoDetailsView.routeName:
|
||||||
|
if (args is Tuple2<Id, String>) {
|
||||||
|
return getRoute(
|
||||||
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
|
builder: (_) => UtxoDetailsView(
|
||||||
|
walletId: args.item2,
|
||||||
|
utxoId: args.item1,
|
||||||
|
),
|
||||||
|
settings: RouteSettings(
|
||||||
|
name: settings.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
|
case PaynymClaimView.routeName:
|
||||||
if (args is String) {
|
if (args is String) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => CoinControlView(
|
builder: (_) => PaynymClaimView(
|
||||||
walletId: args,
|
walletId: args,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
|
|
Loading…
Reference in a new issue