diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart index adceb5a0d..1c6780406 100644 --- a/lib/pages/coin_control/utxo_details_view.dart +++ b/lib/pages/coin_control/utxo_details_view.dart @@ -20,7 +20,8 @@ import 'package:stackwallet/widgets/custom_buttons/simple_edit_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/icon_widgets/utxo_status_icon.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; class UtxoDetailsView extends ConsumerStatefulWidget { const UtxoDetailsView({ @@ -40,7 +41,6 @@ class UtxoDetailsView extends ConsumerStatefulWidget { class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> { final isDesktop = Util.isDesktop; - static const double _spacing = 12; late Stream<UTXO?> streamUTXO; UTXO? utxo; @@ -133,169 +133,147 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> { ), ), ), - child: ConditionalParent( - condition: isDesktop, - builder: (child) { - return DesktopDialog( - maxHeight: double.infinity, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 32), - child: Text( - "Output details", - style: STextStyles.desktopH3(context), - ), - ), - DesktopDialogCloseButton( - onPressedOverride: () { - Navigator.of(context) - .pop(_popWithRefresh ? "refresh" : null); - }, - ), - ], - ), - child, - ], - ), - ); - }, - child: StreamBuilder<UTXO?>( + child: StreamBuilder<UTXO?>( stream: streamUTXO, builder: (context, snapshot) { if (snapshot.hasData) { utxo = snapshot.data!; } - - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox( - height: 10, - ), - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "${Format.satoshisToAmount( - utxo!.value, - coin: coin, - ).toStringAsFixed( - coin.decimals, - )} ${coin.ticker}", - style: STextStyles.pageTitleH2(context), - ), - Text( - utxo!.isBlocked - ? "Frozen" - : confirmed - ? "Available" - : "Unconfirmed", - style: STextStyles.w500_14(context).copyWith( - color: utxo!.isBlocked - ? const Color(0xFF7FA2D4) // todo theme - : confirmed - ? Theme.of(context) - .extension<StackColors>()! - .accentColorGreen - : Theme.of(context) - .extension<StackColors>()! - .accentColorYellow, - ), - ), - ], - ), - ), - const SizedBox( - height: _spacing, - ), - RoundedWhiteContainer( + return ConditionalParent( + condition: isDesktop, + builder: (child) { + return DesktopDialog( + maxHeight: double.infinity, child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - "Label", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Output details", + style: STextStyles.desktopH3(context), ), ), - SimpleEditButton( - editValue: utxo!.name, - editLabel: "label", - onValueChanged: (newName) { - MainDB.instance.putUTXO( - utxo!.copyWith( - name: newName, - ), - ); + DesktopDialogCloseButton( + onPressedOverride: () { + Navigator.of(context) + .pop(_popWithRefresh ? "refresh" : null); }, ), ], ), - const SizedBox( - height: 4, - ), - Text( - utxo!.name, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - const SizedBox( - height: _spacing, - ), - RoundedWhiteContainer( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Address", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ), + IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + top: 10, ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: utxo!.address!, + child: Column( + children: [ + IntrinsicHeight( + child: RoundedContainer( + padding: EdgeInsets.zero, + color: Colors.transparent, + borderColor: Theme.of(context) + .extension<StackColors>()! + .textFieldDefaultBG, + child: child, ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.address!, - style: STextStyles.w500_14(context), + ), + const SizedBox( + height: 20, + ), + SecondaryButton( + buttonHeight: ButtonHeight.l, + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + ], + ), + ), ), ], ), - ), - if (label != null && label!.value.isNotEmpty) - const SizedBox( - height: _spacing, + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (!isDesktop) + const SizedBox( + height: 10, + ), + RoundedContainer( + padding: const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + if (isDesktop) + UTXOStatusIcon( + blocked: utxo!.isBlocked, + status: confirmed + ? UTXOStatusIconStatus.confirmed + : UTXOStatusIconStatus.unconfirmed, + background: Theme.of(context) + .extension<StackColors>()! + .popupBG, + selected: false, + width: 32, + height: 32, + ), + if (isDesktop) + const SizedBox( + width: 16, + ), + Text( + "${Format.satoshisToAmount( + utxo!.value, + coin: coin, + ).toStringAsFixed( + coin.decimals, + )} ${coin.ticker}", + style: STextStyles.pageTitleH2(context), + ), + ], + ), + Text( + utxo!.isBlocked + ? "Frozen" + : confirmed + ? "Available" + : "Unconfirmed", + style: STextStyles.w500_14(context).copyWith( + color: utxo!.isBlocked + ? const Color(0xFF7FA2D4) // todo theme + : confirmed + ? Theme.of(context) + .extension<StackColors>()! + .accentColorGreen + : Theme.of(context) + .extension<StackColors>()! + .accentColorYellow, + ), + ), + ], + ), ), - if (label != null && label!.value.isNotEmpty) - RoundedWhiteContainer( + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -304,7 +282,53 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Address label", + "Label", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.name, + editLabel: "label", + onValueChanged: (newName) { + MainDB.instance.putUTXO( + utxo!.copyWith( + name: newName, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.name, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Address", style: STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! @@ -316,7 +340,7 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> { data: utxo!.address!, ) : SimpleCopyButton( - data: label!.value, + data: utxo!.address!, ), ], ), @@ -324,141 +348,218 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> { height: 4, ), Text( - label!.value, + utxo!.address!, style: STextStyles.w500_14(context), ), ], ), ), - const SizedBox( - height: _spacing, - ), - RoundedWhiteContainer( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if (label != null && label!.value.isNotEmpty) const _Div(), + if (label != null && label!.value.isNotEmpty) + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - "Transaction ID", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ), - ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: utxo!.txid, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Address label", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, ), + ), + isDesktop + ? IconCopyButton( + data: utxo!.address!, + ) + : SimpleCopyButton( + data: label!.value, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + label!.value, + style: STextStyles.w500_14(context), + ), ], ), - const SizedBox( - height: 4, - ), - Text( - utxo!.txid, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - const SizedBox( - height: _spacing, - ), - RoundedWhiteContainer( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Confirmations", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ), - ), - const SizedBox( - height: 4, - ), - Text( - "${utxo!.getConfirmations(currentHeight)}", - style: STextStyles.w500_14(context), - ), - ], - ), - ), - const SizedBox( - height: _spacing, - ), - if (utxo!.isBlocked) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - RoundedWhiteContainer( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Freeze reason", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle1, - ), - ), - SimpleEditButton( - editValue: utxo!.blockedReason ?? "", - editLabel: "freeze reason", - onValueChanged: (newReason) { - MainDB.instance.putUTXO( - utxo!.copyWith( - blockedReason: newReason, - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 4, - ), Text( - utxo!.blockedReason ?? "", - style: STextStyles.w500_14(context), + "Transaction ID", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), ), + isDesktop + ? IconCopyButton( + data: utxo!.address!, + ) + : SimpleCopyButton( + data: utxo!.txid, + ), ], ), - ), - const SizedBox( - height: _spacing, - ), - ], + const SizedBox( + height: 4, + ), + Text( + utxo!.txid, + style: STextStyles.w500_14(context), + ), + ], + ), ), - if (!isDesktop) const Spacer(), - SecondaryButton( - label: utxo!.isBlocked ? "Unfreeze" : "Freeze", - onPressed: _toggleFreeze, - ), - const SizedBox( - height: 16, - ), - ], + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Confirmations", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + ), + const SizedBox( + height: 4, + ), + Text( + "${utxo!.getConfirmations(currentHeight)}", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + if (utxo!.isBlocked) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context) + .extension<StackColors>()! + .popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Freeze reason", + style: + STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.blockedReason ?? "", + editLabel: "freeze reason", + onValueChanged: (newReason) { + MainDB.instance.putUTXO( + utxo!.copyWith( + blockedReason: newReason, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.blockedReason ?? "", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (!isDesktop) const _Div(), + ], + ), + if (!isDesktop) const Spacer(), + if (!isDesktop) + SecondaryButton( + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + if (!isDesktop) + const SizedBox( + height: 16, + ), + ], + ), ); - }, - ), - ), + }), ); } } + +class _Div extends StatelessWidget { + const _Div({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + if (Util.isDesktop) { + return Container( + width: double.infinity, + height: 1.0, + color: Theme.of(context).extension<StackColors>()!.textFieldDefaultBG, + ); + } else { + return const SizedBox( + height: 12, + ); + } + } +}