diff --git a/lib/ui/login_screen.dart b/lib/ui/login_screen.dart index 422acc6..133a510 100644 --- a/lib/ui/login_screen.dart +++ b/lib/ui/login_screen.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; @@ -12,16 +11,14 @@ import '../api/definitions.dart'; import 'home_screen.dart'; class LoginWidget extends StatefulWidget { - - Function callback; - LoginWidget({this.callback, Key key}): super(key: key); + final Function callback; + LoginWidget({this.callback, Key key}) : super(key: key); @override _LoginWidgetState createState() => _LoginWidgetState(); } class _LoginWidgetState extends State { - String _arl; String _error; @@ -38,6 +35,7 @@ class _LoginWidgetState extends State { await hp.save(); } } + //Call _init() void _start() async { if (settings.arl != null) { @@ -50,20 +48,21 @@ class _LoginWidgetState extends State { //Check if deezer available in current country void _checkAvailability() async { bool available = await DeezerAPI.chceckAvailability(); - if (!(available??true)) { + if (!(available ?? true)) { showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text("Deezer is unavailable".i18n), - content: Text("Deezer is unavailable in your country, Freezer might not work properly. Please use a VPN".i18n), - actions: [ - TextButton( - child: Text('Continue'.i18n), - onPressed: () => Navigator.of(context).pop(), - ) - ], - ) - ); + context: context, + builder: (context) => AlertDialog( + title: Text("Deezer is unavailable".i18n), + content: Text( + "Deezer is unavailable in your country, Freezer might not work properly. Please use a VPN" + .i18n), + actions: [ + TextButton( + child: Text('Continue'.i18n), + onPressed: () => Navigator.of(context).pop(), + ) + ], + )); } } @@ -82,29 +81,29 @@ class _LoginWidgetState extends State { void errorDialog() { showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text('Error'.i18n), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Error logging in! Please check your token and internet connection and try again.'.i18n), - if (_error != null) - Text('\n\n$_error') + context: context, + builder: (context) { + return AlertDialog( + title: Text('Error'.i18n), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Error logging in! Please check your token and internet connection and try again.' + .i18n), + if (_error != null) Text('\n\n$_error') + ], + ), + actions: [ + TextButton( + child: Text('Dismiss'.i18n), + onPressed: () { + Navigator.of(context).pop(); + }, + ) ], - ), - actions: [ - FlatButton( - child: Text('Dismiss'.i18n), - onPressed: () { - Navigator.of(context).pop(); - }, - ) - ], - ); - } - ); + ); + }); } void _update() async { @@ -113,11 +112,13 @@ class _LoginWidgetState extends State { //Try logging in try { deezerAPI.arl = settings.arl; - bool resp = await deezerAPI.rawAuthorize(onError: (e) => setState(() => _error = e.toString())); - if (resp == false) { //false, not null + bool resp = await deezerAPI.rawAuthorize( + onError: (e) => setState(() => _error = e.toString())); + if (resp == false) { + //false, not null if (settings.arl.length != 192) { if (_error == null) _error = ''; - _error += 'Invalid ARL length!'; + _error += 'Invalid ARL length!'; } setState(() => settings.arl = null); errorDialog(); @@ -147,7 +148,6 @@ class _LoginWidgetState extends State { @override Widget build(BuildContext context) { - //If arl non null, show loading if (settings.arl != null) return Scaffold( @@ -157,137 +157,146 @@ class _LoginWidgetState extends State { ); TextEditingController _controller = new TextEditingController(); // For "DPAD center" key handling on remote controls - FocusNode focusNode = FocusNode(skipTraversal: true,descendantsAreFocusable: false,onKey: (node, event) { - if (event.logicalKey == LogicalKeyboardKey.select) { - goARL(node, _controller); - } - return true; - }); + FocusNode focusNode = FocusNode( + skipTraversal: true, + descendantsAreFocusable: false, + onKey: (node, event) { + if (event.logicalKey == LogicalKeyboardKey.select) { + goARL(node, _controller); + } + return true; + }); if (settings.arl == null) return Scaffold( - body: Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0), - child: ListView( + body: Padding( + padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 8.0), + child: Theme( + data: Theme.of(context).copyWith( + outlinedButtonTheme: OutlinedButtonThemeData( + style: ButtonStyle( + foregroundColor: + MaterialStateProperty.all(Colors.white)))), + //data: ThemeData( + // outlinedButtonTheme: OutlinedButtonThemeData( + // style: ButtonStyle( + // foregroundColor: + // MaterialStateProperty.all(Colors.white)))), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Container(height: 16.0,), - Text( - 'Welcome to'.i18n, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0 - ), - ), - FreezerTitle(), - Container(height: 8.0,), - Text( - "Please login using your Deezer account.".i18n, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0 - ), - ), - Container(height: 16.0,), - //Email login dialog - Padding( - padding: EdgeInsets.symmetric(horizontal: 32.0), - child: OutlineButton( - child: Text( - 'Login using email'.i18n, - ), - onPressed: () { - showDialog( - context: context, - builder: (context) => EmailLogin(_update) - ); - }, - ) - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32.0), - child: OutlineButton( - child: Text('Login using browser'.i18n), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute(builder: (context) => LoginBrowser(_update)) - ); - }, - ), - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 32.0), - child: OutlineButton( - child: Text('Login using token'.i18n), - onPressed: () { - showDialog( - context: context, - builder: (context) { - Future.delayed(Duration(seconds: 1), () => {focusNode.requestFocus()}); // autofocus doesn't work - it's replacement - return AlertDialog( - title: Text('Enter ARL'.i18n), - content: Container( - child: TextField( - onChanged: (String s) => _arl = s, - decoration: InputDecoration( - labelText: 'Token (ARL)'.i18n - ), - focusNode: focusNode, - controller: _controller, - onSubmitted: (String s) { - goARL(focusNode, _controller); - }, - ), + Expanded( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 32.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + FreezerTitle(), + Container(height: 16.0), + Text( + "Please login using your Deezer account.".i18n, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 16.0), ), - actions: [ - FlatButton( - child: Text('Save'.i18n), - onPressed: () => goARL(null, _controller), - ) - ], - ); - } - ); - }, - ), - ), - Container(height: 16.0,), + Container( + height: 16.0, + ), + //Email login dialog + OutlinedButton( + child: Text( + 'Login using email'.i18n, + ), + onPressed: () { + showDialog( + context: context, + builder: (context) => EmailLogin(_update)); + }, + ), + OutlinedButton( + child: Text('Login using browser'.i18n), + onPressed: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => + LoginBrowser(_update))); + }, + ), + OutlinedButton( + child: Text('Login using token'.i18n), + onPressed: () { + showDialog( + context: context, + builder: (context) { + Future.delayed( + Duration(seconds: 1), + () => { + focusNode.requestFocus() + }); // autofocus doesn't work - it's replacement + return AlertDialog( + title: Text('Enter ARL'.i18n), + content: Container( + child: TextField( + onChanged: (String s) => _arl = s, + decoration: InputDecoration( + labelText: 'Token (ARL)'.i18n), + focusNode: focusNode, + controller: _controller, + onSubmitted: (String s) { + goARL(focusNode, _controller); + }, + ), + ), + actions: [ + TextButton( + child: Text('Save'.i18n), + onPressed: () => + goARL(null, _controller), + ) + ], + ); + }); + }, + ), + ]))), + Container(height: 16.0), Text( - "If you don't have account, you can register on deezer.com for free.".i18n, + "If you don't have account, you can register on deezer.com for free." + .i18n, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0 - ), + style: TextStyle(fontSize: 16.0), ), + Container(height: 8.0), Padding( padding: EdgeInsets.symmetric(horizontal: 32.0), - child: OutlineButton( + child: OutlinedButton( child: Text('Open in browser'.i18n), onPressed: () { - InAppBrowser.openWithSystemBrowser(url: 'https://deezer.com/register'); + InAppBrowser.openWithSystemBrowser( + url: 'https://deezer.com/register'); }, ), ), - Container(height: 8.0,), + Container( + height: 8.0, + ), Divider(), - Container(height: 8.0,), + Container( + height: 8.0, + ), Text( "By using this app, you don't agree with the Deezer ToS".i18n, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16.0 - ), + style: TextStyle(fontSize: 14.0), ) ], ), ), - ); + )); return null; } } - class LoginBrowser extends StatelessWidget { - - Function updateParent; + final Function updateParent; LoginBrowser(this.updateParent); @override @@ -298,11 +307,12 @@ class LoginBrowser extends StatelessWidget { child: Container( child: InAppWebView( initialUrl: 'https://deezer.com/login', - onLoadStart: (InAppWebViewController controller, String url) async { - + onLoadStart: + (InAppWebViewController controller, String url) async { //Offers URL if (!url.contains('/login') && !url.contains('/register')) { - controller.evaluateJavascript(source: 'window.location.href = "/open_app"'); + controller.evaluateJavascript( + source: 'window.location.href = "/open_app"'); } //Parse arl from url @@ -330,16 +340,14 @@ class LoginBrowser extends StatelessWidget { } class EmailLogin extends StatefulWidget { - - Function callback; - EmailLogin(this.callback, {Key key}): super(key: key); + final Function callback; + EmailLogin(this.callback, {Key key}) : super(key: key); @override _EmailLoginState createState() => _EmailLoginState(); } class _EmailLoginState extends State { - String _email; String _password; bool _loading = false; @@ -368,20 +376,21 @@ class _EmailLoginState extends State { //Error showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text("Error logging in!".i18n), - content: Text("Error logging in using email, please check your credentials.\nError: " + exception), - actions: [ - TextButton( - child: Text('Dismiss'.i18n), - onPressed: () { - Navigator.of(context).pop(); - }, - ) - ], - ) - ); + context: context, + builder: (context) => AlertDialog( + title: Text("Error logging in!".i18n), + content: Text( + "Error logging in using email, please check your credentials.\nError: " + + exception), + actions: [ + TextButton( + child: Text('Dismiss'.i18n), + onPressed: () { + Navigator.of(context).pop(); + }, + ) + ], + )); } @override @@ -390,25 +399,22 @@ class _EmailLoginState extends State { title: Text('Email Login'.i18n), content: Column( mainAxisSize: MainAxisSize.min, - children: - _loading ? [ - CircularProgressIndicator() - ]: [ - TextField( - decoration: InputDecoration( - labelText: 'Email'.i18n - ), - onChanged: (s) => _email = s, - ), - Container(height: 8.0,), - TextField( - obscureText: true, - decoration: InputDecoration( - labelText: "Password".i18n - ), - onChanged: (s) => _password = s, - ) - ], + children: _loading + ? [CircularProgressIndicator()] + : [ + TextField( + decoration: InputDecoration(labelText: 'Email'.i18n), + onChanged: (s) => _email = s, + ), + Container( + height: 8.0, + ), + TextField( + obscureText: true, + decoration: InputDecoration(labelText: "Password".i18n), + onChanged: (s) => _password = s, + ) + ], ), actions: [ if (!_loading) @@ -419,10 +425,9 @@ class _EmailLoginState extends State { await _login(); else Fluttertoast.showToast( - msg: "Missing email or password!".i18n, - gravity: ToastGravity.BOTTOM, - toastLength: Toast.LENGTH_SHORT - ); + msg: "Missing email or password!".i18n, + gravity: ToastGravity.BOTTOM, + toastLength: Toast.LENGTH_SHORT); }, ) ],