Fixes for yat

This commit is contained in:
M
2021-11-02 09:17:24 +00:00
parent c9482caa19
commit fe3d00f1a8
36 changed files with 543 additions and 88 deletions
+29 -1
View File
@@ -1,7 +1,9 @@
import 'dart:async';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/yat/yat_popup.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/themes/theme_base.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -20,6 +22,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:cake_wallet/main.dart';
class DashboardPage extends BasePage {
DashboardPage({
@@ -78,6 +81,7 @@ class DashboardPage extends BasePage {
var pages = <Widget>[];
bool _isEffectsInstalled = false;
StreamSubscription<bool> _onInactiveSub;
@override
Widget body(BuildContext context) {
@@ -156,6 +160,8 @@ class DashboardPage extends BasePage {
pages.add(BalancePage(dashboardViewModel: walletViewModel));
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
_isEffectsInstalled = true;
if (walletViewModel.shouldShowYatPopup) {
await Future<void>.delayed(Duration(seconds: 1));
await showPopUp<void>(
@@ -186,7 +192,29 @@ class DashboardPage extends BasePage {
});
});
_isEffectsInstalled = true;
var needToPresentYat = false;
var isInactive = false;
_onInactiveSub = rootKey.currentState.isInactive.listen((inactive) {
isInactive = inactive;
if (needToPresentYat) {
Future<void>.delayed(Duration(milliseconds: 500)).then((_) {
showPopUp<void>(
context: navigatorKey.currentContext,
builder: (_) => YatEmojiId(walletViewModel.yatStore.emoji));
needToPresentYat = false;
});
}
});
walletViewModel.yatStore.emojiIncommingStream.listen((String emoji) {
if (!_isEffectsInstalled || emoji.isEmpty) {
return;
}
needToPresentYat = true;
});
}
Future<void> _onClickBuyButton(BuildContext context) async {
+14 -7
View File
@@ -150,7 +150,7 @@ class QRWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
S.of(context).yat_address,
S.of(context).yat,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
@@ -160,14 +160,21 @@ class QRWidget extends StatelessWidget {
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
addressListViewModel.emoji,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 26,
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(child:Text(
addressListViewModel.emoji,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 26))),
Padding(
padding: EdgeInsets.only(left: 12),
child: copyImage,
)]
),
)
)
]
)
)),
+11 -2
View File
@@ -1,3 +1,4 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
@@ -24,11 +25,14 @@ class Root extends StatefulWidget {
}
class RootState extends State<Root> with WidgetsBindingObserver {
Stream<bool> get isInactive => _isInactiveController.stream;
StreamController<bool> _isInactiveController;
bool _isInactive;
bool _postFrameCallback;
@override
void initState() {
_isInactiveController = StreamController<bool>();
_isInactive = false;
_postFrameCallback = false;
WidgetsBinding.instance.addObserver(this);
@@ -45,7 +49,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
if (!_isInactive &&
widget.authenticationStore.state == AuthenticationState.allowed) {
setState(() => _isInactive = true);
setState(() => _setInactive(true));
}
break;
@@ -77,7 +81,12 @@ class RootState extends State<Root> with WidgetsBindingObserver {
void _reset() {
setState(() {
_postFrameCallback = false;
_isInactive = false;
_setInactive(false);
});
}
void _setInactive(bool value) {
_isInactive = value;
_isInactiveController.add(value);
}
}
+9 -1
View File
@@ -1,5 +1,6 @@
import 'dart:ui';
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/template_tile.dart';
import 'package:cake_wallet/view_model/send/output.dart';
@@ -21,6 +22,8 @@ import 'package:dotted_border/dotted_border.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/src/screens/yat/yat_sending.dart';
class SendPage extends BasePage {
SendPage({@required this.sendViewModel}) :_formKey = GlobalKey<FormState>();
@@ -301,6 +304,10 @@ class SendPage extends BasePage {
}
await sendViewModel.createTransaction();
if (!sendViewModel.isBatchSending && sendViewModel.hasYat) {
Navigator.of(context).push<void>(YatSending.createRoute(sendViewModel));
}
},
text: S.of(context).send,
color: Theme.of(context).accentTextTheme.body2.color,
@@ -336,7 +343,8 @@ class SendPage extends BasePage {
});
}
if (state is ExecutedSuccessfullyState) {
if (state is ExecutedSuccessfullyState
&& !(!sendViewModel.isBatchSending && sendViewModel.hasYat)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
@@ -29,6 +29,6 @@ class SettingsLinkProviderCell extends StandardListRow {
color: Palette.blueCraiola));
static void _launchUrl(String url) async {
if (await canLaunch(url)) await launch(url);
if (await canLaunch(url)) await launch(url, forceSafariVC: false);
}
}
+15
View File
@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
class CircleClipper extends CustomClipper<Path> {
CircleClipper(this.center, this.radius);
final Offset center;
final double radius;
@override
Path getClip(Size size) =>
Path()..addOval(Rect.fromCircle(radius: radius, center: center));
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}
+12 -9
View File
@@ -10,13 +10,9 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:lottie/lottie.dart';
class YatAlert extends StatelessWidget {
YatAlert(this.yatStore)
: baseUrl = YatLink.isDevMode
? YatLink.baseDevUrl
: YatLink.baseReleaseUrl;
YatAlert(this.yatStore);
final YatStore yatStore;
final String baseUrl;
static const aspectRatioImage = 1.133;
final animation = Lottie.asset('assets/animation/anim1.json');
@@ -88,8 +84,15 @@ class YatAlert extends StatelessWidget {
.arrow_up_right_square,
mainAxisAlignment: MainAxisAlignment.end,
onPressed: () {
final url = baseUrl + YatLink.createSuffix;
launch(url);
var createNewYatUrl = YatLink.startFlowUrl;
final createNewYatUrlParameters =
yatStore.defineQueryParameters();
if (createNewYatUrlParameters.isNotEmpty) {
createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
}
launch(createNewYatUrl, forceSafariVC: false);
}),
Padding(
padding: EdgeInsets.only(top: 24),
@@ -104,13 +107,13 @@ class YatAlert extends StatelessWidget {
.arrow_up_right_square,
mainAxisAlignment: MainAxisAlignment.end,
onPressed: () {
String url = baseUrl + YatLink.signInSuffix;
String url = YatLink.baseUrl + YatLink.signInSuffix;
final parameters =
yatStore.defineQueryParameters();
if (parameters.isNotEmpty) {
url += YatLink.queryParameter + parameters;
}
launch(url);
launch(url, forceSafariVC: false);
})
)
]
+10 -3
View File
@@ -160,8 +160,15 @@ class YatPopup extends StatelessWidget {
child: ThirdIntroduction(
onClose: onClose,
onGet: () {
final url = baseUrl + YatLink.createSuffix;
launch(url);
var createNewYatUrl = YatLink.startFlowUrl;
final createNewYatUrlParameters = dashboardViewModel.
yatStore.defineQueryParameters();
if (createNewYatUrlParameters.isNotEmpty) {
createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
}
launch(createNewYatUrl, forceSafariVC: false);
},
onConnect: () {
String url = baseUrl + YatLink.signInSuffix;
@@ -170,7 +177,7 @@ class YatPopup extends StatelessWidget {
if (parameters.isNotEmpty) {
url += YatLink.queryParameter + parameters;
}
launch(url);
launch(url, forceSafariVC: false);
}
))
: Container()
+141
View File
@@ -0,0 +1,141 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart';
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
import 'package:cake_wallet/src/screens/yat/circle_clipper.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart';
class YatSending extends BasePage {
YatSending(this.sendViewModel);
static Route createRoute(SendViewModel sendViewModel) {
return PageRouteBuilder<void>(
transitionDuration: Duration(seconds: 1),
reverseTransitionDuration: Duration(seconds: 1),
opaque: false,
barrierDismissible: false,
pageBuilder: (context, animation, secondaryAnimation) => YatSending(sendViewModel),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
final screenSize = MediaQuery.of(context).size;
final center = Offset(screenSize.width / 2, screenSize.height / 2);
final endRadius = screenSize.height * 1.2;
final tween = Tween(begin: 0.0, end: endRadius);
return ClipPath(
clipper: CircleClipper(center, animation.drive(tween).value),
child: child,
);
},
);
}
final SendViewModel sendViewModel;
@override
Color get titleColor => Colors.white;
@override
bool get resizeToAvoidBottomInset => false;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
@override
Widget trailing(context) =>
YatCloseButton(onClose: () => Navigator.of(context).pop());
@override
Widget leading(BuildContext context) => Container();
@override
Widget body(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Container(
color: Colors.black,
child: Stack(
children: [
Center(
child:FutureBuilder<String>(
future: visualisationForEmojiId(sendViewModel.outputs.first.address),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if (snapshot.hasError || snapshot.data.isEmpty) {
return Image.asset('assets/images/yat_logo.png', width: screenWidth, color: Colors.white);
}
return Image.network(
snapshot.data,
scale: 0.7,
loadingBuilder: (Object z, Widget child, ImageChunkEvent loading)
=> loading != null
? CupertinoActivityIndicator(animating: true)
: child);
default:
return Image.asset('assets/images/yat_logo.png', width: screenWidth, color: Colors.white);
}
}),
),
Positioned(
bottom: 20,
child: Container(
width: screenWidth,
padding: EdgeInsets.fromLTRB(20, 0, 20, 10),
child: Column(children: [
Text(
'You are sending ${sendViewModel.outputs.first.cryptoAmount} ${sendViewModel.currency.title} to ${sendViewModel.outputs.first.address}'.toUpperCase(),
style: TextStyle(
fontSize: 28,
decoration: TextDecoration.none,
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
textAlign: TextAlign.center),
Container(height: 30),
LoadingPrimaryButton(
onPressed: () {
sendViewModel.commitTransaction();
showPopUp<void>(
context: context,
builder: (BuildContext popContext) {
return Observer(builder: (_) {
final state = sendViewModel.state;
if (state is FailureState) {
Navigator.of(context).pop();
}
if (state is TransactionCommitted) {
return AlertWithOneAction(
alertTitle: '',
alertContent: S.of(popContext).send_success(
sendViewModel.currency
.toString()),
buttonText: S.of(popContext).ok,
buttonAction: () {
Navigator.of(popContext).pop();
Navigator.of(context).pop();
});
}
return Offstage();
});
});
},
text: S.of(context).confirm_sending,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting)])))]));
}
}
+129
View File
@@ -0,0 +1,129 @@
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/yat/widgets/first_introduction.dart';
import 'package:cake_wallet/src/screens/yat/widgets/second_introduction.dart';
import 'package:cake_wallet/src/screens/yat/widgets/third_introduction.dart';
import 'package:cake_wallet/src/screens/yat/widgets/yat_close_button.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart';
import 'package:animate_do/animate_do.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/generated/i18n.dart';
class YatEmojiId extends StatelessWidget {
YatEmojiId(this.emojiId);
static const durationInMilliseconds = 250;
final String emojiId;
final image = Image.asset('assets/images/emoji_popup.png');
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.bottomCenter,
children: [
AlertBackground(child: Container()),
SlideInUp(
from: 420,
duration: Duration(milliseconds: durationInMilliseconds),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24)),
child: Container(
height: 420,
color: Theme.of(context).buttonColor,
padding: EdgeInsets.fromLTRB(24, 15, 24, 24),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
YatCloseButton(onClose: () => Navigator.of(context).pop())
]
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.white),
borderRadius: BorderRadius.all(Radius.circular(50))
),
child:
Text(
emojiId,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 46,
decoration: TextDecoration.none,
)
))
]
)
]
),
Container(
padding: EdgeInsets.only(left: 6, right: 6),
child: Column(
children: [
Text(
"That's one nice Yat!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
decoration: TextDecoration.none,
)
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Text(
'You can manage your Yat or purchase additional Yats in your account settings',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
decoration: TextDecoration.none,
)
)
)
]
)
),
PrimaryButton(
text: 'Got it',
textColor: Colors.white,
color: Palette.protectiveBlue,
onPressed: () => Navigator.of(context).pop()
)
],
)
)
),
)
],
);
}
}