mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-18 05:51:34 +02:00
Cw 1247 improve tabs navigation (#2634)
* add dashboard page indicator * refactor dashboard page indicator and UI * refactor fade animation * smoother UI transitions * Improve accessibility for page indicator * localize action names * Update page indicator colors and blur effect * fix page indicator layout * Update Spanish translations for 'apps', 'history', and 'home' * update dashboard labels * changed settings page label * Modify page_indicator.dart * refactor page indicator animation * review fixes --------- Co-authored-by: Jaim3 <github@jaim3.com> Co-authored-by: tuxsudo <tuxsudo@tux.pizza>
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/pages/cake_features_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/page_indicator.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/widgets/bottom_sheet/bottom_sheet_listener_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/services/bottom_sheet_service.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
@@ -220,45 +221,34 @@ class _DashboardPageView extends BasePage {
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: <Widget>[
|
||||
//new Expanded(
|
||||
Observer(
|
||||
builder: (context) {
|
||||
return PageView.builder(
|
||||
key: ValueKey('dashboard_page_view_key'),
|
||||
key: const ValueKey('dashboard_page_view_key'),
|
||||
controller: controller,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) => pages[index],
|
||||
);
|
||||
},
|
||||
),
|
||||
//),
|
||||
Positioned(
|
||||
child: Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
margin: EdgeInsets.only(bottom: 110),
|
||||
child: Observer(
|
||||
builder: (context) {
|
||||
return Semantics(
|
||||
button: false,
|
||||
label: 'Page Indicator',
|
||||
hint: 'Swipe to change page',
|
||||
excludeSemantics: true,
|
||||
child: SmoothPageIndicator(
|
||||
controller: controller,
|
||||
count: pages.length,
|
||||
effect: ColorTransitionEffect(
|
||||
spacing: 6.0,
|
||||
radius: 6.0,
|
||||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context).colorScheme.primary.withOpacity(0.4),
|
||||
activeDotColor: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Semantics(
|
||||
container: true,
|
||||
label: 'Page indicator',
|
||||
hint: 'Swipe left or right to change page, or double tap buttons below to navigate directly.',
|
||||
child: ExcludeSemantics(
|
||||
excluding: false,
|
||||
child: PageIndicator(
|
||||
controller: controller,
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
NavigationDock(
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
@@ -277,7 +267,7 @@ class _DashboardPageView extends BasePage {
|
||||
if (dashboardViewModel.shouldShowMarketPlaceInDashboard) {
|
||||
pages.add(
|
||||
Semantics(
|
||||
label: 'Cake ${S.of(context).features}',
|
||||
label: S.of(context).apps,
|
||||
child: CakeFeaturesPage(
|
||||
dashboardViewModel: dashboardViewModel,
|
||||
cakeFeaturesViewModel: getIt.get<CakeFeaturesViewModel>(),
|
||||
@@ -288,7 +278,7 @@ class _DashboardPageView extends BasePage {
|
||||
pages.add(Semantics(label: S.of(context).balance_page, child: balancePage));
|
||||
pages.add(
|
||||
Semantics(
|
||||
label: S.of(context).settings_transactions,
|
||||
label: S.of(context).history,
|
||||
child: TransactionsPage(dashboardViewModel: dashboardViewModel),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -28,7 +28,7 @@ class CakeFeaturesPage extends StatelessWidget {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, top: 16),
|
||||
child: Text(
|
||||
'Cake ${S.of(context).features}',
|
||||
S.of(context).apps,
|
||||
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
|
||||
@@ -19,7 +19,7 @@ class NavigationDock extends StatelessWidget {
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
return Container(
|
||||
height: 150,
|
||||
height: 84,
|
||||
alignment: Alignment.bottomCenter,
|
||||
decoration: dashboardViewModel.settingsStore.backgroundImage.isEmpty
|
||||
? BoxDecoration(
|
||||
@@ -30,7 +30,6 @@ class NavigationDock extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
: null,
|
||||
//color: Colors.transparent,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
@@ -50,38 +49,51 @@ class NavigationDock extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: MainActions.all
|
||||
.where((element) => element.canShow?.call(dashboardViewModel) ?? true)
|
||||
.map(
|
||||
(action) => Expanded(
|
||||
child: Semantics(
|
||||
button: true,
|
||||
enabled: (action.isEnabled?.call(dashboardViewModel) ?? true),
|
||||
child: ActionButton(
|
||||
key: action.key,
|
||||
image: Image.asset(action.image,
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
title: action.name(context),
|
||||
onClick: (action.isEnabled?.call(dashboardViewModel) ?? true)
|
||||
? () async =>
|
||||
await action.onTap(context, dashboardViewModel)
|
||||
: null,
|
||||
textColor: action.isEnabled?.call(dashboardViewModel) ?? true
|
||||
? null
|
||||
: Theme.of(context).colorScheme.onSurface,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ClipRect(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: MainActions.all
|
||||
.where((element) =>
|
||||
element.canShow?.call(dashboardViewModel) ??
|
||||
true)
|
||||
.map(
|
||||
(action) => Expanded(
|
||||
child: Semantics(
|
||||
button: true,
|
||||
enabled: (action.isEnabled
|
||||
?.call(dashboardViewModel) ??
|
||||
true),
|
||||
child: ActionButton(
|
||||
key: action.key,
|
||||
image: Image.asset(
|
||||
action.image,
|
||||
height: 24,
|
||||
width: 24,
|
||||
color:
|
||||
Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
title: action.name(context),
|
||||
onClick: (action.isEnabled
|
||||
?.call(dashboardViewModel) ??
|
||||
true)
|
||||
? () async => await action.onTap(
|
||||
context, dashboardViewModel)
|
||||
: null,
|
||||
textColor: action.isEnabled
|
||||
?.call(dashboardViewModel) ??
|
||||
true
|
||||
? null
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -21,6 +21,11 @@ class ActionButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
minimumSize: Size.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
onPressed: () {
|
||||
if (route?.isNotEmpty ?? false) {
|
||||
Navigator.of(context, rootNavigator: true).pushNamed(route!);
|
||||
@@ -28,31 +33,32 @@ class ActionButton extends StatelessWidget {
|
||||
onClick?.call();
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.only(top: 5, bottom: 4, left: 0, right: 0),
|
||||
alignment: alignment,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
//mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle),
|
||||
child: image,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.visible,
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: textColor ?? Theme.of(context).colorScheme.onSurface),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
],
|
||||
child: SizedBox.expand(
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
alignment: alignment,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
const SizedBox(height: 4),
|
||||
Flexible(
|
||||
child: Text(
|
||||
title,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: textColor ??
|
||||
Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@ class HeaderRow extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).transactions,
|
||||
S.of(context).history,
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurface),
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/entities/page_indicator_actions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
|
||||
class PageIndicator extends StatefulWidget {
|
||||
const PageIndicator({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.dashboardViewModel,
|
||||
});
|
||||
|
||||
final PageController controller;
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
|
||||
@override
|
||||
State<PageIndicator> createState() => _PageIndicatorState();
|
||||
}
|
||||
|
||||
class _PageIndicatorState extends State<PageIndicator> {
|
||||
static const barHeight = 37.0;
|
||||
static const iconWidth = 16.0;
|
||||
static const iconHeight = 16.0;
|
||||
static const iconSpacing = 5.0;
|
||||
static const barHorizontalPadding = 4.0;
|
||||
static const pillHorizontalPadding = 8.0;
|
||||
static const edgePadding = 5.0;
|
||||
static const barBorderRadius = 50.0;
|
||||
static const pillBorderRadius = 50.0;
|
||||
static const pageSwitchDuration = Duration(milliseconds: 300);
|
||||
static const pillMoveDuration = Duration(milliseconds: 300);
|
||||
static const pillResizeDuration = Duration(milliseconds: 200);
|
||||
static const textStyle = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
);
|
||||
|
||||
late int selectedIndex;
|
||||
late final VoidCallback _pageListener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
selectedIndex = widget.controller.initialPage;
|
||||
|
||||
_pageListener = () {
|
||||
final page = widget.controller.page;
|
||||
if (page == null) return;
|
||||
|
||||
final rounded = page.round();
|
||||
if (rounded != selectedIndex && mounted) {
|
||||
setState(() {
|
||||
selectedIndex = rounded;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
widget.controller.addListener(_pageListener);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.controller.removeListener(_pageListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onItemTap(int index) {
|
||||
if (index == selectedIndex) return;
|
||||
widget.controller.animateToPage(
|
||||
index,
|
||||
duration: pageSwitchDuration,
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
}
|
||||
|
||||
double _estimateItemWidthForAction(
|
||||
BuildContext context, PageIndicatorActions action,
|
||||
{Color? color}) {
|
||||
final text = action.name(context);
|
||||
final textPainter = TextPainter(
|
||||
text: TextSpan(text: text, style: textStyle.copyWith(color: color)),
|
||||
maxLines: 1,
|
||||
textDirection: Directionality.of(context),
|
||||
textScaler: MediaQuery.of(context).textScaler,
|
||||
)..layout();
|
||||
return iconWidth +
|
||||
iconSpacing +
|
||||
textPainter.width +
|
||||
pillHorizontalPadding * 2;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
final visibleActions = PageIndicatorActions.all.where((action) {
|
||||
return action.isEnabled?.call(widget.dashboardViewModel) ?? true;
|
||||
}).toList();
|
||||
|
||||
// Don't show indicator if less than 2 actions
|
||||
if (visibleActions.length < 2) return const SizedBox.shrink();
|
||||
|
||||
selectedIndex = selectedIndex.clamp(0, visibleActions.length - 1);
|
||||
|
||||
// Theme setup
|
||||
final theme = Theme.of(context);
|
||||
final backgroundColor = theme.colorScheme.surfaceContainer.withAlpha(122);
|
||||
final pillColor = theme.colorScheme.onSurface.withAlpha(30);
|
||||
final activeColor = theme.colorScheme.onSurface;
|
||||
final inactiveColor = theme.colorScheme.primary;
|
||||
|
||||
// Size calculations
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
final isRTL = Directionality.of(context) == TextDirection.rtl;
|
||||
|
||||
final pillWidth = _estimateItemWidthForAction(
|
||||
context,
|
||||
visibleActions[selectedIndex],
|
||||
color: activeColor,
|
||||
);
|
||||
|
||||
final actionWidths = [
|
||||
for (final action in visibleActions)
|
||||
_estimateItemWidthForAction(context, action, color: inactiveColor)
|
||||
];
|
||||
|
||||
final totalItemsWidth =
|
||||
actionWidths.fold(0.0, (sum, width) => sum + width) +
|
||||
barHorizontalPadding * 2;
|
||||
|
||||
final barWidth = math.min(totalItemsWidth, screenWidth * 0.95);
|
||||
|
||||
final count = visibleActions.length;
|
||||
final firstLeft = edgePadding;
|
||||
final secondLeft =
|
||||
barWidth - (isRTL ? actionWidths.first : actionWidths[1]) - edgePadding;
|
||||
|
||||
final List<double> positions;
|
||||
|
||||
if (count == 2) {
|
||||
positions = [firstLeft, secondLeft];
|
||||
} else {
|
||||
final lastLeft = barWidth -
|
||||
(isRTL ? actionWidths.first : actionWidths.last) -
|
||||
edgePadding;
|
||||
|
||||
final centerLeft = (isRTL
|
||||
? actionWidths.last + edgePadding
|
||||
: actionWidths.first + edgePadding);
|
||||
|
||||
positions = [firstLeft, centerLeft, lastLeft];
|
||||
}
|
||||
|
||||
final left =
|
||||
(isRTL ? positions.reversed.toList() : positions)[selectedIndex];
|
||||
final currentAction = visibleActions[selectedIndex];
|
||||
|
||||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Container(
|
||||
width: barWidth,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(barBorderRadius),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
|
||||
child: Container(
|
||||
height: barHeight,
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: BorderRadius.circular(barBorderRadius),
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
AnimatedPill(
|
||||
left: left,
|
||||
pillColor: pillColor,
|
||||
currentAction: currentAction,
|
||||
pillIconHeight: iconHeight,
|
||||
pillIconWidth: iconWidth,
|
||||
pillIconSpacing: iconSpacing,
|
||||
pillBorderRadius: pillBorderRadius,
|
||||
contentColor: activeColor,
|
||||
estimateWidthForAction: pillWidth,
|
||||
pillTextStyle: textStyle,
|
||||
pillMoveDuration: pillMoveDuration,
|
||||
pillResizeDuration: pillResizeDuration,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: barHorizontalPadding),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
for (int i = 0; i < visibleActions.length; i++)
|
||||
Semantics(
|
||||
button: true,
|
||||
label: visibleActions[i].name(context),
|
||||
value: i == selectedIndex ? 'Selected' : null,
|
||||
hint: 'Double tap to open ${visibleActions[i].name(context)} page',
|
||||
onTap: () => _onItemTap(i),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () => _onItemTap(i),
|
||||
child: Container(
|
||||
height: barHeight,
|
||||
width: i == selectedIndex
|
||||
? pillWidth
|
||||
: _estimateItemWidthForAction(
|
||||
context, visibleActions[i]),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TweenAnimationBuilder<Color?>(
|
||||
duration: const Duration(
|
||||
milliseconds: 300),
|
||||
curve: Curves.easeOutCubic,
|
||||
tween: ColorTween(
|
||||
begin: inactiveColor,
|
||||
end: i == selectedIndex
|
||||
? activeColor
|
||||
: inactiveColor,
|
||||
),
|
||||
builder: (context, color, _) =>
|
||||
SvgPicture.asset(
|
||||
visibleActions[i].image,
|
||||
width: iconWidth,
|
||||
height: iconHeight,
|
||||
colorFilter: ColorFilter.mode(
|
||||
color!, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
SizedBox(width: iconSpacing),
|
||||
TweenAnimationBuilder<Color?>(
|
||||
duration: const Duration(
|
||||
milliseconds: 300),
|
||||
curve: Curves.easeOutCubic,
|
||||
tween: ColorTween(
|
||||
begin: inactiveColor,
|
||||
end: i == selectedIndex
|
||||
? activeColor
|
||||
: inactiveColor,
|
||||
),
|
||||
builder: (context, color, _) =>
|
||||
Text(
|
||||
visibleActions[i].name(context),
|
||||
style: textStyle.copyWith(
|
||||
color: color),
|
||||
overflow: TextOverflow.fade,
|
||||
softWrap: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AnimatedPill extends StatelessWidget {
|
||||
const AnimatedPill({
|
||||
super.key,
|
||||
required this.left,
|
||||
required this.pillColor,
|
||||
required this.contentColor,
|
||||
required this.pillIconHeight,
|
||||
required this.pillIconWidth,
|
||||
required this.pillBorderRadius,
|
||||
required this.currentAction,
|
||||
required this.estimateWidthForAction,
|
||||
required this.pillIconSpacing,
|
||||
required this.pillTextStyle,
|
||||
required this.pillMoveDuration,
|
||||
required this.pillResizeDuration,
|
||||
});
|
||||
|
||||
final double left;
|
||||
final Color pillColor;
|
||||
final Color contentColor;
|
||||
final double pillIconHeight;
|
||||
final double pillIconWidth;
|
||||
final double pillBorderRadius;
|
||||
final PageIndicatorActions currentAction;
|
||||
final double estimateWidthForAction;
|
||||
final double pillIconSpacing;
|
||||
final TextStyle pillTextStyle;
|
||||
final Duration pillMoveDuration;
|
||||
final Duration pillResizeDuration;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedPositioned(
|
||||
duration: pillMoveDuration,
|
||||
curve: Curves.easeOutCubic,
|
||||
left: left,
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
child: AnimatedContainer(
|
||||
duration: pillResizeDuration,
|
||||
curve: Curves.easeOutCubic,
|
||||
width: estimateWidthForAction,
|
||||
decoration: BoxDecoration(
|
||||
color: pillColor,
|
||||
borderRadius: BorderRadius.circular(pillBorderRadius)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class DisplaySettingsPage extends BasePage {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SettingsSwitcherCell(
|
||||
title: S.of(context).show_market_place,
|
||||
title: S.of(context).apps,
|
||||
value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
|
||||
onValueChange: (_, bool value) {
|
||||
_displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(value);
|
||||
|
||||
Reference in New Issue
Block a user