Merge pull request #909 from cypherstack/hideex

Disable Swap and Buy crypto features based on user preference
This commit is contained in:
julian-CStack 2024-07-29 11:10:42 -06:00 committed by GitHub
commit 9ab411bcb9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 205 additions and 19 deletions

View file

@ -378,7 +378,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
// TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
// unawaited(_nodeService.updateCommunityNodes());
if (AppConfig.hasFeature(AppFeature.swap)) {
if (AppConfig.hasFeature(AppFeature.swap) &&
ref.read(prefsChangeNotifierProvider).enableExchange) {
await ExchangeDataLoadingService.instance.initDB();
// run without awaiting
if (ref.read(prefsChangeNotifierProvider).externalCalls &&

View file

@ -17,6 +17,7 @@ import 'package:flutter_svg/svg.dart';
import '../../app_config.dart';
import '../../providers/global/notifications_provider.dart';
import '../../providers/global/prefs_provider.dart';
import '../../providers/ui/home_view_index_provider.dart';
import '../../providers/ui/unread_notifications_provider.dart';
import '../../services/event_bus/events/global/tor_connection_status_changed_event.dart';
@ -172,6 +173,20 @@ class _HomeViewState extends ConsumerState<HomeView> {
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
// dirty hack
ref.listen(
prefsChangeNotifierProvider.select((value) => value.enableExchange),
(prev, next) {
if (next == false &&
mounted &&
ref.read(homeViewPageIndexStateProvider) != 0) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => ref.read(homeViewPageIndexStateProvider.state).state = 0,
);
}
});
return WillPopScope(
onWillPop: _onWillPop,
child: Background(
@ -345,7 +360,8 @@ class _HomeViewState extends ConsumerState<HomeView> {
),
body: Column(
children: [
if (_children.length > 1)
if (_children.length > 1 &&
ref.watch(prefsChangeNotifierProvider).enableExchange)
Container(
decoration: BoxDecoration(
color: Theme.of(context)

View file

@ -44,8 +44,6 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
@override
Widget build(BuildContext context) {
//todo: check if print needed
// debugPrint("BUILD: HomeViewButtonBar");
final selectedIndex = ref.watch(homeViewPageIndexStateProvider.state).state;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

View file

@ -183,6 +183,55 @@ class AdvancedSettingsView extends StatelessWidget {
},
),
),
// showExchange pref.
const SizedBox(
height: 8,
),
RoundedWhiteContainer(
child: Consumer(
builder: (_, ref, __) {
return RawMaterialButton(
// splashColor: Theme.of(context).extension<StackColors>()!.highlight,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
onPressed: null,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Enable exchange features",
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
SizedBox(
height: 20,
width: 40,
child: DraggableSwitchButton(
isOn: ref.watch(
prefsChangeNotifierProvider.select(
(value) => value.enableExchange,
),
),
onValueChanged: (newValue) {
ref
.read(prefsChangeNotifierProvider)
.enableExchange = newValue;
},
),
),
],
),
),
);
},
),
),
const SizedBox(
height: 8,
),

View file

@ -218,6 +218,9 @@ class TokenWalletOptions extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final prefs = ref.watch(prefsChangeNotifierProvider);
final showExchange = prefs.enableExchange;
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@ -251,11 +254,11 @@ class TokenWalletOptions extends ConsumerWidget {
subLabel: "Send",
iconAssetPathSVG: Assets.svg.arrowUpRight,
),
if (AppConfig.hasFeature(AppFeature.swap))
if (AppConfig.hasFeature(AppFeature.swap) && showExchange)
const SizedBox(
width: 16,
),
if (AppConfig.hasFeature(AppFeature.swap))
if (AppConfig.hasFeature(AppFeature.swap) && showExchange)
TokenOptionsButton(
onPressed: () => _onExchangePressed(context),
subLabel: "Swap",
@ -265,11 +268,11 @@ class TokenWalletOptions extends ConsumerWidget {
),
),
),
if (AppConfig.hasFeature(AppFeature.buy))
if (AppConfig.hasFeature(AppFeature.buy) && showExchange)
const SizedBox(
width: 16,
),
if (AppConfig.hasFeature(AppFeature.buy))
if (AppConfig.hasFeature(AppFeature.buy) && showExchange)
TokenOptionsButton(
onPressed: () => _onBuyPressed(context),
subLabel: "Buy",

View file

@ -518,6 +518,9 @@ class _WalletViewState extends ConsumerState<WalletView> {
final coin = ref.watch(pWalletCoin(walletId));
final prefs = ref.watch(prefsChangeNotifierProvider);
final showExchange = prefs.enableExchange;
return ConditionalParent(
condition: _rescanningOnOpen,
builder: (child) {
@ -1053,7 +1056,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
),
if (Constants.enableExchange &&
ref.watch(pWalletCoin(walletId)) is! FrostCurrency &&
AppConfig.hasFeature(AppFeature.swap))
AppConfig.hasFeature(AppFeature.swap) &&
showExchange)
WalletNavigationBarItemData(
label: "Swap",
icon: const ExchangeNavIcon(),
@ -1061,7 +1065,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
),
if (Constants.enableExchange &&
ref.watch(pWalletCoin(walletId)) is! FrostCurrency &&
AppConfig.hasFeature(AppFeature.buy))
AppConfig.hasFeature(AppFeature.buy) &&
showExchange)
WalletNavigationBarItemData(
label: "Buy",
icon: const BuyNavIcon(),

View file

@ -16,6 +16,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import '../app_config.dart';
import '../providers/desktop/current_desktop_menu_item.dart';
import '../providers/providers.dart';
import '../themes/stack_colors.dart';
import '../utilities/assets.dart';
import '../utilities/text_styles.dart';
@ -58,6 +59,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
late final DMIController torButtonController;
double _width = expandedWidth;
bool get _isMinimized => _width < expandedWidth;
void updateSelectedMenuItem(DesktopMenuItemId idKey) {
widget.onSelectionWillChange?.call(idKey);
@ -112,6 +114,10 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
@override
Widget build(BuildContext context) {
final prefs = ref.watch(prefsChangeNotifierProvider);
final showExchange = prefs.enableExchange;
return Material(
color: Theme.of(context).extension<StackColors>()!.popupBG,
child: AnimatedContainer(
@ -161,7 +167,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
onPressed: () {
ref.read(currentDesktopMenuItemProvider.state).state =
DesktopMenuItemId.settings;
ref.watch(selectedSettingsMenuItemStateProvider.state).state =
ref.read(selectedSettingsMenuItemStateProvider.state).state =
4;
},
),
@ -179,97 +185,116 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
DesktopMenuItem(
key: const ValueKey('myStack'),
duration: duration,
icon: const DesktopMyStackIcon(),
label: "My ${AppConfig.prefix}",
value: DesktopMenuItemId.myStack,
onChanged: updateSelectedMenuItem,
controller: controllers[0],
isExpandedInitially: !_isMinimized,
),
if (AppConfig.hasFeature(AppFeature.swap))
if (AppConfig.hasFeature(AppFeature.swap) &&
showExchange) ...[
const SizedBox(
height: 2,
),
if (AppConfig.hasFeature(AppFeature.swap))
DesktopMenuItem(
key: const ValueKey('swap'),
duration: duration,
icon: const DesktopExchangeIcon(),
label: "Swap",
value: DesktopMenuItemId.exchange,
onChanged: updateSelectedMenuItem,
controller: controllers[1],
isExpandedInitially: !_isMinimized,
),
if (AppConfig.hasFeature(AppFeature.buy))
],
if (AppConfig.hasFeature(AppFeature.buy) &&
showExchange) ...[
const SizedBox(
height: 2,
),
if (AppConfig.hasFeature(AppFeature.buy))
DesktopMenuItem(
key: const ValueKey('buy'),
duration: duration,
icon: const DesktopBuyIcon(),
label: "Buy crypto",
value: DesktopMenuItemId.buy,
onChanged: updateSelectedMenuItem,
controller: controllers[2],
isExpandedInitially: !_isMinimized,
),
],
const SizedBox(
height: 2,
),
DesktopMenuItem(
key: const ValueKey('notifications'),
duration: duration,
icon: const DesktopNotificationsIcon(),
label: "Notifications",
value: DesktopMenuItemId.notifications,
onChanged: updateSelectedMenuItem,
controller: controllers[3],
isExpandedInitially: !_isMinimized,
),
const SizedBox(
height: 2,
),
DesktopMenuItem(
key: const ValueKey('addressBook'),
duration: duration,
icon: const DesktopAddressBookIcon(),
label: "Address Book",
value: DesktopMenuItemId.addressBook,
onChanged: updateSelectedMenuItem,
controller: controllers[4],
isExpandedInitially: !_isMinimized,
),
const SizedBox(
height: 2,
),
DesktopMenuItem(
key: const ValueKey('settings'),
duration: duration,
icon: const DesktopSettingsIcon(),
label: "Settings",
value: DesktopMenuItemId.settings,
onChanged: updateSelectedMenuItem,
controller: controllers[5],
isExpandedInitially: !_isMinimized,
),
const SizedBox(
height: 2,
),
DesktopMenuItem(
key: const ValueKey('support'),
duration: duration,
icon: const DesktopSupportIcon(),
label: "Support",
value: DesktopMenuItemId.support,
onChanged: updateSelectedMenuItem,
controller: controllers[6],
isExpandedInitially: !_isMinimized,
),
const SizedBox(
height: 2,
),
DesktopMenuItem(
key: const ValueKey('about'),
duration: duration,
icon: const DesktopAboutIcon(),
label: "About",
value: DesktopMenuItemId.about,
onChanged: updateSelectedMenuItem,
controller: controllers[7],
isExpandedInitially: !_isMinimized,
),
const Spacer(),
if (!Platform.isIOS)
DesktopMenuItem(
key: const ValueKey('exit'),
duration: duration,
labelLength: 123,
icon: const DesktopExitIcon(),
@ -287,6 +312,7 @@ class _DesktopMenuState extends ConsumerState<DesktopMenu> {
// }
},
controller: controllers[8],
isExpandedInitially: !_isMinimized,
),
],
),

View file

@ -24,6 +24,9 @@ import 'desktop_menu.dart';
class DMIController {
VoidCallback? toggle;
DMIController();
void dispose() {
toggle = null;
}
@ -237,6 +240,7 @@ class DesktopMenuItem<T> extends ConsumerStatefulWidget {
required this.duration,
this.labelLength = 125,
this.controller,
required this.isExpandedInitially,
});
final Widget icon;
@ -246,6 +250,7 @@ class DesktopMenuItem<T> extends ConsumerStatefulWidget {
final Duration duration;
final double labelLength;
final DMIController? controller;
final bool isExpandedInitially;
@override
ConsumerState<DesktopMenuItem<T>> createState() => _DesktopMenuItemState<T>();
@ -287,11 +292,17 @@ class _DesktopMenuItemState<T> extends ConsumerState<DesktopMenuItem<T>>
labelLength = widget.labelLength;
controller = widget.controller;
_iconOnly = !widget.isExpandedInitially;
controller?.toggle = toggle;
animationController = AnimationController(
vsync: this,
duration: duration,
)..forward();
);
if (_iconOnly) {
animationController.value = 0;
} else {
animationController.value = 1;
}
super.initState();
}

View file

@ -353,6 +353,9 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> {
final wallet = ref.watch(pWallets).getWallet(widget.walletId);
final coin = wallet.info.coin;
final prefs = ref.watch(prefsChangeNotifierProvider);
final showExchange = prefs.enableExchange;
final showMore = wallet is PaynymInterface ||
(wallet is CoinControlInterface &&
ref.watch(
@ -368,7 +371,9 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> {
return Row(
children: [
if (Constants.enableExchange && AppConfig.hasFeature(AppFeature.swap))
if (Constants.enableExchange &&
AppConfig.hasFeature(AppFeature.swap) &&
showExchange)
SecondaryButton(
label: "Swap",
width: buttonWidth,
@ -383,11 +388,15 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> {
),
onPressed: () => _onSwapPressed(),
),
if (Constants.enableExchange && AppConfig.hasFeature(AppFeature.buy))
if (Constants.enableExchange &&
AppConfig.hasFeature(AppFeature.buy) &&
showExchange)
const SizedBox(
width: 16,
),
if (Constants.enableExchange && AppConfig.hasFeature(AppFeature.buy))
if (Constants.enableExchange &&
AppConfig.hasFeature(AppFeature.buy) &&
showExchange)
SecondaryButton(
label: "Buy",
width: buttonWidth,

View file

@ -162,6 +162,47 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
],
),
),
// showExchange pref.
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(
thickness: 0.5,
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Enable exchange features",
style: STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
textAlign: TextAlign.left,
),
SizedBox(
height: 20,
width: 40,
child: DraggableSwitchButton(
isOn: ref.watch(
prefsChangeNotifierProvider.select(
(value) => value.enableExchange,
),
),
onValueChanged: (newValue) {
ref
.read(prefsChangeNotifierProvider)
.enableExchange = newValue;
},
),
),
],
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(

View file

@ -71,6 +71,7 @@ class Prefs extends ChangeNotifier {
_useTor = await _getUseTor();
_fusionServerInfo = await _getFusionServerInfo();
_autoPin = await _getAutoPin();
_enableExchange = await _getEnableExchange();
_initialized = true;
}
@ -1131,4 +1132,30 @@ class Prefs extends ChangeNotifier {
) as bool? ??
false;
}
// Show or hide exchange (buy & swap) features.
bool _enableExchange = true;
bool get enableExchange => _enableExchange;
set enableExchange(bool showExchange) {
if (_enableExchange != showExchange) {
DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs,
key: "showExchange",
value: showExchange,
);
_enableExchange = showExchange;
notifyListeners();
}
}
Future<bool> _getEnableExchange() async {
return await DB.instance.get<dynamic>(
boxName: DB.boxNamePrefs,
key: "showExchange",
) as bool? ??
true;
}
}