Merge pull request #1462 from cake-tech/CW-621-Open-external-sites-in-default-browser
Some checks are pending
Cache Dependencies / test (push) Waiting to run

CW-621 Open external sites in default browser
This commit is contained in:
tuxsudo 2024-07-06 00:23:13 +02:00 committed by GitHub
commit c5d3cbf66c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 194 additions and 34 deletions

View file

@ -2,7 +2,6 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_ro
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
import 'package:cake_wallet/themes/extensions/placeholder_theme.dart';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
@ -53,11 +52,7 @@ class TransactionsPage extends StatelessWidget {
try {
final uri = Uri.parse(
"https://guides.cakewallet.com/docs/FAQ/why_are_my_funds_not_appearing/");
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.webViewPage, arguments: ['', uri]);
} else {
launchUrl(uri);
}
launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (_) {}
},
title: S.of(context).syncing_wallet_alert_title,

View file

@ -46,10 +46,6 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
bool _checked = false;
String _fileText = '';
Future<void> launchUrl(String url) async {
if (await canLaunch(url)) await launch(url);
}
Future getFileLines() async {
_fileText = await rootBundle.loadString(
isMoneroOnly
@ -152,7 +148,11 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () => launchUrl(changenowUrl),
onTap: () async {
final uri = Uri.parse(changenowUrl);
if (await canLaunchUrl(uri))
await launchUrl(uri, mode: LaunchMode.externalApplication);
},
child: Text(
changenowUrl,
textAlign: TextAlign.left,

View file

@ -0,0 +1,163 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/core/email_validator.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.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/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:url_launcher/url_launcher.dart';
class IoniaCreateAccountPage extends BasePage {
IoniaCreateAccountPage(this._authViewModel)
: _emailFocus = FocusNode(),
_emailController = TextEditingController(),
_formKey = GlobalKey<FormState>() {
_emailController.text = _authViewModel.email;
_emailController.addListener(() => _authViewModel.email = _emailController.text);
}
final IoniaAuthViewModel _authViewModel;
final GlobalKey<FormState> _formKey;
final FocusNode _emailFocus;
final TextEditingController _emailController;
static const privacyPolicyUrl = 'https://ionia.docsend.com/view/jhjvdn7qq7k3ukwt';
static const termsAndConditionsUrl = 'https://ionia.docsend.com/view/uceirymz2ijacq5g';
@override
Widget middle(BuildContext context) {
return Text(
S.current.sign_up,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
reaction((_) => _authViewModel.createUserState, (IoniaCreateAccountState state) {
if (state is IoniaCreateStateFailure) {
_onCreateUserFailure(context, state.error);
}
if (state is IoniaCreateStateSuccess) {
_onCreateSuccessful(context, _authViewModel);
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: BaseTextFormField(
hintText: S.of(context).email_address,
focusNode: _emailFocus,
validator: EmailValidator(),
keyboardType: TextInputType.emailAddress,
controller: _emailController,
onSubmit: (_) => _createAccount(),
),
),
bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24),
bottomSection: Column(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Observer(
builder: (_) => LoadingPrimaryButton(
text: S.of(context).create_account,
onPressed: _createAccount,
isLoading:
_authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
SizedBox(
height: 20,
),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: S.of(context).agree_to,
style: TextStyle(
color: Color(0xff7A93BA),
fontSize: 12,
fontFamily: 'Lato',
),
children: [
TextSpan(
text: S.of(context).settings_terms_and_conditions,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
final uri = Uri.parse(termsAndConditionsUrl);
if (await canLaunchUrl(uri))
await launchUrl(uri, mode: LaunchMode.externalApplication);
},
),
TextSpan(text: ' ${S.of(context).and} '),
TextSpan(
text: S.of(context).privacy_policy,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
final uri = Uri.parse(privacyPolicyUrl);
if (await canLaunchUrl(uri))
await launchUrl(uri, mode: LaunchMode.externalApplication);
}),
TextSpan(text: ' ${S.of(context).by_cake_pay}'),
],
),
),
],
),
],
),
);
}
void _onCreateUserFailure(BuildContext context, String error) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.current.create_account,
alertContent: error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}
void _onCreateSuccessful(BuildContext context, IoniaAuthViewModel authViewModel) => Navigator.pushNamed(
context,
Routes.ioniaVerifyIoniaOtpPage,
arguments: [authViewModel.email, false],
);
void _createAccount() async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await _authViewModel.createUser(_emailController.text);
}
}

View file

@ -31,7 +31,8 @@ class SettingsLinkProviderCell extends StandardListRow {
static void _launchUrl(String url) async {
try {
await launch(url, forceSafariVC: false);
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e) {}
}
}

View file

@ -161,27 +161,26 @@ class YatPopup extends StatelessWidget {
onClose: onClose,
onGet: () {
var createNewYatUrl = YatLink.startFlowUrl;
final createNewYatUrlParameters = dashboardViewModel.
yatStore.defineQueryParameters();
final createNewYatUrlParameters =
dashboardViewModel.yatStore.defineQueryParameters();
if (createNewYatUrlParameters.isNotEmpty) {
createNewYatUrl += '?sub1=' + createNewYatUrlParameters;
}
launch(createNewYatUrl, forceSafariVC: false);
final uri = Uri.parse(createNewYatUrl);
launchUrl(uri, mode: LaunchMode.externalApplication);
},
onConnect: () {
String url = baseUrl + YatLink.signInSuffix;
final parameters = dashboardViewModel
.yatStore.defineQueryParameters();
final parameters = dashboardViewModel.yatStore.defineQueryParameters();
if (parameters.isNotEmpty) {
url += YatLink.queryParameter + parameters;
}
launch(url, forceSafariVC: false);
}
))
: Container()
)
final uri = Uri.parse(url);
launchUrl(uri, mode: LaunchMode.externalApplication);
}))
: Container())
],
);
}

View file

@ -103,7 +103,8 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
child: PrimaryImageButton(
onPressed: () {
try {
launchUrl(Uri.parse("https://status.cakewallet.com/"));
launchUrl(Uri.parse("https://status.cakewallet.com/"),
mode: LaunchMode.externalApplication);
} catch (_) {}
},
image: Image.asset(

View file

@ -19,7 +19,7 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
abstract class OrderDetailsViewModelBase with Store {
OrderDetailsViewModelBase({required WalletBase wallet, required Order orderForDetails})
: items = ObservableList<StandartListItem>(),
: items = ObservableList<StandartListItem>(),
order = orderForDetails {
if (order.provider != null) {
switch (order.provider) {
@ -101,13 +101,13 @@ abstract class OrderDetailsViewModelBase with Store {
TrackTradeListItem(
title: S.current.track,
value: buildURL,
onTap: () {
onTap: () async {
try {
launch(buildURL);
final uri = Uri.parse(buildURL);
if (await canLaunchUrl(uri))
await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e) {}
}
)
);
}));
}
}

View file

@ -179,7 +179,7 @@ abstract class TradeDetailsViewModelBase with Store {
void _launchUrl(String url) {
final uri = Uri.parse(url);
try {
launchUrl(uri);
launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e) {}
}
}

View file

@ -103,9 +103,10 @@ abstract class TransactionDetailsViewModelBase with Store {
items.add(BlockExplorerListItem(
title: S.current.view_in_block_explorer,
value: _explorerDescription(type),
onTap: () {
onTap: () async {
try {
launch(_explorerUrl(type, tx.id));
final uri = Uri.parse(_explorerUrl(type, tx.id));
if (await canLaunchUrl(uri)) await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e) {}
}));

View file

@ -56,7 +56,7 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
onTap: () {
try {
final url = Uri.parse(_explorerUrl(_type, unspentCoinsItem.hash));
return launchUrl(url);
return launchUrl(url, mode: LaunchMode.externalApplication);
} catch (e) {}
},
));