Browse Source

Add ability to set server URL on login

feature/add-notifications
Tovi Jaeschke-Rogers 2 years ago
parent
commit
b0b82d86e0
5 changed files with 148 additions and 63 deletions
  1. +6
    -1
      mobile/lib/main.dart
  2. +5
    -0
      mobile/lib/models/my_profile.dart
  3. +80
    -4
      mobile/lib/views/authentication/login.dart
  4. +57
    -51
      mobile/lib/views/authentication/unauthenticated_landing.dart
  5. +0
    -7
      mobile/pubspec.lock

+ 6
- 1
mobile/lib/main.dart View File

@ -1,3 +1,4 @@
import 'package:Envelope/models/my_profile.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import '/views/main/home.dart'; import '/views/main/home.dart';
@ -6,7 +7,11 @@ import '/views/authentication/login.dart';
import '/views/authentication/signup.dart'; import '/views/authentication/signup.dart';
void main() async { void main() async {
await dotenv.load(fileName: ".env");
await dotenv.load(fileName: '.env');
// TODO: Replace this with the prod url when server is deployed
MyProfile.setServerUrl(dotenv.env['SERVER_URL'] ?? 'http://localhost:8080/');
runApp(const MyApp()); runApp(const MyApp());
} }


+ 5
- 0
mobile/lib/models/my_profile.dart View File

@ -149,6 +149,11 @@ class MyProfile {
return profile.privateKey!; return profile.privateKey!;
} }
static Future<String> getBaseServerUrl() async {
final preferences = await SharedPreferences.getInstance();
return preferences.getString('server_url') ?? defaultServerUrl;
}
static setServerUrl(String url) async { static setServerUrl(String url) async {
final preferences = await SharedPreferences.getInstance(); final preferences = await SharedPreferences.getInstance();
preferences.setString('server_url', url); preferences.setString('server_url', url);


+ 80
- 4
mobile/lib/views/authentication/login.dart View File

@ -72,6 +72,21 @@ class _LoginWidgetState extends State<LoginWidget> {
final TextEditingController _usernameController = TextEditingController(); final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController(); final TextEditingController _passwordController = TextEditingController();
final TextEditingController _urlController = TextEditingController();
bool _changedUrl = false;
String _initialServerUrl = '';
@override
void initState() {
MyProfile.getBaseServerUrl().then((String url) {
_urlController.text = url;
_initialServerUrl = url;
});
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -158,14 +173,12 @@ class _LoginWidgetState extends State<LoginWidget> {
}, },
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
changeUrl(),
const SizedBox(height: 20),
ElevatedButton( ElevatedButton(
style: buttonStyle, style: buttonStyle,
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
login() login()
.then((val) { .then((val) {
Navigator. Navigator.
@ -192,7 +205,70 @@ class _LoginWidgetState extends State<LoginWidget> {
); );
} }
Widget changeUrl() {
if (_changedUrl) {
return TextFormField(
controller: _urlController,
decoration: InputDecoration(
hintText: 'URL',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
color: Colors.transparent,
)
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
color: Colors.transparent,
)
),
),
style: const TextStyle(
fontSize: 18,
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter a URL';
}
return null;
},
);
}
return GestureDetector(
onTap: () {
setState(() {
_changedUrl = true;
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
'Change URL',
style: TextStyle(
color: Theme.of(context).disabledColor,
),
),
const SizedBox(width: 10),
Icon(
Icons.edit,
color: Theme.of(context).disabledColor,
size: 14,
),
const SizedBox(width: 10),
],
)
);
}
Future<dynamic> login() async { Future<dynamic> login() async {
if (_urlController.text != _initialServerUrl) {
await MyProfile.setServerUrl(_urlController.text);
}
final resp = await http.post( final resp = await http.post(
await MyProfile.getServerUrl('api/v1/login'), await MyProfile.getServerUrl('api/v1/login'),
headers: <String, String>{ headers: <String, String>{


+ 57
- 51
mobile/lib/views/authentication/unauthenticated_landing.dart View File

@ -27,61 +27,67 @@ class _UnauthenticatedLandingWidgetState extends State<UnauthenticatedLandingWid
return WillPopScope( return WillPopScope(
onWillPop: () async => false, onWillPop: () async => false,
child: Scaffold( child: Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Image(
image: AssetImage('assets/logo_orange.png'),
height: 150,
)
]
),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: AssetImage(
MediaQuery.of(context).platformBrightness == Brightness.dark ?
'assets/logo_orange.png' :
'assets/logo_blue.png'
), ),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(
top: 15,
bottom: 15,
left: 20,
right: 20,
),
child: Column (
children: [
ElevatedButton(
child: const Text('Login'),
onPressed: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const Login()),
),
},
height: 150,
)
]
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.only(
top: 15,
bottom: 15,
left: 20,
right: 20,
),
child: Column (
children: [
ElevatedButton(
child: const Text('Login'),
onPressed: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const Login()),
),
},
style: buttonStyle,
),
style: buttonStyle,
),
const SizedBox(height: 20),
ElevatedButton(
child: const Text('Sign Up'),
onPressed: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const Signup()),
),
},
style: buttonStyle,
),
]
),
),
],
const SizedBox(height: 20),
ElevatedButton(
child: const Text('Sign Up'),
onPressed: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const Signup()),
),
},
style: buttonStyle,
),
const SizedBox(height: 50),
]
), ),
),
),
],
),
), ),
),
), ),
); );
} }


+ 0
- 7
mobile/pubspec.lock View File

@ -128,13 +128,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
font_awesome_flutter:
dependency: "direct main"
description:
name: font_awesome_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "10.1.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:


Loading…
Cancel
Save