mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-23 23:58:48 +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/onramper_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/buy/pre_order_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/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/display_settings_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
|
import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/settings/privacy_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:
|
case Routes.desktop_actions:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
builder: (_) => DesktopDashboardActions(getIt<DashboardViewModel>()));
|
builder: (_) => DesktopDashboardActions(getIt<DashboardViewModel>()));
|
||||||
|
|
||||||
|
case Routes.desktop_settings_page:
|
||||||
|
return CupertinoPageRoute<void>(
|
||||||
|
builder: (_) => DesktopSettingsPage());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Routes {
|
||||||
static const exchangeTrade = '/exchange_trade';
|
static const exchangeTrade = '/exchange_trade';
|
||||||
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
|
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
|
||||||
static const exchange = '/exchange';
|
static const exchange = '/exchange';
|
||||||
static const settings = '/settings';
|
static const desktop_settings_page = '/desktop_settings_page';
|
||||||
static const unlock = '/auth_not_closable';
|
static const unlock = '/auth_not_closable';
|
||||||
static const rescan = '/rescan';
|
static const rescan = '/rescan';
|
||||||
static const faq = '/faq';
|
static const faq = '/faq';
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:cake_wallet/entities/main_actions.dart';
|
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_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/src/screens/dashboard/widgets/market_place_page.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/routes.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:mobx/mobx.dart';
|
||||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
import 'package:cake_wallet/main.dart';
|
import 'package:cake_wallet/main.dart';
|
||||||
|
import 'package:cake_wallet/router.dart' as Router;
|
||||||
|
|
||||||
class DashboardPage extends BasePage {
|
class DashboardPage extends StatefulWidget {
|
||||||
DashboardPage({
|
DashboardPage({
|
||||||
required this.balancePage,
|
required this.balancePage,
|
||||||
required this.walletViewModel,
|
required this.walletViewModel,
|
||||||
required this.addressListViewModel,
|
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;
|
final BalancePage balancePage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -38,6 +159,9 @@ class DashboardPage extends BasePage {
|
||||||
@override
|
@override
|
||||||
Color get backgroundDarkColor => Colors.transparent;
|
Color get backgroundDarkColor => Colors.transparent;
|
||||||
|
|
||||||
|
@override
|
||||||
|
AppBarStyle get appBarStyle => AppBarStyle.transparent;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||||
(BuildContext context, Widget scaffold) => Container(
|
(BuildContext context, Widget scaffold) => Container(
|
||||||
|
@ -101,26 +225,24 @@ class DashboardPage extends BasePage {
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
itemCount: pages.length,
|
itemCount: pages.length,
|
||||||
itemBuilder: (context, index) => pages[index])),
|
itemBuilder: (context, index) => pages[index])),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(bottom: 24, top: 10),
|
padding: EdgeInsets.only(bottom: 24, top: 10),
|
||||||
child: SmoothPageIndicator(
|
child: SmoothPageIndicator(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
count: pages.length,
|
count: pages.length,
|
||||||
effect: ColorTransitionEffect(
|
effect: ColorTransitionEffect(
|
||||||
spacing: 6.0,
|
spacing: 6.0,
|
||||||
radius: 6.0,
|
radius: 6.0,
|
||||||
dotWidth: 6.0,
|
dotWidth: 6.0,
|
||||||
dotHeight: 6.0,
|
dotHeight: 6.0,
|
||||||
dotColor: Theme.of(context).indicatorColor,
|
dotColor: Theme.of(context).indicatorColor,
|
||||||
activeDotColor: Theme.of(context)
|
activeDotColor:
|
||||||
.accentTextTheme!
|
Theme.of(context).accentTextTheme!.headline4!.backgroundColor!),
|
||||||
.headline4!
|
)),
|
||||||
.backgroundColor!),
|
|
||||||
)),
|
|
||||||
Observer(builder: (_) {
|
Observer(builder: (_) {
|
||||||
return ClipRect(
|
return ClipRect(
|
||||||
child: Container(
|
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)),
|
bottomRight: Radius.circular(24)),
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [
|
||||||
Theme.of(context)
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
.primaryTextTheme!
|
|
||||||
.subtitle2!
|
Theme.of(context).accentColor,
|
||||||
.color!,
|
],
|
||||||
Theme.of(context)
|
|
||||||
.primaryTextTheme!
|
|
||||||
.subtitle2!
|
|
||||||
.decorationColor!,
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
begin: Alignment.topLeft,
|
||||||
end: Alignment.bottomRight),
|
end: Alignment.topRight),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
|
padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
|
||||||
child: Observer(
|
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