mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-18 08:45:05 +00:00
Add desktop sidebar
This commit is contained in:
parent
42a28d4246
commit
4f1f51e0aa
12 changed files with 314 additions and 31 deletions
BIN
assets/images/settings_outline.png
Normal file
BIN
assets/images/settings_outline.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 871 B |
BIN
assets/images/support_icon.png
Normal file
BIN
assets/images/support_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 819 B |
BIN
assets/images/wallet_outline.png
Normal file
BIN
assets/images/wallet_outline.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 B |
BIN
assets/images/wallet_solid.png
Normal file
BIN
assets/images/wallet_solid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 581 B |
|
@ -6,6 +6,7 @@ import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
|
|||
import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/desktop_settings/dashboard_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
|
||||
|
@ -516,6 +517,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
case Routes.desktop_actions:
|
||||
return CupertinoPageRoute<void>(
|
||||
builder: (_) => DesktopDashboardActions(getIt<DashboardViewModel>()));
|
||||
|
||||
case Routes.desktop_settings_page:
|
||||
return CupertinoPageRoute<void>(
|
||||
builder: (_) => DesktopSettingsPage());
|
||||
|
||||
default:
|
||||
return MaterialPageRoute<void>(
|
||||
|
|
|
@ -36,7 +36,7 @@ class Routes {
|
|||
static const exchangeTrade = '/exchange_trade';
|
||||
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
|
||||
static const exchange = '/exchange';
|
||||
static const settings = '/settings';
|
||||
static const desktop_settings_page = '/desktop_settings_page';
|
||||
static const unlock = '/auth_not_closable';
|
||||
static const rescan = '/rescan';
|
||||
static const faq = '/faq';
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import 'dart:async';
|
||||
import 'package:cake_wallet/entities/main_actions.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/src/screens/dashboard/widgets/market_place_page.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
|
@ -21,14 +24,132 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:cake_wallet/main.dart';
|
||||
import 'package:cake_wallet/router.dart' as Router;
|
||||
|
||||
class DashboardPage extends BasePage {
|
||||
class DashboardPage extends StatefulWidget {
|
||||
DashboardPage({
|
||||
required this.balancePage,
|
||||
required this.walletViewModel,
|
||||
required this.addressListViewModel,
|
||||
});
|
||||
|
||||
final BalancePage balancePage;
|
||||
final DashboardViewModel walletViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
|
||||
@override
|
||||
State<DashboardPage> createState() => _DashboardPageState();
|
||||
}
|
||||
|
||||
class _DashboardPageState extends State<DashboardPage> {
|
||||
PageController page = PageController();
|
||||
SideMenuController sideMenu = SideMenuController();
|
||||
@override
|
||||
void initState() {
|
||||
sideMenu.addListener((p0) {
|
||||
page.jumpToPage(p0);
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: LayoutBuilder(builder: (context, constraints) {
|
||||
if (constraints.maxWidth > 900) {
|
||||
return Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: SideMenu(
|
||||
controller: 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);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 9,
|
||||
child: PageView(
|
||||
controller: page,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
_DashboardPage(
|
||||
balancePage: widget.balancePage,
|
||||
walletViewModel: widget.walletViewModel,
|
||||
addressListViewModel: widget.addressListViewModel,
|
||||
),
|
||||
Container(
|
||||
child: Navigator(
|
||||
initialRoute: Routes.support,
|
||||
onGenerateRoute: (settings) => Router.createRoute(settings),
|
||||
onGenerateInitialRoutes:
|
||||
(NavigatorState navigator, String initialRouteName) {
|
||||
return [
|
||||
navigator
|
||||
.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
|
||||
];
|
||||
},
|
||||
),
|
||||
),
|
||||
Navigator(
|
||||
initialRoute: Routes.desktop_settings_page,
|
||||
onGenerateRoute: (settings) => Router.createRoute(settings),
|
||||
onGenerateInitialRoutes:
|
||||
(NavigatorState navigator, String initialRouteName) {
|
||||
return [
|
||||
navigator
|
||||
.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
|
||||
];
|
||||
},
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return _DashboardPage(
|
||||
balancePage: widget.balancePage,
|
||||
walletViewModel: widget.walletViewModel,
|
||||
addressListViewModel: widget.addressListViewModel);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DashboardPage extends BasePage {
|
||||
_DashboardPage({
|
||||
required this.balancePage,
|
||||
required this.walletViewModel,
|
||||
required this.addressListViewModel,
|
||||
});
|
||||
|
||||
final BalancePage balancePage;
|
||||
|
||||
@override
|
||||
|
@ -38,6 +159,9 @@ class DashboardPage extends BasePage {
|
|||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
|
||||
@override
|
||||
AppBarStyle get appBarStyle => AppBarStyle.transparent;
|
||||
|
||||
@override
|
||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||
(BuildContext context, Widget scaffold) => Container(
|
||||
|
@ -101,26 +225,24 @@ class DashboardPage extends BasePage {
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: PageView.builder(
|
||||
controller: controller,
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) => pages[index])),
|
||||
child: PageView.builder(
|
||||
controller: controller,
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) => pages[index])),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 24, top: 10),
|
||||
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).indicatorColor,
|
||||
activeDotColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.headline4!
|
||||
.backgroundColor!),
|
||||
)),
|
||||
padding: EdgeInsets.only(bottom: 24, top: 10),
|
||||
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).indicatorColor,
|
||||
activeDotColor:
|
||||
Theme.of(context).accentTextTheme!.headline4!.backgroundColor!),
|
||||
)),
|
||||
Observer(builder: (_) {
|
||||
return ClipRect(
|
||||
child: Container(
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
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:flutter/material.dart';
|
||||
|
||||
class SideMenu extends StatelessWidget {
|
||||
const SideMenu({
|
||||
super.key,
|
||||
required this.topItems,
|
||||
required this.controller,
|
||||
required this.bottomItems,
|
||||
});
|
||||
final List<SideMenuItem> topItems;
|
||||
final List<SideMenuItem> bottomItems;
|
||||
|
||||
final SideMenuController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SideMenuGlobal.controller = controller;
|
||||
return Container(
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
...topItems,
|
||||
Spacer(),
|
||||
...bottomItems,
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
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;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SideMenuItem extends StatefulWidget {
|
||||
const SideMenuItem({
|
||||
Key? key,
|
||||
this.onTap,
|
||||
required this.iconPath,
|
||||
required this.priority,
|
||||
}) : super(key: key);
|
||||
|
||||
final void Function(int, SideMenuController)? 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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Image.asset(
|
||||
widget.iconPath,
|
||||
fit: BoxFit.cover,
|
||||
height: 30,
|
||||
width: 30,
|
||||
color: _setColor(),
|
||||
),
|
||||
),
|
||||
onTap: () => widget.onTap?.call(widget.priority, SideMenuGlobal.controller),
|
||||
highlightColor: Colors.transparent,
|
||||
focusColor: Colors.transparent,
|
||||
hoverColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -168,17 +168,12 @@ class ExchangePage extends BasePage {
|
|||
bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.subtitle2!
|
||||
.color!,
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.subtitle2!
|
||||
.decorationColor!,
|
||||
],
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
|
||||
Theme.of(context).accentColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight),
|
||||
end: Alignment.topRight),
|
||||
),
|
||||
padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
|
||||
child: Observer(
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class DesktopSettingsPage extends StatelessWidget {
|
||||
const DesktopSettingsPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Center(
|
||||
child: Text('Desktop settings page'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue