mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-03 17:40:43 +00:00
Refactor sidebar state management
This commit is contained in:
parent
89fe8df459
commit
bdfe070f8d
11 changed files with 140 additions and 146 deletions
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 663 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
|
@ -19,6 +19,7 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart
|
|||
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
|
||||
import 'package:cake_wallet/themes/theme_list.dart';
|
||||
import 'package:cake_wallet/utils/payment_request.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
|
||||
|
@ -168,6 +169,7 @@ import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
|||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
|
||||
final getIt = GetIt.instance;
|
||||
|
||||
var _isSetupFinished = false;
|
||||
|
@ -832,6 +834,8 @@ Future setup(
|
|||
|
||||
getIt.registerFactory(() => DesktopWalletSelectionDropDown(getIt.get<WalletListViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => DesktopSidebarViewModel());
|
||||
|
||||
getIt.registerFactoryParam<IoniaPaymentStatusViewModel, IoniaAnyPayPaymentInfo, AnyPayPaymentCommittedInfo>(
|
||||
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo)
|
||||
=> IoniaPaymentStatusViewModel(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/main_actions.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
|
||||
|
@ -10,6 +11,7 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
|||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
|
@ -37,6 +39,7 @@ class DashboardPage extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final desktopSidebarViewModel = getIt<DesktopSidebarViewModel>();
|
||||
return Scaffold(
|
||||
body: ResponsiveLayoutUtil.instance.isMobile(context)
|
||||
? _DashboardPageView(
|
||||
|
@ -45,7 +48,9 @@ class DashboardPage extends StatelessWidget {
|
|||
addressListViewModel: addressListViewModel,
|
||||
)
|
||||
: DesktopSidebarWrapper(
|
||||
desktopSidebarViewModel: desktopSidebarViewModel,
|
||||
child: DesktopDashboardPage(
|
||||
desktopSidebarViewModel: desktopSidebarViewModel,
|
||||
balancePage: balancePage,
|
||||
walletViewModel: walletViewModel,
|
||||
addressListViewModel: addressListViewModel,
|
||||
|
|
|
@ -4,17 +4,18 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet
|
|||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_view.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
|
||||
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/main.dart';
|
||||
|
||||
|
@ -23,6 +24,7 @@ class DesktopDashboardPage extends BasePage {
|
|||
required this.balancePage,
|
||||
required this.walletViewModel,
|
||||
required this.addressListViewModel,
|
||||
required this.desktopSidebarViewModel,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -58,8 +60,9 @@ class DesktopDashboardPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final iconPath = Image.asset('assets/images/solid_desktop_menu.png',
|
||||
color: Theme.of(context).accentTextTheme.headline2!.backgroundColor!);
|
||||
final selectedIconPath = 'assets/images/desktop_transactions_solid_icon.png';
|
||||
final unselectedIconPath = 'assets/images/desktop_transactions_outline_icon.png';
|
||||
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
String? currentPath;
|
||||
|
@ -70,18 +73,30 @@ class DesktopDashboardPage extends BasePage {
|
|||
});
|
||||
|
||||
if (currentPath == Routes.transactionsPage) {
|
||||
return Navigator.pop(desktopKey.currentContext!);
|
||||
}
|
||||
desktopSidebarViewModel.resetSidebar();
|
||||
return;
|
||||
}
|
||||
desktopSidebarViewModel.onPageChange(SidebarItem.transactions);
|
||||
|
||||
desktopKey.currentState!.pushNamed(Routes.transactionsPage);
|
||||
|
||||
},
|
||||
child: iconPath,
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
return Image.asset(
|
||||
desktopSidebarViewModel.currentPage == SidebarItem.transactions
|
||||
? selectedIconPath
|
||||
: unselectedIconPath,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final BalancePage balancePage;
|
||||
final DashboardViewModel walletViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
final DesktopSidebarViewModel desktopSidebarViewModel;
|
||||
|
||||
bool _isEffectsInstalled = false;
|
||||
StreamSubscription<bool>? _onInactiveSub;
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import 'dart:async';
|
||||
|
||||
class SideMenuController {
|
||||
late int _currentPage;
|
||||
|
||||
int get currentPage => _currentPage;
|
||||
|
||||
SideMenuController({int initialPage = 0}) {
|
||||
_currentPage = initialPage;
|
||||
}
|
||||
final _streameController = StreamController<int>.broadcast();
|
||||
|
||||
Stream<int> get stream => _streameController.stream;
|
||||
|
||||
void changePage(int index) {
|
||||
_currentPage = index;
|
||||
_streameController.sink.add(index);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_streameController.close();
|
||||
}
|
||||
|
||||
void addListener(void Function(int) listener) {
|
||||
_streameController.stream.listen(listener);
|
||||
}
|
||||
|
||||
void removeListener(void Function(int) listener) {
|
||||
_streameController.stream.listen(listener).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
class SideMenuGlobal {
|
||||
static late SideMenuController controller;
|
||||
}
|
|
@ -1,74 +1,39 @@
|
|||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SideMenuItem extends StatefulWidget {
|
||||
class SideMenuItem extends StatelessWidget {
|
||||
const SideMenuItem({
|
||||
Key? key,
|
||||
this.onTap,
|
||||
required this.onTap,
|
||||
required this.iconPath,
|
||||
required this.priority,
|
||||
required this.isSelected,
|
||||
}) : super(key: key);
|
||||
|
||||
final void Function(int, SideMenuController)? onTap;
|
||||
final void Function() onTap;
|
||||
final String iconPath;
|
||||
final int priority;
|
||||
|
||||
@override
|
||||
_SideMenuItemState createState() => _SideMenuItemState();
|
||||
}
|
||||
|
||||
class _SideMenuItemState extends State<SideMenuItem> {
|
||||
late int currentPage = SideMenuGlobal.controller.currentPage;
|
||||
|
||||
void _handleChange(int page) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
setState(() {
|
||||
currentPage = SideMenuGlobal.controller.currentPage;
|
||||
});
|
||||
if (mounted) {
|
||||
SideMenuGlobal.controller.addListener(_handleChange);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
SideMenuGlobal.controller.removeListener(_handleChange);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Color _setColor() {
|
||||
if (widget.priority == currentPage) {
|
||||
return Theme.of(context).primaryTextTheme.headline6!.color!;
|
||||
} else {
|
||||
return Theme.of(context).highlightColor;
|
||||
}
|
||||
}
|
||||
final bool isSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color _setColor() {
|
||||
if (isSelected) {
|
||||
return Theme.of(context).primaryTextTheme.headline6!.color!;
|
||||
} else {
|
||||
return Theme.of(context).highlightColor;
|
||||
}
|
||||
}
|
||||
|
||||
return InkWell(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Image.asset(
|
||||
widget.iconPath,
|
||||
iconPath,
|
||||
fit: BoxFit.cover,
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: _setColor(),
|
||||
),
|
||||
),
|
||||
onTap: () => widget.onTap?.call(widget.priority, SideMenuGlobal.controller),
|
||||
onTap: () => onTap.call(),
|
||||
highlightColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
|
|
|
@ -1,64 +1,76 @@
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_view.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_controller.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/router.dart' as Router;
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class DesktopSidebarWrapper extends StatefulWidget {
|
||||
class DesktopSidebarWrapper extends StatelessWidget {
|
||||
final Widget child;
|
||||
final DesktopSidebarViewModel desktopSidebarViewModel;
|
||||
|
||||
const DesktopSidebarWrapper({required this.child});
|
||||
|
||||
@override
|
||||
State<DesktopSidebarWrapper> createState() => _DesktopSidebarWrapperState();
|
||||
}
|
||||
|
||||
class _DesktopSidebarWrapperState extends State<DesktopSidebarWrapper> {
|
||||
final page = PageController();
|
||||
final sideMenu = SideMenuController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
SideMenuGlobal.controller = sideMenu;
|
||||
sideMenu.addListener((p0) {
|
||||
page.jumpToPage(p0);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
const DesktopSidebarWrapper({required this.child, required this.desktopSidebarViewModel});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final pageController = PageController();
|
||||
|
||||
reaction<SidebarItem>((_) => desktopSidebarViewModel.currentPage, (page) {
|
||||
String? currentPath;
|
||||
|
||||
desktopKey.currentState?.popUntil((route) {
|
||||
currentPath = route.settings.name;
|
||||
return true;
|
||||
});
|
||||
if (page == SidebarItem.transactions) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentPath == Routes.transactionsPage) {
|
||||
Navigator.of(desktopKey.currentContext!).pop();
|
||||
}
|
||||
|
||||
pageController.animateToPage(
|
||||
page.index,
|
||||
duration: Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
});
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SideMenu(
|
||||
topItems: [
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/wallet_outline.png',
|
||||
priority: 0,
|
||||
onTap: (page, _) => sideMenu.changePage(page),
|
||||
),
|
||||
],
|
||||
bottomItems: [
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/support_icon.png',
|
||||
priority: 1,
|
||||
onTap: (page, _) => sideMenu.changePage(page),
|
||||
),
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/settings_outline.png',
|
||||
priority: 2,
|
||||
onTap: (page, _) => sideMenu.changePage(page),
|
||||
),
|
||||
],
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return SideMenu(
|
||||
topItems: [
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/wallet_outline.png',
|
||||
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.dashboard,
|
||||
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.dashboard),
|
||||
),
|
||||
],
|
||||
bottomItems: [
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/support_icon.png',
|
||||
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support,
|
||||
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support)),
|
||||
SideMenuItem(
|
||||
iconPath: 'assets/images/settings_outline.png',
|
||||
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.settings,
|
||||
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.settings),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
Expanded(
|
||||
child: PageView(
|
||||
controller: page,
|
||||
controller: pageController,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
widget.child,
|
||||
child,
|
||||
Container(
|
||||
child: Navigator(
|
||||
initialRoute: Routes.support,
|
||||
|
|
|
@ -22,6 +22,7 @@ class TransactionsPage extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
padding: EdgeInsets.only(
|
||||
top: 24,
|
||||
bottom: 24
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_controller.dart';
|
||||
import 'package:cake_wallet/src/widgets/setting_action_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/setting_actions.dart';
|
||||
import 'package:cake_wallet/typography.dart';
|
||||
|
@ -17,19 +16,14 @@ class DesktopSettingsPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
|
||||
int itemCount = 0;
|
||||
SideMenuController sideMenu = SideMenuController();
|
||||
int itemCount = SettingActions.all.length;
|
||||
int? currentPage;
|
||||
bool isTapped = false;
|
||||
|
||||
initState() {
|
||||
super.initState();
|
||||
itemCount = SettingActions.all.length;
|
||||
sideMenu.addListener((index) {
|
||||
setState(() {
|
||||
isTapped = true;
|
||||
currentPage = index;
|
||||
});
|
||||
void _onItemChange(int index) {
|
||||
setState(() {
|
||||
currentPage = index;
|
||||
isTapped = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -67,8 +61,8 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
|
|||
if (currentPage != index) {
|
||||
final settingContext =
|
||||
_settingsNavigatorKey.currentState?.context ?? context;
|
||||
sideMenu.changePage(index);
|
||||
item.onTap.call(settingContext);
|
||||
_onItemChange(index);
|
||||
}
|
||||
},
|
||||
image: item.image,
|
||||
|
|
33
lib/view_model/dashboard/desktop_sidebar_view_model.dart
Normal file
33
lib/view_model/dashboard/desktop_sidebar_view_model.dart
Normal file
|
@ -0,0 +1,33 @@
|
|||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'desktop_sidebar_view_model.g.dart';
|
||||
|
||||
enum SidebarItem {
|
||||
dashboard(0),
|
||||
support(1),
|
||||
settings(2),
|
||||
transactions(3);
|
||||
|
||||
final int value;
|
||||
const SidebarItem(this.value);
|
||||
}
|
||||
|
||||
class DesktopSidebarViewModel = DesktopSidebarViewModelBase with _$DesktopSidebarViewModel;
|
||||
|
||||
abstract class DesktopSidebarViewModelBase with Store {
|
||||
DesktopSidebarViewModelBase();
|
||||
|
||||
@observable
|
||||
SidebarItem currentPage = SidebarItem.dashboard;
|
||||
|
||||
|
||||
@action
|
||||
void onPageChange(SidebarItem item) {
|
||||
currentPage = item;
|
||||
}
|
||||
|
||||
@action
|
||||
void resetSidebar() {
|
||||
currentPage = SidebarItem.dashboard;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue