utxo details navigation and skeleton view

This commit is contained in:
julian 2023-03-07 09:39:34 -06:00
parent 6465faa4e1
commit 6e547d6f34
5 changed files with 212 additions and 50 deletions

View file

@ -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) =>

View file

@ -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,
),
);
},
); );
}, },
), ),

View file

@ -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,
),
), ),
), ),
), ],
], ),
), ],
], ),
), ),
), ],
], ),
), ),
); );
} }

View 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}",
),
],
),
)
],
);
},
),
),
),
);
}
}

View file

@ -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(