diff --git a/assets/svg/buy/Simplex-Nuvei-Logo.svg b/assets/svg/buy/Simplex-Nuvei-Logo.svg
new file mode 100644
index 000000000..fab7e35e3
--- /dev/null
+++ b/assets/svg/buy/Simplex-Nuvei-Logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/lib/models/buy/response_objects/quote.dart b/lib/models/buy/response_objects/quote.dart
new file mode 100644
index 000000000..b422ff1af
--- /dev/null
+++ b/lib/models/buy/response_objects/quote.dart
@@ -0,0 +1,25 @@
+import 'package:decimal/decimal.dart';
+import 'package:stackwallet/models/buy/response_objects/crypto.dart';
+import 'package:stackwallet/models/buy/response_objects/fiat.dart';
+
+class SimplexQuote {
+ // todo: this class
+
+ final Crypto crypto;
+ final Fiat fiat;
+
+ final Decimal youPayFiatPrice;
+ final Decimal youReceiveCryptoAmount;
+
+ final String purchaseId;
+ final String receivingAddress;
+
+ SimplexQuote({
+ required this.crypto,
+ required this.fiat,
+ required this.youPayFiatPrice,
+ required this.youReceiveCryptoAmount,
+ required this.purchaseId,
+ required this.receivingAddress,
+ });
+}
diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart
index c45bb3b6c..eb41cfa1e 100644
--- a/lib/pages/buy_view/buy_form.dart
+++ b/lib/pages/buy_view/buy_form.dart
@@ -1,12 +1,15 @@
import 'dart:async';
+import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/buy/response_objects/crypto.dart';
import 'package:stackwallet/models/buy/response_objects/fiat.dart';
+import 'package:stackwallet/models/buy/response_objects/quote.dart';
import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
+import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart';
import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart';
import 'package:stackwallet/pages/buy_view/sub_widgets/fiat_crypto_toggle.dart';
import 'package:stackwallet/pages/buy_view/sub_widgets/fiat_selection_view.dart';
@@ -814,10 +817,24 @@ class _BuyFormState extends ConsumerState {
),
PrimaryButton(
buttonHeight: isDesktop ? ButtonHeight.l : null,
- enabled: ref.watch(exchangeFormStateProvider
- .select((value) => value.canExchange)),
+ enabled: _receiveAddressController.text.isNotEmpty &&
+ _buyAmountController.text.isNotEmpty,
onPressed: () {
// preview buy quote
+ // TODO: show loading while fetching quote
+ final quote = SimplexQuote(
+ crypto: selectedCrypto!,
+ fiat: selectedFiat!,
+ youPayFiatPrice: Decimal.parse("100"),
+ youReceiveCryptoAmount: Decimal.parse("1.0238917"),
+ purchaseId: "someID",
+ receivingAddress: _receiveAddressController.text,
+ );
+
+ Navigator.of(context).pushNamed(
+ BuyQuotePreviewView.routeName,
+ arguments: quote,
+ );
},
label: "Preview quote",
)
diff --git a/lib/pages/buy_view/buy_quote_preview.dart b/lib/pages/buy_view/buy_quote_preview.dart
new file mode 100644
index 000000000..df21ad91a
--- /dev/null
+++ b/lib/pages/buy_view/buy_quote_preview.dart
@@ -0,0 +1,197 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:stackwallet/models/buy/response_objects/quote.dart';
+import 'package:stackwallet/utilities/assets.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/widgets/background.dart';
+import 'package:stackwallet/widgets/conditional_parent.dart';
+import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/desktop/primary_button.dart';
+import 'package:stackwallet/widgets/rounded_white_container.dart';
+
+class BuyQuotePreviewView extends StatefulWidget {
+ const BuyQuotePreviewView({
+ Key? key,
+ required this.quote,
+ }) : super(key: key);
+
+ final SimplexQuote quote;
+
+ static const String routeName = "/buyQuotePreview";
+
+ @override
+ State createState() => _BuyQuotePreviewViewState();
+}
+
+class _BuyQuotePreviewViewState extends State {
+ final isDesktop = Util.isDesktop;
+
+ Future _buy() async {
+ // do buy/redirect to simplex page
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ConditionalParent(
+ condition: !isDesktop,
+ builder: (child) {
+ return Background(
+ child: Scaffold(
+ backgroundColor:
+ Theme.of(context).extension()!.background,
+ appBar: AppBar(
+ backgroundColor:
+ Theme.of(context).extension()!.backgroundAppBar,
+ leading: const AppBarBackButton(),
+ title: Text(
+ "Preview quote",
+ style: STextStyles.navBarTitle(context),
+ ),
+ ),
+ body: LayoutBuilder(
+ builder: (builderContext, constraints) {
+ return Padding(
+ padding: const EdgeInsets.only(
+ left: 12,
+ top: 12,
+ right: 12,
+ ),
+ child: SingleChildScrollView(
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: constraints.maxHeight - 24,
+ ),
+ child: IntrinsicHeight(
+ child: Padding(
+ padding: const EdgeInsets.all(4),
+ child: child,
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ );
+ },
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Text(
+ "Buy ${widget.quote.crypto.ticker.toUpperCase()}",
+ style: STextStyles.pageTitleH1(context),
+ ),
+ const SizedBox(
+ height: 16,
+ ),
+ RoundedWhiteContainer(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "You pay",
+ style: STextStyles.label(context),
+ ),
+ Text(
+ "${widget.quote.youPayFiatPrice.toStringAsFixed(2)} ${widget.quote.fiat.ticker.toUpperCase()}",
+ style: STextStyles.label(context).copyWith(
+ color: Theme.of(context).extension()!.textDark,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ RoundedWhiteContainer(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "You receive",
+ style: STextStyles.label(context),
+ ),
+ Text(
+ "${widget.quote.youReceiveCryptoAmount} ${widget.quote.crypto.ticker.toUpperCase()}",
+ style: STextStyles.label(context).copyWith(
+ color: Theme.of(context).extension()!.textDark,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ RoundedWhiteContainer(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "Receiving ${widget.quote.crypto.ticker.toUpperCase()} address",
+ style: STextStyles.label(context),
+ ),
+ Text(
+ "${widget.quote.receivingAddress} ",
+ style: STextStyles.label(context).copyWith(
+ color: Theme.of(context).extension()!.textDark,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ RoundedWhiteContainer(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Purchase ID",
+ style: STextStyles.label(context),
+ ),
+ Text(
+ widget.quote.purchaseId,
+ style: STextStyles.label(context).copyWith(
+ color: Theme.of(context).extension()!.textDark,
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ RoundedWhiteContainer(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Provider",
+ style: STextStyles.label(context),
+ ),
+ SizedBox(
+ width: 64,
+ child: SvgPicture.asset(Assets.buy.simplexLogo),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ const Spacer(),
+ PrimaryButton(
+ label: "Buy",
+ onPressed: _buy,
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 86599f2e5..b9205116b 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -61,6 +61,8 @@ class _ConfirmChangeNowSendViewState
late final String routeOnSuccessName;
late final Trade trade;
+ final isDesktop = Util.isDesktop;
+
Future _attemptSend(BuildContext context) async {
unawaited(
showDialog(
@@ -227,8 +229,6 @@ class _ConfirmChangeNowSendViewState
final managerProvider = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManagerProvider(walletId)));
- final isDesktop = Util.isDesktop;
-
return ConditionalParent(
condition: !isDesktop,
builder: (child) {
@@ -238,7 +238,7 @@ class _ConfirmChangeNowSendViewState
Theme.of(context).extension()!.background,
appBar: AppBar(
backgroundColor:
- Theme.of(context).extension()!.background,
+ Theme.of(context).extension()!.backgroundAppBar,
leading: AppBarBackButton(
onPressed: () async {
// if (FocusScope.of(context).hasFocus) {
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 7af01cacf..f4c6f731e 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -2,6 +2,7 @@ import 'package:decimal/decimal.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:stackwallet/models/buy/response_objects/quote.dart';
import 'package:stackwallet/models/contact_address_entry.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
@@ -22,6 +23,7 @@ import 'package:stackwallet/pages/address_book_views/subviews/address_book_filte
import 'package:stackwallet/pages/address_book_views/subviews/contact_details_view.dart';
import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_address_view.dart';
import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_name_emoji_view.dart';
+import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart';
import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart';
import 'package:stackwallet/pages/exchange_view/edit_trade_note_view.dart';
import 'package:stackwallet/pages/exchange_view/exchange_loading_overlay.dart';
@@ -1001,6 +1003,20 @@ class RouteGenerator {
}
return _routeError("${settings.name} invalid args: ${args.toString()}");
+ case BuyQuotePreviewView.routeName:
+ if (args is SimplexQuote) {
+ return getRoute(
+ shouldUseMaterialRoute: useMaterialPageRoute,
+ builder: (_) => BuyQuotePreviewView(
+ quote: args,
+ ),
+ settings: RouteSettings(
+ name: settings.name,
+ ),
+ );
+ }
+ return _routeError("${settings.name} invalid args: ${args.toString()}");
+
// == Desktop specific routes ============================================
case CreatePasswordView.routeName:
if (args is bool) {
diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart
index f6d43b26a..c8963a870 100644
--- a/lib/utilities/assets.dart
+++ b/lib/utilities/assets.dart
@@ -31,7 +31,12 @@ class _EXCHANGE {
class _BUY {
const _BUY();
+ // TODO: switch this to something like
+ // String buy(BuildContext context) =>
+ // "assets/svg/${Theme.of(context).extension()!.themeType.name}/buy.svg";
String get buy => "assets/svg/light/buy-coins-icon.svg";
+
+ String get simplexLogo => "assets/svg/buy/Simplex-Nuvei-Logo.svg";
}
class _SVG {
diff --git a/pubspec.yaml b/pubspec.yaml
index 27f63c7c6..f9b92de3b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -384,6 +384,9 @@ flutter:
- assets/svg/oceanBreeze/buy-coins-icon.svg
- assets/svg/oceanBreeze/bg.svg
+ # buy
+ - assets/svg/buy/Simplex-Nuvei-Logo.svg
+
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see