From e559ee1cc5cde4d244665754ebc0eadff79c8d43 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 21 Jul 2023 19:52:43 -0600 Subject: [PATCH] WIP desktop ordinal details view --- lib/dto/ordinals/inscription_data.dart | 20 ++ lib/models/isar/ordinal.dart | 13 + lib/pages/ordinals/widgets/ordinal_card.dart | 6 +- .../desktop_ordinal_details_view.dart | 335 +++++++++--------- 4 files changed, 213 insertions(+), 161 deletions(-) diff --git a/lib/dto/ordinals/inscription_data.dart b/lib/dto/ordinals/inscription_data.dart index b7bba8697..2f12bd670 100644 --- a/lib/dto/ordinals/inscription_data.dart +++ b/lib/dto/ordinals/inscription_data.dart @@ -50,4 +50,24 @@ class InscriptionData { offset: json['offset'] as int, ); } + + @override + String toString() { + return 'InscriptionData {' + ' inscriptionId: $inscriptionId,' + ' inscriptionNumber: $inscriptionNumber,' + ' address: $address,' + ' preview: $preview,' + ' content: $content,' + ' contentLength: $contentLength,' + ' contentType: $contentType,' + ' contentBody: $contentBody,' + ' timestamp: $timestamp,' + ' genesisTransaction: $genesisTransaction,' + ' location: $location,' + ' output: $output,' + ' outputValue: $outputValue,' + ' offset: $offset' + ' }'; + } } diff --git a/lib/models/isar/ordinal.dart b/lib/models/isar/ordinal.dart index 0af1d1120..06ba52ef5 100644 --- a/lib/models/isar/ordinal.dart +++ b/lib/models/isar/ordinal.dart @@ -1,5 +1,7 @@ import 'package:isar/isar.dart'; +import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/dto/ordinals/inscription_data.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; part 'ordinal.g.dart'; @@ -62,6 +64,17 @@ class Ordinal { ); } + UTXO? getUTXO(MainDB db) { + return db.isar.utxos + .where() + .walletIdEqualTo(walletId) + .filter() + .txidEqualTo(utxoTXID) + .and() + .voutEqualTo(utxoVOUT) + .findFirstSync(); + } + @override String toString() { return 'Ordinal {' diff --git a/lib/pages/ordinals/widgets/ordinal_card.dart b/lib/pages/ordinals/widgets/ordinal_card.dart index e537611f8..c74366d74 100644 --- a/lib/pages/ordinals/widgets/ordinal_card.dart +++ b/lib/pages/ordinals/widgets/ordinal_card.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; import 'package:stackwallet/models/isar/ordinal.dart'; import 'package:stackwallet/pages/ordinals/ordinal_details_view.dart'; +import 'package:stackwallet/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class OrdinalCard extends StatelessWidget { @@ -21,7 +23,9 @@ class OrdinalCard extends StatelessWidget { radiusMultiplier: 2, onPressed: () { Navigator.of(context).pushNamed( - OrdinalDetailsView.routeName, + Util.isDesktop + ? DesktopOrdinalDetailsView.routeName + : OrdinalDetailsView.routeName, arguments: (walletId: walletId, ordinal: ordinal), ); }, diff --git a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart index a477f6228..27c651213 100644 --- a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart +++ b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart @@ -2,12 +2,20 @@ import 'dart:async'; 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/isar/models/blockchain_data/utxo.dart'; import 'package:stackwallet/models/isar/ordinal.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/ordinals/widgets/dialogs.dart'; +import 'package:stackwallet/providers/db/main_db_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_formatter.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/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; @@ -16,7 +24,7 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; -class DesktopOrdinalDetailsView extends StatefulWidget { +class DesktopOrdinalDetailsView extends ConsumerStatefulWidget { const DesktopOrdinalDetailsView({ Key? key, required this.walletId, @@ -29,15 +37,27 @@ class DesktopOrdinalDetailsView extends StatefulWidget { static const routeName = "/desktopOrdinalDetailsView"; @override - State createState() => + ConsumerState createState() => _DesktopOrdinalDetailsViewState(); } -class _DesktopOrdinalDetailsViewState extends State { +class _DesktopOrdinalDetailsViewState + extends ConsumerState { static const _spacing = 12.0; + late final UTXO? utxo; + + @override + void initState() { + utxo = widget.ordinal.getUTXO(ref.read(mainDBProvider)); + super.initState(); + } + @override Widget build(BuildContext context) { + final coin = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId).coin)); + return DesktopScaffold( appBar: DesktopAppBar( background: Theme.of(context).extension()!.popupBG, @@ -67,18 +87,8 @@ class _DesktopOrdinalDetailsViewState extends State { const SizedBox( width: 18, ), - SvgPicture.asset( - Assets.svg.ordinal, - width: 32, - height: 32, - color: - Theme.of(context).extension()!.textSubtitle1, - ), - const SizedBox( - width: 12, - ), Text( - "Ordinals", + "Ordinal details", style: STextStyles.desktopH3(context), ), ], @@ -87,62 +97,161 @@ class _DesktopOrdinalDetailsViewState extends State { useSpacers: false, isCompactHeight: true, ), - body: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 12, - horizontal: 39, + body: Padding( + padding: const EdgeInsets.only( + left: 24, + top: 24, + right: 24, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 300, + height: 300, + child: ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), - child: _OrdinalImageGroup( - ordinal: widget.ordinal, - walletId: widget.walletId, + child: Image.network( + widget.ordinal + .content, // Use the preview URL as the image source + fit: BoxFit.cover, + filterQuality: + FilterQuality.none, // Set the filter mode to nearest ), ), - _DetailsItemWCopy( - title: "Inscription number", - data: widget.ordinal.inscriptionNumber.toString(), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + RoundedWhiteContainer( + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "INSC. ${widget.ordinal.inscriptionNumber}", + style: STextStyles.w600_20(context), + ), + ], + ), + ), + const SizedBox( + width: 16, + ), + PrimaryButton( + width: 150, + label: "Send", + icon: SvgPicture.asset( + Assets.svg.send, + width: 18, + height: 18, + color: Theme.of(context) + .extension()! + .buttonTextPrimary, + ), + buttonHeight: ButtonHeight.l, + iconSpacing: 8, + onPressed: () async { + final response = await showDialog( + context: context, + builder: (_) => + const SendOrdinalUnfreezeDialog(), + ); + if (response == "unfreeze") { + // TODO: unfreeze and go to send ord screen + } + }, + ), + const SizedBox( + width: 16, + ), + SecondaryButton( + width: 150, + label: "Download", + icon: SvgPicture.asset( + Assets.svg.arrowDown, + width: 13, + height: 18, + color: Theme.of(context) + .extension()! + .buttonTextSecondary, + ), + buttonHeight: ButtonHeight.l, + iconSpacing: 8, + onPressed: () { + // TODO: save and download image to device + }, + ), + ], + ), + ), + const SizedBox( + height: 16, + ), + _DetailsItemWCopy( + title: "Inscription number", + data: widget.ordinal.inscriptionNumber.toString(), + ), + const SizedBox( + height: _spacing, + ), + _DetailsItemWCopy( + title: "Inscription ID", + data: widget.ordinal.inscriptionId, + ), + const SizedBox( + height: _spacing, + ), + // todo: add utxo status + const SizedBox( + height: _spacing, + ), + _DetailsItemWCopy( + title: "Amount", + data: utxo == null + ? "ERROR" + : ref.watch(pAmountFormatter(coin)).format( + Amount( + rawValue: BigInt.from(utxo!.value), + fractionDigits: coin.decimals, + ), + ), + ), + const SizedBox( + height: _spacing, + ), + _DetailsItemWCopy( + title: "Owner address", + data: utxo?.address ?? "ERROR", + ), + const SizedBox( + height: _spacing, + ), + _DetailsItemWCopy( + title: "Transaction ID", + data: widget.ordinal.utxoTXID, + ), + const SizedBox( + height: _spacing, + ), + ], + ), + ), ), - const SizedBox( - height: _spacing, - ), - _DetailsItemWCopy( - title: "ID", - data: widget.ordinal.inscriptionId, - ), - const SizedBox( - height: _spacing, - ), - // todo: add utxo status - const SizedBox( - height: _spacing, - ), - const _DetailsItemWCopy( - title: "Amount", - data: "TODO", // TODO infer from utxo utxoTXID:utxoVOUT - ), - const SizedBox( - height: _spacing, - ), - const _DetailsItemWCopy( - title: "Owner address", - data: "TODO", // infer from address associated w utxoTXID - ), - const SizedBox( - height: _spacing, - ), - _DetailsItemWCopy( - title: "Transaction ID", - data: widget.ordinal.utxoTXID, - ), - const SizedBox( - height: _spacing, - ), - ], - ), + ), + ], ), ), ); @@ -206,97 +315,3 @@ class _DetailsItemWCopy extends StatelessWidget { ); } } - -class _OrdinalImageGroup extends StatelessWidget { - const _OrdinalImageGroup({ - Key? key, - required this.walletId, - required this.ordinal, - }) : super(key: key); - - final String walletId; - final Ordinal ordinal; - - static const _spacing = 12.0; - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // Text( - // "${ordinal.inscriptionId}", // Use any other property you want - // style: STextStyles.w600_16(context), - // ), - // const SizedBox( - // height: _spacing, - // ), - AspectRatio( - aspectRatio: 1, - child: Container( - color: Colors.red, - child: Image.network( - ordinal.content, // Use the preview URL as the image source - fit: BoxFit.cover, - filterQuality: - FilterQuality.none, // Set the filter mode to nearest - ), - ), - ), - const SizedBox( - height: _spacing, - ), - Row( - children: [ - Expanded( - child: SecondaryButton( - label: "Download", - icon: SvgPicture.asset( - Assets.svg.arrowDown, - width: 10, - height: 12, - color: Theme.of(context) - .extension()! - .buttonTextSecondary, - ), - buttonHeight: ButtonHeight.l, - iconSpacing: 4, - onPressed: () { - // TODO: save and download image to device - }, - ), - ), - const SizedBox( - width: _spacing, - ), - Expanded( - child: PrimaryButton( - label: "Send", - icon: SvgPicture.asset( - Assets.svg.send, - width: 10, - height: 10, - color: Theme.of(context) - .extension()! - .buttonTextPrimary, - ), - buttonHeight: ButtonHeight.l, - iconSpacing: 4, - onPressed: () async { - final response = await showDialog( - context: context, - builder: (_) => const SendOrdinalUnfreezeDialog(), - ); - if (response == "unfreeze") { - // TODO: unfreeze and go to send ord screen - } - }, - ), - ), - ], - ), - ], - ); - } -}