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:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.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'; import 'package:stackwallet/widgets/stack_dialog.dart';
class ConfirmFullRescanDialog extends StatelessWidget { class ConfirmFullRescanDialog extends StatelessWidget {
@ -11,40 +16,110 @@ class ConfirmFullRescanDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return WillPopScope( if (Util.isDesktop) {
onWillPop: () async { return DesktopDialog(
return true; maxWidth: 576,
}, child: Column(
child: StackDialog( mainAxisSize: MainAxisSize.min,
title: "Rescan blockchain", children: [
message: Row(
"Warning! It may take a while. If you exit before completion, you will have to redo the process.", mainAxisAlignment: MainAxisAlignment.spaceBetween,
leftButton: TextButton( children: [
style: Theme.of(context) Padding(
.extension<StackColors>()! padding: const EdgeInsets.only(
.getSecondaryEnabledButtonColor(context), left: 32,
child: Text( ),
"Cancel", child: Text(
style: STextStyles.itemSubtitle12(context), "Rescan blockchain",
), style: STextStyles.desktopH3(context),
onPressed: () { ),
Navigator.of(context).pop(); ),
}, 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) } else {
.extension<StackColors>()! return WillPopScope(
.getPrimaryEnabledButtonColor(context), onWillPop: () async {
child: Text( return true;
"Rescan", },
style: STextStyles.button(context), 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<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop();
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Rescan",
style: STextStyles.button(context),
),
onPressed: () {
Navigator.of(context).pop();
onConfirm.call();
},
), ),
onPressed: () {
Navigator.of(context).pop();
onConfirm.call();
},
), ),
), );
); }
} }
} }

View file

@ -285,6 +285,7 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
children: [ children: [
Expanded( Expanded(
child: RawMaterialButton( child: RawMaterialButton(
elevation: 0,
fillColor: Theme.of(context).extension<StackColors>()!.popupBG, fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: !externalCallsEnabled 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/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@ -260,11 +261,19 @@ class _TransactionDetailsViewState
bottom: 32, bottom: 32,
) )
: const EdgeInsets.all(0), : const EdgeInsets.all(0),
child: RoundedWhiteContainer( child: ConditionalParent(
borderColor: isDesktop condition: isDesktop,
? Theme.of(context).extension<StackColors>()!.background builder: (child) {
: null, return RoundedWhiteContainer(
padding: const EdgeInsets.all(0), borderColor: isDesktop
? Theme.of(context)
.extension<StackColors>()!
.background
: null,
padding: const EdgeInsets.all(0),
child: child,
);
},
child: SingleChildScrollView( child: SingleChildScrollView(
primary: isDesktop ? false : null, primary: isDesktop ? false : null,
child: Padding( child: Padding(

View file

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.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/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/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/currency_settings/currency_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_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/nodes_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/security_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'; 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: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/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart';
import 'package:stackwallet/providers/providers.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/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/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.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'; import 'package:tuple/tuple.dart';
class NetworkInfoButton extends ConsumerStatefulWidget { class NetworkInfoButton extends ConsumerStatefulWidget {
@ -150,14 +154,116 @@ class _NetworkInfoButtonState extends ConsumerState<NetworkInfoButton> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
Navigator.of(context).pushNamed( if (Util.isDesktop) {
WalletNetworkSettingsView.routeName, // showDialog<void>(
arguments: Tuple3( // context: context,
walletId, // builder: (context) => DesktopDialog(
_currentSyncStatus, // maxHeight: MediaQuery.of(context).size.height - 64,
_currentNodeStatus, // 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(
walletId,
_currentSyncStatus,
_currentNodeStatus,
),
);
}
}, },
child: Container( child: Container(
color: Colors.transparent, color: Colors.transparent,

View file

@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.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/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/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
@ -22,6 +21,8 @@ class UnlockWalletKeysDesktop extends ConsumerStatefulWidget {
final String walletId; final String walletId;
static const String routeName = "/desktopUnlockWalletKeys";
@override @override
ConsumerState<UnlockWalletKeysDesktop> createState() => ConsumerState<UnlockWalletKeysDesktop> createState() =>
_UnlockWalletKeysDesktopState(); _UnlockWalletKeysDesktopState();
@ -59,8 +60,13 @@ class _UnlockWalletKeysDesktopState
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: const [ children: [
DesktopDialogCloseButton(), DesktopDialogCloseButton(
onPressedOverride: Navigator.of(
context,
rootNavigator: true,
).pop,
),
], ],
), ),
const SizedBox( const SizedBox(
@ -175,7 +181,10 @@ class _UnlockWalletKeysDesktopState
Expanded( Expanded(
child: SecondaryButton( child: SecondaryButton(
label: "Cancel", label: "Cancel",
onPressed: Navigator.of(context).pop, onPressed: Navigator.of(
context,
rootNavigator: true,
).pop,
), ),
), ),
const SizedBox( const SizedBox(
@ -188,29 +197,35 @@ class _UnlockWalletKeysDesktopState
onPressed: continueEnabled onPressed: continueEnabled
? () async { ? () async {
// todo: check password // todo: check password
Navigator.of(context).pop(); // Navigator.of(context).pop();
final words = await ref final words = await ref
.read(walletsChangeNotifierProvider) .read(walletsChangeNotifierProvider)
.getManager(widget.walletId) .getManager(widget.walletId)
.mnemonic; .mnemonic;
await showDialog<void>(
context: context, await Navigator.of(context).pushReplacementNamed(
barrierDismissible: false, WalletKeysDesktopPopup.routeName,
builder: (context) => Navigator( arguments: words,
initialRoute: WalletKeysDesktopPopup.routeName,
onGenerateRoute: RouteGenerator.generateRoute,
onGenerateInitialRoutes: (_, __) {
return [
RouteGenerator.generateRoute(
RouteSettings(
name: 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, : null,
), ),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.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/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/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
@ -20,10 +21,29 @@ class WalletKeysButton extends StatelessWidget {
showDialog<void>( showDialog<void>(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (context) => UnlockWalletKeysDesktop( builder: (context) => Navigator(
walletId: walletId, 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( child: Container(
color: Colors.transparent, color: Colors.transparent,

View file

@ -1,7 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.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/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
@ -165,7 +166,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
.textDark), .textDark),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
const ShowLogsButton(), ShowLogsButton(),
], ],
), ),
), ),
@ -190,7 +191,7 @@ class StackPrivacyButton extends ConsumerWidget {
useSafeArea: false, useSafeArea: false,
barrierDismissible: true, barrierDismissible: true,
builder: (context) { builder: (context) {
return const StackPrivacyDialog(); return StackPrivacyDialog();
}, },
); );
} }
@ -223,20 +224,19 @@ class ShowLogsButton extends ConsumerWidget {
const ShowLogsButton({ const ShowLogsButton({
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
Future<void> viewDebugLogs() async {
// await showDialog<dynamic>(
// context: context,
// useSafeArea: false,
// barrierDismissible: true,
// builder: (context) {
// return const DebugInfoDialog();
// },
// );
}
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// Future<void> viewDebugLogs() async {
// await showDialog<dynamic>(
// context: context,
// useSafeArea: false,
// barrierDismissible: true,
// builder: (context) {
// return const DebugInfoDialog();
// },
// );
// }
return SizedBox( return SizedBox(
width: 101, width: 101,
height: 37, height: 37,
@ -246,7 +246,7 @@ class ShowLogsButton extends ConsumerWidget {
.getPrimaryEnabledButtonColor(context), .getPrimaryEnabledButtonColor(context),
onPressed: () { onPressed: () {
// //
viewDebugLogs(); // viewDebugLogs();
}, },
child: Text( child: Text(
"Show logs", "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/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.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/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.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.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';
class StackPrivacyDialog extends ConsumerStatefulWidget { class StackPrivacyDialog extends ConsumerStatefulWidget {
const StackPrivacyDialog({Key? key}) : super(key: key); const StackPrivacyDialog({Key? key}) : super(key: key);

View file

@ -40,20 +40,6 @@ class _CreateAutoBackup extends State<CreateAutoBackup> {
"Every 30 minutes", "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 @override
void initState() { void initState() {
fileLocationController = TextEditingController(); 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/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.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/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
@ -87,6 +88,17 @@ class ChangeLanguageButton extends ConsumerWidget {
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { 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( return SizedBox(
width: 200, width: 200,
height: 48, height: 48,
@ -94,7 +106,9 @@ class ChangeLanguageButton extends ConsumerWidget {
style: Theme.of(context) style: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.getPrimaryEnabledButtonColor(context), .getPrimaryEnabledButtonColor(context),
onPressed: () {}, onPressed: () {
chooseLanguage();
},
child: Text( child: Text(
"Change language", "Change language",
style: STextStyles.button(context), 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/wallet_view/wallet_view.dart';
import 'package:stackwallet/pages/wallets_view/wallets_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/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_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_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/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/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/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/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/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/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/currency_settings/currency_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/nodes_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/security_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/settings_menu.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:stackwallet/utilities/enums/coin_enum.dart';
import 'package:tuple/tuple.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 { class RouteGenerator {
static const bool useMaterialPageRoute = true; static const bool useMaterialPageRoute = true;
@ -1084,29 +1086,67 @@ class RouteGenerator {
case WalletKeysDesktopPopup.routeName: case WalletKeysDesktopPopup.routeName:
if (args is List<String>) { if (args is List<String>) {
return getRoute( return FadePageRoute(
shouldUseMaterialRoute: useMaterialPageRoute, WalletKeysDesktopPopup(
builder: (_) => WalletKeysDesktopPopup(
words: args, words: args,
), ),
settings: RouteSettings( RouteSettings(
name: settings.name, 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()}"); return _routeError("${settings.name} invalid args: ${args.toString()}");
case QRCodeDesktopPopupContent.routeName: case QRCodeDesktopPopupContent.routeName:
if (args is String) { if (args is String) {
return getRoute( return FadePageRoute(
shouldUseMaterialRoute: useMaterialPageRoute, QRCodeDesktopPopupContent(
builder: (_) => QRCodeDesktopPopupContent(
value: args, value: args,
), ),
settings: RouteSettings( RouteSettings(
name: settings.name, name: settings.name,
), ),
); );
// return getRoute(
// shouldUseMaterialRoute: useMaterialPageRoute,
// builder: (_) => QRCodeDesktopPopupContent(
// value: args,
// ),
// settings: RouteSettings(
// name: settings.name,
// ),
// );
} }
return _routeError("${settings.name} invalid args: ${args.toString()}"); return _routeError("${settings.name} invalid args: ${args.toString()}");
@ -1180,3 +1220,37 @@ class RouteGenerator {
builder: (_) => errorView); 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 downloadFolder => "assets/svg/folder-down.svg";
String get lock => "assets/svg/lock-keyhole.svg"; String get lock => "assets/svg/lock-keyhole.svg";
String get network => "assets/svg/network-wired.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 addressBook => "assets/svg/address-book.svg";
String get addressBook2 => "assets/svg/address-book2.svg"; String get addressBook2 => "assets/svg/address-book2.svg";
String get arrowRotate3 => "assets/svg/rotate-exclamation.svg"; String get arrowRotate3 => "assets/svg/rotate-exclamation.svg";

View file

@ -4,13 +4,13 @@ class ConditionalParent extends StatelessWidget {
const ConditionalParent({ const ConditionalParent({
Key? key, Key? key,
required this.condition, required this.condition,
required this.child,
required this.builder, required this.builder,
required this.child,
}) : super(key: key); }) : super(key: key);
final bool condition; final bool condition;
final Widget child;
final Widget Function(Widget) builder; final Widget Function(Widget) builder;
final Widget child;
@override @override
Widget build(BuildContext context) { 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'; import 'package:stackwallet/utilities/text_styles.dart';
class BlueTextButton extends ConsumerStatefulWidget { class BlueTextButton extends ConsumerStatefulWidget {
const BlueTextButton({Key? key, required this.text, this.onTap}) const BlueTextButton({
: super(key: key); Key? key,
required this.text,
this.onTap,
this.enabled = true,
}) : super(key: key);
final String text; final String text;
final VoidCallback? onTap; final VoidCallback? onTap;
final bool enabled;
@override @override
ConsumerState<BlueTextButton> createState() => _BlueTextButtonState(); ConsumerState<BlueTextButton> createState() => _BlueTextButtonState();
@ -17,38 +22,42 @@ class BlueTextButton extends ConsumerStatefulWidget {
class _BlueTextButtonState extends ConsumerState<BlueTextButton> class _BlueTextButtonState extends ConsumerState<BlueTextButton>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late AnimationController controller; AnimationController? controller;
late Animation<dynamic> animation; Animation<dynamic>? animation;
late Color color; late Color color;
@override @override
void initState() { void initState() {
color = ref.read(colorThemeProvider.state).state.buttonTextBorderless; if (widget.enabled) {
controller = AnimationController( color = ref.read(colorThemeProvider.state).state.buttonTextBorderless;
vsync: this, controller = AnimationController(
duration: const Duration(milliseconds: 100), vsync: this,
); duration: const Duration(milliseconds: 100),
animation = ColorTween( );
begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless, animation = ColorTween(
end: ref begin: ref.read(colorThemeProvider.state).state.buttonTextBorderless,
.read(colorThemeProvider.state) end: ref
.state .read(colorThemeProvider.state)
.buttonTextBorderless .state
.withOpacity(0.4), .buttonTextBorderless
).animate(controller); .withOpacity(0.4),
).animate(controller!);
animation.addListener(() { animation!.addListener(() {
setState(() { setState(() {
color = animation.value as Color; color = animation!.value as Color;
});
}); });
}); } else {
color = ref.read(colorThemeProvider.state).state.textSubtitle1;
}
super.initState(); super.initState();
} }
@override @override
void dispose() { void dispose() {
controller.dispose(); controller?.dispose();
super.dispose(); super.dispose();
} }
@ -59,11 +68,13 @@ class _BlueTextButtonState extends ConsumerState<BlueTextButton>
text: TextSpan( text: TextSpan(
text: widget.text, text: widget.text,
style: STextStyles.link2(context).copyWith(color: color), style: STextStyles.link2(context).copyWith(color: color),
recognizer: TapGestureRecognizer() recognizer: widget.enabled
..onTap = () { ? (TapGestureRecognizer()
widget.onTap?.call(); ..onTap = () {
controller.forward().then((value) => controller.reverse()); widget.onTap?.call();
}, controller?.forward().then((value) => controller?.reverse());
})
: null,
), ),
); );
} }

View file

@ -1,15 +1,31 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.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/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/enums/coin_enum.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/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.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/node_options_sheet.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
class NodeCard extends ConsumerStatefulWidget { class NodeCard extends ConsumerStatefulWidget {
const NodeCard({ const NodeCard({
@ -30,6 +46,125 @@ class NodeCard extends ConsumerStatefulWidget {
class _NodeCardState extends ConsumerState<NodeCard> { class _NodeCardState extends ConsumerState<NodeCard> {
String _status = "Disconnected"; String _status = "Disconnected";
late final String nodeId; 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 @override
void initState() { void initState() {
@ -50,91 +185,176 @@ class _NodeCardState extends ConsumerState<NodeCard> {
_status = "Disconnected"; _status = "Disconnected";
} }
final isDesktop = Util.isDesktop;
return RoundedWhiteContainer( return RoundedWhiteContainer(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
child: RawMaterialButton( borderColor: isDesktop
shape: RoundedRectangleBorder( ? Theme.of(context).extension<StackColors>()!.background
borderRadius: BorderRadius.circular( : null,
Constants.size.circularBorderRadius, child: ConditionalParent(
), condition: !isDesktop,
), builder: (child) {
onPressed: () { return RawMaterialButton(
showModalBottomSheet<dynamic>( shape: RoundedRectangleBorder(
backgroundColor: Colors.transparent, borderRadius: BorderRadius.circular(
context: context, Constants.size.circularBorderRadius,
builder: (_) => NodeOptionsSheet( ),
nodeId: nodeId,
coin: widget.coin,
popBackToRoute: widget.popBackToRoute,
), ),
onPressed: () {
showModalBottomSheet<void>(
backgroundColor: Colors.transparent,
context: context,
builder: (_) => NodeOptionsSheet(
nodeId: nodeId,
coin: widget.coin,
popBackToRoute: widget.popBackToRoute,
),
);
},
child: child,
); );
}, },
child: Padding( child: ConditionalParent(
padding: const EdgeInsets.all(12), condition: isDesktop,
child: Row( builder: (child) {
children: [ return Expandable(
Container( onExpandChanged: (state) {
width: 24, setState(() {
height: 24, _advancedIsExpanded = state == ExpandableState.expanded;
decoration: BoxDecoration( });
color: _node.name == DefaultNodes.defaultName },
? Theme.of(context) header: child,
.extension<StackColors>()! body: Padding(
.buttonBackSecondary padding: const EdgeInsets.only(
: Theme.of(context) bottom: 24,
.extension<StackColors>()!
.infoItemIcons
.withOpacity(0.2),
borderRadius: BorderRadius.circular(100),
), ),
child: Center( child: Row(
child: SvgPicture.asset( children: [
Assets.svg.node, const SizedBox(
height: 11, width: 66,
width: 14, ),
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 color: _node.name == DefaultNodes.defaultName
? Theme.of(context) ? Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark .buttonBackSecondary
: Theme.of(context) : Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.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<StackColors>()!
.accentColorDark
: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
), ),
), ),
), const SizedBox(
const SizedBox( width: 12,
width: 12, ),
), Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Text(
Text( _node.name,
_node.name, style: STextStyles.titleBold12(context),
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<StackColors>()!
.accentColorGreen
: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
width: 20,
height: 20,
), ),
const SizedBox( if (isDesktop)
height: 2, SvgPicture.asset(
), _advancedIsExpanded
Text( ? Assets.svg.chevronDown
_status, : Assets.svg.chevronUp,
style: STextStyles.label(context), width: 12,
), height: 6,
], color: Theme.of(context)
),
const Spacer(),
SvgPicture.asset(
Assets.svg.network,
color: _status == "Connected"
? Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorGreen .textSubtitle1,
: Theme.of(context) ),
.extension<StackColors>()! ],
.buttonBackSecondary, ),
width: 20,
height: 20,
),
],
), ),
), ),
), ),

View file

@ -237,6 +237,7 @@ flutter:
- assets/svg/rotate-exclamation.svg - assets/svg/rotate-exclamation.svg
- assets/svg/folder-down.svg - assets/svg/folder-down.svg
- assets/svg/network-wired.svg - assets/svg/network-wired.svg
- assets/svg/network-wired-2.svg
- assets/svg/address-book.svg - assets/svg/address-book.svg
- assets/svg/address-book2.svg - assets/svg/address-book2.svg
- assets/svg/arrow-right.svg - assets/svg/arrow-right.svg

View file

@ -1,15 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockito/annotations.dart'; import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/providers/providers.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/enums/coin_enum.dart';
import 'package:stackwallet/utilities/theme/light_colors.dart'; import 'package:stackwallet/utilities/theme/light_colors.dart';
import 'package:stackwallet/utilities/theme/stack_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_card.dart';
import 'package:stackwallet/widgets/node_options_sheet.dart'; import 'package:stackwallet/widgets/node_options_sheet.dart';
@ -190,13 +191,22 @@ void main() {
await tester.tap(find.byType(NodeCard)); await tester.tap(find.byType(NodeCard));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text("Connect"), findsOneWidget); if (Util.isDesktop) {
expect(find.text("Details"), findsOneWidget); expect(find.text("Connect"), findsNothing);
expect(find.byType(NodeOptionsSheet), findsOneWidget); expect(find.text("Details"), findsNothing);
expect(find.byType(Text), findsNWidgets(7));
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); verify(nodeService.addListener(any)).called(1);
verifyNoMoreInteractions(nodeService); verifyNoMoreInteractions(nodeService);