mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
Function for interactive login in the browser [BETA]
This commit is contained in:
parent
a35eece00c
commit
86b3f20c34
2
.gitignore
vendored
2
.gitignore
vendored
@ -78,3 +78,5 @@ android/key.properties
|
|||||||
**/pb_data
|
**/pb_data
|
||||||
|
|
||||||
tm.json
|
tm.json
|
||||||
|
.local-chrome
|
||||||
|
.vs
|
@ -325,5 +325,6 @@
|
|||||||
"connect_client_alert": "You're being controlled by {client}",
|
"connect_client_alert": "You're being controlled by {client}",
|
||||||
"this_device": "This Device",
|
"this_device": "This Device",
|
||||||
"remote": "Remote",
|
"remote": "Remote",
|
||||||
"stats": "Stats"
|
"stats": "Stats",
|
||||||
|
"continue_in_browser": "Continue in browser"
|
||||||
}
|
}
|
@ -325,5 +325,6 @@
|
|||||||
"add_library_location": "Añadir a la biblioteca",
|
"add_library_location": "Añadir a la biblioteca",
|
||||||
"remove_library_location": "Eliminar de la biblioteca",
|
"remove_library_location": "Eliminar de la biblioteca",
|
||||||
"local_tab": "Local",
|
"local_tab": "Local",
|
||||||
"stats": "Estadísticas"
|
"stats": "Estadísticas",
|
||||||
|
"continue_in_browser": "Continuar en el navegador"
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:puppeteer/protocol/network.dart';
|
||||||
|
import 'package:puppeteer/puppeteer.dart';
|
||||||
import 'package:spotube/extensions/context.dart';
|
import 'package:spotube/extensions/context.dart';
|
||||||
|
|
||||||
import 'package:spotube/provider/authentication_provider.dart';
|
import 'package:spotube/provider/authentication_provider.dart';
|
||||||
@ -16,13 +18,22 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final authenticationNotifier = ref.watch(authenticationProvider.notifier);
|
final authenticationNotifier = ref.watch(authenticationProvider.notifier);
|
||||||
final directCodeController = useTextEditingController();
|
final directCodeController = useTextEditingController();
|
||||||
|
final platform = Theme.of(context).platform;
|
||||||
|
final isDesktop =
|
||||||
|
platform == TargetPlatform.linux || platform == TargetPlatform.windows;
|
||||||
|
|
||||||
final isLoading = useState(false);
|
final isLoading = useState(false);
|
||||||
|
final showManualConf = useState(false);
|
||||||
|
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxWidth: 400,
|
maxWidth: 400,
|
||||||
),
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Visibility(
|
||||||
|
visible: showManualConf.value,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
@ -43,7 +54,8 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
if (directCodeController.text.isEmpty) {
|
if (directCodeController.text.isEmpty) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(context.l10n.fill_in_all_fields),
|
content:
|
||||||
|
Text(context.l10n.fill_in_all_fields),
|
||||||
behavior: SnackBarBehavior.floating,
|
behavior: SnackBarBehavior.floating,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -66,6 +78,69 @@ class TokenLoginForm extends HookConsumerWidget {
|
|||||||
child: Text(context.l10n.submit),
|
child: Text(context.l10n.submit),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
)),
|
||||||
|
Visibility(
|
||||||
|
visible: isDesktop && !showManualConf.value,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 48.0,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: isLoading.value
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
final browser =
|
||||||
|
await puppeteer.launch(headless: false);
|
||||||
|
try {
|
||||||
|
List<Cookie> cookies = [];
|
||||||
|
final page = await browser.newPage();
|
||||||
|
|
||||||
|
await page.goto(
|
||||||
|
'https://accounts.spotify.com/en/login',
|
||||||
|
wait: Until.domContentLoaded);
|
||||||
|
|
||||||
|
while (browser.isConnected) {
|
||||||
|
cookies = await page.cookies();
|
||||||
|
for (final cookie in cookies) {
|
||||||
|
if (cookie.name == "sp_dc") {
|
||||||
|
await browser.close();
|
||||||
|
final cookieHeader =
|
||||||
|
"sp_dc=${cookie.value.trim()}";
|
||||||
|
|
||||||
|
authenticationNotifier.setCredentials(
|
||||||
|
await AuthenticationCredentials
|
||||||
|
.fromCookie(cookieHeader),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
onDone?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
showManualConf.value = true;
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: ButtonStyle(
|
||||||
|
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(15.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(context.l10n.continue_in_browser),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
14
pubspec.lock
14
pubspec.lock
@ -1258,18 +1258,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.1"
|
version: "4.9.0"
|
||||||
json_serializable:
|
json_serializable:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: json_serializable
|
name: json_serializable
|
||||||
sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969
|
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.7.1"
|
version: "6.8.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1711,13 +1711,13 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.2.3"
|
||||||
puppeteer:
|
puppeteer:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: puppeteer
|
name: puppeteer
|
||||||
sha256: "6833edca01b1e9dcdd9a6e41bad84b706dfba4366d095c4edff64b00c02ac472"
|
sha256: c45c51b4ad8d70acdffeb1cfb9d16b60a7eaab7bfef314dd5b02c3607269b556
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.8.0"
|
version: "3.11.0"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -121,6 +121,7 @@ dependencies:
|
|||||||
tray_manager: ^0.2.2
|
tray_manager: ^0.2.2
|
||||||
http: ^1.2.1
|
http: ^1.2.1
|
||||||
riverpod: ^2.5.1
|
riverpod: ^2.5.1
|
||||||
|
puppeteer: ^3.11.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.4.11
|
build_runner: ^2.4.11
|
||||||
|
@ -1 +1,101 @@
|
|||||||
{}
|
{
|
||||||
|
"ar": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"bn": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ca": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"cs": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"de": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"eu": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fa": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fi": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"hi": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"id": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"it": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ja": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ka": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ne": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"nl": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"pl": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"pt": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ru": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"th": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"tr": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"uk": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"vi": [
|
||||||
|
"continue_in_browser"
|
||||||
|
],
|
||||||
|
|
||||||
|
"zh": [
|
||||||
|
"continue_in_browser"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user