diff --git a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart similarity index 59% rename from lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart rename to lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart index e55326527..85eca20c0 100644 --- a/lib/pages_desktop_specific/home/settings_menu/advanced_settings.dart +++ b/lib/pages_desktop_specific/home/advanced_settings/advanced_settings.dart @@ -2,16 +2,15 @@ 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/stack_privacy_calls.dart'; +import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart'; +import 'package:stackwallet/pages_desktop_specific/home/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'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; -import '../../../pages/settings_views/global_settings_view/advanced_views/debug_view.dart'; -import '../../../providers/global/prefs_provider.dart'; -import '../../../widgets/custom_buttons/draggable_switch_button.dart'; - class AdvancedSettings extends ConsumerStatefulWidget { const AdvancedSettings({Key? key}) : super(key: key); @@ -109,63 +108,69 @@ class _AdvancedSettings extends ConsumerState { ), /// TODO: Make a dialog popup - Padding( - padding: const EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Stack Experience", - style: - STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark), - textAlign: TextAlign.left, - ), - Text( - "Easy Crypto", - style: STextStyles.desktopTextExtraExtraSmall( - context), - ), - ], - ), - const StackPrivacyButton(), - ], - ), - ), - const Padding( - padding: EdgeInsets.all(10.0), - child: Divider( - thickness: 0.5, - ), - ), - - /// TODO: Make a dialog popup - Padding( - padding: const EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Debug info", - style: STextStyles.desktopTextExtraSmall(context) - .copyWith( - color: Theme.of(context) - .extension()! - .textDark), - textAlign: TextAlign.left, - ), - ShowLogsButton(), - ], - ), - ), + Consumer(builder: (_, ref, __) { + final externalCalls = ref.watch( + prefsChangeNotifierProvider + .select((value) => value.externalCalls), + ); + return Padding( + padding: const EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Stack Experience", + style: + STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark), + textAlign: TextAlign.left, + ), + Text( + externalCalls ? "Easy crypto" : "Incognito", + style: STextStyles.desktopTextExtraExtraSmall( + context), + ), + ], + ), + const StackPrivacyButton(), + ], + ), + ); + }), ], ), + const Padding( + padding: EdgeInsets.all(10.0), + child: Divider( + thickness: 0.5, + ), + ), + + /// TODO: Make a dialog popup + Padding( + padding: const EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Debug info", + style: STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark), + textAlign: TextAlign.left, + ), + ShowLogsButton(), + ], + ), + ), ], ), ), @@ -181,6 +186,17 @@ class StackPrivacyButton extends ConsumerWidget { }) : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { + Future changePrivacySettings() async { + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackPrivacyDialog(); + }, + ); + } + return SizedBox( width: 84, height: 37, @@ -189,10 +205,11 @@ class StackPrivacyButton extends ConsumerWidget { .extension()! .getPrimaryEnabledButtonColor(context), onPressed: () { - Navigator.of(context).pushNamed( - StackPrivacyCalls.routeName, - arguments: false, - ); + // Navigator.of(context).pushNamed( + // StackPrivacyCalls.routeName, + // arguments: false, + // ); + changePrivacySettings(); }, child: Text( "Change", @@ -210,6 +227,17 @@ class ShowLogsButton extends ConsumerWidget { }) : super(key: key); @override Widget build(BuildContext context, WidgetRef ref) { + Future viewDebugLogs() async { + await showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return const DebugInfoDialog(); + }, + ); + } + return SizedBox( width: 101, height: 37, @@ -218,7 +246,8 @@ class ShowLogsButton extends ConsumerWidget { .extension()! .getPrimaryEnabledButtonColor(context), onPressed: () { - Navigator.of(context).pushNamed(DebugView.routeName); + // + viewDebugLogs(); }, child: Text( "Show logs", diff --git a/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/debug_info_dialog.dart new file mode 100644 index 000000000..e69de29bb diff --git a/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart b/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart new file mode 100644 index 000000000..8e385fd37 --- /dev/null +++ b/lib/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart @@ -0,0 +1,437 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.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 '../../../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 { + const StackPrivacyDialog({Key? key}) : super(key: key); + + @override + ConsumerState createState() => _StackPrivacyDialog(); +} + +class _StackPrivacyDialog extends ConsumerState { + late final bool isDesktop; + late bool isEasy; + late bool infoToggle; + + @override + void initState() { + isDesktop = Util.isDesktop; + isEasy = ref.read(prefsChangeNotifierProvider).externalCalls; + infoToggle = isEasy; + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return DesktopDialog( + maxHeight: 650, + maxWidth: 600, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.all(32), + child: Text( + "Choose Your Stack Experience", + style: STextStyles.desktopH3(context), + textAlign: TextAlign.center, + ), + ), + const DesktopDialogCloseButton(), + ], + ), + const SizedBox( + height: 35, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 32), + child: PrivacyToggle( + externalCallsEnabled: isEasy, + onChanged: (externalCalls) { + isEasy = externalCalls; + setState(() { + infoToggle = isEasy; + }); + }, + ), + ), + Padding( + padding: const EdgeInsets.all(32.0), + child: RoundedWhiteContainer( + borderColor: Theme.of(context) + .extension()! + .textFieldDefaultBG, + child: Center( + child: RichText( + textAlign: TextAlign.left, + text: TextSpan( + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + : STextStyles.label(context).copyWith( + fontSize: 12.0, + ), + children: infoToggle + ? [ + const TextSpan( + text: + "Exchange data preloaded for a seamless experience."), + const TextSpan( + text: + "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."), + TextSpan( + text: "\n\nRecommended for most crypto users.", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall600( + context) + : TextStyle( + color: Theme.of(context) + .extension()! + .textDark, + fontWeight: FontWeight.w600, + ), + ), + ] + : [ + const TextSpan( + text: + "Exchange data not preloaded (slower experience)."), + const TextSpan( + text: + "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."), + TextSpan( + text: + "\n\nRecommended for the privacy conscious.", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall600( + context) + : TextStyle( + color: Theme.of(context) + .extension()! + .textDark, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + ), + // const Spacer(), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: Row( + children: [ + Expanded( + child: SecondaryButton( + label: "Cancel", + onPressed: () {}, + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + label: "Save", + onPressed: () { + ref.read(prefsChangeNotifierProvider).externalCalls = + isEasy; + + DB.instance + .put( + boxName: DB.boxNamePrefs, + key: "externalCalls", + value: isEasy) + .then((_) { + if (isEasy) { + unawaited(ExchangeDataLoadingService().loadAll(ref)); + ref + .read(priceAnd24hChangeNotifierProvider) + .start(true); + } + }); + if (isDesktop) { + Navigator.pop(context); + } + }, + ), + ) + ], + ), + ), + ], + ), + ); + } +} + +class PrivacyToggle extends StatefulWidget { + const PrivacyToggle({ + Key? key, + required this.externalCallsEnabled, + this.onChanged, + }) : super(key: key); + + final bool externalCallsEnabled; + final void Function(bool)? onChanged; + + @override + State createState() => _PrivacyToggleState(); +} + +class _PrivacyToggleState extends State { + late bool externalCallsEnabled; + + late final bool isDesktop; + + @override + void initState() { + isDesktop = Util.isDesktop; + // initial toggle state + externalCallsEnabled = widget.externalCallsEnabled; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: RawMaterialButton( + elevation: 0, + hoverElevation: 0, + fillColor: Theme.of(context).extension()!.popupBG, + shape: RoundedRectangleBorder( + side: !externalCallsEnabled + ? BorderSide.none + : BorderSide( + color: Theme.of(context) + .extension()! + .infoItemIcons, + width: 2, + ), + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius * 2, + ), + ), + onPressed: () { + setState(() { + // update toggle state + externalCallsEnabled = true; + }); + // call callback with newly set value + widget.onChanged?.call(externalCallsEnabled); + }, + child: Padding( + padding: const EdgeInsets.all( + 12, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + const SizedBox( + height: 10, + ), + SvgPicture.asset( + Assets.svg.personaEasy, + width: 120, + height: 120, + ), + if (isDesktop) + const SizedBox( + height: 12, + ), + Center( + child: Text( + "Easy Crypto", + style: isDesktop + ? STextStyles.desktopTextSmall(context) + : STextStyles.label700(context), + ), + ), + Center( + child: Text( + "Recommended", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + : STextStyles.label(context), + ), + ), + if (isDesktop) + const SizedBox( + height: 12, + ), + ], + ), + if (externalCallsEnabled) + Positioned( + top: 4, + right: 4, + child: SvgPicture.asset( + Assets.svg.checkCircle, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .infoItemIcons, + ), + ), + if (!externalCallsEnabled) + Positioned( + top: 4, + right: 4, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1000), + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + ), + ), + ), + ], + ), + ), + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: RawMaterialButton( + elevation: 0, + hoverElevation: 0, + fillColor: Theme.of(context).extension()!.popupBG, + shape: RoundedRectangleBorder( + side: externalCallsEnabled + ? BorderSide.none + : BorderSide( + color: Theme.of(context) + .extension()! + .infoItemIcons, + width: 2, + ), + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius * 2, + ), + ), + onPressed: () { + setState(() { + // update toggle state + externalCallsEnabled = false; + }); + // call callback with newly set value + widget.onChanged?.call(externalCallsEnabled); + }, + child: Padding( + padding: const EdgeInsets.all( + 12, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + const SizedBox( + height: 10, + ), + SvgPicture.asset( + Assets.svg.personaIncognito, + width: 120, + height: 120, + ), + if (isDesktop) + const SizedBox( + height: 12, + ), + Center( + child: Text( + "Incognito", + style: isDesktop + ? STextStyles.desktopTextSmall(context) + : STextStyles.label700(context), + ), + ), + Center( + child: Text( + "Privacy conscious", + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + : STextStyles.label(context), + ), + ), + if (isDesktop) + const SizedBox( + height: 12, + ), + ], + ), + if (!externalCallsEnabled) + Positioned( + top: 4, + right: 4, + child: SvgPicture.asset( + Assets.svg.checkCircle, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .infoItemIcons, + ), + ), + if (externalCallsEnabled) + Positioned( + top: 4, + right: 4, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1000), + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + ), + ), + ), + ], + ), + ), + ), + ), + ], + ); + } +}