Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions android/app/src/main/res/drawable/receive.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="251dp"
android:height="251dp"
android:viewportWidth="251"
android:viewportHeight="251">
<path
android:pathData="M125.5,0.5L125.5,0.5A125,125 0,0 1,250.5 125.5L250.5,125.5A125,125 0,0 1,125.5 250.5L125.5,250.5A125,125 0,0 1,0.5 125.5L0.5,125.5A125,125 0,0 1,125.5 0.5z"
android:fillColor="#233461"/>
<path
android:pathData="M125,154.99L91.2,121.19L99.55,112.61L119.06,132.13V65.63H130.94V132.13L150.45,112.61L158.8,121.19L125,154.99ZM79.94,184.38C75.94,184.38 72.55,182.99 69.78,180.22C67.01,177.45 65.63,174.06 65.63,170.06V148.6H77.5V170.06C77.5,170.67 77.75,171.23 78.26,171.74C78.77,172.25 79.33,172.5 79.94,172.5H170.06C170.67,172.5 171.23,172.25 171.74,171.74C172.25,171.23 172.5,170.67 172.5,170.06V148.6H184.38V170.06C184.38,174.06 182.99,177.45 180.22,180.22C177.45,182.99 174.06,184.38 170.06,184.38H79.94Z"
android:fillColor="#91B0FF"/>
</vector>
12 changes: 12 additions & 0 deletions android/app/src/main/res/drawable/send.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="251dp"
android:height="251dp"
android:viewportWidth="251"
android:viewportHeight="251">
<path
android:pathData="M125.5,0.5L125.5,0.5A125,125 0,0 1,250.5 125.5L250.5,125.5A125,125 0,0 1,125.5 250.5L125.5,250.5A125,125 0,0 1,0.5 125.5L0.5,125.5A125,125 0,0 1,125.5 0.5z"
android:fillColor="#233461"/>
<path
android:pathData="M63.02,177.86V137.2L113.5,125L63.02,112.8V72.14L188.52,125L63.02,177.86Z"
android:fillColor="#91B0FF"/>
</vector>
6 changes: 6 additions & 0 deletions ios/Runner/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
23 changes: 23 additions & 0 deletions ios/Runner/Assets.xcassets/receive.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "receive.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "receive-1.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "receive-2.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/receive.imageset/receive-1.svg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming should not contain spaces, use underscore _ instead

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/receive.imageset/receive-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/receive.imageset/receive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions ios/Runner/Assets.xcassets/send.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "send.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "send-1.svg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "send-2.svg",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/send.imageset/send-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/send.imageset/send-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions ios/Runner/Assets.xcassets/send.imageset/send.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 69 additions & 4 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import 'package:flutter_daemon/flutter_daemon.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:hive/hive.dart';
import 'package:cw_core/root_dir.dart';
import 'package:quick_actions/quick_actions.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cw_core/window_size.dart';
import 'package:logging/logging.dart';
Expand All @@ -68,6 +69,7 @@ import 'package:trezor_connect/trezor_connect.dart';
final navigatorKey = GlobalKey<NavigatorState>();
final rootKey = GlobalKey<RootState>();
final RouteObserver<PageRoute<dynamic>> routeObserver = RouteObserver<PageRoute<dynamic>>();
final quickActionsStream = StreamController<Uri?>.broadcast();

Future<void> main({Key? topLevelKey}) async {
await runAppWithZone(topLevelKey: topLevelKey);
Expand All @@ -78,6 +80,43 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {

await runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();

final Completer<String?> initialShortcutCompleter = Completer<String?>();

const QuickActions quickActions = QuickActions();

quickActions.initialize((String shortcutType) {
// Complete the completer only once (for cold starts)
if (!initialShortcutCompleter.isCompleted) {
initialShortcutCompleter.complete(shortcutType);
}

// Convert the shortcut type to a URI and add it to the stream
final uri = Uri.parse('cakewallet://quickaction/$shortcutType');
quickActionsStream.sink.add(uri);
});

quickActions.setShortcutItems(<ShortcutItem>[
const ShortcutItem(
type: 'send',
icon: 'send',
localizedTitle: 'Send',
localizedSubtitle: 'Send funds'),
const ShortcutItem(
type: 'receive',
icon: 'receive',
localizedTitle: 'Receive',
localizedSubtitle: 'Receive funds')
]);

// Fallback in case the initial shortcut is not received (normal cold start)
Future<void>.delayed(const Duration(milliseconds: 500), () {
if (!initialShortcutCompleter.isCompleted) {
initialShortcutCompleter.complete(null);
}
});

final initialQuickAction = await initialShortcutCompleter.future;
FlutterError.onError = ExceptionHandler.onError;

/// A callback that is invoked when an unhandled error occurs in the root
Expand Down Expand Up @@ -125,11 +164,11 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
runApp(
DefaultAssetBundle(
bundle: TestAssetBundle(),
child: App(key: topLevelKey),
child: App(key: topLevelKey, initialQuickAction:initialQuickAction,quickActionsStream: quickActionsStream.stream),
),
);
} else {
runApp(App(key: topLevelKey));
runApp(App(key: topLevelKey, initialQuickAction: initialQuickAction, quickActionsStream: quickActionsStream.stream));
}

isAppRunning = true;
Expand Down Expand Up @@ -325,9 +364,11 @@ Future<void> initialSetup({
}

class App extends StatefulWidget {
App({this.key});
App({this.key, this.initialQuickAction, required this.quickActionsStream});

final Key? key;
final String? initialQuickAction;
final Stream<Uri?> quickActionsStream;
@override
AppState createState() => AppState();
}
Expand Down Expand Up @@ -358,9 +399,13 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
statusBarBrightness: statusBarBrightness,
statusBarIconBrightness: statusBarIconBrightness));

final appRouteObserver = AppRouteObserver();

return Root(
key: widget.key ?? rootKey,
appStore: appStore,
initialQuickAction: widget.initialQuickAction,
quickActionsStream: widget.quickActionsStream,
authenticationStore: authenticationStore,
navigatorKey: navigatorKey,
authService: authService,
Expand All @@ -371,7 +416,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
child: ThemeProvider(
themeStore: appStore.themeStore,
materialAppBuilder: (context, theme, darkTheme, themeMode) => MaterialApp(
navigatorObservers: [routeObserver],
navigatorObservers: [routeObserver, appRouteObserver],
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
theme: theme,
Expand Down Expand Up @@ -497,3 +542,23 @@ Future<void> backgroundSync() async {
}
}
}

class AppRouteObserver extends RouteObserver<PageRoute<dynamic>> {
final AppStore appStore = getIt.get<AppStore>();

@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPush(route, previousRoute);
if (route is PageRoute) {
appStore.currentRouteName = route.settings.name;
}
}

@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPop(route, previousRoute);
if (previousRoute is PageRoute) {
appStore.currentRouteName = previousRoute.settings.name;
}
}
}
11 changes: 6 additions & 5 deletions lib/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@ late RouteSettings currentRouteSettings;

Route<T> handleRouteWithPlatformAwareness<T>(
Widget Function(BuildContext) builder, {
RouteSettings? settings,
bool fullscreenDialog = false,
}) {
if (Platform.isIOS) {
return CupertinoPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog);
return CupertinoPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
} else {
return MaterialPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog);
return MaterialPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
}
}

Expand Down Expand Up @@ -423,19 +424,19 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: initialPaymentRequest,
param2: coinTypeToSpendFrom,
),
settings: settings
);

case Routes.sendTemplate:
return CupertinoPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<SendTemplatePage>());

case Routes.receive:
return CupertinoPageRoute<void>(builder: (context) => getIt.get<ReceivePage>());
return CupertinoPageRoute<void>(builder: (context) => getIt.get<ReceivePage>(), settings: settings);

case Routes.addressPage:
return handleRouteWithPlatformAwareness(
(context) => getIt.get<AddressPage>(),
);
(context) => getIt.get<AddressPage>(), settings: settings);

case Routes.transactionDetails:
return CupertinoPageRoute<void>(
Expand Down
26 changes: 24 additions & 2 deletions lib/src/screens/root/root.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Root extends StatefulWidget {
required this.tradeMonitor,
required this.nodeSwitchingService,
required this.trezorConnect,
this.initialQuickAction,
required this.quickActionsStream,
}) : super(key: key);

final AuthenticationStore authenticationStore;
Expand All @@ -47,6 +49,8 @@ class Root extends StatefulWidget {
final TradeMonitor tradeMonitor;
final NodeSwitchingService nodeSwitchingService;
final TrezorConnect trezorConnect;
final String? initialQuickAction;
final Stream<Uri?> quickActionsStream;

@override
RootState createState() => RootState();
Expand Down Expand Up @@ -103,7 +107,18 @@ class RootState extends State<Root> with WidgetsBindingObserver {
handleDeepLinking(uri);
});

// listen for quick actions
widget.quickActionsStream.listen((Uri? uri) {
handleDeepLinking(uri);
});

handleDeepLinking(await getInitialUri());

if (widget.initialQuickAction != null) {
final uri = Uri.parse('cakewallet://quickaction/${widget.initialQuickAction}');
handleDeepLinking(uri);
}

} catch (e) {
printV(e);
}
Expand All @@ -121,15 +136,22 @@ class RootState extends State<Root> with WidgetsBindingObserver {

bool requireAuth = await widget.authService.requireAuth();

if (!requireAuth && widget.authenticationStore.state == AuthenticationState.allowed) {

if (widget.authenticationStore.state == AuthenticationState.allowedCreate) {
requireAuth = false;
}

if (!requireAuth &&
(widget.authenticationStore.state == AuthenticationState.allowed ||
widget.authenticationStore.state == AuthenticationState.allowedCreate)) {
_navigateToDeepLinkScreen();
return;
}

_deepLinksReactionDisposer = reaction(
(_) => widget.authenticationStore.state,
(AuthenticationState state) {
if (state == AuthenticationState.allowed) {
if (state == AuthenticationState.allowed || state == AuthenticationState.allowedCreate) {
if (widget.appStore.wallet == null) {
waitForWalletInstance(context);
} else {
Expand Down
3 changes: 3 additions & 0 deletions lib/store/app_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ abstract class AppStoreBase with Store {
@observable
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>? wallet;

@observable
String? currentRouteName;

WalletListStore walletList;

SettingsStore settingsStore;
Expand Down
Loading