Merge pull request #198 from cypherstack/desktop

Desktop
This commit is contained in:
Rylee Davis 2022-11-02 18:53:31 -06:00 committed by GitHub
commit 1226e2bfa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 2404 additions and 664 deletions

View file

@ -0,0 +1,10 @@
<svg width="24" height="19" viewBox="0 0 24 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_6129_18406)">
<path d="M14.9173 0C15.8835 0 16.6673 0.769499 16.6673 1.71875V5.15625C16.6673 6.10514 15.8835 6.875 14.9173 6.875H13.1673V8.02083H22.5007C23.146 8.02083 23.6673 8.53288 23.6673 9.16667C23.6673 9.80046 23.146 10.3125 22.5007 10.3125H19.0007V11.4583H20.7507C21.7168 11.4583 22.5007 12.2282 22.5007 13.1771V16.6146C22.5007 17.5635 21.7168 18.3333 20.7507 18.3333H14.9173C13.9512 18.3333 13.1673 17.5635 13.1673 16.6146V13.1771C13.1673 12.2282 13.9512 11.4583 14.9173 11.4583H16.6673V10.3125H7.33398V11.4583H9.08398C10.0501 11.4583 10.834 12.2282 10.834 13.1771V16.6146C10.834 17.5635 10.0501 18.3333 9.08398 18.3333H3.25065C2.28414 18.3333 1.50065 17.5635 1.50065 16.6146V13.1771C1.50065 12.2282 2.28414 11.4583 3.25065 11.4583H5.00065V10.3125H1.50065C0.856432 10.3125 0.333984 9.80046 0.333984 9.16667C0.333984 8.53288 0.856432 8.02083 1.50065 8.02083H10.834V6.875H9.08398C8.11784 6.875 7.33398 6.10514 7.33398 5.15625V1.71875C7.33398 0.769499 8.11784 0 9.08398 0H14.9173ZM9.66732 2.29167V4.58333H14.334V2.29167H9.66732ZM8.50065 16.0417V13.75H3.83398V16.0417H8.50065ZM15.5007 13.75V16.0417H20.1673V13.75H15.5007Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_6129_18406">
<rect width="23.3333" height="18.3333" fill="white" transform="translate(0.333984)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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,6 +16,75 @@ class ConfirmFullRescanDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
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",
),
),
],
)
],
),
)
],
),
);
} else {
return WillPopScope(
onWillPop: () async {
return true;
@ -48,3 +122,4 @@ class ConfirmFullRescanDialog extends StatelessWidget {
);
}
}
}

View file

@ -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<WalletNetworkSettingsView> {
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<void> _attemptRescan() async {
if (!Platform.isLinux) Wakelock.enable();
if (!Platform.isLinux) await Wakelock.enable();
int maxUnusedAddressGap = 20;
const int maxNumberOfIndexesToCheck = 1000;
unawaited(
showDialog<dynamic>(
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,8 +309,12 @@ class _WalletNetworkSettingsViewState
}
}
return ConditionalParent(
condition: !isDesktop,
builder: (child) {
return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
@ -325,7 +338,8 @@ class _WalletNetworkSettingsViewState
key: const Key("walletNetworkSettingsAddNewNodeViewButton"),
size: 36,
shadows: const [],
color: Theme.of(context).extension<StackColors>()!.background,
color:
Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.verticalEllipsis,
color: Theme.of(context)
@ -356,12 +370,13 @@ class _WalletNetworkSettingsViewState
boxShadow: const [],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Navigator.of(context).pop();
showDialog<dynamic>(
showDialog<void>(
context: context,
useSafeArea: false,
barrierDismissible: true,
@ -377,7 +392,8 @@ class _WalletNetworkSettingsViewState
color: Colors.transparent,
child: Text(
"Rescan blockchain",
style: STextStyles.baseXS(context),
style:
STextStyles.baseXS(context),
),
),
),
@ -406,7 +422,14 @@ class _WalletNetworkSettingsViewState
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Column(
child,
],
),
),
),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
@ -415,7 +438,9 @@ class _WalletNetworkSettingsViewState
Text(
"Blockchain status",
textAlign: TextAlign.left,
style: STextStyles.smallMed12(context),
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
GestureDetector(
onTap: () {
@ -431,11 +456,17 @@ class _WalletNetworkSettingsViewState
),
],
),
const SizedBox(
height: 9,
SizedBox(
height: isDesktop ? 12 : 9,
),
if (_currentSyncStatus == WalletSyncStatus.synced)
RoundedWhiteContainer(
borderColor: isDesktop
? Theme.of(context).extension<StackColors>()!.background
: null,
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(12),
child: Row(
children: [
Container(
@ -451,8 +482,8 @@ class _WalletNetworkSettingsViewState
child: Center(
child: SvgPicture.asset(
Assets.svg.radio,
height: 14,
width: 14,
height: isDesktop ? 19 : 14,
width: isDesktop ? 19 : 14,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen,
@ -467,8 +498,7 @@ class _WalletNetworkSettingsViewState
SizedBox(
width: progressLength,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Synchronized",
@ -476,8 +506,7 @@ class _WalletNetworkSettingsViewState
),
Text(
"100%",
style: STextStyles.syncPercent(context)
.copyWith(
style: STextStyles.syncPercent(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen,
@ -507,6 +536,12 @@ class _WalletNetworkSettingsViewState
),
if (_currentSyncStatus == WalletSyncStatus.syncing)
RoundedWhiteContainer(
borderColor: isDesktop
? Theme.of(context).extension<StackColors>()!.background
: null,
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(12),
child: Row(
children: [
Container(
@ -538,8 +573,7 @@ class _WalletNetworkSettingsViewState
SizedBox(
width: progressLength,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AnimatedText(
style: STextStyles.w600_10(context),
@ -555,8 +589,7 @@ class _WalletNetworkSettingsViewState
Text(
_percentString(_percent),
style:
STextStyles.syncPercent(context)
.copyWith(
STextStyles.syncPercent(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorYellow,
@ -567,8 +600,7 @@ class _WalletNetworkSettingsViewState
coin == Coin.epicCash)
Text(
" (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
style:
STextStyles.syncPercent(context)
style: STextStyles.syncPercent(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
@ -601,6 +633,12 @@ class _WalletNetworkSettingsViewState
),
if (_currentSyncStatus == WalletSyncStatus.unableToSync)
RoundedWhiteContainer(
borderColor: isDesktop
? Theme.of(context).extension<StackColors>()!.background
: null,
padding: isDesktop
? const EdgeInsets.all(16)
: const EdgeInsets.all(12),
child: Row(
children: [
Container(
@ -632,13 +670,11 @@ class _WalletNetworkSettingsViewState
SizedBox(
width: progressLength,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Unable to synchronize",
style:
STextStyles.w600_10(context).copyWith(
style: STextStyles.w600_10(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorRed,
@ -646,8 +682,7 @@ class _WalletNetworkSettingsViewState
),
Text(
"0%",
style: STextStyles.syncPercent(context)
.copyWith(
style: STextStyles.syncPercent(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorRed,
@ -694,8 +729,8 @@ class _WalletNetworkSettingsViewState
),
),
),
const SizedBox(
height: 20,
SizedBox(
height: isDesktop ? 32 : 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -703,7 +738,9 @@ class _WalletNetworkSettingsViewState
Text(
"${ref.watch(walletsChangeNotifierProvider.select((value) => value.getManager(widget.walletId).coin)).prettyName} nodes",
textAlign: TextAlign.left,
style: STextStyles.smallMed12(context),
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.smallMed12(context),
),
BlueTextButton(
text: "Add new node",
@ -724,19 +761,145 @@ class _WalletNetworkSettingsViewState
),
],
),
const SizedBox(
height: 8,
SizedBox(
height: isDesktop ? 12 : 8,
),
NodesList(
coin: ref.watch(walletsChangeNotifierProvider.select(
(value) => value.getManager(widget.walletId).coin)),
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<StackColors>()!.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<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(_iconSize),
),
child: Center(
child: SvgPicture.asset(
Assets.svg.networkWired,
width: 24,
color: Theme.of(context)
.extension<StackColors>()!
.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<StackColors>()!
.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<StackColors>()!
.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<void>(
ConfirmFullRescanDialog(
onConfirm: _attemptRescan,
),
const RouteSettings(),
),
);
// await showDialog<dynamic>(
// context: context,
// builder: (context) {
// return ConfirmFullRescanDialog(
// onConfirm: _attemptRescan,
// );
// },
// );
},
),
),
],
),
),
),
],
),
);
}

View file

@ -285,6 +285,7 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
children: [
Expanded(
child: RawMaterialButton(
elevation: 0,
fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
shape: RoundedRectangleBorder(
side: !externalCallsEnabled

View file

@ -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(
child: ConditionalParent(
condition: isDesktop,
builder: (child) {
return RoundedWhiteContainer(
borderColor: isDesktop
? Theme.of(context).extension<StackColors>()!.background
? Theme.of(context)
.extension<StackColors>()!
.background
: null,
padding: const EdgeInsets.all(0),
child: child,
);
},
child: SingleChildScrollView(
primary: isDesktop ? false : null,
child: Padding(

View file

@ -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';

View file

@ -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,6 +154,107 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (Util.isDesktop) {
// showDialog<void>(
// 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<void>(
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(
@ -158,6 +263,7 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
_currentNodeStatus,
),
);
}
},
child: Container(
color: Colors.transparent,

View file

@ -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<UnlockWalletKeysDesktop> 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<void>(
context: context,
barrierDismissible: false,
builder: (context) => Navigator(
initialRoute: WalletKeysDesktopPopup.routeName,
onGenerateRoute: RouteGenerator.generateRoute,
onGenerateInitialRoutes: (_, __) {
return [
RouteGenerator.generateRoute(
RouteSettings(
name: WalletKeysDesktopPopup.routeName,
await Navigator.of(context).pushReplacementNamed(
WalletKeysDesktopPopup.routeName,
arguments: words,
),
)
];
},
),
);
//
// await showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (context) => Navigator(
// initialRoute: WalletKeysDesktopPopup.routeName,
// onGenerateRoute: RouteGenerator.generateRoute,
// onGenerateInitialRoutes: (_, __) {
// return [
// RouteGenerator.generateRoute(
// RouteSettings(
// name: WalletKeysDesktopPopup.routeName,
// arguments: words,
// ),
// )
// ];
// },
// ),
// );
}
: null,
),

View file

@ -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<void>(
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<void>(
// context: context,
// barrierDismissible: false,
// builder: (context) => UnlockWalletKeysDesktop(
// walletId: walletId,
// ),
// );
},
child: Container(
color: Colors.transparent,

View file

@ -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<AdvancedSettings> {
.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,8 +224,9 @@ class ShowLogsButton extends ConsumerWidget {
const ShowLogsButton({
Key? key,
}) : super(key: key);
Future<void> viewDebugLogs() async {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Future<void> viewDebugLogs() async {
// await showDialog<dynamic>(
// context: context,
// useSafeArea: false,
@ -233,10 +235,8 @@ class ShowLogsButton extends ConsumerWidget {
// return const DebugInfoDialog();
// },
// );
}
// }
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox(
width: 101,
height: 37,
@ -246,7 +246,7 @@ class ShowLogsButton extends ConsumerWidget {
.getPrimaryEnabledButtonColor(context),
onPressed: () {
//
viewDebugLogs();
// viewDebugLogs();
},
child: Text(
"Show logs",

View file

@ -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<StatefulWidget> createState() => _DebugInfoDialog();
}
class _DebugInfoDialog extends State<DebugInfoDialog> {
final _searchController = TextEditingController();
final _searchFocusNode = FocusNode();
final scrollController = ScrollController();
String _searchTerm = "";
List<Log> filtered(List<Log> 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: () {},
),
)
],
),
),
],
),
);
}
}

View file

@ -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);

View file

@ -40,20 +40,6 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
"Every 30 minutes",
];
// List<DropdownMenuItem<String>> get dropdownItems {
// List<DropdownMenuItem<String>> 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();

View file

@ -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<CurrencyDialog> createState() => _CurrencyDialog();
}
class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
late String current;
late List<String> 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<String> _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<StackColors>()!
.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<StackColors>()!
.currencyListItemBG
: Theme.of(context)
.extension<StackColors>()!
.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<StackColors>()!
.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: () {},
),
)
],
),
),
],
),
);
}
}

View file

@ -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<CurrencySettings> createState() => _CurrencySettings();
}
class _CurrencySettings extends ConsumerState<CurrencySettings> {
@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<void> chooseCurrency() async {
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return CurrencyDialog();
},
);
}
return SizedBox(
width: 200,
height: 48,
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
chooseCurrency();
},
child: Text(
"Change currency",
style: STextStyles.button(context),
),
),
);
}
}

View file

@ -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<LanguageDialog> createState() => _LanguageDialog();
}
class _LanguageDialog extends ConsumerState<LanguageDialog> {
late final TextEditingController searchLanguageController;
late final FocusNode searchLanguageFocusNode;
final languages = Language.values.map((e) => e.description).toList();
late String current;
late List<String> 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<String> _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<StackColors>()!
.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<StackColors>()!
.currencyListItemBG
: Theme.of(context)
.extension<StackColors>()!
.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<StackColors>()!
.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: () {},
),
)
],
),
),
],
),
);
}
}

View file

@ -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<void> chooseLanguage() async {
await showDialog<dynamic>(
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<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {},
onPressed: () {
chooseLanguage();
},
child: Text(
"Change language",
style: STextStyles.button(context),

View file

@ -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<String>) {
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<T> extends PageRoute<T> {
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<double> animation,
Animation<double> 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;
}

View file

@ -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";

View file

@ -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) {

View file

@ -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<BlueTextButton> createState() => _BlueTextButtonState();
@ -17,12 +22,13 @@ class BlueTextButton extends ConsumerStatefulWidget {
class _BlueTextButtonState extends ConsumerState<BlueTextButton>
with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<dynamic> animation;
AnimationController? controller;
Animation<dynamic>? animation;
late Color color;
@override
void initState() {
if (widget.enabled) {
color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
controller = AnimationController(
vsync: this,
@ -35,20 +41,23 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton>
.state
.buttonTextBorderless
.withOpacity(0.4),
).animate(controller);
).animate(controller!);
animation.addListener(() {
animation!.addListener(() {
setState(() {
color = animation.value as Color;
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<BlueTextButton>
text: TextSpan(
text: widget.text,
style: STextStyles.link2(context).copyWith(color: color),
recognizer: TapGestureRecognizer()
recognizer: widget.enabled
? (TapGestureRecognizer()
..onTap = () {
widget.onTap?.call();
controller.forward().then((value) => controller.reverse());
},
controller?.forward().then((value) => controller?.reverse());
})
: null,
),
);
}

View file

@ -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<NodeCard> {
String _status = "Disconnected";
late final String nodeId;
bool _advancedIsExpanded = true;
Future<void> _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<String> 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<bool> _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,16 +185,24 @@ class _NodeCardState extends ConsumerState<NodeCard> {
_status = "Disconnected";
}
final isDesktop = Util.isDesktop;
return RoundedWhiteContainer(
padding: const EdgeInsets.all(0),
child: RawMaterialButton(
borderColor: isDesktop
? Theme.of(context).extension<StackColors>()!.background
: null,
child: ConditionalParent(
condition: !isDesktop,
builder: (child) {
return RawMaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
onPressed: () {
showModalBottomSheet<dynamic>(
showModalBottomSheet<void>(
backgroundColor: Colors.transparent,
context: context,
builder: (_) => NodeOptionsSheet(
@ -69,13 +212,77 @@ class _NodeCardState extends ConsumerState<NodeCard> {
),
);
},
child: child,
);
},
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: 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: const EdgeInsets.all(12),
padding: EdgeInsets.all(isDesktop ? 16 : 12),
child: Row(
children: [
Container(
width: 24,
height: 24,
width: isDesktop ? 40 : 24,
height: isDesktop ? 40 : 24,
decoration: BoxDecoration(
color: _node.name == DefaultNodes.defaultName
? Theme.of(context)
@ -90,8 +297,8 @@ class _NodeCardState extends ConsumerState<NodeCard> {
child: Center(
child: SvgPicture.asset(
Assets.svg.node,
height: 11,
width: 14,
height: isDesktop ? 18 : 11,
width: isDesktop ? 20 : 14,
color: _node.name == DefaultNodes.defaultName
? Theme.of(context)
.extension<StackColors>()!
@ -122,6 +329,7 @@ class _NodeCardState extends ConsumerState<NodeCard> {
],
),
const Spacer(),
if (!isDesktop)
SvgPicture.asset(
Assets.svg.network,
color: _status == "Connected"
@ -134,10 +342,22 @@ class _NodeCardState extends ConsumerState<NodeCard> {
width: 20,
height: 20,
),
if (isDesktop)
SvgPicture.asset(
_advancedIsExpanded
? Assets.svg.chevronDown
: Assets.svg.chevronUp,
width: 12,
height: 6,
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
],
),
),
),
),
);
}
}

View file

@ -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

View file

@ -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,6 +191,13 @@ void main() {
await tester.tap(find.byType(NodeCard));
await tester.pumpAndSettle();
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);
@ -197,6 +205,8 @@ void main() {
verify(nodeService.getPrimaryNodeFor(coin: Coin.bitcoin)).called(2);
verify(nodeService.getNodeById(id: "node id")).called(2);
}
verify(nodeService.addListener(any)).called(1);
verifyNoMoreInteractions(nodeService);