Add desktop sidebar

This commit is contained in:
Godwin Asuquo 2023-01-25 15:57:56 +02:00
parent 42a28d4246
commit 4f1f51e0aa
12 changed files with 314 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

View file

@ -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>(

View file

@ -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';

View file

@ -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(

View file

@ -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),
],
),
);
}
}

View file

@ -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;
}

View file

@ -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,
);
}
}

View file

@ -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(

View file

@ -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'),
),
);
}
}