Merge branch 'staging' into testing-exchange

This commit is contained in:
Marco 2022-10-10 11:59:33 -06:00
commit 5707a846b4
16 changed files with 498 additions and 21 deletions

View file

@ -0,0 +1 @@
<svg viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg"><circle cx="500" cy="500" fill="#3030d0" r="432"/><path d="m442.46 592.28-.57 268.21 198.9-5.86 11.38-321.78z" fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><path d="m442.09 765.51 203.95-59.38 6.13-173.28-209.71 59.43z" opacity=".22"/><path d="m299.56 684.62s-8.22-210.92 8.29-329.62c8.89-63.9 6.27-86.42 58.8-92.57 52.53-6.16 222.73-16.46 273.84-16.36s77.74 48.91 70.71 85.32c-7.03 36.4-88.37 376.37-88.37 376.37l-301.28 5.73s-18.98.58-21.98-28.86z" fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><path d="m416.46 801.5v70.09l245.8-2.47 5.5-66.78c1.19-14.45-9.89-26.63-23.33-25.65-29.56 2.17-77.95 5.24-108.03 4.68-30.37-.57-73.34-1.57-98.76-2.18-11.62-.28-21.18 9.79-21.18 22.31z"/><path d="m212.11 1000s22.98-177.76 322.9-169.37 367.93 169.37 367.93 169.37z"/><path d="m640.48 246.07c-24.39-.05-75.9 2.27-128.79 5.38 11.79 5.42 37.9 15.11 56.38 16.52 30.63 2.34 58.35 12.55 62.75 53.5 4.92 45.8-4.27 142.61 48.4 148.92 15.72-66.74 29.29-125.09 31.98-139.01 7.03-36.4-19.6-85.21-70.71-85.32z" fill="#737577"/><path d="m374.41 456.19s1 44.15-22.69 63.11-30.98 32.54-22.93 53.72c8.27 21.75 65.71 28.98 66.07-15.06" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><path d="m373.02 452.24 36.19-1.69" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/><path d="m537.85 454.95 145.93-5.41" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/><circle cx="307.82" cy="449.54" fill="none" r="64.32" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/><circle cx="473.53" cy="450.55" fill="none" r="64.32" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"/><path d="m364.36 646.64c2.67-.29 54.2 9.08 59.48-10.41" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><path d="m321.83 450.13c-1.12 10.47 2.47 28.19 15.33 27.24s18.88-14.37 19.08-27.24-3.26-23.84-15.13-23.84-17.81 9.98-19.29 23.84z"/><path d="m504.71 453.56c1.12-10.47-2.47-28.19-15.33-27.24s-18.88 14.37-19.08 27.24 3.26 23.84 15.13 23.84 17.81-9.98 19.29-23.84z"/><g stroke-linecap="round" stroke-linejoin="round"><path d="m512.3 368.41-57.19 1.59" fill="none" stroke="#000" stroke-width="3"/><path d="m349.98 367.85h-42.16" fill="none" stroke="#000" stroke-width="3"/><path d="m436.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m456.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m476.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m496.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m606.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m626.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m646.62 797.73v49.55" fill="none" stroke="#737577" stroke-width="3"/><path d="m299.56 684.62s-8.22-210.92 8.29-329.62c8.89-63.9 6.27-86.42 58.8-92.57 52.53-6.16 222.73-16.46 273.84-16.36s77.74 48.91 70.71 85.32c-7.03 36.4-88.37 376.37-88.37 376.37l-301.28 5.73s-18.98.58-21.98-28.86z" fill="none" stroke="#000" stroke-width="3"/><path d="m511.69 251.45s-37.95-15.01-57.83-50.66-68.35-27.46-87.75-13.63-34.85 32.58-24.99 61.63c10.76 31.71 57.41 38.43 101.33 20.24s37.13-15.61 37.13-15.61z" fill="#737577" stroke="#000" stroke-width="3"/></g><path d="m640.62 556.81c-.42 40.78 1.06 71.9 1.06 71.9l15.01-63.14-16.08-8.76z" opacity=".22"/><path d="m657.01 461.55s5.39-27.35 26.77-25.44c21.37 1.91 25.82 15.62 26.27 21.99s-10.85 81.79-16.87 112.22c-1.78 9.02-12.6 19.12-28.76 17.53-12.39-1.22-26.41-11.7-23.93-29.01" fill="#fff" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><path d="m387.22 602.43c-11.56 2.17 4.45 17.83 11.14 17.83h63.23s-42.63-23.78-74.36-17.83z" fill="#737577"/><path d="m374.54 602.43c11.56 2.17-4.45 17.83-11.14 17.83h-63.23s42.63-23.78 74.36-17.83z" fill="#737577"/><path d="m0 0v1000h1000v-1000zm500 932c-238.59 0-432-193.41-432-432s193.41-432 432-432 432 193.41 432 432-193.41 432-432 432z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -21,6 +21,10 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/utilities/logger.dart';
class HomeView extends ConsumerStatefulWidget {
const HomeView({Key? key}) : super(key: key);
@ -81,7 +85,15 @@ class _HomeViewState extends ConsumerState<HomeView> {
void _loadCNData() {
// unawaited future
//
final externalCalls = DB.instance
.get<dynamic>(boxName: DB.boxNamePrefs, key: "externalCalls") as bool?;
if (externalCalls ?? false) {
_cnLoadingService.loadAll(ref);
} else {
Logging.instance.log("User does not want to use external calls",
level: LogLevel.Info);
}
}
@override

View file

@ -6,6 +6,9 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/services/change_now/change_now_loading_service.dart';
class HomeViewButtonBar extends ConsumerStatefulWidget {
const HomeViewButtonBar({Key? key}) : super(key: key);
@ -101,7 +104,14 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
ref.read(homeViewPageIndexStateProvider.state).state = 1;
}
DateTime now = DateTime.now();
// TODO: find out why it infinitely loads
final _cnLoadingService = ChangeNowLoadingService();
final externalCalls = DB.instance.get<dynamic>(
boxName: DB.boxNamePrefs, key: "externalCalls") as bool?;
if (!(externalCalls ?? false)) {
print("loading?");
unawaited(_cnLoadingService.loadAll(ref));
}
if (now.difference(_lastRefreshed) > _refreshInterval) {
// bool okPressed = false;
// showDialog<dynamic>(

View file

@ -1,17 +1,23 @@
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
import 'package:stackwallet/pages/stack_privacy_calls.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:url_launcher/url_launcher.dart';
import 'package:stackwallet/hive/db.dart';
class IntroView extends StatefulWidget {
const IntroView({Key? key}) : super(key: key);
static const String routeName = "/introView";
@override
State<IntroView> createState() => _IntroViewState();
}
@ -240,7 +246,9 @@ class GetStartedButton extends StatelessWidget {
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(CreatePinView.routeName);
unawaited(DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs, key: "externalCalls", value: true));
Navigator.of(context).pushNamed(StackPrivacyCalls.routeName);
},
child: Text(
"Get started",
@ -255,7 +263,7 @@ class GetStartedButton extends StatelessWidget {
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(CreatePasswordView.routeName);
Navigator.of(context).pushNamed(StackPrivacyCalls.routeName);
},
child: Text(
"Get started",

View file

@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/intro_view.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class DeleteAccountView extends StatefulWidget {
const DeleteAccountView({Key? key}) : super(key: key);
static const String routeName = "/deleteAccountView";
@override
State<DeleteAccountView> createState() => _DeleteAccountViewState();
}
class _DeleteAccountViewState extends State<DeleteAccountView> {
final isDesktop = Util.isDesktop;
Future<void> onConfirmDeleteAccount() async {
// TODO delete everything then pop to intro view
await Navigator.of(context).pushNamedAndRemoveUntil(
IntroView.routeName,
(route) => false,
);
}
@override
Widget build(BuildContext context) {
return MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop
? DesktopAppBar(isCompactHeight: true)
: AppBar(
leading: AppBarBackButton(
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 75));
}
if (mounted) {
Navigator.of(context).pop();
}
},
),
title: Text(
"Delete account",
style: STextStyles.navBarTitle(context),
),
),
body: Padding(
padding: const EdgeInsets.all(14),
child: Column(
children: [
RoundedWhiteContainer(
child: Text(
"There is no account to delete, but Apple requires that we have a way to 'delete accounts' in the app and will reject our app updates if we don't, so here it is. Clicking this will delete all app data (not from our servers, because we never had it in the first place).\n\nWhen you click confirm, all app data will be deleted, including wallets and preferences, and you will be taken back to the very first onboarding screen. BE SURE TO BACKUP ALL SEEDS!!\n\nAre you sure you want to delete your \"account\"?",
style: STextStyles.smallMed12(context),
),
),
const Spacer(),
PrimaryButton(
label: "Confirm",
onPressed: onConfirmDeleteAccount,
)
],
),
),
);
}
}

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/address_book_views/address_book_view.dart';
import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
@ -5,6 +7,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/about_view
import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/advanced_settings_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/appearance_settings_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/delete_account_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/language_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/security_views/security_view.dart';
@ -224,6 +227,20 @@ class GlobalSettingsView extends StatelessWidget {
.pushNamed(SupportView.routeName);
},
),
if (Platform.isIOS)
const SizedBox(
height: 8,
),
if (Platform.isIOS)
SettingsListButton(
iconAssetName: Assets.svg.circleAlert,
iconSize: 16,
title: "Delete account",
onPressed: () async {
await Navigator.of(context)
.pushNamed(DeleteAccountView.routeName);
},
),
// TextButton(
// style: Theme.of(context)
// .textButtonTheme

View file

@ -0,0 +1,300 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/util.dart';
class StackPrivacyCalls extends ConsumerStatefulWidget {
const StackPrivacyCalls({
Key? key,
}) : super(key: key);
static const String routeName = "/stackPrivacy";
@override
ConsumerState<StackPrivacyCalls> createState() => _StackPrivacyCalls();
}
class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
late final bool isDesktop;
bool isEasy = true;
final PageController _pageController =
PageController(initialPage: 0, keepPage: true);
@override
void initState() {
isDesktop = Util.isDesktop;
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: SafeArea(
child: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Choose your Stack experience",
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"You can change it later in Settings",
style: STextStyles.subtitle(context),
),
const SizedBox(
height: 36,
),
Center(
child: CustomRadio((bool isEasy) {
setState(() {
this.isEasy = isEasy;
DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs,
key: "externalCalls",
value: isEasy);
});
}),
),
const SizedBox(
height: 36,
),
RoundedWhiteContainer(
child: Center(
child: RichText(
textAlign: TextAlign.left,
text: TextSpan(
style:
STextStyles.label(context).copyWith(fontSize: 12.0),
children: isEasy
? const [
TextSpan(
text:
"Exchange data preloaded for a seamless experience."),
TextSpan(
text:
"\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
TextSpan(
text:
"\n\nRecommended for most crypto users.",
style:
TextStyle(fontWeight: FontWeight.bold)),
]
: const [
TextSpan(
text:
"Exchange data not preloaded (slower experience)."),
TextSpan(
text:
"\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
TextSpan(
text:
"\n\nRecommended for the privacy conscious.",
style:
TextStyle(fontWeight: FontWeight.bold)),
],
),
),
),
),
const Spacer(
flex: 4,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 16,
),
child: Row(
children: [
Expanded(
child: ContinueButton(
isDesktop: isDesktop,
),
),
],
),
),
],
),
],
),
),
);
}
}
class ContinueButton extends StatelessWidget {
const ContinueButton({Key? key, required this.isDesktop}) : super(key: key);
final bool isDesktop;
@override
Widget build(BuildContext context) {
return !isDesktop
? TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(CreatePinView.routeName);
},
child: Text(
"Continue",
style: STextStyles.button(context),
),
)
: SizedBox(
width: 328,
height: 70,
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(StackPrivacyCalls.routeName);
},
child: Text(
"Continue",
style: STextStyles.button(context).copyWith(fontSize: 20),
),
),
);
}
}
class CustomRadio extends StatefulWidget {
CustomRadio(this.upperCall, {Key? key}) : super(key: key);
Function upperCall;
@override
createState() {
return CustomRadioState();
}
}
class CustomRadioState extends State<CustomRadio> {
List<RadioModel> sampleData = <RadioModel>[];
@override
void initState() {
super.initState();
sampleData.add(
RadioModel(true, Assets.svg.personaEasy, 'Easy Crypto', 'Recommended'));
sampleData.add(RadioModel(
false, Assets.svg.personaIncognito, 'Incognito', 'Privacy conscious'));
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
setState(() {
// if (!sampleData[0].isSelected) {
widget.upperCall.call(true);
// }
for (var element in sampleData) {
element.isSelected = false;
}
sampleData[0].isSelected = true;
});
},
child: RadioItem(sampleData[0]),
),
InkWell(
onTap: () {
setState(() {
// if (!sampleData[1].isSelected) {
widget.upperCall.call(false);
// }
for (var element in sampleData) {
element.isSelected = false;
}
sampleData[1].isSelected = true;
});
},
child: RadioItem(sampleData[1]),
)
],
);
}
}
class RadioItem extends StatelessWidget {
final RadioModel _item;
const RadioItem(this._item, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(15.0),
child: RoundedWhiteContainer(
borderColor: _item.isSelected ? const Color(0xFF0056D2) : null,
child: Center(
child: Column(
children: [
SvgPicture.asset(
_item.svg,
// color: Theme.of(context).extension<StackColors>()!.textWhite,
width: 96,
height: 96,
),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: STextStyles.label(context).copyWith(fontSize: 12.0),
children: [
TextSpan(
text: _item.topText,
style: const TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: "\n${_item.bottomText}"),
],
),
),
],
)),
),
);
}
}
class RadioModel {
bool isSelected;
final String svg;
final String topText;
final String bottomText;
RadioModel(this.isSelected, this.svg, this.topText, this.bottomText);
}

View file

@ -45,6 +45,10 @@ import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:tuple/tuple.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/utilities/logger.dart';
/// [eventBus] should only be set during testing
class WalletView extends ConsumerStatefulWidget {
const WalletView({
@ -359,7 +363,14 @@ class _WalletViewState extends ConsumerState<WalletView> {
void _loadCNData() {
// unawaited future
final externalCalls = DB.instance
.get<dynamic>(boxName: DB.boxNamePrefs, key: "externalCalls") as bool?;
if (externalCalls ?? false) {
_cnLoadingService.loadAll(ref, coin: ref.read(managerProvider).coin);
} else {
Logging.instance.log("User does not want to use external calls",
level: LogLevel.Info);
}
}
@override

View file

@ -33,6 +33,7 @@ import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages/intro_view.dart';
import 'package:stackwallet/pages/manage_favorites_view/manage_favorites_view.dart';
import 'package:stackwallet/pages/notification_views/notifications_view.dart';
import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
@ -43,6 +44,7 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_v
import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/debug_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/appearance_settings_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/delete_account_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/global_settings_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/hidden_settings.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/language_view.dart';
@ -73,6 +75,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_set
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/rename_wallet_view.dart';
import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart';
import 'package:stackwallet/pages/stack_privacy_calls.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
@ -97,6 +100,18 @@ class RouteGenerator {
final args = settings.arguments;
switch (settings.name) {
case IntroView.routeName:
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => const IntroView(),
settings: RouteSettings(name: settings.name));
case DeleteAccountView.routeName:
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => const DeleteAccountView(),
settings: RouteSettings(name: settings.name));
case HomeView.routeName:
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
@ -120,6 +135,12 @@ class RouteGenerator {
builder: (_) => const CreatePinView(),
settings: RouteSettings(name: settings.name));
case StackPrivacyCalls.routeName:
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => const StackPrivacyCalls(),
settings: RouteSettings(name: settings.name));
case WalletsView.routeName:
return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute,

View file

@ -2444,8 +2444,8 @@ class NamecoinWallet extends CoinServiceAPI {
for (final out in tx["vout"] as List) {
if (prevOut == out["n"]) {
String? address = out["scriptPubKey"]["address"] as String?;
if (address == null && out["scriptPubKey"]["addresses"] != null) {
address = out["scriptPubKey"]["addresses"][0] as String?;
if (address == null && out["scriptPubKey"]["address"] != null) {
address = out["scriptPubKey"]["address"] as String?;
}
if (address != null) {
@ -2459,8 +2459,8 @@ class NamecoinWallet extends CoinServiceAPI {
for (final output in txObject["vout"] as List) {
String? address = output["scriptPubKey"]["address"] as String?;
if (address == null && output["scriptPubKey"]["addresses"] != null) {
address = output["scriptPubKey"]["addresses"][0] as String?;
if (address == null && output["scriptPubKey"]["address"] != null) {
address = output["scriptPubKey"]["address"] as String?;
}
if (address != null) {
recipientsArray.add(address);
@ -2501,7 +2501,8 @@ class NamecoinWallet extends CoinServiceAPI {
int totalOutput = 0;
for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["addresses"][0];
Logging.instance.log(output, level: LogLevel.Info);
final address = output["scriptPubKey"]["address"];
final value = output["value"];
final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin))
@ -2527,8 +2528,8 @@ class NamecoinWallet extends CoinServiceAPI {
// add up received tx value
for (final output in txObject["vout"] as List) {
String? address = output["scriptPubKey"]["address"] as String?;
if (address == null && output["scriptPubKey"]["addresses"] != null) {
address = output["scriptPubKey"]["addresses"][0] as String?;
if (address == null && output["scriptPubKey"]["address"] != null) {
address = output["scriptPubKey"]["address"] as String?;
}
if (address != null) {
final value = (Decimal.parse(output["value"].toString()) *
@ -3048,7 +3049,7 @@ class NamecoinWallet extends CoinServiceAPI {
for (final output in tx["vout"] as List) {
final n = output["n"];
if (n != null && n == utxosToUse[i].vout) {
final address = output["scriptPubKey"]["addresses"][0] as String;
final address = output["scriptPubKey"]["address"] as String;
if (!addressTxid.containsKey(address)) {
addressTxid[address] = <String>[];
}

View file

@ -76,6 +76,14 @@ class PriceAPI {
return _cachedPrices;
}
final externalCalls = DB.instance
.get<dynamic>(boxName: DB.boxNamePrefs, key: "externalCalls") as bool?;
if (!(externalCalls ?? false)) {
Logging.instance.log("User does not want to use external calls",
level: LogLevel.Info);
return _cachedPrices;
}
Map<Coin, Tuple2<Decimal, double>> result = {};
try {
final uri = Uri.parse(
@ -88,14 +96,8 @@ class PriceAPI {
headers: {'Content-Type': 'application/json'},
);
// debugPrint(coinGeckoResponse.statusCode.toString());
// debugPrint(coinGeckoResponse.body.toString());
// debugPrint(coinGeckoResponse.headers.toString());
final coinGeckoData = jsonDecode(coinGeckoResponse.body) as List<dynamic>;
// log(JsonEncoder.withIndent(" ").convert(coinGeckoData));
for (final map in coinGeckoData) {
final String coinName = map["name"] as String;
final coin = coinFromPrettyName(coinName);
@ -120,6 +122,14 @@ class PriceAPI {
}
static Future<List<String>?> availableBaseCurrencies() async {
final externalCalls = DB.instance
.get<dynamic>(boxName: DB.boxNamePrefs, key: "externalCalls") as bool?;
print("externalCalls hi2 $externalCalls");
if (!(externalCalls ?? false)) {
Logging.instance.log("User does not want to use external calls",
level: LogLevel.Info);
return null;
}
const uriString =
"https://api.coingecko.com/api/v3/simple/supported_vs_currencies";
try {

View file

@ -60,6 +60,8 @@ class _SVG {
"assets/svg/${Theme.of(context).extension<StackColors>()!.themeType.name}/tx-exchange-icon-failed.svg";
String get polygon => "assets/svg/Polygon.svg";
String get personaIncognito => "assets/svg/persona-incognito-1.svg";
String get personaEasy => "assets/svg/persona-easy-1.svg";
String get drd => "assets/svg/drd-icon.svg";
String get boxAuto => "assets/svg/box-auto.svg";
String get plus => "assets/svg/plus.svg";

View file

@ -10,6 +10,7 @@ class RoundedContainer extends StatelessWidget {
this.radiusMultiplier = 1.0,
this.width,
this.height,
this.borderColor,
}) : super(key: key);
final Widget? child;
@ -18,6 +19,7 @@ class RoundedContainer extends StatelessWidget {
final double radiusMultiplier;
final double? width;
final double? height;
final Color? borderColor;
@override
Widget build(BuildContext context) {
@ -29,6 +31,7 @@ class RoundedContainer extends StatelessWidget {
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius * radiusMultiplier,
),
border: borderColor == null ? null : Border.all(color: borderColor!),
),
child: Padding(
padding: padding,

View file

@ -10,6 +10,7 @@ class RoundedWhiteContainer extends StatelessWidget {
this.radiusMultiplier = 1.0,
this.width,
this.height,
this.borderColor,
}) : super(key: key);
final Widget? child;
@ -17,6 +18,7 @@ class RoundedWhiteContainer extends StatelessWidget {
final double radiusMultiplier;
final double? width;
final double? height;
final Color? borderColor;
@override
Widget build(BuildContext context) {
@ -27,6 +29,7 @@ class RoundedWhiteContainer extends StatelessWidget {
width: width,
height: height,
child: child,
borderColor: borderColor,
);
}
}

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.4.53+69
version: 1.5.1+71
environment:
sdk: ">=2.17.0 <3.0.0"
@ -290,6 +290,8 @@ flutter:
- assets/svg/tx-icon-anonymize-pending.svg
- assets/svg/tx-icon-anonymize-failed.svg
- assets/svg/Polygon.svg
- assets/svg/persona-easy-1.svg
- assets/svg/persona-incognito-1.svg
# coin icons
- assets/svg/coin_icons/Bitcoin.svg
- assets/svg/coin_icons/Bitcoincash.svg