feat: show error dialog on failed to login

This commit is contained in:
Kingkor Roy Tirtho 2023-09-27 13:16:35 +06:00
parent 15d466a045
commit 101c32523d
2 changed files with 70 additions and 37 deletions

View File

@ -20,6 +20,8 @@ class TokenLoginForm extends HookConsumerWidget {
final keyCodeController = useTextEditingController(); final keyCodeController = useTextEditingController();
final mounted = useIsMounted(); final mounted = useIsMounted();
final isLoading = useState(false);
return ConstrainedBox( return ConstrainedBox(
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: 400, maxWidth: 400,
@ -45,27 +47,35 @@ class TokenLoginForm extends HookConsumerWidget {
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
FilledButton( FilledButton(
onPressed: () async { onPressed: isLoading.value
if (keyCodeController.text.isEmpty || ? null
directCodeController.text.isEmpty) { : () async {
ScaffoldMessenger.of(context).showSnackBar( try {
SnackBar( isLoading.value = true;
content: Text(context.l10n.fill_in_all_fields), if (keyCodeController.text.isEmpty ||
behavior: SnackBarBehavior.floating, directCodeController.text.isEmpty) {
), ScaffoldMessenger.of(context).showSnackBar(
); SnackBar(
return; content: Text(context.l10n.fill_in_all_fields),
} behavior: SnackBarBehavior.floating,
final cookieHeader = ),
"sp_dc=${directCodeController.text}; sp_key=${keyCodeController.text}"; );
return;
}
final cookieHeader =
"sp_dc=${directCodeController.text}; sp_key=${keyCodeController.text}";
authenticationNotifier.setCredentials( authenticationNotifier.setCredentials(
await AuthenticationCredentials.fromCookie(cookieHeader), await AuthenticationCredentials.fromCookie(
); cookieHeader),
if (mounted()) { );
onDone?.call(); if (mounted()) {
} onDone?.call();
}, }
} finally {
isLoading.value = false;
}
},
child: Text(context.l10n.submit), child: Text(context.l10n.submit),
) )
], ],

View File

@ -4,6 +4,9 @@ import 'dart:convert';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:spotube/collections/routes.dart';
import 'package:spotube/components/shared/dialogs/prompt_dialog.dart';
import 'package:spotube/extensions/context.dart';
import 'package:spotube/utils/persisted_state_notifier.dart'; import 'package:spotube/utils/persisted_state_notifier.dart';
import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/platform.dart';
@ -21,24 +24,44 @@ class AuthenticationCredentials {
}); });
static Future<AuthenticationCredentials> fromCookie(String cookie) async { static Future<AuthenticationCredentials> fromCookie(String cookie) async {
final Map body = await get( try {
Uri.parse( final res = await get(
"https://open.spotify.com/get_access_token?reason=transport&productType=web_player", Uri.parse(
), "https://open.spotify.com/get_access_token?reason=transport&productType=web_player",
headers: { ),
"Cookie": cookie, headers: {
"User-Agent": "Cookie": cookie,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" "User-Agent":
}, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
).then((res) => jsonDecode(res.body)); },
);
final body = jsonDecode(res.body);
return AuthenticationCredentials( if (res.statusCode >= 400) {
cookie: cookie, throw Exception(
accessToken: body['accessToken'], "Failed to get access token: ${body['error'] ?? res.reasonPhrase}",
expiration: DateTime.fromMillisecondsSinceEpoch( );
body['accessTokenExpirationTimestampMs'], }
),
); return AuthenticationCredentials(
cookie: cookie,
accessToken: body['accessToken'],
expiration: DateTime.fromMillisecondsSinceEpoch(
body['accessTokenExpirationTimestampMs'],
),
);
} catch (e) {
if (rootNavigatorKey?.currentContext != null) {
showPromptDialog(
context: rootNavigatorKey!.currentContext!,
title: rootNavigatorKey!.currentContext!.l10n
.error("Authentication Failure"),
message: e.toString(),
cancelText: null,
);
}
rethrow;
}
} }
factory AuthenticationCredentials.fromJson(Map<String, dynamic> json) { factory AuthenticationCredentials.fromJson(Map<String, dynamic> json) {