mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
feat: show error dialog on failed to login
This commit is contained in:
parent
15d466a045
commit
101c32523d
@ -20,6 +20,8 @@ class TokenLoginForm extends HookConsumerWidget {
|
||||
final keyCodeController = useTextEditingController();
|
||||
final mounted = useIsMounted();
|
||||
|
||||
final isLoading = useState(false);
|
||||
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 400,
|
||||
@ -45,27 +47,35 @@ class TokenLoginForm extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
if (keyCodeController.text.isEmpty ||
|
||||
directCodeController.text.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(context.l10n.fill_in_all_fields),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final cookieHeader =
|
||||
"sp_dc=${directCodeController.text}; sp_key=${keyCodeController.text}";
|
||||
onPressed: isLoading.value
|
||||
? null
|
||||
: () async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
if (keyCodeController.text.isEmpty ||
|
||||
directCodeController.text.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(context.l10n.fill_in_all_fields),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final cookieHeader =
|
||||
"sp_dc=${directCodeController.text}; sp_key=${keyCodeController.text}";
|
||||
|
||||
authenticationNotifier.setCredentials(
|
||||
await AuthenticationCredentials.fromCookie(cookieHeader),
|
||||
);
|
||||
if (mounted()) {
|
||||
onDone?.call();
|
||||
}
|
||||
},
|
||||
authenticationNotifier.setCredentials(
|
||||
await AuthenticationCredentials.fromCookie(
|
||||
cookieHeader),
|
||||
);
|
||||
if (mounted()) {
|
||||
onDone?.call();
|
||||
}
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
},
|
||||
child: Text(context.l10n.submit),
|
||||
)
|
||||
],
|
||||
|
@ -4,6 +4,9 @@ import 'dart:convert';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.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/platform.dart';
|
||||
|
||||
@ -21,24 +24,44 @@ class AuthenticationCredentials {
|
||||
});
|
||||
|
||||
static Future<AuthenticationCredentials> fromCookie(String cookie) async {
|
||||
final Map body = await get(
|
||||
Uri.parse(
|
||||
"https://open.spotify.com/get_access_token?reason=transport&productType=web_player",
|
||||
),
|
||||
headers: {
|
||||
"Cookie": cookie,
|
||||
"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));
|
||||
try {
|
||||
final res = await get(
|
||||
Uri.parse(
|
||||
"https://open.spotify.com/get_access_token?reason=transport&productType=web_player",
|
||||
),
|
||||
headers: {
|
||||
"Cookie": cookie,
|
||||
"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"
|
||||
},
|
||||
);
|
||||
final body = jsonDecode(res.body);
|
||||
|
||||
return AuthenticationCredentials(
|
||||
cookie: cookie,
|
||||
accessToken: body['accessToken'],
|
||||
expiration: DateTime.fromMillisecondsSinceEpoch(
|
||||
body['accessTokenExpirationTimestampMs'],
|
||||
),
|
||||
);
|
||||
if (res.statusCode >= 400) {
|
||||
throw Exception(
|
||||
"Failed to get access token: ${body['error'] ?? res.reasonPhrase}",
|
||||
);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user