From b0b82d86e05bed15d7f551648540e5e4cb4d8d1a Mon Sep 17 00:00:00 2001 From: Tovi Jaeschke-Rogers Date: Wed, 12 Oct 2022 21:56:16 +1000 Subject: [PATCH] Add ability to set server URL on login --- mobile/lib/main.dart | 7 +- mobile/lib/models/my_profile.dart | 5 + mobile/lib/views/authentication/login.dart | 84 +++++++++++++- .../unauthenticated_landing.dart | 108 +++++++++--------- mobile/pubspec.lock | 7 -- 5 files changed, 148 insertions(+), 63 deletions(-) diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index ce2ea93..e8bfd8e 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -1,3 +1,4 @@ +import 'package:Envelope/models/my_profile.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import '/views/main/home.dart'; @@ -6,7 +7,11 @@ import '/views/authentication/login.dart'; import '/views/authentication/signup.dart'; 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()); } diff --git a/mobile/lib/models/my_profile.dart b/mobile/lib/models/my_profile.dart index add753a..999a576 100644 --- a/mobile/lib/models/my_profile.dart +++ b/mobile/lib/models/my_profile.dart @@ -149,6 +149,11 @@ class MyProfile { return profile.privateKey!; } + static Future getBaseServerUrl() async { + final preferences = await SharedPreferences.getInstance(); + return preferences.getString('server_url') ?? defaultServerUrl; + } + static setServerUrl(String url) async { final preferences = await SharedPreferences.getInstance(); preferences.setString('server_url', url); diff --git a/mobile/lib/views/authentication/login.dart b/mobile/lib/views/authentication/login.dart index 57b2af7..8835080 100644 --- a/mobile/lib/views/authentication/login.dart +++ b/mobile/lib/views/authentication/login.dart @@ -72,6 +72,21 @@ class _LoginWidgetState extends State { final TextEditingController _usernameController = 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 Widget build(BuildContext context) { @@ -158,14 +173,12 @@ class _LoginWidgetState extends State { }, ), const SizedBox(height: 15), + changeUrl(), + const SizedBox(height: 20), ElevatedButton( style: buttonStyle, onPressed: () { if (_formKey.currentState!.validate()) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Processing Data')), - ); - login() .then((val) { Navigator. @@ -192,7 +205,70 @@ class _LoginWidgetState extends State { ); } + 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 login() async { + if (_urlController.text != _initialServerUrl) { + await MyProfile.setServerUrl(_urlController.text); + } + final resp = await http.post( await MyProfile.getServerUrl('api/v1/login'), headers: { diff --git a/mobile/lib/views/authentication/unauthenticated_landing.dart b/mobile/lib/views/authentication/unauthenticated_landing.dart index 8bda322..2dcb15f 100644 --- a/mobile/lib/views/authentication/unauthenticated_landing.dart +++ b/mobile/lib/views/authentication/unauthenticated_landing.dart @@ -27,61 +27,67 @@ class _UnauthenticatedLandingWidgetState extends State false, child: Scaffold( - body: SafeArea( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - 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: [ + 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), + ] ), - ), + ), + ], + ), ), + ), ), ); } diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 93f2c89..824f474 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -128,13 +128,6 @@ packages: description: flutter source: sdk 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: dependency: "direct main" description: