mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
CAKE-360 | merged all yat branches into current; saving information about yat to connected wallet; fixed qr widget; applied yat, unstoppable domains and open alias to contact book
This commit is contained in:
parent
5389543988
commit
f353442a2a
26 changed files with 789 additions and 113 deletions
BIN
assets/images/emoji_popup.png
Normal file
BIN
assets/images/emoji_popup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
10
lib/di.dart
10
lib/di.dart
|
@ -62,7 +62,7 @@ import 'package:cake_wallet/src/screens/send/send_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
|
import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
|
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
|
||||||
import 'package:cake_wallet/store/wallet_list_store.dart';
|
import 'package:cake_wallet/store/wallet_list_store.dart';
|
||||||
import 'package:cake_wallet/store/yat_store.dart';
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:cake_wallet/view_model/backup_view_model.dart';
|
import 'package:cake_wallet/view_model/backup_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
|
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
|
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
|
||||||
|
@ -193,7 +193,9 @@ Future setup(
|
||||||
SendTemplateStore(templateSource: _templates));
|
SendTemplateStore(templateSource: _templates));
|
||||||
getIt.registerSingleton<ExchangeTemplateStore>(
|
getIt.registerSingleton<ExchangeTemplateStore>(
|
||||||
ExchangeTemplateStore(templateSource: _exchangeTemplates));
|
ExchangeTemplateStore(templateSource: _exchangeTemplates));
|
||||||
getIt.registerSingleton<YatStore>(YatStore());
|
getIt.registerSingleton<YatStore>(YatStore(
|
||||||
|
appStore: getIt.get<AppStore>()
|
||||||
|
));
|
||||||
|
|
||||||
final secretStore =
|
final secretStore =
|
||||||
await SecretStoreBase.load(getIt.get<FlutterSecureStorage>());
|
await SecretStoreBase.load(getIt.get<FlutterSecureStorage>());
|
||||||
|
@ -254,6 +256,7 @@ Future setup(
|
||||||
tradeFilterStore: getIt.get<TradeFilterStore>(),
|
tradeFilterStore: getIt.get<TradeFilterStore>(),
|
||||||
transactionFilterStore: getIt.get<TransactionFilterStore>(),
|
transactionFilterStore: getIt.get<TransactionFilterStore>(),
|
||||||
settingsStore: settingsStore,
|
settingsStore: settingsStore,
|
||||||
|
yatStore: getIt.get<YatStore>(),
|
||||||
ordersStore: getIt.get<OrdersStore>()));
|
ordersStore: getIt.get<OrdersStore>()));
|
||||||
|
|
||||||
getIt.registerFactory<AuthService>(() => AuthService(
|
getIt.registerFactory<AuthService>(() => AuthService(
|
||||||
|
@ -391,7 +394,8 @@ Future setup(
|
||||||
|
|
||||||
getIt.registerFactory(() {
|
getIt.registerFactory(() {
|
||||||
final appStore = getIt.get<AppStore>();
|
final appStore = getIt.get<AppStore>();
|
||||||
return SettingsViewModel(appStore.settingsStore, appStore.wallet);
|
final yatStore = getIt.get<YatStore>();
|
||||||
|
return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet);
|
||||||
});
|
});
|
||||||
|
|
||||||
getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
|
getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:cake_wallet/entities/openalias_record.dart';
|
import 'package:cake_wallet/entities/openalias_record.dart';
|
||||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||||
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
|
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
|
||||||
import 'package:cake_wallet/yat/yat_record.dart';
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
|
|
||||||
const unstoppableDomains = [
|
const unstoppableDomains = [
|
||||||
'crypto',
|
'crypto',
|
||||||
|
|
|
@ -7,7 +7,8 @@ part 'wallet_info.g.dart';
|
||||||
@HiveType(typeId: WalletInfo.typeId)
|
@HiveType(typeId: WalletInfo.typeId)
|
||||||
class WalletInfo extends HiveObject {
|
class WalletInfo extends HiveObject {
|
||||||
WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
|
WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
|
||||||
this.timestamp, this.dirPath, this.path, this.address);
|
this.timestamp, this.dirPath, this.path, this.address, this.yatEid,
|
||||||
|
this.yatRefreshToken);
|
||||||
|
|
||||||
factory WalletInfo.external(
|
factory WalletInfo.external(
|
||||||
{@required String id,
|
{@required String id,
|
||||||
|
@ -18,9 +19,12 @@ class WalletInfo extends HiveObject {
|
||||||
@required DateTime date,
|
@required DateTime date,
|
||||||
@required String dirPath,
|
@required String dirPath,
|
||||||
@required String path,
|
@required String path,
|
||||||
@required String address}) {
|
@required String address,
|
||||||
|
String yatEid ='',
|
||||||
|
String yatRefreshToken = ''}) {
|
||||||
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
||||||
date.millisecondsSinceEpoch ?? 0, dirPath, path, address);
|
date.millisecondsSinceEpoch ?? 0, dirPath, path, address,
|
||||||
|
yatEid, yatRefreshToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const typeId = 4;
|
static const typeId = 4;
|
||||||
|
@ -56,5 +60,15 @@ class WalletInfo extends HiveObject {
|
||||||
@HiveField(10)
|
@HiveField(10)
|
||||||
Map<String, String> addresses;
|
Map<String, String> addresses;
|
||||||
|
|
||||||
|
@HiveField(11)
|
||||||
|
String yatEid;
|
||||||
|
|
||||||
|
@HiveField(12)
|
||||||
|
String yatRefreshToken;
|
||||||
|
|
||||||
|
String get yatEmojiId => yatEid ?? '';
|
||||||
|
|
||||||
|
String get yatToken => yatRefreshToken ?? '';
|
||||||
|
|
||||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||||
import 'package:cake_wallet/bitcoin/unspent_coins_info.dart';
|
import 'package:cake_wallet/bitcoin/unspent_coins_info.dart';
|
||||||
import 'package:cake_wallet/entities/language_service.dart';
|
import 'package:cake_wallet/entities/language_service.dart';
|
||||||
import 'package:cake_wallet/buy/order.dart';
|
import 'package:cake_wallet/buy/order.dart';
|
||||||
import 'package:cake_wallet/store/yat_store.dart';
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -190,8 +190,8 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_handleIncomingLinks(yatStore);
|
_handleIncomingLinks();
|
||||||
_handleInitialUri(yatStore);
|
_handleInitialUri();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -200,25 +200,25 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleInitialUri(YatStore yatStore) async {
|
Future<void> _handleInitialUri() async {
|
||||||
try {
|
try {
|
||||||
final uri = await getInitialUri();
|
final uri = await getInitialUri();
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_fetchEmojiFromUri(uri, yatStore);
|
_fetchEmojiFromUri(uri);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleIncomingLinks(YatStore yatStore) {
|
void _handleIncomingLinks() {
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
stream = getUriLinksStream().listen((Uri uri) {
|
stream = getUriLinksStream().listen((Uri uri) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_fetchEmojiFromUri(uri, yatStore);
|
_fetchEmojiFromUri(uri);
|
||||||
}, onError: (Object error) {
|
}, onError: (Object error) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
print('Error: $error');
|
print('Error: $error');
|
||||||
|
@ -226,16 +226,18 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _fetchEmojiFromUri(Uri uri, YatStore yatStore) {
|
void _fetchEmojiFromUri(Uri uri) {
|
||||||
final queryParameters = uri.queryParameters;
|
final queryParameters = uri.queryParameters;
|
||||||
if (queryParameters?.isEmpty ?? true) {
|
if (queryParameters?.isEmpty ?? true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final emoji = queryParameters['eid'];
|
final emoji = queryParameters['eid'];
|
||||||
if (emoji?.isEmpty ?? true) {
|
final refreshToken = queryParameters['refresh_token'];
|
||||||
|
if ((emoji?.isEmpty ?? true)||(refreshToken?.isEmpty ?? true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
yatStore.emoji = emoji;
|
yatStore.emoji = emoji;
|
||||||
|
yatStore.refreshToken = refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/core/validator.dart';
|
||||||
import 'package:cake_wallet/palette.dart';
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -97,8 +98,9 @@ class ContactPage extends BasePage {
|
||||||
buttonColor: Theme.of(context).accentTextTheme.display2.color,
|
buttonColor: Theme.of(context).accentTextTheme.display2.color,
|
||||||
iconColor: PaletteDark.gray,
|
iconColor: PaletteDark.gray,
|
||||||
borderColor: Theme.of(context).primaryTextTheme.title.backgroundColor,
|
borderColor: Theme.of(context).primaryTextTheme.title.backgroundColor,
|
||||||
validator: AddressValidator(
|
validator: TextValidator()
|
||||||
type: contactViewModel.currency),
|
// AddressValidator(
|
||||||
|
// type: contactViewModel.currency),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
import 'package:cake_wallet/entities/wallet_type.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';
|
||||||
|
import 'package:cake_wallet/src/screens/yat/yat_popup.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
@ -145,7 +146,7 @@ class DashboardPage extends BasePage {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setEffects(BuildContext context) {
|
void _setEffects(BuildContext context) async {
|
||||||
if (_isEffectsInstalled) {
|
if (_isEffectsInstalled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -155,6 +156,15 @@ class DashboardPage extends BasePage {
|
||||||
pages.add(BalancePage(dashboardViewModel: walletViewModel));
|
pages.add(BalancePage(dashboardViewModel: walletViewModel));
|
||||||
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
|
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
|
||||||
|
|
||||||
|
await Future<void>.delayed(Duration(seconds: 1));
|
||||||
|
await showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return YatPopup(
|
||||||
|
dashboardViewModel: walletViewModel,
|
||||||
|
onClose: () => Navigator.of(context).pop());
|
||||||
|
});
|
||||||
|
|
||||||
autorun((_) async {
|
autorun((_) async {
|
||||||
if (!walletViewModel.isOutdatedElectrumWallet) {
|
if (!walletViewModel.isOutdatedElectrumWallet) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -235,6 +235,15 @@ class ExchangePage extends BasePage {
|
||||||
await fetchParsedAddress(
|
await fetchParsedAddress(
|
||||||
context, domain, ticker);
|
context, domain, ticker);
|
||||||
},
|
},
|
||||||
|
onPushAddressBookButton: (context) async {
|
||||||
|
final domain =
|
||||||
|
exchangeViewModel.depositAddress;
|
||||||
|
final ticker = exchangeViewModel
|
||||||
|
.depositCurrency.title.toLowerCase();
|
||||||
|
exchangeViewModel.depositAddress =
|
||||||
|
await fetchParsedAddress(
|
||||||
|
context, domain, ticker);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -291,6 +300,15 @@ class ExchangePage extends BasePage {
|
||||||
await fetchParsedAddress(
|
await fetchParsedAddress(
|
||||||
context, domain, ticker);
|
context, domain, ticker);
|
||||||
},
|
},
|
||||||
|
onPushAddressBookButton: (context) async {
|
||||||
|
final domain =
|
||||||
|
exchangeViewModel.receiveAddress;
|
||||||
|
final ticker = exchangeViewModel
|
||||||
|
.receiveCurrency.title.toLowerCase();
|
||||||
|
exchangeViewModel.receiveAddress =
|
||||||
|
await fetchParsedAddress(
|
||||||
|
context, domain, ticker);
|
||||||
|
},
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -34,7 +34,8 @@ class ExchangeCard extends StatefulWidget {
|
||||||
this.addressFocusNode,
|
this.addressFocusNode,
|
||||||
this.hasAllAmount = false,
|
this.hasAllAmount = false,
|
||||||
this.allAmount,
|
this.allAmount,
|
||||||
this.onPushPasteButton})
|
this.onPushPasteButton,
|
||||||
|
this.onPushAddressBookButton})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
final List<CryptoCurrency> currencies;
|
final List<CryptoCurrency> currencies;
|
||||||
|
@ -59,6 +60,7 @@ class ExchangeCard extends StatefulWidget {
|
||||||
final bool hasAllAmount;
|
final bool hasAllAmount;
|
||||||
final Function allAmount;
|
final Function allAmount;
|
||||||
final Function(BuildContext context) onPushPasteButton;
|
final Function(BuildContext context) onPushPasteButton;
|
||||||
|
final Function(BuildContext context) onPushAddressBookButton;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ExchangeCardState createState() => ExchangeCardState();
|
ExchangeCardState createState() => ExchangeCardState();
|
||||||
|
@ -321,6 +323,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
buttonColor: widget.addressButtonsColor,
|
buttonColor: widget.addressButtonsColor,
|
||||||
validator: widget.addressTextFieldValidator,
|
validator: widget.addressTextFieldValidator,
|
||||||
onPushPasteButton: widget.onPushPasteButton,
|
onPushPasteButton: widget.onPushPasteButton,
|
||||||
|
onPushAddressBookButton: widget.onPushAddressBookButton
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
|
@ -366,6 +369,8 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
setState(() =>
|
setState(() =>
|
||||||
addressController.text =
|
addressController.text =
|
||||||
contact.address);
|
contact.address);
|
||||||
|
widget.onPushAddressBookButton
|
||||||
|
?.call(context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
|
@ -101,7 +101,7 @@ class QRWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 16, bottom: 16),
|
padding: EdgeInsets.only(top: 10, bottom: 10),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) => Observer(
|
builder: (context) => Observer(
|
||||||
builder: (context) => GestureDetector(
|
builder: (context) => GestureDetector(
|
||||||
|
@ -164,7 +164,7 @@ class QRWidget extends StatelessWidget {
|
||||||
addressListViewModel.emoji,
|
addressListViewModel.emoji,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 26,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -156,8 +156,10 @@ class SendCardState extends State<SendCard>
|
||||||
output.resetParsedAddress();
|
output.resetParsedAddress();
|
||||||
await output.fetchParsedAddress(context);
|
await output.fetchParsedAddress(context);
|
||||||
},
|
},
|
||||||
onPushAddressBookButton: (context) =>
|
onPushAddressBookButton: (context) async {
|
||||||
output.resetParsedAddress(),
|
output.resetParsedAddress();
|
||||||
|
await output.fetchParsedAddress(context);
|
||||||
|
},
|
||||||
validator: validator,
|
validator: validator,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
|
90
lib/src/screens/yat/widgets/first_introduction.dart
Normal file
90
lib/src/screens/yat/widgets/first_introduction.dart
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
|
class FirstIntroduction extends StatelessWidget {
|
||||||
|
FirstIntroduction({this.onClose, this.onNext});
|
||||||
|
|
||||||
|
static const aspectRatioImage = 1.133;
|
||||||
|
final VoidCallback onClose;
|
||||||
|
final VoidCallback onNext;
|
||||||
|
final animation = Lottie.asset('assets/animation/anim1.json');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: screenHeight,
|
||||||
|
width: screenWidth,
|
||||||
|
color: Colors.white,
|
||||||
|
child: ScrollableWithBottomSection(
|
||||||
|
contentPadding: EdgeInsets.only(top: 40, bottom: 40),
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 45,
|
||||||
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
|
child: YatBar(onClose: () => Navigator.of(context).pop())
|
||||||
|
),
|
||||||
|
animation,
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(left: 30, right: 30),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Send and receive crypto more easily with Yat',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 20),
|
||||||
|
child: Text(
|
||||||
|
'Cake Wallet users can now send and receive all their favorite currencies with a one-of-a-kind emoji-based username.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
|
||||||
|
bottomSection: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
PrimaryButton(
|
||||||
|
text: 'Next',
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: Palette.protectiveBlue,
|
||||||
|
onPressed: onNext
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 24),
|
||||||
|
child: YatPageIndicator(filled: 0)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
89
lib/src/screens/yat/widgets/second_introduction.dart
Normal file
89
lib/src/screens/yat/widgets/second_introduction.dart
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
|
class SecondIntroduction extends StatelessWidget {
|
||||||
|
SecondIntroduction({this.onClose, this.onNext});
|
||||||
|
|
||||||
|
final VoidCallback onClose;
|
||||||
|
final VoidCallback onNext;
|
||||||
|
final animation = Lottie.asset('assets/animation/anim2.json');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: screenHeight,
|
||||||
|
width: screenWidth,
|
||||||
|
color: Colors.white,
|
||||||
|
child: ScrollableWithBottomSection(
|
||||||
|
contentPadding: EdgeInsets.only(top: 40, bottom: 40),
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 45,
|
||||||
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
|
child: YatBar(onClose: onClose)
|
||||||
|
),
|
||||||
|
animation,
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 40, left: 30, right: 30),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'One emoji address to rule them all',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 20),
|
||||||
|
child: Text(
|
||||||
|
'Your Yat is a single unique emoji address that replaces all of your long hexadecimal addresses for all of your currencies.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
|
||||||
|
bottomSection: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
PrimaryButton(
|
||||||
|
text: 'Next',
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: Palette.protectiveBlue,
|
||||||
|
onPressed: onNext
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 24),
|
||||||
|
child: YatPageIndicator(filled: 1)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
109
lib/src/screens/yat/widgets/third_introduction.dart
Normal file
109
lib/src/screens/yat/widgets/third_introduction.dart
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_page_indicator.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
|
class ThirdIntroduction extends StatelessWidget {
|
||||||
|
ThirdIntroduction({this.onClose, this.onGet, this.onConnect});
|
||||||
|
|
||||||
|
final VoidCallback onClose;
|
||||||
|
final VoidCallback onGet;
|
||||||
|
final VoidCallback onConnect;
|
||||||
|
final animation = Lottie.asset('assets/animation/anim3.json');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: screenHeight,
|
||||||
|
width: screenWidth,
|
||||||
|
color: Colors.white,
|
||||||
|
child: ScrollableWithBottomSection(
|
||||||
|
contentPadding: EdgeInsets.only(top: 40, bottom: 40),
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 90,
|
||||||
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
|
child: YatBar(onClose: onClose)
|
||||||
|
),
|
||||||
|
animation,
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 40, left: 30, right: 30),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Yat plays nicely with others',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 20),
|
||||||
|
child: Text(
|
||||||
|
'Yats live outside of Cake Wallet, too. Any wallet address on earth can be replaced with a Yat!',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
|
||||||
|
bottomSection: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
PrimaryIconButton(
|
||||||
|
text: 'Get your Yat',
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: Palette.protectiveBlue,
|
||||||
|
borderColor: Palette.protectiveBlue,
|
||||||
|
iconColor: Colors.white,
|
||||||
|
iconBackgroundColor: Colors.transparent,
|
||||||
|
iconData: CupertinoIcons
|
||||||
|
.arrow_up_right_square,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
onPressed: onGet),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 12),
|
||||||
|
child: PrimaryIconButton(
|
||||||
|
text: 'Connect an existing Yat',
|
||||||
|
textColor: Colors.black,
|
||||||
|
color: Palette.blueAlice,
|
||||||
|
borderColor: Palette.blueAlice,
|
||||||
|
iconColor: Colors.black,
|
||||||
|
iconBackgroundColor: Colors.transparent,
|
||||||
|
iconData: CupertinoIcons
|
||||||
|
.arrow_up_right_square,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
onPressed: onConnect)
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 24),
|
||||||
|
child: YatPageIndicator(filled: 2)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
33
lib/src/screens/yat/widgets/yat_page_indicator.dart
Normal file
33
lib/src/screens/yat/widgets/yat_page_indicator.dart
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
|
||||||
|
class YatPageIndicator extends StatelessWidget {
|
||||||
|
YatPageIndicator({this.filled});
|
||||||
|
|
||||||
|
final int filled;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: 44,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: List.generate(3, (index) {
|
||||||
|
final size = 8.0;
|
||||||
|
final isFilled = index == filled;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
height: size,
|
||||||
|
width: size,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: isFilled
|
||||||
|
? Palette.frostySky
|
||||||
|
: Palette.stateGray.withOpacity(0.1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:cake_wallet/core/wallet_base.dart';
|
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart';
|
import 'package:cake_wallet/src/screens/yat/widgets/yat_bar.dart';
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/palette.dart';
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
@ -11,22 +10,13 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:lottie/lottie.dart';
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
class YatAlert extends StatelessWidget {
|
class YatAlert extends StatelessWidget {
|
||||||
YatAlert({@required this.wallet, this.isYatDevMode = false})
|
YatAlert(this.yatStore)
|
||||||
: baseUrl = isYatDevMode ? _baseDevUrl : _baseReleaseUrl,
|
: baseUrl = isYatDevMode ? baseDevUrl : baseReleaseUrl;
|
||||||
address = wallet.walletAddresses.address;
|
|
||||||
|
|
||||||
final WalletBase wallet;
|
final YatStore yatStore;
|
||||||
final bool isYatDevMode;
|
|
||||||
final String address;
|
|
||||||
final String baseUrl;
|
final String baseUrl;
|
||||||
static const aspectRatioImage = 1.133;
|
static const aspectRatioImage = 1.133;
|
||||||
static const _baseDevUrl = 'https://yat.fyi';
|
final animation = Lottie.asset('assets/animation/anim1.json');
|
||||||
static const _baseReleaseUrl = 'https://y.at';
|
|
||||||
static const _signInSuffix = '/partner/CW/link-email';
|
|
||||||
static const _createSuffix = '/create';
|
|
||||||
static const _queryParameter = '?addresses=';
|
|
||||||
final image = Image.asset('assets/images/yat_crypto.png');
|
|
||||||
final anim = Lottie.asset('assets/animation/anim1.json');
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -42,15 +32,11 @@ class YatAlert extends StatelessWidget {
|
||||||
content: Column(
|
content: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 45, // 90
|
height: 45,
|
||||||
padding: EdgeInsets.only(left: 24, right: 24),
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
child: YatBar(onClose: () => Navigator.of(context).pop())
|
child: YatBar(onClose: () => Navigator.of(context).pop())
|
||||||
),
|
),
|
||||||
anim,
|
animation,
|
||||||
// AspectRatio(
|
|
||||||
// aspectRatio: aspectRatioImage,
|
|
||||||
// child: FittedBox(child: image, fit: BoxFit.fill)
|
|
||||||
// ),
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(left: 30, right: 30),
|
padding: EdgeInsets.only(left: 30, right: 30),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -100,7 +86,7 @@ class YatAlert extends StatelessWidget {
|
||||||
.arrow_up_right_square,
|
.arrow_up_right_square,
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final url = baseUrl + _createSuffix;
|
final url = baseUrl + createSuffix;
|
||||||
launch(url);
|
launch(url);
|
||||||
}),
|
}),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -116,8 +102,12 @@ class YatAlert extends StatelessWidget {
|
||||||
.arrow_up_right_square,
|
.arrow_up_right_square,
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final url = baseUrl + _signInSuffix + _queryParameter +
|
String url = baseUrl + signInSuffix;
|
||||||
_defineTag() + '%3D' + address;
|
final parameters =
|
||||||
|
yatStore.defineQueryParameters();
|
||||||
|
if (parameters.isNotEmpty) {
|
||||||
|
url += queryParameter + parameters;
|
||||||
|
}
|
||||||
launch(url);
|
launch(url);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -126,24 +116,4 @@ class YatAlert extends StatelessWidget {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _defineTag() {
|
|
||||||
String tag;
|
|
||||||
switch (wallet.type) {
|
|
||||||
case WalletType.monero:
|
|
||||||
tag = address.startsWith('4')
|
|
||||||
? '0x1001'
|
|
||||||
: '0x1002';
|
|
||||||
break;
|
|
||||||
case WalletType.bitcoin:
|
|
||||||
tag = '0x1003';
|
|
||||||
break;
|
|
||||||
case WalletType.litecoin:
|
|
||||||
tag = '0x3fff';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tag = '0x3fff';
|
|
||||||
}
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
}
|
}
|
178
lib/src/screens/yat/yat_popup.dart
Normal file
178
lib/src/screens/yat/yat_popup.dart
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
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';
|
||||||
|
|
||||||
|
class YatPopup extends StatelessWidget {
|
||||||
|
YatPopup({this.dashboardViewModel, this.onClose})
|
||||||
|
: baseUrl = isYatDevMode ? baseDevUrl : baseReleaseUrl;
|
||||||
|
|
||||||
|
static const durationInMilliseconds = 250;
|
||||||
|
|
||||||
|
final DashboardViewModel dashboardViewModel;
|
||||||
|
final VoidCallback onClose;
|
||||||
|
final String baseUrl;
|
||||||
|
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: Colors.white,
|
||||||
|
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: onClose)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 64,
|
||||||
|
width: 165,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius
|
||||||
|
.all(Radius.circular(32)),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withOpacity(0.05),
|
||||||
|
blurRadius: 15,
|
||||||
|
offset: Offset(0, 5)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
child: image
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(left: 6, right: 6),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Your wallet address can be emojified.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 20),
|
||||||
|
child: Text(
|
||||||
|
'You can now send and receive crypto in Cake Wallet with your Yat - a short, emoji-based username. Manage Yats at any time on the settings screen',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Colors.black,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
PrimaryButton(
|
||||||
|
text: 'Learn More',
|
||||||
|
textColor: Colors.white,
|
||||||
|
color: Palette.protectiveBlue,
|
||||||
|
onPressed: () => dashboardViewModel
|
||||||
|
.isShowFirstYatIntroduction = true
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Observer(builder: (_) => dashboardViewModel.isShowFirstYatIntroduction
|
||||||
|
? SlideInRight(
|
||||||
|
from: screenWidth,
|
||||||
|
duration: Duration(milliseconds: durationInMilliseconds),
|
||||||
|
child: FirstIntroduction(
|
||||||
|
onClose: onClose,
|
||||||
|
onNext: () => dashboardViewModel
|
||||||
|
.isShowSecondYatIntroduction = true
|
||||||
|
))
|
||||||
|
: Container()
|
||||||
|
),
|
||||||
|
Observer(builder: (_) => dashboardViewModel.isShowSecondYatIntroduction
|
||||||
|
? SlideInRight(
|
||||||
|
from: screenWidth,
|
||||||
|
duration: Duration(milliseconds: durationInMilliseconds),
|
||||||
|
child: SecondIntroduction(
|
||||||
|
onClose: onClose,
|
||||||
|
onNext: () => dashboardViewModel
|
||||||
|
.isShowThirdYatIntroduction = true
|
||||||
|
))
|
||||||
|
: Container()
|
||||||
|
),
|
||||||
|
Observer(builder: (_) => dashboardViewModel.isShowThirdYatIntroduction
|
||||||
|
? SlideInRight(
|
||||||
|
from: screenWidth,
|
||||||
|
duration: Duration(milliseconds: durationInMilliseconds),
|
||||||
|
child: ThirdIntroduction(
|
||||||
|
onClose: onClose,
|
||||||
|
onGet: () {
|
||||||
|
final url = baseUrl + createSuffix;
|
||||||
|
launch(url);
|
||||||
|
},
|
||||||
|
onConnect: () {
|
||||||
|
String url = baseUrl + signInSuffix;
|
||||||
|
final parameters = dashboardViewModel
|
||||||
|
.yatStore.defineQueryParameters();
|
||||||
|
if (parameters.isNotEmpty) {
|
||||||
|
url += queryParameter + parameters;
|
||||||
|
}
|
||||||
|
launch(url);
|
||||||
|
}
|
||||||
|
))
|
||||||
|
: Container()
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
166
lib/store/yat/yat_store.dart
Normal file
166
lib/store/yat/yat_store.dart
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
import 'package:cake_wallet/core/transaction_history.dart';
|
||||||
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
import 'package:cake_wallet/monero/monero_subaddress_list.dart';
|
||||||
|
import 'package:cake_wallet/monero/monero_wallet.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:cake_wallet/store/yat/yat_exception.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
|
part 'yat_store.g.dart';
|
||||||
|
|
||||||
|
const baseDevUrl = 'https://yat.fyi';
|
||||||
|
const baseReleaseUrl = 'https://y.at';
|
||||||
|
const signInSuffix = '/partner/CW/link-email';
|
||||||
|
const createSuffix = '/create';
|
||||||
|
const queryParameter = '?addresses=';
|
||||||
|
const requestDevUrl = 'https://a.yat.fyi/emoji_id/';
|
||||||
|
const requestReleaseUrl = 'https://a.y.at/emoji_id/';
|
||||||
|
const isYatDevMode = true;
|
||||||
|
|
||||||
|
Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
|
||||||
|
final requestURL = isYatDevMode ? requestDevUrl : requestReleaseUrl;
|
||||||
|
final url = requestURL + emojiId + '/' + ticker.toUpperCase();
|
||||||
|
final response = await get(url);
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw YatException(text: response.body.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||||
|
final result = responseJSON['result'] as List<dynamic>;
|
||||||
|
|
||||||
|
if (result?.isEmpty ?? true) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> addresses = [];
|
||||||
|
|
||||||
|
for (var elem in result) {
|
||||||
|
final yatAddress = elem['data'] as String;
|
||||||
|
if (yatAddress?.isNotEmpty ?? false) {
|
||||||
|
addresses.add(yatAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
class YatStore = YatStoreBase with _$YatStore;
|
||||||
|
|
||||||
|
abstract class YatStoreBase with Store {
|
||||||
|
YatStoreBase({@required this.appStore}) {
|
||||||
|
_wallet ??= appStore.wallet;
|
||||||
|
emoji = _wallet?.walletInfo?.yatEmojiId ?? '';
|
||||||
|
refreshToken = _wallet?.walletInfo?.yatToken ?? '';
|
||||||
|
reaction((_) => appStore.wallet, _onWalletChange);
|
||||||
|
reaction((_) => emoji, (String emoji) => _onEmojiChange());
|
||||||
|
}
|
||||||
|
|
||||||
|
AppStore appStore;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String emoji;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String refreshToken;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
|
||||||
|
_wallet;
|
||||||
|
|
||||||
|
@action
|
||||||
|
void _onWalletChange(
|
||||||
|
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||||
|
TransactionInfo>
|
||||||
|
wallet) {
|
||||||
|
this._wallet = wallet;
|
||||||
|
emoji = wallet?.walletInfo?.yatEmojiId ?? '';
|
||||||
|
refreshToken = wallet?.walletInfo?.yatToken ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void _onEmojiChange() {
|
||||||
|
try {
|
||||||
|
final walletInfo = _wallet.walletInfo;
|
||||||
|
|
||||||
|
if (walletInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
walletInfo.yatEid = emoji;
|
||||||
|
walletInfo.yatRefreshToken = refreshToken;
|
||||||
|
|
||||||
|
if (walletInfo.isInBox) {
|
||||||
|
walletInfo.save();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String defineQueryParameters() {
|
||||||
|
String parameters = '';
|
||||||
|
switch (_wallet.type) {
|
||||||
|
case WalletType.monero:
|
||||||
|
final wallet = _wallet as MoneroWallet;
|
||||||
|
final subaddressList = MoneroSubaddressList();
|
||||||
|
var isFirstAddress = true;
|
||||||
|
|
||||||
|
wallet.walletAddresses.accountList.accounts.forEach((account) {
|
||||||
|
subaddressList.update(accountIndex: account.id);
|
||||||
|
subaddressList.subaddresses.forEach((subaddress) {
|
||||||
|
if (!isFirstAddress) {
|
||||||
|
parameters += '%7C';
|
||||||
|
} else {
|
||||||
|
isFirstAddress = !isFirstAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters += subaddress.address.startsWith('4')
|
||||||
|
? '0x1001%3D'
|
||||||
|
: '0x1002%3D';
|
||||||
|
|
||||||
|
parameters += subaddress.address;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case WalletType.bitcoin:
|
||||||
|
final wallet = _wallet as ElectrumWallet;
|
||||||
|
var isFirstAddress = true;
|
||||||
|
|
||||||
|
wallet.walletAddresses.addresses.forEach((record) {
|
||||||
|
if (!isFirstAddress) {
|
||||||
|
parameters += '%7C';
|
||||||
|
} else {
|
||||||
|
isFirstAddress = !isFirstAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters += '0x1003%3D' + record.address;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case WalletType.litecoin:
|
||||||
|
final wallet = _wallet as ElectrumWallet;
|
||||||
|
var isFirstAddress = true;
|
||||||
|
|
||||||
|
wallet.walletAddresses.addresses.forEach((record) {
|
||||||
|
if (!isFirstAddress) {
|
||||||
|
parameters += '%7C';
|
||||||
|
} else {
|
||||||
|
isFirstAddress = !isFirstAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters += '0x3fff%3D' + record.address;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parameters = '';
|
||||||
|
}
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
import 'package:mobx/mobx.dart';
|
|
||||||
|
|
||||||
part 'yat_store.g.dart';
|
|
||||||
|
|
||||||
class YatStore = YatStoreBase with _$YatStore;
|
|
||||||
|
|
||||||
abstract class YatStoreBase with Store {
|
|
||||||
YatStoreBase() : emoji = '';
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String emoji;
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||||
import 'package:cake_wallet/store/settings_store.dart';
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:cake_wallet/utils/mobx.dart';
|
import 'package:cake_wallet/utils/mobx.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
|
||||||
|
@ -46,6 +47,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
this.tradeFilterStore,
|
this.tradeFilterStore,
|
||||||
this.transactionFilterStore,
|
this.transactionFilterStore,
|
||||||
this.settingsStore,
|
this.settingsStore,
|
||||||
|
this.yatStore,
|
||||||
this.ordersStore}) {
|
this.ordersStore}) {
|
||||||
filterItems = {
|
filterItems = {
|
||||||
S.current.transactions: [
|
S.current.transactions: [
|
||||||
|
@ -86,6 +88,9 @@ abstract class DashboardViewModelBase with Store {
|
||||||
type = wallet.type;
|
type = wallet.type;
|
||||||
isOutdatedElectrumWallet =
|
isOutdatedElectrumWallet =
|
||||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
||||||
|
isShowFirstYatIntroduction = false;
|
||||||
|
isShowSecondYatIntroduction = false;
|
||||||
|
isShowThirdYatIntroduction = false;
|
||||||
final _wallet = wallet;
|
final _wallet = wallet;
|
||||||
|
|
||||||
if (_wallet is MoneroWallet) {
|
if (_wallet is MoneroWallet) {
|
||||||
|
@ -147,6 +152,15 @@ abstract class DashboardViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
String subname;
|
String subname;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isShowFirstYatIntroduction;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isShowSecondYatIntroduction;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isShowThirdYatIntroduction;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
String get address => wallet.walletAddresses.address;
|
String get address => wallet.walletAddresses.address;
|
||||||
|
|
||||||
|
@ -208,6 +222,8 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
SettingsStore settingsStore;
|
SettingsStore settingsStore;
|
||||||
|
|
||||||
|
YatStore yatStore;
|
||||||
|
|
||||||
TradesStore tradesStore;
|
TradesStore tradesStore;
|
||||||
|
|
||||||
OrdersStore ordersStore;
|
OrdersStore ordersStore;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cake_wallet/src/screens/yat/yat_alert.dart';
|
import 'package:cake_wallet/src/screens/yat/yat_alert.dart';
|
||||||
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -50,6 +51,7 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
|
||||||
abstract class SettingsViewModelBase with Store {
|
abstract class SettingsViewModelBase with Store {
|
||||||
SettingsViewModelBase(
|
SettingsViewModelBase(
|
||||||
this._settingsStore,
|
this._settingsStore,
|
||||||
|
this._yatStore,
|
||||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||||
TransactionInfo>
|
TransactionInfo>
|
||||||
wallet)
|
wallet)
|
||||||
|
@ -162,7 +164,7 @@ abstract class SettingsViewModelBase with Store {
|
||||||
await showPopUp<void>(
|
await showPopUp<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return YatAlert(wallet: wallet, isYatDevMode: true);
|
return YatAlert(_yatStore);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -213,6 +215,7 @@ abstract class SettingsViewModelBase with Store {
|
||||||
final Map<String, String> itemHeaders;
|
final Map<String, String> itemHeaders;
|
||||||
List<List<SettingsListItem>> sections;
|
List<List<SettingsListItem>> sections;
|
||||||
final SettingsStore _settingsStore;
|
final SettingsStore _settingsStore;
|
||||||
|
final YatStore _yatStore;
|
||||||
final WalletType _walletType;
|
final WalletType _walletType;
|
||||||
final BiometricAuth _biometricAuth;
|
final BiometricAuth _biometricAuth;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:cake_wallet/store/yat_store.dart';
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:cake_wallet/yat/yat_exception.dart';
|
|
||||||
import 'package:http/http.dart';
|
|
||||||
|
|
||||||
Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
|
|
||||||
const _requestURL = 'https://a.y.at/emoji_id/';
|
|
||||||
final url = _requestURL + emojiId + '/' + ticker.toUpperCase();
|
|
||||||
final response = await get(url);
|
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
|
||||||
throw YatException(text: response.body.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
|
||||||
final result = responseJSON['result'] as List<dynamic>;
|
|
||||||
|
|
||||||
if (result?.isEmpty ?? true) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> addresses = [];
|
|
||||||
|
|
||||||
for (var elem in result) {
|
|
||||||
final yatAddress = elem['data'] as String;
|
|
||||||
if (yatAddress?.isNotEmpty ?? false) {
|
|
||||||
addresses.add(yatAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return addresses;
|
|
||||||
}
|
|
|
@ -15,6 +15,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.41.2"
|
version: "0.41.2"
|
||||||
|
animate_do:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: animate_do
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
archive:
|
archive:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -59,6 +59,7 @@ dependencies:
|
||||||
flutter_spinkit: ^5.0.0
|
flutter_spinkit: ^5.0.0
|
||||||
uni_links: ^0.4.0
|
uni_links: ^0.4.0
|
||||||
lottie: ^0.7.0
|
lottie: ^0.7.0
|
||||||
|
animate_do: ^2.0.0
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue