From 5fd47de9a2473b0d682c3bcfd2bf4cc29c63ddd0 Mon Sep 17 00:00:00 2001 From: julian Date: Sat, 29 Oct 2022 13:35:03 -0600 Subject: [PATCH] desktop tx details + edit note ui --- .../all_transactions_view.dart | 34 +- .../transaction_views/edit_note_view.dart | 272 ++- .../transaction_details_view.dart | 1474 +++++++++++------ lib/widgets/icon_widgets/copy_icon.dart | 27 + lib/widgets/icon_widgets/pencil_icon.dart | 27 + lib/widgets/transaction_card.dart | 34 +- pubspec.lock | 43 +- 7 files changed, 1302 insertions(+), 609 deletions(-) create mode 100644 lib/widgets/icon_widgets/copy_icon.dart create mode 100644 lib/widgets/icon_widgets/pencil_icon.dart diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 120425c2a..8604ae721 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -23,6 +23,7 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; @@ -865,16 +866,31 @@ class _DesktopTransactionCardRowState ); return; } - unawaited( - Navigator.of(context).pushNamed( - TransactionDetailsView.routeName, - arguments: Tuple3( - _transaction, - coin, - walletId, + if (Util.isDesktop) { + await showDialog( + 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.symmetric( diff --git a/lib/pages/wallet_view/transaction_views/edit_note_view.dart b/lib/pages/wallet_view/transaction_views/edit_note_view.dart index b811dc62d..4baaaffc9 100644 --- a/lib/pages/wallet_view/transaction_views/edit_note_view.dart +++ b/lib/pages/wallet_view/transaction_views/edit_note_view.dart @@ -4,13 +4,14 @@ import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/stack_text_field.dart'; import 'package:stackwallet/widgets/textfield_icon_button.dart'; -import 'package:stackwallet/utilities/util.dart'; - class EditNoteView extends ConsumerStatefulWidget { const EditNoteView({ Key? key, @@ -33,8 +34,11 @@ class _EditNoteViewState extends ConsumerState { late final TextEditingController _noteController; final noteFieldFocusNode = FocusNode(); + late final bool isDesktop; + @override void initState() { + isDesktop = Util.isDesktop; _noteController = TextEditingController(); _noteController.text = widget.note; super.initState(); @@ -50,29 +54,178 @@ class _EditNoteViewState extends ConsumerState { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Theme.of(context).extension()!.background, - appBar: AppBar( - backgroundColor: - Theme.of(context).extension()!.background, - leading: AppBarBackButton( - onPressed: () async { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed(const Duration(milliseconds: 75)); - } - if (mounted) { - Navigator.of(context).pop(); - } - }, - ), - title: Text( - "Edit note", - style: STextStyles.navBarTitle(context), - ), + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension()!.background, + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 75)); + } + if (mounted) { + Navigator.of(context).pop(); + } + }, + ), + title: Text( + "Edit note", + style: STextStyles.navBarTitle(context), + ), + ), + body: MobileEditNoteScaffold( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 12, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Edit note", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), + ), + Padding( + padding: isDesktop + ? const EdgeInsets.symmetric( + horizontal: 32, + ) + : const EdgeInsets.all(0), + child: ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: Util.isDesktop ? false : true, + enableSuggestions: Util.isDesktop ? false : true, + controller: _noteController, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + focusNode: noteFieldFocusNode, + decoration: standardInputDecoration( + "Note", + noteFieldFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + contentPadding: isDesktop + ? const EdgeInsets.only( + left: 16, + top: 11, + bottom: 12, + right: 5, + ) + : null, + suffixIcon: _noteController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _noteController.text = ""; + }); + }, + ), + ], + ), + ), + ) + : null, + ), + ), + ), + ), + // if (!isDesktop) + const Spacer(), + if (isDesktop) + Padding( + padding: const EdgeInsets.all(32), + child: PrimaryButton( + label: "Save", + onPressed: () async { + await ref + .read( + notesServiceChangeNotifierProvider(widget.walletId)) + .editOrAddNote( + txid: widget.txid, + note: _noteController.text, + ); + if (mounted) { + Navigator.of(context).pop(); + } + }, + ), + ), + if (!isDesktop) + TextButton( + onPressed: () async { + await ref + .read(notesServiceChangeNotifierProvider(widget.walletId)) + .editOrAddNote( + txid: widget.txid, + note: _noteController.text, + ); + if (mounted) { + Navigator.of(context).pop(); + } + }, + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonColor(context), + child: Text( + "Save", + style: STextStyles.button(context), + ), + ) + ], ), - body: Padding( - padding: const EdgeInsets.all(12), - child: LayoutBuilder(builder: (context, constraints) { + ), + ); + } +} + +class MobileEditNoteScaffold extends StatelessWidget { + const MobileEditNoteScaffold({ + Key? key, + required this.child, + }) : super(key: key); + + final Widget child; + + @override + Widget build(BuildContext context) { + if (Util.isDesktop) { + return child; + } else { + return Padding( + padding: const EdgeInsets.all(12), + child: LayoutBuilder( + builder: (context, constraints) { return SingleChildScrollView( child: ConstrainedBox( constraints: BoxConstraints( @@ -81,75 +234,14 @@ class _EditNoteViewState extends ConsumerState { child: IntrinsicHeight( child: Padding( padding: const EdgeInsets.all(4), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - autocorrect: Util.isDesktop ? false : true, - enableSuggestions: Util.isDesktop ? false : true, - controller: _noteController, - style: STextStyles.field(context), - focusNode: noteFieldFocusNode, - decoration: standardInputDecoration( - "Note", - noteFieldFocusNode, - context, - ).copyWith( - suffixIcon: _noteController.text.isNotEmpty - ? Padding( - padding: const EdgeInsets.only(right: 0), - child: UnconstrainedBox( - child: Row( - children: [ - TextFieldIconButton( - child: const XIcon(), - onTap: () async { - setState(() { - _noteController.text = ""; - }); - }, - ), - ], - ), - ), - ) - : null, - ), - ), - ), - const Spacer(), - TextButton( - onPressed: () async { - await ref - .read(notesServiceChangeNotifierProvider( - widget.walletId)) - .editOrAddNote( - txid: widget.txid, - note: _noteController.text, - ); - if (mounted) { - Navigator.of(context).pop(); - } - }, - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonColor(context), - child: Text( - "Save", - style: STextStyles.button(context), - ), - ) - ], - ), + child: child, ), ), ), ); - }), - )); + }, + ), + ); + } } } diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index 8d7aac85f..d7f06095d 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:decimal/decimal.dart'; 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'; @@ -23,8 +24,13 @@ import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart'; +import 'package:stackwallet/widgets/icon_widgets/pencil_icon.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:tuple/tuple.dart'; @@ -51,6 +57,7 @@ class TransactionDetailsView extends ConsumerStatefulWidget { class _TransactionDetailsViewState extends ConsumerState { + late final bool isDesktop; late Transaction _transaction; late final String walletId; @@ -63,6 +70,7 @@ class _TransactionDetailsViewState @override void initState() { + isDesktop = Util.isDesktop; _transaction = widget.transaction; walletId = widget.walletId; @@ -74,7 +82,7 @@ class _TransactionDetailsViewState _transaction.subType == "mint") { amountPrefix = ""; } else { - amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "- " : "+ "; + amountPrefix = _transaction.txType.toLowerCase() == "sent" ? "-" : "+"; } // if (coin == Coin.firo || coin == Coin.firoTestNet) { @@ -205,267 +213,524 @@ class _TransactionDetailsViewState @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Theme.of(context).extension()!.background, - appBar: AppBar( - backgroundColor: Theme.of(context).extension()!.background, - leading: AppBarBackButton( - onPressed: () async { - // if (FocusScope.of(context).hasFocus) { - // FocusScope.of(context).unfocus(); - // await Future.delayed(Duration(milliseconds: 50)); - // } - Navigator.of(context).pop(); - }, - ), - title: Text( - "Transaction details", - style: STextStyles.navBarTitle(context), - ), - ), + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension()!.background, + leading: AppBarBackButton( + onPressed: () async { + // if (FocusScope.of(context).hasFocus) { + // FocusScope.of(context).unfocus(); + // await Future.delayed(Duration(milliseconds: 50)); + // } + Navigator.of(context).pop(); + }, + ), + title: Text( + "Transaction details", + style: STextStyles.navBarTitle(context), + ), + ), body: Padding( - padding: const EdgeInsets.all(12), - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(4), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SelectableText( - "$amountPrefix${Format.localizedStringAsFixed( - value: coin == Coin.monero - ? (amount / 10000.toDecimal()).toDecimal() - : coin == Coin.wownero - ? (amount / 1000.toDecimal()).toDecimal() - : amount, - locale: ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - decimalPlaces: Constants.decimalPlaces, - )} ${coin.ticker}", - style: STextStyles.titleBold12(context), - ), - const SizedBox( - height: 2, - ), - if (ref.watch(prefsChangeNotifierProvider - .select((value) => value.externalCalls))) - SelectableText( - "${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), decimalPlaces: 2)} ${ref.watch( - prefsChangeNotifierProvider.select( - (value) => value.currency, - ), - )}", - style: STextStyles.itemSubtitle(context), - ), - ], - ), - TxIcon( - transaction: _transaction, - ), - ], + padding: isDesktop + ? const EdgeInsets.only(left: 32) + : const EdgeInsets.all(12), + child: Column( + children: [ + if (isDesktop) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Transaction details", + style: STextStyles.desktopH3(context), ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Status", - style: STextStyles.itemSubtitle(context), - ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - _transaction.isCancelled - ? "Cancelled" - : whatIsIt(_transaction.txType), - style: STextStyles.itemSubtitle12(context), - ), - // ), - // ), - ], - ), - ), - if (!((coin == Coin.monero || coin == Coin.wownero) && - _transaction.txType.toLowerCase() == "sent") && - !((coin == Coin.firo || coin == Coin.firoTestNet) && - _transaction.subType == "mint")) - const SizedBox( - height: 12, - ), - if (!((coin == Coin.monero || coin == Coin.wownero) && - _transaction.txType.toLowerCase() == "sent") && - !((coin == Coin.firo || coin == Coin.firoTestNet) && - _transaction.subType == "mint")) - RoundedWhiteContainer( + const DesktopDialogCloseButton(), + ], + ), + Padding( + padding: isDesktop + ? const EdgeInsets.only( + right: 32, + bottom: 32, + ) + : const EdgeInsets.all(0), + child: RoundedWhiteContainer( + borderColor: isDesktop + ? Theme.of(context).extension()!.background + : null, + padding: const EdgeInsets.all(0), + child: SingleChildScrollView( + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(4), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text( - _transaction.txType.toLowerCase() == "sent" - ? "Sent to" - : "Received on", - style: STextStyles.itemSubtitle(context), - ), - const SizedBox( - height: 8, - ), - _transaction.txType.toLowerCase() == "received" - ? FutureBuilder( - future: - fetchContactNameFor(_transaction.address), - builder: (builderContext, - AsyncSnapshot snapshot) { - String addressOrContactName = - _transaction.address; - if (snapshot.connectionState == - ConnectionState.done && - snapshot.hasData) { - addressOrContactName = snapshot.data!; - } - return SelectableText( - addressOrContactName, - style: STextStyles.itemSubtitle12(context), - ); - }, - ) - : SelectableText( - _transaction.address, - style: STextStyles.itemSubtitle12(context), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(12), + child: Container( + decoration: isDesktop + ? BoxDecoration( + color: Theme.of(context) + .extension()! + .background, + borderRadius: BorderRadius.vertical( + top: Radius.circular( + Constants.size.circularBorderRadius, + ), + ), + ) + : null, + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(12) + : const EdgeInsets.all(0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + if (isDesktop) + Row( + children: [ + TxIcon( + transaction: _transaction, + ), + const SizedBox( + width: 16, + ), + SelectableText( + _transaction.isCancelled + ? "Cancelled" + : whatIsIt(_transaction.txType), + style: STextStyles.desktopTextMedium( + context), + ), + ], + ), + Column( + crossAxisAlignment: isDesktop + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + SelectableText( + "$amountPrefix${Format.localizedStringAsFixed( + value: coin == Coin.monero + ? (amount / 10000.toDecimal()) + .toDecimal() + : coin == Coin.wownero + ? (amount / 1000.toDecimal()) + .toDecimal() + : amount, + locale: ref.watch( + localeServiceChangeNotifierProvider + .select( + (value) => value.locale), + ), + decimalPlaces: + Constants.decimalPlaces, + )} ${coin.ticker}", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.titleBold12(context), + ), + const SizedBox( + height: 2, + ), + if (ref.watch( + prefsChangeNotifierProvider.select( + (value) => value.externalCalls))) + SelectableText( + "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch( + localeServiceChangeNotifierProvider + .select((value) => + value.locale), + ), decimalPlaces: 2)} ${ref.watch( + prefsChangeNotifierProvider.select( + (value) => value.currency, + ), + )}", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + ], + ), + if (!isDesktop) + TxIcon( + transaction: _transaction, + ), + ], ), - ], - ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Note", - style: STextStyles.itemSubtitle(context), + ), ), - GestureDetector( - onTap: () { - Navigator.of(context).pushNamed( - EditNoteView.routeName, - arguments: Tuple3( - _transaction.txid, - walletId, - _note, + ), + + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Status", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: + SelectableText( + _transaction.isCancelled + ? "Cancelled" + : whatIsIt(_transaction.txType), + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: _transaction.txType == "Sent" + ? Theme.of(context) + .extension()! + .accentColorOrange + : Theme.of(context) + .extension()! + .accentColorGreen, + ) + : STextStyles.itemSubtitle12(context), + ), + // ), + // ), + ], + ), + ), + if (!((coin == Coin.monero || coin == Coin.wownero) && + _transaction.txType.toLowerCase() == "sent") && + !((coin == Coin.firo || coin == Coin.firoTestNet) && + _transaction.subType == "mint")) + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, ), - ); - }, + if (!((coin == Coin.monero || coin == Coin.wownero) && + _transaction.txType.toLowerCase() == "sent") && + !((coin == Coin.firo || coin == Coin.firoTestNet) && + _transaction.subType == "mint")) + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - SvgPicture.asset( - Assets.svg.pencil, - width: 10, - height: 10, - color: Theme.of(context) - .extension()! - .infoItemIcons, - ), - const SizedBox( - width: 4, - ), - Text( - "Edit", - style: STextStyles.link2(context), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _transaction.txType.toLowerCase() == + "sent" + ? "Sent to" + : "Receiving address", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 8, + ), + _transaction.txType.toLowerCase() == + "received" + ? FutureBuilder( + future: fetchContactNameFor( + _transaction.address), + builder: (builderContext, + AsyncSnapshot + snapshot) { + String addressOrContactName = + _transaction.address; + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + addressOrContactName = + snapshot.data!; + } + return SelectableText( + addressOrContactName, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles + .itemSubtitle12( + context), + ); + }, + ) + : SelectableText( + _transaction.address, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], ), + if (isDesktop) + IconCopyButton( + data: _transaction.address, + ), ], ), ), - ], - ), - const SizedBox( - height: 8, - ), - FutureBuilder( - future: ref.watch( - notesServiceChangeNotifierProvider(walletId).select( - (value) => - value.getNoteFor(txid: _transaction.txid))), - builder: - (builderContext, AsyncSnapshot snapshot) { - if (snapshot.connectionState == - ConnectionState.done && - snapshot.hasData) { - _note = snapshot.data ?? ""; - } - return SelectableText( - _note, - style: STextStyles.itemSubtitle12(context), - ); - }, - ), - ], - ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Date", - style: STextStyles.itemSubtitle(context), - ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - Format.extractDateFrom(_transaction.timestamp), - style: STextStyles.itemSubtitle12(context), - ), - // ), - // ), - ], - ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Transaction fee", - style: STextStyles.itemSubtitle(context), - ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - showFeePending - ? _transaction.confirmedStatus - ? Format.localizedStringAsFixed( + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Note", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall(context) + : STextStyles.itemSubtitle(context), + ), + isDesktop + ? IconPencilButton( + onPressed: () { + showDialog( + context: context, + builder: (context) { + return DesktopDialog( + maxWidth: 580, + maxHeight: 360, + child: EditNoteView( + txid: _transaction.txid, + walletId: walletId, + note: _note, + ), + ); + }, + ); + }, + ) + : GestureDetector( + onTap: () { + Navigator.of(context).pushNamed( + EditNoteView.routeName, + arguments: Tuple3( + _transaction.txid, + walletId, + _note, + ), + ); + }, + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.pencil, + width: 10, + height: 10, + color: Theme.of(context) + .extension()! + .infoItemIcons, + ), + const SizedBox( + width: 4, + ), + Text( + "Edit", + style: + STextStyles.link2(context), + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + FutureBuilder( + future: ref.watch( + notesServiceChangeNotifierProvider(walletId) + .select((value) => value.getNoteFor( + txid: _transaction.txid))), + builder: (builderContext, + AsyncSnapshot snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + _note = snapshot.data ?? ""; + } + return SelectableText( + _note, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ); + }, + ), + ], + ), + ), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Date", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall(context) + : STextStyles.itemSubtitle(context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + Format.extractDateFrom( + _transaction.timestamp, + ), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + ], + ), + if (!isDesktop) + SelectableText( + Format.extractDateFrom( + _transaction.timestamp, + ), + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + if (isDesktop) + IconCopyButton( + data: Format.extractDateFrom( + _transaction.timestamp, + ), + ), + ], + ), + ), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Builder(builder: (context) { + final feeString = showFeePending + ? _transaction.confirmedStatus + ? Format.localizedStringAsFixed( + value: coin == Coin.monero + ? (fee / 10000.toDecimal()) + .toDecimal() + : coin == Coin.wownero + ? (fee / 1000.toDecimal()) + .toDecimal() + : fee, + locale: ref.watch( + localeServiceChangeNotifierProvider + .select( + (value) => value.locale)), + decimalPlaces: Constants.decimalPlaces) + : "Pending" + : Format.localizedStringAsFixed( value: coin == Coin.monero ? (fee / 10000.toDecimal()).toDecimal() : coin == Coin.wownero @@ -475,251 +740,403 @@ class _TransactionDetailsViewState locale: ref.watch( localeServiceChangeNotifierProvider .select((value) => value.locale)), - decimalPlaces: Constants.decimalPlaces) - : "Pending" - : Format.localizedStringAsFixed( - value: coin == Coin.monero - ? (fee / 10000.toDecimal()).toDecimal() - : coin == Coin.wownero - ? (fee / 1000.toDecimal()).toDecimal() - : fee, - locale: ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale)), - decimalPlaces: Constants.decimalPlaces), - style: STextStyles.itemSubtitle12(context), - ), - // ), - // ), - ], - ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Block height", - style: STextStyles.itemSubtitle(context), - ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - widget.coin != Coin.epicCash && - _transaction.confirmedStatus - ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}" - : _transaction.confirmations > 0 - ? "${_transaction.height}" - : "Pending", - style: STextStyles.itemSubtitle12(context), - ), - // ), - // ), - ], - ), - ), - const SizedBox( - height: 12, - ), - RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Transaction ID", - style: STextStyles.itemSubtitle(context), - ), - ], - ), - const SizedBox( - height: 8, - ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - _transaction.txid, - style: STextStyles.itemSubtitle12(context), - ), - if (coin != Coin.epicCash) - const SizedBox( - height: 8, - ), - if (coin != Coin.epicCash) - BlueTextButton( - text: "Open in block explorer", - onTap: () async { - final uri = getBlockExplorerTransactionUrlFor( - coin: coin, - txid: _transaction.txid, - ); + decimalPlaces: Constants.decimalPlaces); - if (ref - .read(prefsChangeNotifierProvider) - .hideBlockExplorerWarning == - false) { - final shouldContinue = await showExplorerWarning( - "${uri.scheme}://${uri.host}"); - - if (!shouldContinue) { - return; - } - } - - // ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = false; - try { - await launchUrl( - uri, - mode: LaunchMode.externalApplication, - ); - } catch (_) { - unawaited(showDialog( - context: context, - builder: (_) => StackOkDialog( - title: "Could not open in block explorer", - message: - "Failed to open \"${uri.toString()}\"", + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Transaction fee", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + feeString, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], ), - )); - } finally { - // Future.delayed( - // const Duration(seconds: 1), - // () => ref - // .read( - // shouldShowLockscreenOnResumeStateProvider - // .state) - // .state = true, - // ); - } - }, + if (!isDesktop) + SelectableText( + feeString, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + if (isDesktop) IconCopyButton(data: feeString) + ], + ); + }), ), - // ), - // ), - ], - ), - ), - // if ((coin == Coin.firoTestNet || coin == Coin.firo) && - // _transaction.subType == "mint") - // const SizedBox( - // height: 12, - // ), - // if ((coin == Coin.firoTestNet || coin == Coin.firo) && - // _transaction.subType == "mint") - // RoundedWhiteContainer( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Text( - // "Mint Transaction ID", - // style: STextStyles.itemSubtitle(context), - // ), - // ], - // ), - // const SizedBox( - // height: 8, - // ), - // // Flexible( - // // child: FittedBox( - // // fit: BoxFit.scaleDown, - // // child: - // SelectableText( - // _transaction.otherData ?? "Unknown", - // style: STextStyles.itemSubtitle12(context), - // ), - // // ), - // // ), - // const SizedBox( - // height: 8, - // ), - // BlueTextButton( - // text: "Open in block explorer", - // onTap: () async { - // final uri = getBlockExplorerTransactionUrlFor( - // coin: coin, - // txid: _transaction.otherData ?? "Unknown", - // ); - // // ref - // // .read( - // // shouldShowLockscreenOnResumeStateProvider - // // .state) - // // .state = false; - // try { - // await launchUrl( - // uri, - // mode: LaunchMode.externalApplication, - // ); - // } catch (_) { - // unawaited(showDialog( - // context: context, - // builder: (_) => StackOkDialog( - // title: "Could not open in block explorer", - // message: - // "Failed to open \"${uri.toString()}\"", - // ), - // )); - // } finally { - // // Future.delayed( - // // const Duration(seconds: 1), - // // () => ref - // // .read( - // // shouldShowLockscreenOnResumeStateProvider - // // .state) - // // .state = true, - // // ); - // } - // }, - // ), - // ], - // ), - // ), - if (coin == Coin.epicCash) - const SizedBox( - height: 12, - ), - if (coin == Coin.epicCash) - RoundedWhiteContainer( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Slate ID", - style: STextStyles.itemSubtitle(context), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Builder(builder: (context) { + final height = widget.coin != Coin.epicCash && + _transaction.confirmedStatus + ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}" + : _transaction.confirmations > 0 + ? "${_transaction.height}" + : "Pending"; + + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Block height", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + height, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], + ), + if (!isDesktop) + SelectableText( + height, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + if (isDesktop) IconCopyButton(data: height), + ], + ); + }), ), - // Flexible( - // child: FittedBox( - // fit: BoxFit.scaleDown, - // child: - SelectableText( - _transaction.slateId ?? "Unknown", - style: STextStyles.itemSubtitle12(context), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Transaction ID", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + const SizedBox( + height: 8, + ), + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: + SelectableText( + _transaction.txid, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + if (coin != Coin.epicCash) + const SizedBox( + height: 8, + ), + if (coin != Coin.epicCash) + BlueTextButton( + text: "Open in block explorer", + onTap: () async { + final uri = + getBlockExplorerTransactionUrlFor( + coin: coin, + txid: _transaction.txid, + ); + + if (ref + .read( + prefsChangeNotifierProvider) + .hideBlockExplorerWarning == + false) { + final shouldContinue = + await showExplorerWarning( + "${uri.scheme}://${uri.host}"); + + if (!shouldContinue) { + return; + } + } + + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = false; + try { + await launchUrl( + uri, + mode: LaunchMode + .externalApplication, + ); + } catch (_) { + unawaited(showDialog( + context: context, + builder: (_) => StackOkDialog( + title: + "Could not open in block explorer", + message: + "Failed to open \"${uri.toString()}\"", + ), + )); + } finally { + // Future.delayed( + // const Duration(seconds: 1), + // () => ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true, + // ); + } + }, + ), + // ), + // ), + ], + ), + ), + if (isDesktop) + const SizedBox( + width: 12, + ), + if (isDesktop) + IconCopyButton( + data: _transaction.txid, + ), + ], + ), ), + // if ((coin == Coin.firoTestNet || coin == Coin.firo) && + // _transaction.subType == "mint") + // const SizedBox( + // height: 12, // ), - // ), + // if ((coin == Coin.firoTestNet || coin == Coin.firo) && + // _transaction.subType == "mint") + // RoundedWhiteContainer( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // "Mint Transaction ID", + // style: STextStyles.itemSubtitle(context), + // ), + // ], + // ), + // const SizedBox( + // height: 8, + // ), + // // Flexible( + // // child: FittedBox( + // // fit: BoxFit.scaleDown, + // // child: + // SelectableText( + // _transaction.otherData ?? "Unknown", + // style: STextStyles.itemSubtitle12(context), + // ), + // // ), + // // ), + // const SizedBox( + // height: 8, + // ), + // BlueTextButton( + // text: "Open in block explorer", + // onTap: () async { + // final uri = getBlockExplorerTransactionUrlFor( + // coin: coin, + // txid: _transaction.otherData ?? "Unknown", + // ); + // // ref + // // .read( + // // shouldShowLockscreenOnResumeStateProvider + // // .state) + // // .state = false; + // try { + // await launchUrl( + // uri, + // mode: LaunchMode.externalApplication, + // ); + // } catch (_) { + // unawaited(showDialog( + // context: context, + // builder: (_) => StackOkDialog( + // title: "Could not open in block explorer", + // message: + // "Failed to open \"${uri.toString()}\"", + // ), + // )); + // } finally { + // // Future.delayed( + // // const Duration(seconds: 1), + // // () => ref + // // .read( + // // shouldShowLockscreenOnResumeStateProvider + // // .state) + // // .state = true, + // // ); + // } + // }, + // ), + // ], + // ), + // ), + if (coin == Coin.epicCash) + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + if (coin == Coin.epicCash) + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Slate ID", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: + SelectableText( + _transaction.slateId ?? "Unknown", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + // ), + // ), + ], + ), + if (isDesktop) + const SizedBox( + width: 12, + ), + if (isDesktop) + IconCopyButton( + data: _transaction.slateId ?? "Unknown", + ), + ], + ), + ), + if (!isDesktop) + const SizedBox( + height: 12, + ), ], ), ), - const SizedBox( - height: 12, ), - ], + ), ), - ), + ], ), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, @@ -805,3 +1222,94 @@ class _TransactionDetailsViewState ); } } + +class _Divider extends StatelessWidget { + const _Divider({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 1, + color: Theme.of(context).extension()!.background, + ); + } +} + +class IconCopyButton extends StatelessWidget { + const IconCopyButton({ + Key? key, + required this.data, + }) : super(key: key); + + final String data; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 26, + width: 26, + child: RawMaterialButton( + fillColor: + Theme.of(context).extension()!.buttonBackSecondary, + elevation: 0, + hoverElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + onPressed: () async { + await Clipboard.setData(ClipboardData(text: data)); + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + }, + child: Padding( + padding: const EdgeInsets.all(5), + child: CopyIcon( + width: 16, + height: 16, + color: Theme.of(context).extension()!.textDark, + ), + ), + ), + ); + } +} + +class IconPencilButton extends StatelessWidget { + const IconPencilButton({ + Key? key, + this.onPressed, + }) : super(key: key); + + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 26, + width: 26, + child: RawMaterialButton( + fillColor: + Theme.of(context).extension()!.buttonBackSecondary, + elevation: 0, + hoverElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + onPressed: () => onPressed?.call(), + child: Padding( + padding: const EdgeInsets.all(5), + child: PencilIcon( + width: 16, + height: 16, + color: Theme.of(context).extension()!.textDark, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/icon_widgets/copy_icon.dart b/lib/widgets/icon_widgets/copy_icon.dart new file mode 100644 index 000000000..9f82a8066 --- /dev/null +++ b/lib/widgets/icon_widgets/copy_icon.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; + +class CopyIcon extends StatelessWidget { + const CopyIcon({ + Key? key, + this.width = 18, + this.height = 18, + this.color, + }) : super(key: key); + + final double width; + final double height; + final Color? color; + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + Assets.svg.copy, + width: width, + height: height, + color: color ?? Theme.of(context).extension()!.textDark3, + ); + } +} diff --git a/lib/widgets/icon_widgets/pencil_icon.dart b/lib/widgets/icon_widgets/pencil_icon.dart new file mode 100644 index 000000000..cb14f1cbf --- /dev/null +++ b/lib/widgets/icon_widgets/pencil_icon.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; + +class PencilIcon extends StatelessWidget { + const PencilIcon({ + Key? key, + this.width = 18, + this.height = 18, + this.color, + }) : super(key: key); + + final double width; + final double height; + final Color? color; + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + Assets.svg.pencil, + width: width, + height: height, + color: color ?? Theme.of(context).extension()!.textDark3, + ); + } +} diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart index de0447684..8867e34f6 100644 --- a/lib/widgets/transaction_card.dart +++ b/lib/widgets/transaction_card.dart @@ -14,6 +14,7 @@ import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:tuple/tuple.dart'; class TransactionCard extends ConsumerStatefulWidget { @@ -138,16 +139,31 @@ class _TransactionCardState extends ConsumerState { )); return; } - unawaited( - Navigator.of(context).pushNamed( - TransactionDetailsView.routeName, - arguments: Tuple3( - _transaction, - coin, - walletId, + if (Util.isDesktop) { + await showDialog( + 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), diff --git a/pubspec.lock b/pubspec.lock index 4f886e8bb..20992d827 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -42,7 +42,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.3.0" + version: "3.1.11" args: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.9.0" + version: "2.8.2" barcode_scan2: dependency: "direct main" description: @@ -190,7 +190,14 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" checked_yaml: dependency: transitive description: @@ -204,7 +211,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.0" code_builder: dependency: transitive description: @@ -274,7 +281,7 @@ packages: name: coverage url: "https://pub.dartlang.org" source: hosted - version: "1.5.0" + version: "1.2.0" cross_file: dependency: transitive description: @@ -428,7 +435,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.3.0" ffi: dependency: "direct main" description: @@ -857,21 +864,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.12" + version: "0.12.11" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.4" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.7.0" mime: dependency: transitive description: @@ -983,7 +990,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.8.1" path_drawing: dependency: transitive description: @@ -1359,7 +1366,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -1417,35 +1424,35 @@ packages: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.3.1" + version: "0.3.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.2.0" test: dependency: transitive description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.21.4" + version: "1.21.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.12" + version: "0.4.9" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.16" + version: "0.4.13" time: dependency: transitive description: @@ -1494,7 +1501,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.3.0" universal_io: dependency: transitive description: @@ -1578,7 +1585,7 @@ packages: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "9.0.0" + version: "8.2.2" wakelock: dependency: "direct main" description: