login_screen: redesign

This commit is contained in:
pato05 2021-04-05 00:59:07 +02:00
parent 519adc910f
commit ccb00191ad

View file

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