Skip to content

Commit

Permalink
Merge pull request #54 from Emmanueleclipse/develop
Browse files Browse the repository at this point in the history
Add ability to change backend URL on the setting page
  • Loading branch information
pshenmic authored Feb 25, 2024
2 parents b1b6c63 + 1b9b5b7 commit cfdc543
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 17 deletions.
12 changes: 7 additions & 5 deletions lib/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import 'dart:convert';
import 'dart:io';

class Client {
static final protocol = 'https';
static final domain = 'api.anypayx.com';
static final host = "$protocol://$domain";
static Uri apiUri = Uri(scheme: 'https', host: 'api.anypayx.com');

static String humanize(String str) {
return StringUtils.capitalize(str);
Expand Down Expand Up @@ -132,7 +130,7 @@ class Client {

var response = await makeRequest('get',
unauthorized: (() => Authentication.logout()),
uri: Uri.https(domain, '/invoices', {
uri: Uri.https(apiUri.host, '/invoices', {
'limit': perPage.toString(),
'offset': offset.toString(),
'complete': 'true',
Expand Down Expand Up @@ -192,7 +190,7 @@ class Client {

static Future<Map<dynamic, dynamic>> makeRequest(method, {path, uri, headers, body, requireAuth, basicAuth, unauthorized, genericErrorCodes}) async {
try {
http.Request request = http.Request(method, uri ?? Uri.parse('$host$path'));
http.Request request = http.Request(method, uri ?? Uri.parse('${apiUri.toString()}$path'));
if (requireAuth ?? false) request.headers['authorization'] = buildAuthHeader();
if (basicAuth != null) request.headers['authorization'] = basicAuth;
if (genericErrorCodes == null) genericErrorCodes = [500];
Expand Down Expand Up @@ -238,4 +236,8 @@ class Client {
};
}
}

static updateUri({required Uri uri}) {
apiUri = uri;
}
}
14 changes: 13 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:app/app_controller.dart';
import 'package:app/router.dart';
import 'client.dart';
import 'native_storage.dart';

void main() {
WidgetsFlutterBinding.ensureInitialized();
setDefaultUrl();
Authentication.checkForAuth().then((isAuthenticated) {
AnyFluroRouter.setupRouter();
runApp(Anypay(isAuthenticated));
Expand Down Expand Up @@ -39,14 +42,16 @@ class Anypay extends StatelessWidget {
),
fontFamily: 'Ubuntu',
);

var darkTheme = ThemeData(
primaryColorDark: Color(0xffCCCCCC),
primaryColorLight: Color(0xFFFFFFFF),
textTheme: TextTheme(
bodyMedium: TextStyle(color: Color(0xFFFFFFFF)),
bodyLarge: TextStyle(color: Color(0xFFFFFFFF)),
),
dialogTheme: DialogTheme(
titleTextStyle: TextStyle(color: Color(0xFFFFFFFF),fontSize: 24),
),
inputDecorationTheme: const InputDecorationTheme(
labelStyle: TextStyle(color: Color(0xFFFFFFFF)),
enabledBorder:
Expand Down Expand Up @@ -87,3 +92,10 @@ class Anypay extends StatelessWidget {
});
}
}

void setDefaultUrl() async {
final storedUrl = await Storage.read("backend_url");
if (storedUrl != null) {
Client.updateUri(uri: Uri.parse(storedUrl));
}
}
4 changes: 2 additions & 2 deletions lib/models/invoice.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class Invoice {

String urlStyleUri([useCurrency]) {
useCurrency = useCurrency ?? currency;
String host = Client.host;
String host = Client.apiUri.toString();
String protocol = {
'BTC': 'bitcoin',
'BCH': 'bitcoincash',
Expand All @@ -143,7 +143,7 @@ class Invoice {
}

String uriFor(currency, {format}) {
if (format == 'pay') return "pay:?r=${Client.host}/r/$uid";
if (format == 'pay') return "pay:?r=${Client.apiUri.toString()}/r/$uid";
if (format == 'url') return urlStyleUri(currency);

return paymentOptionFor(currency)['uri'];
Expand Down
6 changes: 6 additions & 0 deletions lib/router.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:app/routes/edit_backend_url.dart';
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';

Expand Down Expand Up @@ -84,6 +85,11 @@ class AnyFluroRouter {
handler: newHandler(() => SetCurrency(), []),
transitionType: TransitionType.inFromBottom,
);
router.define(
'settings/backend_url',
handler: newHandler(() => EditBackEndUrl(), []),
transitionType: TransitionType.inFromBottom,
);
router.define(
'settings/addresses',
handler: newHandler(() => Addresses(), []),
Expand Down
145 changes: 145 additions & 0 deletions lib/routes/edit_backend_url.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import 'package:app/authentication.dart';
import 'package:flutter/material.dart';
import 'package:app/back_button.dart';
import 'package:app/app_controller.dart';
import 'package:app/currencies.dart';
import '../client.dart';
import '../native_storage.dart';

class EditBackEndUrl extends StatelessWidget {
@override
Widget build(BuildContext context) {
return EditBackEndUrlPage(title: "Edit Backend Url");
}
}

class EditBackEndUrlPage extends StatefulWidget {
EditBackEndUrlPage({Key? key, required this.title}) : super(key: key);

final String title;

@override
_EditBackEndUrlState createState() => _EditBackEndUrlState();
}

class _EditBackEndUrlState extends State<EditBackEndUrlPage> {
var urlController = TextEditingController();

GlobalKey<FormState> _formKey = GlobalKey();


@override
void initState() {
super.initState();
setBackendUrl();
}

void setBackendUrl() {
urlController.text = Client.apiUri.toString();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_EditUrlLink(),
CircleBackButton(
margin: EdgeInsets.only(top: 20.0),
backPath: 'navigation',
),
],
)),
],
),
),
),
);
}

Widget _EditUrlLink() {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: urlController,
decoration: InputDecoration(
labelText: 'Backend Url',
hintText: "http:// or https://"),
validator: (value) {
if (value != null && Uri.parse(value).isAbsolute) {
return null;
} else {
return "Please provide valid url";
}
}),
Container(
margin: EdgeInsets.only(top: 40.0),
child: GestureDetector(
child: Text('SAVE', style: TextStyle(
fontWeight: FontWeight.bold,
color: AppController.blue,
fontSize: 18,
)),
onTap: () async {
if (_formKey.currentState!.validate()) {
showAlertDialog(
context: context,
title: "Confirmation",
desc: "Are you sure you want to change the backend API url?",
onOkPressed: () async {
await Storage.write(
"backend_url", urlController.text);
Client.updateUri(
uri: Uri.parse(urlController.text));
Authentication.logout();
});
}
},
),
),
],
),
);
}
showAlertDialog(
{required BuildContext context,
required String title,
required String desc,
required onOkPressed}) {
Widget okButton = TextButton(
child: Text("OK"),
onPressed: onOkPressed,
);
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
);
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(desc),
actions: [
cancelButton,
okButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
}
29 changes: 27 additions & 2 deletions lib/routes/login.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';

import 'package:email_validator/email_validator.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:app/app_controller.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -68,6 +69,13 @@ class _LoginPageState extends State<LoginPage> {
});
Client.authenticate(email.text, password.text).then((response) {
_submitting = false;
if (response['body'] == null || response['body'].isEmpty) {
setState(() {
_errorMessage =
"An unknown error occured, try changing the backend url.";
});
return;
}
if (response['success']) {
AppController.closeUntilPath('/new-invoice');
}
Expand Down Expand Up @@ -141,7 +149,7 @@ class _LoginPageState extends State<LoginPage> {
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: _submitting ? 20.0 : 40.0),
margin: EdgeInsets.only(bottom: 20.0),
child: _submitting ?
SpinKitCircle(color: AppController.blue) :
GestureDetector(
Expand Down Expand Up @@ -183,9 +191,26 @@ class _LoginPageState extends State<LoginPage> {
]
),
),
Container(
margin: EdgeInsets.only(top: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
child: Text('Settings', style: TextStyle(
fontWeight: FontWeight.bold,
color: AppController.blue,
fontSize: 18,
)),
onTap: () {
Navigator.pushNamed(context, 'settings');
}
),
]
),
),
],
),
);
}

}
43 changes: 36 additions & 7 deletions lib/routes/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:app/back_button.dart';
import 'package:app/app_controller.dart';
import 'package:app/currencies.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import '../client.dart';

class Settings extends StatelessWidget {
@override
Expand All @@ -24,14 +26,17 @@ class _SettingsPageState extends State<SettingsPage> {
var _successMessage = '';
var denomination;
var symbol;

bool? isUserLoggedIn;
@override
void initState() {
_rebuild();
super.initState();
Authentication.getAccount().then((account) {
_rebuild();
});
isUserLoggedIn = Authentication.currentAccount.email != null;
if (isUserLoggedIn == true) {
Authentication.getAccount().then((account) {
_rebuild();
});
}
}

@override
Expand All @@ -51,9 +56,10 @@ class _SettingsPageState extends State<SettingsPage> {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_SelectCurrencyLink(context),
_BusinessInfoLink(context),
_AddressesLink(context),
_EditUrlLink(context),
if (isUserLoggedIn == true) _SelectCurrencyLink(context),
if (isUserLoggedIn == true) _BusinessInfoLink(context),
if (isUserLoggedIn == true) _AddressesLink(context),
CircleBackButton(
margin: EdgeInsets.only(top: 20.0),
backPath: 'navigation',
Expand All @@ -68,6 +74,29 @@ class _SettingsPageState extends State<SettingsPage> {
);
}

Widget _EditUrlLink(context) {
return Container(
margin: EdgeInsets.all(10.0),
child: GestureDetector(
behavior: HitTestBehavior.translucent,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.all(AppController.scale(20.0)),
child: Text("Backend URL",
style: TextStyle(
fontSize: 22,
))),
Icon(Icons.edit),
],
),
onTap: () {
Navigator.pushNamed(context, 'settings/backend_url');
}),
);
}

void _rebuild() {
setState(() {
if (Authentication.currentAccount.denomination != null) {
Expand Down

0 comments on commit cfdc543

Please sign in to comment.