Skip to content

Commit

Permalink
Cw 497 wallet connect for desktop (#1134)
Browse files Browse the repository at this point in the history
* feat: Implement WalletConnect for Desktop

* feat: WalletConnect for Desktop

* fix: Properly handle and dispose textEditingController for URI

* chore: Move BottomSheetListener to Sidebar for desktop app

* Remove unused variable and imports

* Update desktop_settings_page.dart

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
  • Loading branch information
Blazebrain and OmarHatem28 authored Oct 19, 2023
1 parent 8ca9fa0 commit 374110d
Show file tree
Hide file tree
Showing 35 changed files with 344 additions and 129 deletions.
6 changes: 5 additions & 1 deletion lib/di.dart
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/entities/qr_view_data.dart';

import 'core/totp_request_details.dart';
import 'src/screens/settings/desktop_settings/desktop_settings_page.dart';

final getIt = GetIt.instance;

Expand Down Expand Up @@ -488,6 +489,7 @@ Future<void> setup({
getIt.registerFactory<DesktopSidebarWrapper>(() {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
return DesktopSidebarWrapper(
bottomSheetService: getIt.get<BottomSheetService>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
desktopSidebarViewModel: getIt.get<DesktopSidebarViewModel>(),
child: getIt.get<DesktopDashboardPage>(param1: _navigatorKey),
Expand All @@ -496,7 +498,6 @@ Future<void> setup({
});
getIt.registerFactoryParam<DesktopDashboardPage, GlobalKey<NavigatorState>, void>(
(desktopKey, _) => DesktopDashboardPage(
bottomSheetService: getIt.get<BottomSheetService>(),
balancePage: getIt.get<BalancePage>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
Expand All @@ -515,6 +516,9 @@ Future<void> setup({
getIt.registerFactory<Modify2FAPage>(
() => Modify2FAPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));

getIt.registerFactory<DesktopSettingsPage>(
() => DesktopSettingsPage());

getIt.registerFactoryParam<ReceiveOptionViewModel, ReceivePageOption?, void>(
(pageOption, _) => ReceiveOptionViewModel(getIt.get<AppStore>().wallet!, pageOption));

Expand Down
2 changes: 1 addition & 1 deletion lib/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
);

case Routes.desktop_settings_page:
return CupertinoPageRoute<void>(builder: (_) => DesktopSettingsPage());
return CupertinoPageRoute<void>(builder: (_) => getIt.get<DesktopSettingsPage>());

case Routes.empty_no_route:
return MaterialPageRoute<void>(builder: (_) => SizedBox.shrink());
Expand Down
53 changes: 23 additions & 30 deletions lib/src/screens/dashboard/desktop_dashboard_page.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dart:async';
import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.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/utils/show_pop_up.dart';
Expand All @@ -21,14 +19,12 @@ import 'package:shared_preferences/shared_preferences.dart';
class DesktopDashboardPage extends StatelessWidget {
DesktopDashboardPage({
required this.balancePage,
required this.bottomSheetService,
required this.dashboardViewModel,
required this.addressListViewModel,
required this.desktopKey,
});

final BalancePage balancePage;
final BottomSheetService bottomSheetService;
final DashboardViewModel dashboardViewModel;
final WalletAddressListViewModel addressListViewModel;
final GlobalKey<NavigatorState> desktopKey;
Expand All @@ -40,34 +36,31 @@ class DesktopDashboardPage extends StatelessWidget {
Widget build(BuildContext context) {
_setEffects(context);

return BottomSheetListener(
bottomSheetService: bottomSheetService,
child: Container(
color: Theme.of(context).colorScheme.background,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 400,
child: balancePage,
),
Flexible(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 500),
child: Navigator(
key: desktopKey,
initialRoute: Routes.desktop_actions,
onGenerateRoute: (settings) => Router.createRoute(settings),
onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) {
return [
navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
];
},
),
return Container(
color: Theme.of(context).colorScheme.background,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 400,
child: balancePage,
),
Flexible(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 500),
child: Navigator(
key: desktopKey,
initialRoute: Routes.desktop_actions,
onGenerateRoute: (settings) => Router.createRoute(settings),
onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) {
return [
navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
];
},
),
),
],
),
),
],
),
);
}
Expand Down
143 changes: 75 additions & 68 deletions lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:cake_wallet/core/wallet_connect/wc_bottom_sheet_service.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
Expand All @@ -7,6 +8,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sideba
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:flutter/cupertino.dart';
Expand All @@ -16,13 +18,15 @@ import 'package:cake_wallet/router.dart' as Router;
import 'package:mobx/mobx.dart';

class DesktopSidebarWrapper extends BasePage {
final BottomSheetService bottomSheetService;
final Widget child;
final DesktopSidebarViewModel desktopSidebarViewModel;
final DashboardViewModel dashboardViewModel;
final GlobalKey<NavigatorState> desktopNavigatorKey;

DesktopSidebarWrapper({
required this.child,
required this.bottomSheetService,
required this.desktopSidebarViewModel,
required this.dashboardViewModel,
required this.desktopNavigatorKey,
Expand Down Expand Up @@ -67,84 +71,87 @@ class DesktopSidebarWrapper extends BasePage {
Widget body(BuildContext context) {
_setEffects();

return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Observer(builder: (_) {
return SideMenu(
width: sideMenuWidth,
topItems: [
SideMenuItem(
imagePath: 'assets/images/wallet_outline.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.dashboard,
onTap: () {
desktopSidebarViewModel.onPageChange(SidebarItem.dashboard);
desktopNavigatorKey.currentState
?.pushNamedAndRemoveUntil(Routes.desktop_actions, (route) => false);
},
),
SideMenuItem(
onTap: () {
if (desktopSidebarViewModel.currentPage == SidebarItem.transactions) {
return BottomSheetListener(
bottomSheetService: bottomSheetService,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Observer(builder: (_) {
return SideMenu(
width: sideMenuWidth,
topItems: [
SideMenuItem(
imagePath: 'assets/images/wallet_outline.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.dashboard,
onTap: () {
desktopSidebarViewModel.onPageChange(SidebarItem.dashboard);
desktopNavigatorKey.currentState
?.pushNamedAndRemoveUntil(Routes.desktop_actions, (route) => false);
desktopSidebarViewModel.resetSidebar();
} else {
desktopSidebarViewModel.onPageChange(SidebarItem.transactions);
desktopNavigatorKey.currentState?.pushNamed(Routes.transactionsPage);
}
},
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.transactions,
imagePath: desktopSidebarViewModel.currentPage == SidebarItem.transactions
? selectedIconPath
: unselectedIconPath,
),
],
bottomItems: [
SideMenuItem(
imagePath: 'assets/images/support_icon.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support,
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support)),
SideMenuItem(
imagePath: 'assets/images/settings_outline.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.settings,
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.settings),
),
],
);
}),
Expanded(
child: PageView(
controller: pageController,
physics: NeverScrollableScrollPhysics(),
children: [
child,
Container(
color: Theme.of(context).colorScheme.background,
padding: EdgeInsets.all(20),
child: Navigator(
initialRoute: Routes.support,
},
),
SideMenuItem(
onTap: () {
if (desktopSidebarViewModel.currentPage == SidebarItem.transactions) {
desktopNavigatorKey.currentState
?.pushNamedAndRemoveUntil(Routes.desktop_actions, (route) => false);
desktopSidebarViewModel.resetSidebar();
} else {
desktopSidebarViewModel.onPageChange(SidebarItem.transactions);
desktopNavigatorKey.currentState?.pushNamed(Routes.transactionsPage);
}
},
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.transactions,
imagePath: desktopSidebarViewModel.currentPage == SidebarItem.transactions
? selectedIconPath
: unselectedIconPath,
),
],
bottomItems: [
SideMenuItem(
imagePath: 'assets/images/support_icon.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support,
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support)),
SideMenuItem(
imagePath: 'assets/images/settings_outline.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.settings,
onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.settings),
),
],
);
}),
Expanded(
child: PageView(
controller: pageController,
physics: NeverScrollableScrollPhysics(),
children: [
child,
Container(
color: Theme.of(context).colorScheme.background,
padding: EdgeInsets.all(20),
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))!
];
},
),
),
Navigator(
initialRoute: Routes.desktop_settings_page,
onGenerateRoute: (settings) => Router.createRoute(settings),
onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) {
return [
navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
];
},
),
],
],
),
),
),
],
],
),
);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/src/screens/settings/connection_sync_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ConnectionSyncPage extends BasePage {
);
},
),
if (dashboardViewModel.wallet.type == WalletType.ethereum && DeviceInfo.instance.isMobile) ...[
if (dashboardViewModel.wallet.type == WalletType.ethereum) ...[
WalletConnectTile(
onTap: () async {
Navigator.of(context).push(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ final _settingsNavigatorKey = GlobalKey<NavigatorState>();
class DesktopSettingsPage extends StatefulWidget {
const DesktopSettingsPage({super.key});


@override
State<DesktopSettingsPage> createState() => _DesktopSettingsPageState();
}
Expand Down
20 changes: 19 additions & 1 deletion lib/src/screens/wallet_connect/wc_connections_listing_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import 'dart:developer';
import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/enter_wallet_connect_uri_widget.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart';
Expand Down Expand Up @@ -36,7 +38,13 @@ class WCPairingsWidget extends BasePage {
String get title => S.current.walletConnect;

Future<void> _onScanQrCode(BuildContext context, Web3Wallet web3Wallet) async {
final String? uri = await presentQRScanner();
final String? uri;

if (DeviceInfo.instance.isMobile) {
uri = await presentQRScanner();
} else {
uri = await _showEnterWalletConnectURIPopUp(context);
}

if (uri == null) return _invalidUriToast(context, S.current.nullURIError);

Expand All @@ -51,6 +59,16 @@ class WCPairingsWidget extends BasePage {
}
}

Future<String?> _showEnterWalletConnectURIPopUp(BuildContext context) async {
final walletConnectURI = await showPopUp<String>(
context: context,
builder: (BuildContext context) {
return EnterWalletConnectURIWrapperWidget();
},
);
return walletConnectURI;
}

Future<void> _invalidUriToast(BuildContext context, String message) async {
await showPopUp<void>(
context: context,
Expand Down
Loading

0 comments on commit 374110d

Please sign in to comment.