diff --git a/assets/svg/network-wired-2.svg b/assets/svg/network-wired-2.svg
new file mode 100644
index 000000000..bbbfa056f
--- /dev/null
+++ b/assets/svg/network-wired-2.svg
@@ -0,0 +1,10 @@
+
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
index 141eb4c99..950d8d79e 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
@@ -1,6 +1,11 @@
import 'package:flutter/material.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:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class ConfirmFullRescanDialog extends StatelessWidget {
@@ -11,40 +16,110 @@ class ConfirmFullRescanDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return WillPopScope(
- onWillPop: () async {
- return true;
- },
- child: StackDialog(
- title: "Rescan blockchain",
- message:
- "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
- leftButton: TextButton(
- style: Theme.of(context)
- .extension()!
- .getSecondaryEnabledButtonColor(context),
- child: Text(
- "Cancel",
- style: STextStyles.itemSubtitle12(context),
- ),
- onPressed: () {
- Navigator.of(context).pop();
- },
+ if (Util.isDesktop) {
+ return DesktopDialog(
+ maxWidth: 576,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(
+ left: 32,
+ ),
+ child: Text(
+ "Rescan blockchain",
+ style: STextStyles.desktopH3(context),
+ ),
+ ),
+ const DesktopDialogCloseButton(),
+ ],
+ ),
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 8,
+ left: 32,
+ right: 32,
+ bottom: 32,
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Text(
+ "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
+ style: STextStyles.desktopTextSmall(context),
+ ),
+ const SizedBox(
+ height: 43,
+ ),
+ Row(
+ children: [
+ Expanded(
+ child: SecondaryButton(
+ desktopMed: true,
+ onPressed: Navigator.of(context).pop,
+ label: "Cancel",
+ ),
+ ),
+ const SizedBox(
+ width: 16,
+ ),
+ Expanded(
+ child: PrimaryButton(
+ desktopMed: true,
+ onPressed: () {
+ Navigator.of(context).pop();
+ onConfirm.call();
+ },
+ label: "Rescan",
+ ),
+ ),
+ ],
+ )
+ ],
+ ),
+ )
+ ],
),
- rightButton: TextButton(
- style: Theme.of(context)
- .extension()!
- .getPrimaryEnabledButtonColor(context),
- child: Text(
- "Rescan",
- style: STextStyles.button(context),
+ );
+ } else {
+ return WillPopScope(
+ onWillPop: () async {
+ return true;
+ },
+ child: StackDialog(
+ title: "Rescan blockchain",
+ message:
+ "Warning! It may take a while. If you exit before completion, you will have to redo the process.",
+ leftButton: TextButton(
+ style: Theme.of(context)
+ .extension()!
+ .getSecondaryEnabledButtonColor(context),
+ child: Text(
+ "Cancel",
+ style: STextStyles.itemSubtitle12(context),
+ ),
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ rightButton: TextButton(
+ style: Theme.of(context)
+ .extension()!
+ .getPrimaryEnabledButtonColor(context),
+ child: Text(
+ "Rescan",
+ style: STextStyles.button(context),
+ ),
+ onPressed: () {
+ Navigator.of(context).pop();
+ onConfirm.call();
+ },
),
- onPressed: () {
- Navigator.of(context).pop();
- onConfirm.call();
- },
),
- ),
- );
+ );
+ }
}
}
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
index 5b1c57214..accf244eb 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
@@ -10,6 +10,7 @@ import 'package:stackwallet/pages/settings_views/sub_widgets/nodes_list.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/rescanning_dialog.dart';
import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/coins/epiccash/epiccash_wallet.dart';
import 'package:stackwallet/services/coins/monero/monero_wallet.dart';
import 'package:stackwallet/services/coins/wownero/wownero_wallet.dart';
@@ -23,9 +24,12 @@ import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.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/animated_text.dart';
+import 'package:stackwallet/widgets/conditional_parent.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/expandable.dart';
import 'package:stackwallet/widgets/progress_bar.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -59,7 +63,7 @@ class _WalletNetworkSettingsViewState
extends ConsumerState {
final double _padding = 16;
final double _boxPadding = 12;
- final double _iconSize = 28;
+ final double _iconSize = Util.isDesktop ? 40 : 28;
late final EventBus eventBus;
@@ -73,19 +77,22 @@ class _WalletNetworkSettingsViewState
late double _percent;
late int _blocksRemaining;
+ bool _advancedIsExpanded = true;
Future _attemptRescan() async {
- if (!Platform.isLinux) Wakelock.enable();
+ if (!Platform.isLinux) await Wakelock.enable();
int maxUnusedAddressGap = 20;
const int maxNumberOfIndexesToCheck = 1000;
- showDialog(
- context: context,
- useSafeArea: false,
- barrierDismissible: false,
- builder: (context) => const RescanningDialog(),
+ unawaited(
+ showDialog(
+ context: context,
+ useSafeArea: false,
+ barrierDismissible: false,
+ builder: (context) => const RescanningDialog(),
+ ),
);
try {
@@ -131,7 +138,7 @@ class _WalletNetworkSettingsViewState
);
}
} catch (e) {
- if (!Platform.isLinux) Wakelock.disable();
+ if (!Platform.isLinux) await Wakelock.disable();
if (mounted) {
// pop rescanning dialog
@@ -162,7 +169,7 @@ class _WalletNetworkSettingsViewState
}
}
- if (!Platform.isLinux) Wakelock.disable();
+ if (!Platform.isLinux) await Wakelock.disable();
}
String _percentString(double value) {
@@ -262,9 +269,11 @@ class _WalletNetworkSettingsViewState
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
+ final bool isDesktop = Util.isDesktop;
- final progressLength =
- screenWidth - (_padding * 2) - (_boxPadding * 3) - _iconSize;
+ final progressLength = isDesktop
+ ? 430.0
+ : screenWidth - (_padding * 2) - (_boxPadding * 3) - _iconSize;
final coin = ref
.read(walletsChangeNotifierProvider)
@@ -300,443 +309,597 @@ class _WalletNetworkSettingsViewState
}
}
- return Scaffold(
- backgroundColor: Theme.of(context).extension()!.background,
- appBar: AppBar(
- leading: AppBarBackButton(
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- title: Text(
- "Network",
- style: STextStyles.navBarTitle(context),
- ),
- actions: [
- Padding(
- padding: const EdgeInsets.only(
- top: 10,
- bottom: 10,
- right: 10,
+ return ConditionalParent(
+ condition: !isDesktop,
+ builder: (child) {
+ return Scaffold(
+ backgroundColor:
+ Theme.of(context).extension()!.background,
+ appBar: AppBar(
+ leading: AppBarBackButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
),
- child: AspectRatio(
- aspectRatio: 1,
- child: AppBarIconButton(
- key: const Key("walletNetworkSettingsAddNewNodeViewButton"),
- size: 36,
- shadows: const [],
- color: Theme.of(context).extension()!.background,
- icon: SvgPicture.asset(
- Assets.svg.verticalEllipsis,
- color: Theme.of(context)
- .extension()!
- .accentColorDark,
- width: 20,
- height: 20,
+ title: Text(
+ "Network",
+ style: STextStyles.navBarTitle(context),
+ ),
+ actions: [
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 10,
+ bottom: 10,
+ right: 10,
),
- onPressed: () {
- showDialog(
- barrierColor: Colors.transparent,
- barrierDismissible: true,
- context: context,
- builder: (_) {
- return Stack(
- children: [
- Positioned(
- top: 9,
- right: 10,
- child: Container(
- decoration: BoxDecoration(
- color: Theme.of(context)
- .extension()!
- .popupBG,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius),
- // boxShadow: [CFColors.standardBoxShadow],
- boxShadow: const [],
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- GestureDetector(
- onTap: () {
- Navigator.of(context).pop();
- showDialog(
- context: context,
- useSafeArea: false,
- barrierDismissible: true,
- builder: (context) {
- return ConfirmFullRescanDialog(
- onConfirm: _attemptRescan,
+ child: AspectRatio(
+ aspectRatio: 1,
+ child: AppBarIconButton(
+ key: const Key("walletNetworkSettingsAddNewNodeViewButton"),
+ size: 36,
+ shadows: const [],
+ color:
+ Theme.of(context).extension()!.background,
+ icon: SvgPicture.asset(
+ Assets.svg.verticalEllipsis,
+ color: Theme.of(context)
+ .extension()!
+ .accentColorDark,
+ width: 20,
+ height: 20,
+ ),
+ onPressed: () {
+ showDialog(
+ barrierColor: Colors.transparent,
+ barrierDismissible: true,
+ context: context,
+ builder: (_) {
+ return Stack(
+ children: [
+ Positioned(
+ top: 9,
+ right: 10,
+ child: Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .popupBG,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius),
+ // boxShadow: [CFColors.standardBoxShadow],
+ boxShadow: const [],
+ ),
+ child: Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ GestureDetector(
+ onTap: () {
+ Navigator.of(context).pop();
+ showDialog(
+ context: context,
+ useSafeArea: false,
+ barrierDismissible: true,
+ builder: (context) {
+ return ConfirmFullRescanDialog(
+ onConfirm: _attemptRescan,
+ );
+ },
);
},
- );
- },
- child: RoundedWhiteContainer(
- child: Material(
- color: Colors.transparent,
- child: Text(
- "Rescan blockchain",
- style: STextStyles.baseXS(context),
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- ],
- );
- },
- );
- },
- ),
- ),
- ),
- ],
- ),
- body: Padding(
- padding: EdgeInsets.only(
- top: 12,
- left: _padding,
- right: _padding,
- ),
- child: SingleChildScrollView(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Blockchain status",
- textAlign: TextAlign.left,
- style: STextStyles.smallMed12(context),
- ),
- GestureDetector(
- onTap: () {
- ref
- .read(walletsChangeNotifierProvider)
- .getManager(widget.walletId)
- .refresh();
- },
- child: Text(
- "Resync",
- style: STextStyles.link2(context),
- ),
- ),
- ],
- ),
- const SizedBox(
- height: 9,
- ),
- if (_currentSyncStatus == WalletSyncStatus.synced)
- RoundedWhiteContainer(
- child: Row(
- children: [
- Container(
- width: _iconSize,
- height: _iconSize,
- decoration: BoxDecoration(
- color: Theme.of(context)
- .extension()!
- .accentColorGreen
- .withOpacity(0.2),
- borderRadius: BorderRadius.circular(_iconSize),
- ),
- child: Center(
- child: SvgPicture.asset(
- Assets.svg.radio,
- height: 14,
- width: 14,
- color: Theme.of(context)
- .extension()!
- .accentColorGreen,
- ),
- ),
- ),
- SizedBox(
- width: _boxPadding,
- ),
- Column(
- children: [
- SizedBox(
- width: progressLength,
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Synchronized",
- style: STextStyles.w600_10(context),
- ),
- Text(
- "100%",
- style: STextStyles.syncPercent(context)
- .copyWith(
- color: Theme.of(context)
- .extension()!
- .accentColorGreen,
- ),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: 4,
- ),
- ProgressBar(
- width: progressLength,
- height: 5,
- fillColor: Theme.of(context)
- .extension()!
- .accentColorGreen,
- backgroundColor: Theme.of(context)
- .extension()!
- .textFieldDefaultBG,
- percent: 1,
- ),
- ],
- ),
- ],
- ),
- ),
- if (_currentSyncStatus == WalletSyncStatus.syncing)
- RoundedWhiteContainer(
- child: Row(
- children: [
- Container(
- width: _iconSize,
- height: _iconSize,
- decoration: BoxDecoration(
- color: Theme.of(context)
- .extension()!
- .accentColorYellow
- .withOpacity(0.2),
- borderRadius: BorderRadius.circular(_iconSize),
- ),
- child: Center(
- child: SvgPicture.asset(
- Assets.svg.radioSyncing,
- height: 14,
- width: 14,
- color: Theme.of(context)
- .extension()!
- .accentColorYellow,
- ),
- ),
- ),
- SizedBox(
- width: _boxPadding,
- ),
- Column(
- children: [
- SizedBox(
- width: progressLength,
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- AnimatedText(
- style: STextStyles.w600_10(context),
- stringsToLoopThrough: const [
- "Synchronizing",
- "Synchronizing.",
- "Synchronizing..",
- "Synchronizing...",
- ],
- ),
- Row(
- children: [
- Text(
- _percentString(_percent),
- style:
- STextStyles.syncPercent(context)
- .copyWith(
- color: Theme.of(context)
- .extension()!
- .accentColorYellow,
- ),
- ),
- if (coin == Coin.monero ||
- coin == Coin.wownero ||
- coin == Coin.epicCash)
- Text(
- " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
- style:
- STextStyles.syncPercent(context)
- .copyWith(
- color: Theme.of(context)
- .extension()!
- .accentColorYellow,
+ child: RoundedWhiteContainer(
+ child: Material(
+ color: Colors.transparent,
+ child: Text(
+ "Rescan blockchain",
+ style:
+ STextStyles.baseXS(context),
),
),
- ],
- )
- ],
+ ),
+ ),
+ ],
+ ),
),
),
- const SizedBox(
- height: 4,
- ),
- ProgressBar(
- width: progressLength,
- height: 5,
- fillColor: Theme.of(context)
- .extension()!
- .accentColorYellow,
- backgroundColor: Theme.of(context)
- .extension()!
- .textFieldDefaultBG,
- percent: _percent,
- ),
],
- ),
- ],
- ),
- ),
- if (_currentSyncStatus == WalletSyncStatus.unableToSync)
- RoundedWhiteContainer(
- child: Row(
- children: [
- Container(
- width: _iconSize,
- height: _iconSize,
- decoration: BoxDecoration(
- color: Theme.of(context)
- .extension()!
- .accentColorRed
- .withOpacity(0.2),
- borderRadius: BorderRadius.circular(_iconSize),
- ),
- child: Center(
- child: SvgPicture.asset(
- Assets.svg.radioProblem,
- height: 14,
- width: 14,
- color: Theme.of(context)
- .extension()!
- .accentColorRed,
- ),
- ),
- ),
- SizedBox(
- width: _boxPadding,
- ),
- Column(
- children: [
- SizedBox(
- width: progressLength,
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Unable to synchronize",
- style:
- STextStyles.w600_10(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .accentColorRed,
- ),
- ),
- Text(
- "0%",
- style: STextStyles.syncPercent(context)
- .copyWith(
- color: Theme.of(context)
- .extension()!
- .accentColorRed,
- ),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: 4,
- ),
- ProgressBar(
- width: progressLength,
- height: 5,
- fillColor: Theme.of(context)
- .extension()!
- .accentColorRed,
- backgroundColor: Theme.of(context)
- .extension()!
- .textFieldDefaultBG,
- percent: 0,
- ),
- ],
- ),
- ],
- ),
- ),
- if (_currentSyncStatus == WalletSyncStatus.unableToSync)
- Padding(
- padding: const EdgeInsets.only(
- top: 12,
- ),
- child: RoundedContainer(
- color: Theme.of(context)
- .extension()!
- .warningBackground,
- child: Text(
- "Please check your internet connection and make sure your current node is not having issues.",
- style: STextStyles.baseXS(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .warningForeground,
- ),
- ),
- ),
- ),
- const SizedBox(
- height: 20,
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).coin)).prettyName} nodes",
- textAlign: TextAlign.left,
- style: STextStyles.smallMed12(context),
- ),
- BlueTextButton(
- text: "Add new node",
- onTap: () {
- Navigator.of(context).pushNamed(
- AddEditNodeView.routeName,
- arguments: Tuple4(
- AddEditNodeViewType.add,
- ref
- .read(walletsChangeNotifierProvider)
- .getManager(widget.walletId)
- .coin,
- null,
- WalletNetworkSettingsView.routeName,
- ),
);
},
- ),
- ],
+ );
+ },
),
- const SizedBox(
- height: 8,
- ),
- NodesList(
- coin: ref.watch(walletsChangeNotifierProvider.select(
- (value) => value.getManager(widget.walletId).coin)),
- popBackToRoute: WalletNetworkSettingsView.routeName,
- ),
- ],
+ ),
),
],
),
- ),
+ body: Padding(
+ padding: EdgeInsets.only(
+ top: 12,
+ left: _padding,
+ right: _padding,
+ ),
+ child: SingleChildScrollView(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ child,
+ ],
+ ),
+ ),
+ ),
+ );
+ },
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Blockchain status",
+ textAlign: TextAlign.left,
+ style: isDesktop
+ ? STextStyles.desktopTextExtraExtraSmall(context)
+ : STextStyles.smallMed12(context),
+ ),
+ GestureDetector(
+ onTap: () {
+ ref
+ .read(walletsChangeNotifierProvider)
+ .getManager(widget.walletId)
+ .refresh();
+ },
+ child: Text(
+ "Resync",
+ style: STextStyles.link2(context),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(
+ height: isDesktop ? 12 : 9,
+ ),
+ if (_currentSyncStatus == WalletSyncStatus.synced)
+ RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context).extension()!.background
+ : null,
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ child: Row(
+ children: [
+ Container(
+ width: _iconSize,
+ height: _iconSize,
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorGreen
+ .withOpacity(0.2),
+ borderRadius: BorderRadius.circular(_iconSize),
+ ),
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.radio,
+ height: isDesktop ? 19 : 14,
+ width: isDesktop ? 19 : 14,
+ color: Theme.of(context)
+ .extension()!
+ .accentColorGreen,
+ ),
+ ),
+ ),
+ SizedBox(
+ width: _boxPadding,
+ ),
+ Column(
+ children: [
+ SizedBox(
+ width: progressLength,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Synchronized",
+ style: STextStyles.w600_10(context),
+ ),
+ Text(
+ "100%",
+ style: STextStyles.syncPercent(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorGreen,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ ProgressBar(
+ width: progressLength,
+ height: 5,
+ fillColor: Theme.of(context)
+ .extension()!
+ .accentColorGreen,
+ backgroundColor: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ percent: 1,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ if (_currentSyncStatus == WalletSyncStatus.syncing)
+ RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context).extension()!.background
+ : null,
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ child: Row(
+ children: [
+ Container(
+ width: _iconSize,
+ height: _iconSize,
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorYellow
+ .withOpacity(0.2),
+ borderRadius: BorderRadius.circular(_iconSize),
+ ),
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.radioSyncing,
+ height: 14,
+ width: 14,
+ color: Theme.of(context)
+ .extension()!
+ .accentColorYellow,
+ ),
+ ),
+ ),
+ SizedBox(
+ width: _boxPadding,
+ ),
+ Column(
+ children: [
+ SizedBox(
+ width: progressLength,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ AnimatedText(
+ style: STextStyles.w600_10(context),
+ stringsToLoopThrough: const [
+ "Synchronizing",
+ "Synchronizing.",
+ "Synchronizing..",
+ "Synchronizing...",
+ ],
+ ),
+ Row(
+ children: [
+ Text(
+ _percentString(_percent),
+ style:
+ STextStyles.syncPercent(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorYellow,
+ ),
+ ),
+ if (coin == Coin.monero ||
+ coin == Coin.wownero ||
+ coin == Coin.epicCash)
+ Text(
+ " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
+ style: STextStyles.syncPercent(context)
+ .copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorYellow,
+ ),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ ProgressBar(
+ width: progressLength,
+ height: 5,
+ fillColor: Theme.of(context)
+ .extension()!
+ .accentColorYellow,
+ backgroundColor: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ percent: _percent,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ if (_currentSyncStatus == WalletSyncStatus.unableToSync)
+ RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context).extension()!.background
+ : null,
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ child: Row(
+ children: [
+ Container(
+ width: _iconSize,
+ height: _iconSize,
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorRed
+ .withOpacity(0.2),
+ borderRadius: BorderRadius.circular(_iconSize),
+ ),
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.radioProblem,
+ height: 14,
+ width: 14,
+ color: Theme.of(context)
+ .extension()!
+ .accentColorRed,
+ ),
+ ),
+ ),
+ SizedBox(
+ width: _boxPadding,
+ ),
+ Column(
+ children: [
+ SizedBox(
+ width: progressLength,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Unable to synchronize",
+ style: STextStyles.w600_10(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorRed,
+ ),
+ ),
+ Text(
+ "0%",
+ style: STextStyles.syncPercent(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .accentColorRed,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ ProgressBar(
+ width: progressLength,
+ height: 5,
+ fillColor: Theme.of(context)
+ .extension()!
+ .accentColorRed,
+ backgroundColor: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ percent: 0,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ if (_currentSyncStatus == WalletSyncStatus.unableToSync)
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 12,
+ ),
+ child: RoundedContainer(
+ color: Theme.of(context)
+ .extension()!
+ .warningBackground,
+ child: Text(
+ "Please check your internet connection and make sure your current node is not having issues.",
+ style: STextStyles.baseXS(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .warningForeground,
+ ),
+ ),
+ ),
+ ),
+ SizedBox(
+ height: isDesktop ? 32 : 20,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).coin)).prettyName} nodes",
+ textAlign: TextAlign.left,
+ style: isDesktop
+ ? STextStyles.desktopTextExtraExtraSmall(context)
+ : STextStyles.smallMed12(context),
+ ),
+ BlueTextButton(
+ text: "Add new node",
+ onTap: () {
+ Navigator.of(context).pushNamed(
+ AddEditNodeView.routeName,
+ arguments: Tuple4(
+ AddEditNodeViewType.add,
+ ref
+ .read(walletsChangeNotifierProvider)
+ .getManager(widget.walletId)
+ .coin,
+ null,
+ WalletNetworkSettingsView.routeName,
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ SizedBox(
+ height: isDesktop ? 12 : 8,
+ ),
+ NodesList(
+ coin: ref.watch(walletsChangeNotifierProvider
+ .select((value) => value.getManager(widget.walletId).coin)),
+ popBackToRoute: WalletNetworkSettingsView.routeName,
+ ),
+ if (isDesktop)
+ const SizedBox(
+ height: 32,
+ ),
+ if (isDesktop)
+ Padding(
+ padding: const EdgeInsets.only(
+ bottom: 12,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Text(
+ "Advanced",
+ textAlign: TextAlign.left,
+ style: STextStyles.desktopTextExtraExtraSmall(context),
+ ),
+ ],
+ ),
+ ),
+ if (isDesktop)
+ RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context).extension()!.background
+ : null,
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ child: Expandable(
+ onExpandChanged: (state) {
+ setState(() {
+ _advancedIsExpanded = state == ExpandableState.expanded;
+ });
+ },
+ header: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ Container(
+ width: _iconSize,
+ height: _iconSize,
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ borderRadius: BorderRadius.circular(_iconSize),
+ ),
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.networkWired,
+ width: 24,
+ color: Theme.of(context)
+ .extension()!
+ .textDark,
+ ),
+ ),
+ ),
+ const SizedBox(
+ width: 10,
+ ),
+ Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "Advanced",
+ style: STextStyles.desktopTextExtraExtraSmall(
+ context)
+ .copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textDark,
+ ),
+ ),
+ Text(
+ "Rescan blockchain",
+ style: STextStyles.desktopTextExtraExtraSmall(
+ context),
+ ),
+ ],
+ )
+ ],
+ ),
+ SvgPicture.asset(
+ _advancedIsExpanded
+ ? Assets.svg.chevronDown
+ : Assets.svg.chevronUp,
+ width: 12,
+ height: 6,
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ],
+ ),
+ body: Row(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(
+ left: 50,
+ top: 16,
+ bottom: 6,
+ ),
+ child: BlueTextButton(
+ text: "Rescan",
+ onTap: () async {
+ await Navigator.of(context).push(
+ FadePageRoute(
+ ConfirmFullRescanDialog(
+ onConfirm: _attemptRescan,
+ ),
+ const RouteSettings(),
+ ),
+ );
+ // await showDialog(
+ // context: context,
+ // builder: (context) {
+ // return ConfirmFullRescanDialog(
+ // onConfirm: _attemptRescan,
+ // );
+ // },
+ // );
+ },
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
),
);
}
diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart
index 7e981b91a..fd6f60def 100644
--- a/lib/pages/stack_privacy_calls.dart
+++ b/lib/pages/stack_privacy_calls.dart
@@ -285,6 +285,7 @@ class _PrivacyToggleState extends State {
children: [
Expanded(
child: RawMaterialButton(
+ elevation: 0,
fillColor: Theme.of(context).extension()!.popupBG,
shape: RoundedRectangleBorder(
side: !externalCallsEnabled
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 d1e415b26..6f23f2e01 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -25,6 +25,7 @@ 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/conditional_parent.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';
@@ -260,11 +261,19 @@ class _TransactionDetailsViewState
bottom: 32,
)
: const EdgeInsets.all(0),
- child: RoundedWhiteContainer(
- borderColor: isDesktop
- ? Theme.of(context).extension()!.background
- : null,
- padding: const EdgeInsets.all(0),
+ child: ConditionalParent(
+ condition: isDesktop,
+ builder: (child) {
+ return RoundedWhiteContainer(
+ borderColor: isDesktop
+ ? Theme.of(context)
+ .extension()!
+ .background
+ : null,
+ padding: const EdgeInsets.all(0),
+ child: child,
+ );
+ },
child: SingleChildScrollView(
primary: isDesktop ? false : null,
child: Padding(
diff --git a/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart
deleted file mode 100644
index e69de29bb..000000000
diff --git a/lib/pages_desktop_specific/home/desktop_settings_view.dart b/lib/pages_desktop_specific/home/desktop_settings_view.dart
index 34cb07f27..63e1ee613 100644
--- a/lib/pages_desktop_specific/home/desktop_settings_view.dart
+++ b/lib/pages_desktop_specific/home/desktop_settings_view.dart
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
index 830b5e667..c001f9bf3 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/network_info_button.dart
@@ -6,12 +6,16 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.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/utilities/util.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:tuple/tuple.dart';
class NetworkInfoButton extends ConsumerStatefulWidget {
@@ -150,14 +154,116 @@ class _NetworkInfoButtonState extends ConsumerState {
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
- Navigator.of(context).pushNamed(
- WalletNetworkSettingsView.routeName,
- arguments: Tuple3(
- walletId,
- _currentSyncStatus,
- _currentNodeStatus,
- ),
- );
+ if (Util.isDesktop) {
+ // showDialog(
+ // context: context,
+ // builder: (context) => DesktopDialog(
+ // maxHeight: MediaQuery.of(context).size.height - 64,
+ // maxWidth: 580,
+ // child: Column(
+ // mainAxisSize: MainAxisSize.min,
+ // children: [
+ // Padding(
+ // padding: const EdgeInsets.only(
+ // left: 32,
+ // ),
+ // child: Row(
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ // children: [
+ // Text(
+ // "Network",
+ // style: STextStyles.desktopH3(context),
+ // ),
+ // const DesktopDialogCloseButton(),
+ // ],
+ // ),
+ // ),
+ // Padding(
+ // padding: const EdgeInsets.only(
+ // top: 16,
+ // left: 32,
+ // right: 32,
+ // bottom: 32,
+ // ),
+ // child: WalletNetworkSettingsView(
+ // walletId: walletId,
+ // initialSyncStatus: _currentSyncStatus,
+ // initialNodeStatus: _currentNodeStatus,
+ // ),
+ // ),
+ // ],
+ // ),
+ // ),
+ // );
+
+ showDialog(
+ context: context,
+ builder: (context) => Navigator(
+ initialRoute: WalletNetworkSettingsView.routeName,
+ onGenerateRoute: RouteGenerator.generateRoute,
+ onGenerateInitialRoutes: (_, __) {
+ return [
+ FadePageRoute(
+ DesktopDialog(
+ maxHeight: MediaQuery.of(context).size.height - 64,
+ maxWidth: 580,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(
+ left: 32,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Network",
+ style: STextStyles.desktopH3(context),
+ ),
+ DesktopDialogCloseButton(
+ onPressedOverride: Navigator.of(
+ context,
+ rootNavigator: true,
+ ).pop,
+ ),
+ ],
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(
+ top: 16,
+ left: 32,
+ right: 32,
+ bottom: 32,
+ ),
+ child: WalletNetworkSettingsView(
+ walletId: walletId,
+ initialSyncStatus: _currentSyncStatus,
+ initialNodeStatus: _currentNodeStatus,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const RouteSettings(
+ name: WalletNetworkSettingsView.routeName,
+ ),
+ ),
+ ];
+ },
+ ),
+ );
+ } else {
+ Navigator.of(context).pushNamed(
+ WalletNetworkSettingsView.routeName,
+ arguments: Tuple3(
+ walletId,
+ _currentSyncStatus,
+ _currentNodeStatus,
+ ),
+ );
+ }
},
child: Container(
color: Colors.transparent,
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
index 37f047eed..e65820737 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart
@@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@@ -22,6 +21,8 @@ class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
final String walletId;
+ static const String routeName = "/desktopUnlockWalletKeys";
+
@override
ConsumerState createState() =>
_UnlockWalletKeysDesktopState();
@@ -59,8 +60,13 @@ class _UnlockWalletKeysDesktopState
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
- children: const [
- DesktopDialogCloseButton(),
+ children: [
+ DesktopDialogCloseButton(
+ onPressedOverride: Navigator.of(
+ context,
+ rootNavigator: true,
+ ).pop,
+ ),
],
),
const SizedBox(
@@ -175,7 +181,10 @@ class _UnlockWalletKeysDesktopState
Expanded(
child: SecondaryButton(
label: "Cancel",
- onPressed: Navigator.of(context).pop,
+ onPressed: Navigator.of(
+ context,
+ rootNavigator: true,
+ ).pop,
),
),
const SizedBox(
@@ -188,29 +197,35 @@ class _UnlockWalletKeysDesktopState
onPressed: continueEnabled
? () async {
// todo: check password
- Navigator.of(context).pop();
+ // Navigator.of(context).pop();
final words = await ref
.read(walletsChangeNotifierProvider)
.getManager(widget.walletId)
.mnemonic;
- await showDialog(
- context: context,
- barrierDismissible: false,
- builder: (context) => Navigator(
- initialRoute: WalletKeysDesktopPopup.routeName,
- onGenerateRoute: RouteGenerator.generateRoute,
- onGenerateInitialRoutes: (_, __) {
- return [
- RouteGenerator.generateRoute(
- RouteSettings(
- name: WalletKeysDesktopPopup.routeName,
- arguments: words,
- ),
- )
- ];
- },
- ),
+
+ await Navigator.of(context).pushReplacementNamed(
+ WalletKeysDesktopPopup.routeName,
+ arguments: words,
);
+ //
+ // await showDialog(
+ // context: context,
+ // barrierDismissible: false,
+ // builder: (context) => Navigator(
+ // initialRoute: WalletKeysDesktopPopup.routeName,
+ // onGenerateRoute: RouteGenerator.generateRoute,
+ // onGenerateInitialRoutes: (_, __) {
+ // return [
+ // RouteGenerator.generateRoute(
+ // RouteSettings(
+ // name: WalletKeysDesktopPopup.routeName,
+ // arguments: words,
+ // ),
+ // )
+ // ];
+ // },
+ // ),
+ // );
}
: null,
),
diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
index d4921276d..649433d52 100644
--- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
+++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_button.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
+import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -20,10 +21,29 @@ class WalletKeysButton extends StatelessWidget {
showDialog(
context: context,
barrierDismissible: false,
- builder: (context) => UnlockWalletKeysDesktop(
- walletId: walletId,
+ builder: (context) => Navigator(
+ initialRoute: UnlockWalletKeysDesktop.routeName,
+ onGenerateRoute: RouteGenerator.generateRoute,
+ onGenerateInitialRoutes: (_, __) {
+ return [
+ RouteGenerator.generateRoute(
+ RouteSettings(
+ name: UnlockWalletKeysDesktop.routeName,
+ arguments: walletId,
+ ),
+ )
+ ];
+ },
),
);
+
+ // showDialog(
+ // context: context,
+ // barrierDismissible: false,
+ // builder: (context) => UnlockWalletKeysDesktop(
+ // walletId: walletId,
+ // ),
+ // );
},
child: Container(
color: Colors.transparent,
diff --git a/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
similarity index 93%
rename from lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
rename to lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
index 7361d9773..1632576fd 100644
--- a/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart
@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
@@ -165,7 +166,7 @@ class _AdvancedSettings extends ConsumerState {
.textDark),
textAlign: TextAlign.left,
),
- const ShowLogsButton(),
+ ShowLogsButton(),
],
),
),
@@ -190,7 +191,7 @@ class StackPrivacyButton extends ConsumerWidget {
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
- return const StackPrivacyDialog();
+ return StackPrivacyDialog();
},
);
}
@@ -223,20 +224,19 @@ class ShowLogsButton extends ConsumerWidget {
const ShowLogsButton({
Key? key,
}) : super(key: key);
-
- Future viewDebugLogs() async {
- // await showDialog(
- // context: context,
- // useSafeArea: false,
- // barrierDismissible: true,
- // builder: (context) {
- // return const DebugInfoDialog();
- // },
- // );
- }
-
@override
Widget build(BuildContext context, WidgetRef ref) {
+ // Future viewDebugLogs() async {
+ // await showDialog(
+ // context: context,
+ // useSafeArea: false,
+ // barrierDismissible: true,
+ // builder: (context) {
+ // return const DebugInfoDialog();
+ // },
+ // );
+ // }
+
return SizedBox(
width: 101,
height: 37,
@@ -246,7 +246,7 @@ class ShowLogsButton extends ConsumerWidget {
.getPrimaryEnabledButtonColor(context),
onPressed: () {
//
- viewDebugLogs();
+ // viewDebugLogs();
},
child: Text(
"Show logs",
diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
new file mode 100644
index 000000000..342d9180a
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/debug_info_dialog.dart
@@ -0,0 +1,188 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/isar/models/log.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+
+// import '../../../utilities/assets.dart';
+// import '../../../utilities/util.dart';
+// import '../../../widgets/icon_widgets/x_icon.dart';
+// import '../../../widgets/stack_text_field.dart';
+// import '../../../widgets/textfield_icon_button.dart';
+
+class DebugInfoDialog extends StatefulWidget {
+ const DebugInfoDialog({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _DebugInfoDialog();
+}
+
+class _DebugInfoDialog extends State {
+ final _searchController = TextEditingController();
+ final _searchFocusNode = FocusNode();
+
+ final scrollController = ScrollController();
+
+ String _searchTerm = "";
+
+ List filtered(List unfiltered, String filter) {
+ if (filter == "") {
+ return unfiltered;
+ }
+ return unfiltered
+ .where(
+ (e) => (e.toString().toLowerCase().contains(filter.toLowerCase())))
+ .toList();
+ }
+
+ BorderRadius? _borderRadius(int index, int listLength) {
+ if (index == 0 && listLength == 1) {
+ return BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ );
+ } else if (index == 0) {
+ return BorderRadius.vertical(
+ bottom: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ } else if (index == listLength - 1) {
+ return BorderRadius.vertical(
+ top: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ }
+ return null;
+ }
+
+ @override
+ void initState() {
+ // ref.read(debugServiceProvider).updateRecentLogs();
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ _searchController.dispose();
+ scrollController.dispose();
+ _searchFocusNode.dispose();
+
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return DesktopDialog(
+ maxHeight: 800,
+ maxWidth: 600,
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Text(
+ "Debug info",
+ style: STextStyles.desktopH3(context),
+ textAlign: TextAlign.center,
+ ),
+ ),
+ const DesktopDialogCloseButton(),
+ ],
+ ),
+ Row(
+ children: [
+ // ClipRRect(
+ // borderRadius: BorderRadius.circular(
+ // Constants.size.circularBorderRadius,
+ // ),
+ // child: TextField(
+ // key: const Key("desktopSettingDebugInfo"),
+ // autocorrect: Util.isDesktop ? false : true,
+ // enableSuggestions: Util.isDesktop ? false : true,
+ // controller: _searchController,
+ // focusNode: _searchFocusNode,
+ // // onChanged: (newString) {
+ // // setState(() => _searchTerm = newString);
+ // // },
+ // style: STextStyles.field(context),
+ // decoration: standardInputDecoration(
+ // "Search",
+ // _searchFocusNode,
+ // context,
+ // ).copyWith(
+ // prefixIcon: Padding(
+ // padding: const EdgeInsets.symmetric(
+ // horizontal: 10,
+ // vertical: 16,
+ // ),
+ // child: SvgPicture.asset(
+ // Assets.svg.search,
+ // width: 16,
+ // height: 16,
+ // ),
+ // ),
+ // suffixIcon: _searchController.text.isNotEmpty
+ // ? Padding(
+ // padding: const EdgeInsets.only(right: 0),
+ // child: UnconstrainedBox(
+ // child: Row(
+ // children: [
+ // TextFieldIconButton(
+ // child: const XIcon(),
+ // onTap: () async {
+ // setState(() {
+ // _searchController.text = "";
+ // _searchTerm = "";
+ // });
+ // },
+ // ),
+ // ],
+ // ),
+ // ),
+ // )
+ // : null,
+ // ),
+ // ),
+ // ),
+ ],
+ ),
+ // Column(
+ // children: [
+ //
+ // ],
+ // ),
+ const Spacer(),
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Row(
+ children: [
+ Expanded(
+ child: SecondaryButton(
+ label: "Clear logs",
+ onPressed: () {},
+ ),
+ ),
+ const SizedBox(
+ width: 16,
+ ),
+ Expanded(
+ child: PrimaryButton(
+ label: "Save logs to file",
+ onPressed: () {},
+ ),
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
similarity index 96%
rename from lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
rename to lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
index 8e385fd37..32c20c010 100644
--- a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/advanced_settings/stack_privacy_dialog.dart
@@ -3,21 +3,20 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/hive/db.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/providers/global/price_provider.dart';
+import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
+import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-
-import '../../../hive/db.dart';
-import '../../../providers/global/prefs_provider.dart';
-import '../../../providers/global/price_provider.dart';
-import '../../../services/exchange/exchange_data_loading_service.dart';
-import '../../../utilities/assets.dart';
-import '../../../utilities/constants.dart';
-import '../../../utilities/theme/stack_colors.dart';
-import '../../../utilities/util.dart';
-import '../../../widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
class StackPrivacyDialog extends ConsumerStatefulWidget {
const StackPrivacyDialog({Key? key}) : super(key: key);
diff --git a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
index 16bda2ff7..f3e502bcb 100644
--- a/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/backup_and_restore/create_auto_backup.dart
@@ -40,20 +40,6 @@ class _CreateAutoBackup extends State {
"Every 30 minutes",
];
- // List> get dropdownItems {
- // List> menuItems = [
- // const DropdownMenuItem(
- // value: "Every 10 minutes",
- // child: Text("Every 10 minutes"),
- // ),
- // const DropdownMenuItem(
- // value: "Every 20 minutes",
- // child: Text("Every 20 minutes"),
- // ),
- // ];
- // return menuItems;
- // }
-
@override
void initState() {
fileLocationController = TextEditingController();
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
new file mode 100644
index 000000000..bbe98c1af
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_dialog.dart
@@ -0,0 +1,371 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/base_currencies_provider.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/utilities/assets.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/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+import 'package:stackwallet/widgets/textfield_icon_button.dart';
+
+class CurrencyDialog extends ConsumerStatefulWidget {
+ const CurrencyDialog({Key? key}) : super(key: key);
+
+ @override
+ ConsumerState createState() => _CurrencyDialog();
+}
+
+class _CurrencyDialog extends ConsumerState {
+ late String current;
+ late List currenciesWithoutSelected;
+
+ late final TextEditingController searchCurrencyController;
+
+ late final FocusNode searchCurrencyFocusNode;
+
+ void onTap(int index) {
+ if (currenciesWithoutSelected[index] == current || current.isEmpty) {
+ // ignore if already selected currency
+ return;
+ }
+ current = currenciesWithoutSelected[index];
+ currenciesWithoutSelected.remove(current);
+ currenciesWithoutSelected.insert(0, current);
+ ref.read(prefsChangeNotifierProvider).currency = current;
+ }
+
+ BorderRadius? _borderRadius(int index) {
+ if (index == 0 && currenciesWithoutSelected.length == 1) {
+ return BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ );
+ } else if (index == 0) {
+ return BorderRadius.vertical(
+ top: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ } else if (index == currenciesWithoutSelected.length - 1) {
+ return BorderRadius.vertical(
+ bottom: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ }
+ return null;
+ }
+
+ String filter = "";
+
+ List _filtered() {
+ final currencyMap = ref.read(baseCurrenciesProvider).map;
+ return currenciesWithoutSelected.where((element) {
+ return element.toLowerCase().contains(filter.toLowerCase()) ||
+ (currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
+ false);
+ }).toList();
+ }
+
+ @override
+ void initState() {
+ searchCurrencyController = TextEditingController();
+
+ searchCurrencyFocusNode = FocusNode();
+
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ searchCurrencyController.dispose();
+
+ searchCurrencyFocusNode.dispose();
+
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ current = ref
+ .watch(prefsChangeNotifierProvider.select((value) => value.currency));
+
+ currenciesWithoutSelected = ref
+ .watch(baseCurrenciesProvider.select((value) => value.map))
+ .keys
+ .toList();
+ if (current.isNotEmpty) {
+ currenciesWithoutSelected.remove(current);
+ currenciesWithoutSelected.insert(0, current);
+ }
+ currenciesWithoutSelected = _filtered();
+
+ return DesktopDialog(
+ maxHeight: 800,
+ maxWidth: 600,
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Text(
+ "Select currency",
+ style: STextStyles.desktopH3(context),
+ textAlign: TextAlign.center,
+ ),
+ ),
+ const DesktopDialogCloseButton(),
+ ],
+ ),
+ Expanded(
+ flex: 24,
+ child: NestedScrollView(
+ floatHeaderSlivers: true,
+ headerSliverBuilder: (context, innerBoxIsScrolled) {
+ return [
+ SliverOverlapAbsorber(
+ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+ context),
+ sliver: SliverToBoxAdapter(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ vertical: 16, horizontal: 32),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(bottom: 16),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ child: TextField(
+ autocorrect: Util.isDesktop ? false : true,
+ enableSuggestions:
+ Util.isDesktop ? false : true,
+ controller: searchCurrencyController,
+ focusNode: searchCurrencyFocusNode,
+ onChanged: (newString) {
+ setState(() => filter = newString);
+ },
+ style: STextStyles.field(context),
+ decoration: standardInputDecoration(
+ "Search",
+ searchCurrencyFocusNode,
+ context,
+ ).copyWith(
+ prefixIcon: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 10,
+ vertical: 16,
+ ),
+ child: SvgPicture.asset(
+ Assets.svg.search,
+ width: 16,
+ height: 16,
+ ),
+ ),
+ suffixIcon: searchCurrencyController
+ .text.isNotEmpty
+ ? Padding(
+ padding:
+ const EdgeInsets.only(right: 0),
+ child: UnconstrainedBox(
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ searchCurrencyController
+ .text = "";
+ filter = "";
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ )
+ : null,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ];
+ },
+ body: Builder(
+ builder: (context) {
+ return CustomScrollView(
+ slivers: [
+ SliverOverlapInjector(
+ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+ context,
+ ),
+ ),
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (context, index) {
+ return Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .popupBG,
+ borderRadius: _borderRadius(index),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(4),
+ key: Key(
+ "desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 32),
+ child: RoundedContainer(
+ padding: const EdgeInsets.all(0),
+ color: currenciesWithoutSelected[index] ==
+ current
+ ? Theme.of(context)
+ .extension()!
+ .currencyListItemBG
+ : Theme.of(context)
+ .extension()!
+ .popupBG,
+ child: RawMaterialButton(
+ onPressed: () async {
+ onTap(index);
+ },
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: Row(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ SizedBox(
+ width: 20,
+ height: 20,
+ child: Radio(
+ activeColor: Theme.of(context)
+ .extension()!
+ .radioButtonIconEnabled,
+ materialTapTargetSize:
+ MaterialTapTargetSize
+ .shrinkWrap,
+ value: true,
+ groupValue:
+ currenciesWithoutSelected[
+ index] ==
+ current,
+ onChanged: (_) {
+ onTap(index);
+ },
+ ),
+ ),
+ const SizedBox(
+ width: 12,
+ ),
+ Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Text(
+ currenciesWithoutSelected[
+ index],
+ key: (currenciesWithoutSelected[
+ index] ==
+ current)
+ ? const Key(
+ "desktopSettingsSelectedCurrencyText")
+ : null,
+ style:
+ STextStyles.largeMedium14(
+ context),
+ ),
+ const SizedBox(
+ height: 2,
+ ),
+ Text(
+ ref.watch(baseCurrenciesProvider
+ .select((value) =>
+ value.map))[
+ currenciesWithoutSelected[
+ index]] ??
+ "",
+ key: (currenciesWithoutSelected[
+ index] ==
+ current)
+ ? const Key(
+ "desktopSelectedCurrencyTextDescription")
+ : null,
+ style:
+ STextStyles.itemSubtitle(
+ context),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ childCount: currenciesWithoutSelected.length,
+ ),
+ ),
+ ],
+ );
+ },
+ ),
+ ),
+ ),
+ const Spacer(),
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Row(
+ children: [
+ Expanded(
+ child: SecondaryButton(
+ label: "Cancel",
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ ),
+ const SizedBox(
+ width: 16,
+ ),
+ Expanded(
+ child: PrimaryButton(
+ label: "Save Changes",
+ onPressed: () {},
+ ),
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
new file mode 100644
index 000000000..b8ce76d25
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart
@@ -0,0 +1,117 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.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/rounded_white_container.dart';
+
+import 'currency_dialog.dart';
+
+class CurrencySettings extends ConsumerStatefulWidget {
+ const CurrencySettings({Key? key}) : super(key: key);
+
+ static const String routeName = "/settingsMenuCurrency";
+
+ @override
+ ConsumerState createState() => _CurrencySettings();
+}
+
+class _CurrencySettings extends ConsumerState {
+ @override
+ Widget build(BuildContext context) {
+ debugPrint("BUILD: $runtimeType");
+ return Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(
+ right: 30,
+ ),
+ child: RoundedWhiteContainer(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SvgPicture.asset(
+ Assets.svg.circleDollarSign,
+ width: 48,
+ height: 48,
+ ),
+ Center(
+ child: Padding(
+ padding: const EdgeInsets.all(10),
+ child: RichText(
+ textAlign: TextAlign.start,
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: "Currency",
+ style: STextStyles.desktopTextSmall(context),
+ ),
+ TextSpan(
+ text:
+ "\n\nProtect your Stack Wallet with a strong password. Stack Wallet does not store "
+ "your password, and is therefore NOT able to restore it. Keep your password safe and secure.",
+ style:
+ STextStyles.desktopTextExtraExtraSmall(context),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: const [
+ Padding(
+ padding: EdgeInsets.all(
+ 10,
+ ),
+ child: NewPasswordButton(),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
+
+class NewPasswordButton extends ConsumerWidget {
+ const NewPasswordButton({
+ Key? key,
+ }) : super(key: key);
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ Future chooseCurrency() async {
+ await showDialog(
+ context: context,
+ useSafeArea: false,
+ barrierDismissible: true,
+ builder: (context) {
+ return CurrencyDialog();
+ },
+ );
+ }
+
+ return SizedBox(
+ width: 200,
+ height: 48,
+ child: TextButton(
+ style: Theme.of(context)
+ .extension()!
+ .getPrimaryEnabledButtonColor(context),
+ onPressed: () {
+ chooseCurrency();
+ },
+ child: Text(
+ "Change currency",
+ style: STextStyles.button(context),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
new file mode 100644
index 000000000..d07c9729f
--- /dev/null
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart
@@ -0,0 +1,349 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/utilities/constants.dart';
+import 'package:stackwallet/utilities/enums/languages_enum.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/stack_text_field.dart';
+
+import '../../../../utilities/assets.dart';
+import '../../../../utilities/theme/stack_colors.dart';
+import '../../../../widgets/icon_widgets/x_icon.dart';
+import '../../../../widgets/rounded_container.dart';
+import '../../../../widgets/textfield_icon_button.dart';
+
+class LanguageDialog extends ConsumerStatefulWidget {
+ const LanguageDialog({Key? key}) : super(key: key);
+
+ @override
+ ConsumerState createState() => _LanguageDialog();
+}
+
+class _LanguageDialog extends ConsumerState {
+ late final TextEditingController searchLanguageController;
+
+ late final FocusNode searchLanguageFocusNode;
+
+ final languages = Language.values.map((e) => e.description).toList();
+
+ late String current;
+ late List listWithoutSelected;
+
+ void onTap(int index) {
+ if (index == 0 || current.isEmpty) {
+ // ignore if already selected language
+ return;
+ }
+ current = listWithoutSelected[index];
+ listWithoutSelected.remove(current);
+ listWithoutSelected.insert(0, current);
+ ref.read(prefsChangeNotifierProvider).language = current;
+ }
+
+ BorderRadius? _borderRadius(int index) {
+ if (index == 0 && listWithoutSelected.length == 1) {
+ return BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ );
+ } else if (index == 0) {
+ return BorderRadius.vertical(
+ top: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ } else if (index == listWithoutSelected.length - 1) {
+ return BorderRadius.vertical(
+ bottom: Radius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ );
+ }
+ return null;
+ }
+
+ String filter = "";
+
+ List _filtered() {
+ return listWithoutSelected
+ .where(
+ (element) => element.toLowerCase().contains(filter.toLowerCase()))
+ .toList();
+ }
+
+ @override
+ void initState() {
+ searchLanguageController = TextEditingController();
+
+ searchLanguageFocusNode = FocusNode();
+
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ searchLanguageController.dispose();
+
+ searchLanguageFocusNode.dispose();
+
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ current = ref
+ .watch(prefsChangeNotifierProvider.select((value) => value.language));
+
+ listWithoutSelected = languages;
+ if (current.isNotEmpty) {
+ listWithoutSelected.remove(current);
+ listWithoutSelected.insert(0, current);
+ }
+ listWithoutSelected = _filtered();
+
+ return DesktopDialog(
+ maxHeight: 700,
+ maxWidth: 600,
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Text(
+ "Select language",
+ style: STextStyles.desktopH3(context),
+ textAlign: TextAlign.center,
+ ),
+ ),
+ const DesktopDialogCloseButton(),
+ ],
+ ),
+ Expanded(
+ flex: 24,
+ child: NestedScrollView(
+ floatHeaderSlivers: true,
+ headerSliverBuilder: (context, innerBoxIsScrolled) {
+ return [
+ SliverOverlapAbsorber(
+ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+ context),
+ sliver: SliverToBoxAdapter(
+ child: Padding(
+ padding:
+ EdgeInsets.symmetric(vertical: 16, horizontal: 32),
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(bottom: 16),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ child: TextField(
+ autocorrect: false,
+ enableSuggestions: false,
+ controller: searchLanguageController,
+ focusNode: searchLanguageFocusNode,
+ style: STextStyles.desktopTextMedium(context)
+ .copyWith(
+ height: 2,
+ ),
+ textAlign: TextAlign.left,
+ decoration: standardInputDecoration("Search",
+ searchLanguageFocusNode, context)
+ .copyWith(
+ prefixIcon: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 10,
+ vertical: 16,
+ ),
+ child: SvgPicture.asset(
+ Assets.svg.search,
+ width: 16,
+ height: 16,
+ ),
+ ),
+ suffixIcon: searchLanguageController
+ .text.isNotEmpty
+ ? Padding(
+ padding:
+ const EdgeInsets.only(right: 0),
+ child: UnconstrainedBox(
+ child: Row(
+ children: [
+ TextFieldIconButton(
+ child: const XIcon(),
+ onTap: () async {
+ setState(() {
+ searchLanguageController
+ .text = "";
+ filter = "";
+ });
+ },
+ ),
+ ],
+ ),
+ ),
+ )
+ : null,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ];
+ },
+ body: Builder(
+ builder: (context) {
+ return CustomScrollView(
+ slivers: [
+ SliverOverlapInjector(
+ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
+ context,
+ ),
+ ),
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (context, index) {
+ return Container(
+ decoration: BoxDecoration(
+ color: Theme.of(context)
+ .extension()!
+ .popupBG,
+ borderRadius: _borderRadius(index),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(4),
+ key: Key(
+ "desktopSelectLanguage_${listWithoutSelected[index]}"),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 32),
+ child: RoundedContainer(
+ padding: const EdgeInsets.all(0),
+ color: index == 0
+ ? Theme.of(context)
+ .extension()!
+ .currencyListItemBG
+ : Theme.of(context)
+ .extension()!
+ .popupBG,
+ child: RawMaterialButton(
+ onPressed: () async {
+ onTap(index);
+ },
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(12.0),
+ child: Row(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ SizedBox(
+ width: 20,
+ height: 20,
+ child: Radio(
+ activeColor: Theme.of(context)
+ .extension()!
+ .radioButtonIconEnabled,
+ value: true,
+ groupValue: index == 0,
+ onChanged: (_) {
+ onTap(index);
+ },
+ ),
+ ),
+ const SizedBox(
+ width: 12,
+ ),
+ Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Text(
+ listWithoutSelected[index],
+ key: (index == 0)
+ ? const Key(
+ "desktopSettingsSelectedLanguageText")
+ : null,
+ style:
+ STextStyles.largeMedium14(
+ context),
+ ),
+ const SizedBox(
+ height: 2,
+ ),
+ Text(
+ listWithoutSelected[index],
+ key: (index == 0)
+ ? const Key(
+ "desktopSettingsSelectedLanguageTextDescription")
+ : null,
+ style:
+ STextStyles.itemSubtitle(
+ context),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ childCount: listWithoutSelected.length,
+ ),
+ ),
+ ],
+ );
+ },
+ ),
+ ),
+ ),
+ const Spacer(),
+ Padding(
+ padding: const EdgeInsets.all(32),
+ child: Row(
+ children: [
+ Expanded(
+ child: SecondaryButton(
+ label: "Cancel",
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ ),
+ const SizedBox(
+ width: 16,
+ ),
+ Expanded(
+ child: PrimaryButton(
+ label: "Save Changes",
+ onPressed: () {},
+ ),
+ )
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages_desktop_specific/home/settings_menu/language_settings.dart b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
similarity index 88%
rename from lib/pages_desktop_specific/home/settings_menu/language_settings.dart
rename to lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
index 7655188e1..97b807b3b 100644
--- a/lib/pages_desktop_specific/home/settings_menu/language_settings.dart
+++ b/lib/pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
@@ -87,6 +88,17 @@ class ChangeLanguageButton extends ConsumerWidget {
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
+ Future chooseLanguage() async {
+ await showDialog(
+ context: context,
+ useSafeArea: false,
+ barrierDismissible: true,
+ builder: (context) {
+ return LanguageDialog();
+ },
+ );
+ }
+
return SizedBox(
width: 200,
height: 48,
@@ -94,7 +106,9 @@ class ChangeLanguageButton extends ConsumerWidget {
style: Theme.of(context)
.extension()!
.getPrimaryEnabledButtonColor(context),
- onPressed: () {},
+ onPressed: () {
+ chooseLanguage();
+ },
child: Text(
"Change language",
style: STextStyles.button(context),
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 613e0d509..a6f23ffdc 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -85,17 +85,16 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
-import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';
-import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
+import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings/currency_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.dart';
@@ -107,6 +106,9 @@ import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:tuple/tuple.dart';
+import 'pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart';
+import 'pages_desktop_specific/home/settings_menu/language_settings/language_settings.dart';
+
class RouteGenerator {
static const bool useMaterialPageRoute = true;
@@ -1084,29 +1086,67 @@ class RouteGenerator {
case WalletKeysDesktopPopup.routeName:
if (args is List) {
- return getRoute(
- shouldUseMaterialRoute: useMaterialPageRoute,
- builder: (_) => WalletKeysDesktopPopup(
+ return FadePageRoute(
+ WalletKeysDesktopPopup(
words: args,
),
- settings: RouteSettings(
+ RouteSettings(
name: settings.name,
),
);
+ // return getRoute(
+ // shouldUseMaterialRoute: useMaterialPageRoute,
+ // builder: (_) => WalletKeysDesktopPopup(
+ // words: args,
+ // ),
+ // settings: RouteSettings(
+ // name: settings.name,
+ // ),
+ // );
+ }
+ return _routeError("${settings.name} invalid args: ${args.toString()}");
+
+ case UnlockWalletKeysDesktop.routeName:
+ if (args is String) {
+ return FadePageRoute(
+ UnlockWalletKeysDesktop(
+ walletId: args,
+ ),
+ RouteSettings(
+ name: settings.name,
+ ),
+ );
+ // return getRoute(
+ // shouldUseMaterialRoute: useMaterialPageRoute,
+ // builder: (_) => WalletKeysDesktopPopup(
+ // words: args,
+ // ),
+ // settings: RouteSettings(
+ // name: settings.name,
+ // ),
+ // );
}
return _routeError("${settings.name} invalid args: ${args.toString()}");
case QRCodeDesktopPopupContent.routeName:
if (args is String) {
- return getRoute(
- shouldUseMaterialRoute: useMaterialPageRoute,
- builder: (_) => QRCodeDesktopPopupContent(
+ return FadePageRoute(
+ QRCodeDesktopPopupContent(
value: args,
),
- settings: RouteSettings(
+ RouteSettings(
name: settings.name,
),
);
+ // return getRoute(
+ // shouldUseMaterialRoute: useMaterialPageRoute,
+ // builder: (_) => QRCodeDesktopPopupContent(
+ // value: args,
+ // ),
+ // settings: RouteSettings(
+ // name: settings.name,
+ // ),
+ // );
}
return _routeError("${settings.name} invalid args: ${args.toString()}");
@@ -1180,3 +1220,37 @@ class RouteGenerator {
builder: (_) => errorView);
}
}
+
+class FadePageRoute extends PageRoute {
+ FadePageRoute(this.child, RouteSettings settings) : _settings = settings;
+
+ final Widget child;
+ final RouteSettings _settings;
+
+ @override
+ Color? get barrierColor => null;
+
+ @override
+ String? get barrierLabel => null;
+
+ @override
+ Widget buildPage(
+ BuildContext context,
+ Animation animation,
+ Animation secondaryAnimation,
+ ) {
+ return FadeTransition(
+ opacity: animation,
+ child: child,
+ );
+ }
+
+ @override
+ bool get maintainState => true;
+
+ @override
+ Duration get transitionDuration => const Duration(milliseconds: 100);
+
+ @override
+ RouteSettings get settings => _settings;
+}
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index 78535c19b..386ea1cd8 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -101,6 +101,7 @@ class _SVG {
String get downloadFolder => "assets/svg/folder-down.svg";
String get lock => "assets/svg/lock-keyhole.svg";
String get network => "assets/svg/network-wired.svg";
+ String get networkWired => "assets/svg/network-wired-2.svg";
String get addressBook => "assets/svg/address-book.svg";
String get addressBook2 => "assets/svg/address-book2.svg";
String get arrowRotate3 => "assets/svg/rotate-exclamation.svg";
diff --git a/lib/widgets/conditional_parent.dart b/lib/widgets/conditional_parent.dart
index 6db50c6e8..757c8f992 100644
--- a/lib/widgets/conditional_parent.dart
+++ b/lib/widgets/conditional_parent.dart
@@ -4,13 +4,13 @@ class ConditionalParent extends StatelessWidget {
const ConditionalParent({
Key? key,
required this.condition,
- required this.child,
required this.builder,
+ required this.child,
}) : super(key: key);
final bool condition;
- final Widget child;
final Widget Function(Widget) builder;
+ final Widget child;
@override
Widget build(BuildContext context) {
diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart
index 18757ab93..aa7f75b1f 100644
--- a/lib/widgets/custom_buttons/blue_text_button.dart
+++ b/lib/widgets/custom_buttons/blue_text_button.dart
@@ -5,11 +5,16 @@ import 'package:stackwallet/providers/ui/color_theme_provider.dart';
import 'package:stackwallet/utilities/text_styles.dart';
class BlueTextButton extends ConsumerStatefulWidget {
- const BlueTextButton({Key? key, required this.text, this.onTap})
- : super(key: key);
+ const BlueTextButton({
+ Key? key,
+ required this.text,
+ this.onTap,
+ this.enabled = true,
+ }) : super(key: key);
final String text;
final VoidCallback? onTap;
+ final bool enabled;
@override
ConsumerState createState() => _BlueTextButtonState();
@@ -17,38 +22,42 @@ class BlueTextButton extends ConsumerStatefulWidget {
class _BlueTextButtonState extends ConsumerState
with SingleTickerProviderStateMixin {
- late AnimationController controller;
- late Animation animation;
+ AnimationController? controller;
+ Animation? animation;
late Color color;
@override
void initState() {
- color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
- controller = AnimationController(
- vsync: this,
- duration: const Duration(milliseconds: 100),
- );
- animation = ColorTween(
- begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless,
- end: ref
- .read(colorThemeProvider.state)
- .state
- .buttonTextBorderless
- .withOpacity(0.4),
- ).animate(controller);
+ if (widget.enabled) {
+ color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
+ controller = AnimationController(
+ vsync: this,
+ duration: const Duration(milliseconds: 100),
+ );
+ animation = ColorTween(
+ begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless,
+ end: ref
+ .read(colorThemeProvider.state)
+ .state
+ .buttonTextBorderless
+ .withOpacity(0.4),
+ ).animate(controller!);
- animation.addListener(() {
- setState(() {
- color = animation.value as Color;
+ animation!.addListener(() {
+ setState(() {
+ color = animation!.value as Color;
+ });
});
- });
+ } else {
+ color = ref.read(colorThemeProvider.state).state.textSubtitle1;
+ }
super.initState();
}
@override
void dispose() {
- controller.dispose();
+ controller?.dispose();
super.dispose();
}
@@ -59,11 +68,13 @@ class _BlueTextButtonState extends ConsumerState
text: TextSpan(
text: widget.text,
style: STextStyles.link2(context).copyWith(color: color),
- recognizer: TapGestureRecognizer()
- ..onTap = () {
- widget.onTap?.call();
- controller.forward().then((value) => controller.reverse());
- },
+ recognizer: widget.enabled
+ ? (TapGestureRecognizer()
+ ..onTap = () {
+ widget.onTap?.call();
+ controller?.forward().then((value) => controller?.reverse());
+ })
+ : null,
),
);
}
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index 1f0287013..bf9d2746e 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -1,15 +1,31 @@
+import 'dart:async';
+
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/electrumx_rpc/electrumx.dart';
+import 'package:stackwallet/models/node_model.dart';
+import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
+import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
+import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/test_epic_box_connection.dart';
+import 'package:stackwallet/utilities/test_monero_node_connection.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/conditional_parent.dart';
+import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
+import 'package:stackwallet/widgets/expandable.dart';
import 'package:stackwallet/widgets/node_options_sheet.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:tuple/tuple.dart';
class NodeCard extends ConsumerStatefulWidget {
const NodeCard({
@@ -30,6 +46,125 @@ class NodeCard extends ConsumerStatefulWidget {
class _NodeCardState extends ConsumerState {
String _status = "Disconnected";
late final String nodeId;
+ bool _advancedIsExpanded = true;
+
+ Future _notifyWalletsOfUpdatedNode(WidgetRef ref) async {
+ final managers = ref
+ .read(walletsChangeNotifierProvider)
+ .managers
+ .where((e) => e.coin == widget.coin);
+ final prefs = ref.read(prefsChangeNotifierProvider);
+
+ switch (prefs.syncType) {
+ case SyncingType.currentWalletOnly:
+ for (final manager in managers) {
+ if (manager.isActiveWallet) {
+ manager.updateNode(true);
+ } else {
+ manager.updateNode(false);
+ }
+ }
+ break;
+ case SyncingType.selectedWalletsAtStartup:
+ final List walletIdsToSync = prefs.walletIdsSyncOnStartup;
+ for (final manager in managers) {
+ if (walletIdsToSync.contains(manager.walletId)) {
+ manager.updateNode(true);
+ } else {
+ manager.updateNode(false);
+ }
+ }
+ break;
+ case SyncingType.allWalletsOnStartup:
+ for (final manager in managers) {
+ manager.updateNode(true);
+ }
+ break;
+ }
+ }
+
+ Future _testConnection(
+ NodeModel node,
+ BuildContext context,
+ WidgetRef ref,
+ ) async {
+ bool testPassed = false;
+
+ switch (widget.coin) {
+ case Coin.epicCash:
+ try {
+ final String uriString = "${node.host}:${node.port}/v1/version";
+
+ testPassed = await testEpicBoxNodeConnection(Uri.parse(uriString));
+ } catch (e, s) {
+ Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+ }
+ break;
+
+ case Coin.monero:
+ case Coin.wownero:
+ try {
+ final uri = Uri.parse(node.host);
+ if (uri.scheme.startsWith("http")) {
+ final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
+
+ String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
+
+ testPassed = await testMoneroNodeConnection(Uri.parse(uriString));
+ }
+ } catch (e, s) {
+ Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+ }
+
+ break;
+
+ case Coin.bitcoin:
+ case Coin.litecoin:
+ case Coin.dogecoin:
+ case Coin.firo:
+ case Coin.bitcoinTestNet:
+ case Coin.firoTestNet:
+ case Coin.dogecoinTestNet:
+ case Coin.bitcoincash:
+ case Coin.litecoinTestNet:
+ case Coin.namecoin:
+ case Coin.bitcoincashTestnet:
+ final client = ElectrumX(
+ host: node.host,
+ port: node.port,
+ useSSL: node.useSSL,
+ failovers: [],
+ prefs: ref.read(prefsChangeNotifierProvider),
+ );
+
+ try {
+ testPassed = await client.ping();
+ } catch (_) {
+ testPassed = false;
+ }
+
+ break;
+ }
+
+ if (testPassed) {
+ // showFloatingFlushBar(
+ // type: FlushBarType.success,
+ // message: "Server ping success",
+ // context: context,
+ // );
+ } else {
+ unawaited(
+ showFloatingFlushBar(
+ type: FlushBarType.warning,
+ iconAsset: Assets.svg.circleAlert,
+ message: "Could not connect to node",
+ context: context,
+ ),
+ );
+ }
+
+ return testPassed;
+ }
@override
void initState() {
@@ -50,91 +185,176 @@ class _NodeCardState extends ConsumerState {
_status = "Disconnected";
}
+ final isDesktop = Util.isDesktop;
+
return RoundedWhiteContainer(
padding: const EdgeInsets.all(0),
- child: RawMaterialButton(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
- ),
- ),
- onPressed: () {
- showModalBottomSheet(
- backgroundColor: Colors.transparent,
- context: context,
- builder: (_) => NodeOptionsSheet(
- nodeId: nodeId,
- coin: widget.coin,
- popBackToRoute: widget.popBackToRoute,
+ borderColor: isDesktop
+ ? Theme.of(context).extension()!.background
+ : null,
+ child: ConditionalParent(
+ condition: !isDesktop,
+ builder: (child) {
+ return RawMaterialButton(
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
),
+ onPressed: () {
+ showModalBottomSheet(
+ backgroundColor: Colors.transparent,
+ context: context,
+ builder: (_) => NodeOptionsSheet(
+ nodeId: nodeId,
+ coin: widget.coin,
+ popBackToRoute: widget.popBackToRoute,
+ ),
+ );
+ },
+ child: child,
);
},
- child: Padding(
- padding: const EdgeInsets.all(12),
- child: Row(
- children: [
- Container(
- width: 24,
- height: 24,
- decoration: BoxDecoration(
- color: _node.name == DefaultNodes.defaultName
- ? Theme.of(context)
- .extension()!
- .buttonBackSecondary
- : Theme.of(context)
- .extension()!
- .infoItemIcons
- .withOpacity(0.2),
- borderRadius: BorderRadius.circular(100),
+ child: ConditionalParent(
+ condition: isDesktop,
+ builder: (child) {
+ return Expandable(
+ onExpandChanged: (state) {
+ setState(() {
+ _advancedIsExpanded = state == ExpandableState.expanded;
+ });
+ },
+ header: child,
+ body: Padding(
+ padding: const EdgeInsets.only(
+ bottom: 24,
),
- child: Center(
- child: SvgPicture.asset(
- Assets.svg.node,
- height: 11,
- width: 14,
+ child: Row(
+ children: [
+ const SizedBox(
+ width: 66,
+ ),
+ BlueTextButton(
+ text: "Connect",
+ enabled: _status == "Disconnected",
+ onTap: () async {
+ final canConnect =
+ await _testConnection(_node, context, ref);
+ if (!canConnect) {
+ return;
+ }
+
+ await ref
+ .read(nodeServiceChangeNotifierProvider)
+ .setPrimaryNodeFor(
+ coin: widget.coin,
+ node: _node,
+ shouldNotifyListeners: true,
+ );
+
+ await _notifyWalletsOfUpdatedNode(ref);
+ },
+ ),
+ const SizedBox(
+ width: 48,
+ ),
+ BlueTextButton(
+ text: "Details",
+ onTap: () {
+ Navigator.of(context).pushNamed(
+ NodeDetailsView.routeName,
+ arguments: Tuple3(
+ widget.coin,
+ widget.nodeId,
+ widget.popBackToRoute,
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ child: Padding(
+ padding: EdgeInsets.all(isDesktop ? 16 : 12),
+ child: Row(
+ children: [
+ Container(
+ width: isDesktop ? 40 : 24,
+ height: isDesktop ? 40 : 24,
+ decoration: BoxDecoration(
color: _node.name == DefaultNodes.defaultName
? Theme.of(context)
.extension()!
- .accentColorDark
+ .buttonBackSecondary
: Theme.of(context)
.extension()!
- .infoItemIcons,
+ .infoItemIcons
+ .withOpacity(0.2),
+ borderRadius: BorderRadius.circular(100),
+ ),
+ child: Center(
+ child: SvgPicture.asset(
+ Assets.svg.node,
+ height: isDesktop ? 18 : 11,
+ width: isDesktop ? 20 : 14,
+ color: _node.name == DefaultNodes.defaultName
+ ? Theme.of(context)
+ .extension()!
+ .accentColorDark
+ : Theme.of(context)
+ .extension()!
+ .infoItemIcons,
+ ),
),
),
- ),
- const SizedBox(
- width: 12,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- _node.name,
- style: STextStyles.titleBold12(context),
+ const SizedBox(
+ width: 12,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ _node.name,
+ style: STextStyles.titleBold12(context),
+ ),
+ const SizedBox(
+ height: 2,
+ ),
+ Text(
+ _status,
+ style: STextStyles.label(context),
+ ),
+ ],
+ ),
+ const Spacer(),
+ if (!isDesktop)
+ SvgPicture.asset(
+ Assets.svg.network,
+ color: _status == "Connected"
+ ? Theme.of(context)
+ .extension()!
+ .accentColorGreen
+ : Theme.of(context)
+ .extension()!
+ .buttonBackSecondary,
+ width: 20,
+ height: 20,
),
- const SizedBox(
- height: 2,
- ),
- Text(
- _status,
- style: STextStyles.label(context),
- ),
- ],
- ),
- const Spacer(),
- SvgPicture.asset(
- Assets.svg.network,
- color: _status == "Connected"
- ? Theme.of(context)
+ if (isDesktop)
+ SvgPicture.asset(
+ _advancedIsExpanded
+ ? Assets.svg.chevronDown
+ : Assets.svg.chevronUp,
+ width: 12,
+ height: 6,
+ color: Theme.of(context)
.extension()!
- .accentColorGreen
- : Theme.of(context)
- .extension()!
- .buttonBackSecondary,
- width: 20,
- height: 20,
- ),
- ],
+ .textSubtitle1,
+ ),
+ ],
+ ),
),
),
),
diff --git a/pubspec.yaml b/pubspec.yaml
index 29d25cb84..b84135f4a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -237,6 +237,7 @@ flutter:
- assets/svg/rotate-exclamation.svg
- assets/svg/folder-down.svg
- assets/svg/network-wired.svg
+ - assets/svg/network-wired-2.svg
- assets/svg/address-book.svg
- assets/svg/address-book2.svg
- assets/svg/arrow-right.svg
diff --git a/test/widget_tests/node_card_test.dart b/test/widget_tests/node_card_test.dart
index 2728fc304..22e0661bf 100644
--- a/test/widget_tests/node_card_test.dart
+++ b/test/widget_tests/node_card_test.dart
@@ -1,15 +1,16 @@
import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutter_test/flutter_test.dart';
-import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/theme/light_colors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
-import 'package:stackwallet/services/node_service.dart';
+import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/node_card.dart';
import 'package:stackwallet/widgets/node_options_sheet.dart';
@@ -190,13 +191,22 @@ void main() {
await tester.tap(find.byType(NodeCard));
await tester.pumpAndSettle();
- expect(find.text("Connect"), findsOneWidget);
- expect(find.text("Details"), findsOneWidget);
- expect(find.byType(NodeOptionsSheet), findsOneWidget);
- expect(find.byType(Text), findsNWidgets(7));
+ if (Util.isDesktop) {
+ expect(find.text("Connect"), findsNothing);
+ expect(find.text("Details"), findsNothing);
+
+ verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(1);
+ verify(nodeService.getNodeById(id: "node id")).called(1);
+ } else {
+ expect(find.text("Connect"), findsOneWidget);
+ expect(find.text("Details"), findsOneWidget);
+ expect(find.byType(NodeOptionsSheet), findsOneWidget);
+ expect(find.byType(Text), findsNWidgets(7));
+
+ verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(2);
+ verify(nodeService.getNodeById(id: "node id")).called(2);
+ }
- verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(2);
- verify(nodeService.getNodeById(id: "node id")).called(2);
verify(nodeService.addListener(any)).called(1);
verifyNoMoreInteractions(nodeService);