diff --git a/lib/auth/device_code.dart b/lib/auth/device_code.dart index 4707a60..a7e9ff0 100644 --- a/lib/auth/device_code.dart +++ b/lib/auth/device_code.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:open_media_server_app/globals.dart'; +import 'package:qr_flutter/qr_flutter.dart'; class DeviceCode { Future> getDeviceCode( @@ -20,15 +22,54 @@ class DeviceCode { } } - Future authenticateUser( - String clientId, String scope, String deviceCodeUrl) async { + Future authenticateUser(String clientId, String scope, + String deviceCodeUrl, BuildContext context) async { try { final deviceCodeResponse = await getDeviceCode(clientId, scope, deviceCodeUrl); final userCode = deviceCodeResponse['user_code']; final verificationUri = deviceCodeResponse['verification_uri']; - print('Please go to $verificationUri?code=$userCode'); + String fullVerificationUrl = "$verificationUri?code=$userCode"; + + print('Please go to $fullVerificationUrl'); + + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Login with your phone'), + content: SizedBox( + height: 200, + width: 200, + child: QrImageView( + eyeStyle: const QrEyeStyle( + color: Colors.white, + eyeShape: QrEyeShape.square, + ), + dataModuleStyle: const QrDataModuleStyle( + color: Colors.white, + dataModuleShape: QrDataModuleShape.square, + ), + data: fullVerificationUrl, + version: QrVersions.auto, + // size: 200.0, + ), + ), + actions: [ + TextButton( + style: TextButton.styleFrom( + textStyle: Theme.of(context).textTheme.labelLarge, + ), + child: const Text('Done'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); final code = deviceCodeResponse['device_code']; final interval = deviceCodeResponse['interval']; diff --git a/lib/auth/login_manager.dart b/lib/auth/login_manager.dart index 74a7659..f5deccc 100644 --- a/lib/auth/login_manager.dart +++ b/lib/auth/login_manager.dart @@ -2,6 +2,7 @@ // import 'package:fedodo_general/widgets/auth/oauth_handler/custom_web_base_dummy.dart' // if (dart.library.html) '../oauth_handler/custom_web_base.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:oauth2_client/access_token_response.dart'; import 'package:oauth2_client/interfaces.dart'; import 'package:oauth2_client/oauth2_client.dart'; @@ -42,10 +43,10 @@ class LoginManager { // } } - Future login(String clientId, String clientSecret) async { + Future login(String clientId, String clientSecret, BuildContext context) async { if (Globals.isTv) { DeviceCode deviceCode = DeviceCode(); - var token = await deviceCode.authenticateUser(Globals.ClientId, "offline_access", Globals.DeviceCodeUrl); + var token = await deviceCode.authenticateUser(Globals.ClientId, "offline_access", Globals.DeviceCodeUrl, context); Preferences.prefs?.setString("AccessToken", token!); diff --git a/lib/main.dart b/lib/main.dart index 4fbb1d4..41829d2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -36,9 +36,6 @@ Future main() async { var prefs = await SharedPreferences.getInstance(); Preferences.prefs = prefs; - LoginManager loginManager = LoginManager(); - var token = await loginManager.login(Globals.ClientId, Globals.ClientSecret); - runApp(const MyApp()); } @@ -56,30 +53,42 @@ class MyApp extends StatelessWidget { ), useMaterial3: true, ), - home: MyHomePage(title: Globals.Title), + home: HomePage(title: Globals.Title), ); } } -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); +class HomePage extends StatelessWidget { + const HomePage({super.key, required this.title}); final String title; - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, surfaceTintColor: Colors.transparent, - title: Text(widget.title), + title: Text(title), + ), + body: FutureBuilder( + future: authenticate(context), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text('Error: ${snapshot.error}')); + } + + return const Gallery(); + }, ), - body: const Gallery(), ); } + + Future authenticate(BuildContext context) async { + LoginManager loginManager = LoginManager(); + var token = + await loginManager.login(Globals.ClientId, Globals.ClientSecret, context); + } } diff --git a/pubspec.lock b/pubspec.lock index 1d7fbea..71e569f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" async: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" cupertino_icons: dependency: "direct main" description: @@ -109,10 +109,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: db03b2d2a3fa466a4627709e1db58692c3f7f658e36a5942d342d86efedc4091 + sha256: c4af09051b4f0508f6c1dc0a5c085bf014d5c9a4a0678ce1799c2b4d716387a0 url: "https://pub.dev" source: hosted - version: "11.0.0" + version: "11.1.0" device_info_plus_platform_interface: dependency: transitive description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -268,10 +268,10 @@ packages: dependency: transitive description: name: image - sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" + sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "4.3.0" js: dependency: transitive description: @@ -428,10 +428,10 @@ packages: dependency: transitive description: name: package_info_plus - sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 + sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.1.0" package_info_plus_platform_interface: dependency: transitive description: @@ -452,10 +452,10 @@ packages: dependency: transitive description: name: path_provider - sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_android: dependency: transitive description: @@ -520,6 +520,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" random_string: dependency: "direct main" description: @@ -761,10 +777,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" universal_platform: dependency: transitive description: @@ -905,10 +921,10 @@ packages: dependency: transitive description: name: win32 - sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" + sha256: "10169d3934549017f0ae278ccb07f828f9d6ea21573bab0fb77b0e1ef0fce454" url: "https://pub.dev" source: hosted - version: "5.5.4" + version: "5.7.2" win32_registry: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d5660c7..9e21cde 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: shared_preferences: ^2.3.2 oauth2_client: ^3.3.0 random_string: ^2.3.1 + qr_flutter: ^4.1.0 dev_dependencies: flutter_test: