mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-30 14:15:52 +00:00
desktop paynym details subview
This commit is contained in:
parent
3c1bc42bbf
commit
91696ebb4b
7 changed files with 451 additions and 75 deletions
|
@ -7,9 +7,11 @@ import 'package:flutter_svg/svg.dart';
|
|||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||
import 'package:stackwallet/pages/paynym/add_new_paynym_follow_view.dart';
|
||||
import 'package:stackwallet/pages/paynym/dialogs/paynym_qr_popup.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/desktop_paynym_details.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_followers_list.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_following_list.dart';
|
||||
import 'package:stackwallet/providers/ui/selected_paynym_details_item_Provider.dart';
|
||||
import 'package:stackwallet/providers/wallet/my_paynym_account_state_provider.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
|
@ -553,10 +555,48 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> {
|
|||
condition: isDesktop,
|
||||
builder: (child) => Padding(
|
||||
padding: const EdgeInsets.only(left: 24),
|
||||
child: SizedBox(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 490,
|
||||
child: child,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 24,
|
||||
),
|
||||
if (ref
|
||||
.watch(selectedPaynymDetailsItemProvider.state)
|
||||
.state !=
|
||||
null)
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 600,
|
||||
),
|
||||
child: DesktopPaynymDetails(
|
||||
walletId: widget.walletId,
|
||||
accountLite: ref
|
||||
.watch(selectedPaynymDetailsItemProvider
|
||||
.state)
|
||||
.state!,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (ref
|
||||
.watch(selectedPaynymDetailsItemProvider.state)
|
||||
.state !=
|
||||
null)
|
||||
const SizedBox(
|
||||
width: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: ConditionalParent(
|
||||
condition: !isDesktop,
|
||||
|
|
271
lib/pages/paynym/subwidgets/desktop_paynym_details.dart
Normal file
271
lib/pages/paynym/subwidgets/desktop_paynym_details.dart
Normal file
|
@ -0,0 +1,271 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart';
|
||||
import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart';
|
||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||
import 'package:stackwallet/route_generator.dart';
|
||||
import 'package:stackwallet/services/coins/coin_paynym_extension.dart';
|
||||
import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
|
||||
import 'package:stackwallet/widgets/custom_buttons/paynym_follow_toggle_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/loading_indicator.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
|
||||
import '../../../notifications/show_flush_bar.dart';
|
||||
|
||||
class DesktopPaynymDetails extends ConsumerStatefulWidget {
|
||||
const DesktopPaynymDetails({
|
||||
Key? key,
|
||||
required this.walletId,
|
||||
required this.accountLite,
|
||||
}) : super(key: key);
|
||||
|
||||
final String walletId;
|
||||
final PaynymAccountLite accountLite;
|
||||
|
||||
@override
|
||||
ConsumerState<DesktopPaynymDetails> createState() =>
|
||||
_PaynymDetailsPopupState();
|
||||
}
|
||||
|
||||
class _PaynymDetailsPopupState extends ConsumerState<DesktopPaynymDetails> {
|
||||
Future<void> _onConnectPressed() async {
|
||||
bool canPop = false;
|
||||
unawaited(
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => WillPopScope(
|
||||
onWillPop: () async => canPop,
|
||||
child: const LoadingIndicator(
|
||||
width: 200,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final wallet = ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(widget.walletId)
|
||||
.wallet as DogecoinWallet;
|
||||
|
||||
// sanity check to prevent second notifcation tx
|
||||
if (wallet.hasConnectedConfirmed(widget.accountLite.code)) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
// TODO show info popup
|
||||
return;
|
||||
} else if (wallet.hasConnected(widget.accountLite.code)) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
// TODO show info popup
|
||||
return;
|
||||
}
|
||||
|
||||
final rates = await wallet.fees;
|
||||
|
||||
Map<String, dynamic> preparedTx;
|
||||
|
||||
try {
|
||||
preparedTx = await wallet.buildNotificationTx(
|
||||
selectedTxFeeRate: rates.medium,
|
||||
targetPaymentCodeString: widget.accountLite.code,
|
||||
);
|
||||
} on InsufficientBalanceException catch (e) {
|
||||
if (mounted) {
|
||||
canPop = true;
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
// TODO show info popup
|
||||
print(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
// We have enough balance and prepared tx should be good to go.
|
||||
|
||||
canPop = true;
|
||||
// close loading
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// Close details
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// show info pop up
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => ConfirmPaynymConnectDialog(
|
||||
nymName: widget.accountLite.nymName,
|
||||
onConfirmPressed: () {
|
||||
//
|
||||
print("CONFIRM NOTIF TX: $preparedTx");
|
||||
|
||||
Navigator.of(context).push(
|
||||
RouteGenerator.getRoute(
|
||||
builder: (_) => ConfirmTransactionView(
|
||||
walletId: wallet.walletId,
|
||||
transactionInfo: {
|
||||
"hex": preparedTx["hex"],
|
||||
"recipient": preparedTx["recipientPaynym"],
|
||||
"recipientAmt": preparedTx["amount"],
|
||||
"fee": preparedTx["fee"],
|
||||
"vSize": preparedTx["vSize"],
|
||||
"note": "PayNym connect"
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
amount: (preparedTx["amount"] as int) + (preparedTx["fee"] as int),
|
||||
coin: wallet.coin,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RoundedWhiteContainer(
|
||||
padding: const EdgeInsets.all(0),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
PayNymBot(
|
||||
paymentCodeString: widget.accountLite.code,
|
||||
size: 32,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(
|
||||
widget.accountLite.nymName,
|
||||
style: STextStyles.desktopTextSmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
label: "Connect",
|
||||
buttonHeight: ButtonHeight.s,
|
||||
icon: SvgPicture.asset(
|
||||
Assets.svg.circlePlusFilled,
|
||||
width: 16,
|
||||
height: 16,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.buttonTextPrimary,
|
||||
),
|
||||
iconSpacing: 6,
|
||||
onPressed: _onConnectPressed,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: PaynymFollowToggleButton(
|
||||
walletId: widget.walletId,
|
||||
paymentCodeStringToFollow: widget.accountLite.code,
|
||||
style: PaynymFollowToggleButtonStyle.detailsDesktop,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Theme.of(context).extension<StackColors>()!.backgroundAppBar,
|
||||
height: 1,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"PayNym address",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(minHeight: 100),
|
||||
child: Text(
|
||||
widget.accountLite.code,
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context)
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
QrImage(
|
||||
padding: const EdgeInsets.all(0),
|
||||
size: 100,
|
||||
data: widget.accountLite.code,
|
||||
foregroundColor:
|
||||
Theme.of(context).extension<StackColors>()!.textDark,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
BlueTextButton(
|
||||
text: "Copy",
|
||||
onTap: () async {
|
||||
await Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: widget.accountLite.code,
|
||||
),
|
||||
);
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
iconAsset: Assets.svg.copy,
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
import 'package:stackwallet/pages/paynym/dialogs/paynym_details_popup.dart';
|
||||
import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart';
|
||||
import 'package:stackwallet/providers/ui/selected_paynym_details_item_Provider.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
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/rounded_container.dart';
|
||||
|
||||
class PaynymCardButton extends StatefulWidget {
|
||||
class PaynymCardButton extends ConsumerStatefulWidget {
|
||||
const PaynymCardButton({
|
||||
Key? key,
|
||||
required this.walletId,
|
||||
|
@ -19,21 +22,29 @@ class PaynymCardButton extends StatefulWidget {
|
|||
final PaynymAccountLite accountLite;
|
||||
|
||||
@override
|
||||
State<PaynymCardButton> createState() => _PaynymCardButtonState();
|
||||
ConsumerState<PaynymCardButton> createState() => _PaynymCardButtonState();
|
||||
}
|
||||
|
||||
class _PaynymCardButtonState extends State<PaynymCardButton> {
|
||||
class _PaynymCardButtonState extends ConsumerState<PaynymCardButton> {
|
||||
final isDesktop = Util.isDesktop;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 12,
|
||||
)
|
||||
: const EdgeInsets.all(4),
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: RoundedContainer(
|
||||
padding: const EdgeInsets.all(0),
|
||||
color: isDesktop &&
|
||||
ref
|
||||
.watch(selectedPaynymDetailsItemProvider.state)
|
||||
.state
|
||||
?.nymId ==
|
||||
widget.accountLite.nymId
|
||||
? Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.accentColorDark
|
||||
.withOpacity(0.08)
|
||||
: Colors.transparent,
|
||||
child: RawMaterialButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
|
@ -43,6 +54,10 @@ class _PaynymCardButtonState extends State<PaynymCardButton> {
|
|||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (isDesktop) {
|
||||
ref.read(selectedPaynymDetailsItemProvider.state).state =
|
||||
widget.accountLite;
|
||||
} else {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => PaynymDetailsPopup(
|
||||
|
@ -50,9 +65,15 @@ class _PaynymCardButtonState extends State<PaynymCardButton> {
|
|||
walletId: widget.walletId,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 12,
|
||||
)
|
||||
: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
PayNymBot(
|
||||
|
@ -97,6 +118,7 @@ class _PaynymCardButtonState extends State<PaynymCardButton> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:stackwallet/models/paynym/paynym_account_lite.dart';
|
||||
|
||||
final selectedPaynymDetailsItemProvider =
|
||||
StateProvider.autoDispose<PaynymAccountLite?>((_) => null);
|
|
@ -21,6 +21,7 @@ import 'package:stackwallet/widgets/loading_indicator.dart';
|
|||
enum PaynymFollowToggleButtonStyle {
|
||||
primary,
|
||||
detailsPopup,
|
||||
detailsDesktop,
|
||||
}
|
||||
|
||||
class PaynymFollowToggleButton extends ConsumerStatefulWidget {
|
||||
|
@ -288,6 +289,21 @@ class _PaynymFollowToggleButtonState
|
|||
iconSpacing: 4,
|
||||
onPressed: _onPressed,
|
||||
);
|
||||
|
||||
case PaynymFollowToggleButtonStyle.detailsDesktop:
|
||||
return SecondaryButton(
|
||||
label: isFollowing ? "Unfollow" : "Follow",
|
||||
buttonHeight: ButtonHeight.s,
|
||||
icon: SvgPicture.asset(
|
||||
isFollowing ? Assets.svg.userMinus : Assets.svg.userPlus,
|
||||
width: 16,
|
||||
height: 16,
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.buttonTextSecondary,
|
||||
),
|
||||
iconSpacing: 6,
|
||||
onPressed: _onPressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,10 +149,21 @@ class PrimaryButton extends StatelessWidget {
|
|||
width: iconSpacing,
|
||||
),
|
||||
if (label != null)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
label!,
|
||||
style: getStyle(isDesktop, context),
|
||||
),
|
||||
if (buttonHeight != null && buttonHeight == ButtonHeight.s)
|
||||
const SizedBox(
|
||||
height: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -152,10 +152,21 @@ class SecondaryButton extends StatelessWidget {
|
|||
width: iconSpacing,
|
||||
),
|
||||
if (label != null)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
label!,
|
||||
style: getStyle(isDesktop, context),
|
||||
),
|
||||
if (buttonHeight != null && buttonHeight == ButtonHeight.s)
|
||||
const SizedBox(
|
||||
height: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue