diff --git a/assets/images/client_app_keys.png b/assets/images/client_app_keys.png new file mode 100644 index 0000000..8f80ab3 Binary files /dev/null and b/assets/images/client_app_keys.png differ diff --git a/lib/widgets/components/row_input.dart b/lib/widgets/components/row_input.dart new file mode 100644 index 0000000..4176e0e --- /dev/null +++ b/lib/widgets/components/row_input.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class RowInput extends StatelessWidget { + const RowInput({Key? key, required this.label, required this.controller}) + : super(key: key); + + final String label; + final TextEditingController controller; + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 400, + height: 70, + child: Expanded( + child: TextField( + controller: controller, + decoration: InputDecoration( + hintText: label, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/components/tutorials/step1.dart b/lib/widgets/components/tutorials/step1.dart index 0ed66b1..b5147fd 100644 --- a/lib/widgets/components/tutorials/step1.dart +++ b/lib/widgets/components/tutorials/step1.dart @@ -1,6 +1,5 @@ import 'package:desktopapp/widgets/components/link.dart'; import 'package:flutter/material.dart'; -import 'package:url_launcher/url_launcher.dart'; class Step1 extends StatelessWidget { const Step1({Key? key}) : super(key: key); @@ -61,8 +60,6 @@ class Step1 extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - // TextButton( - // onPressed: () {}, child: const Text('Étape précédente')), TextButton(onPressed: () {}, child: const Text('Étape suivante')) ], ), diff --git a/lib/widgets/components/tutorials/step2.dart b/lib/widgets/components/tutorials/step2.dart new file mode 100644 index 0000000..51b68e8 --- /dev/null +++ b/lib/widgets/components/tutorials/step2.dart @@ -0,0 +1,108 @@ +import 'package:desktopapp/widgets/components/link.dart'; +import 'package:desktopapp/widgets/components/row_input.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class Step2 extends StatelessWidget { + Step2({Key? key}) : super(key: key); + + final TextEditingController _clientIdController = TextEditingController(); + final TextEditingController _clientSecretController = TextEditingController(); + + Widget buildFieldDescription(String field, String description) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(field, style: const TextStyle(fontWeight: FontWeight.bold)), + const Text(' : '), + Text(description) + ], + ); + } + + Widget buildContent(BuildContext context) { + return Column(children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text('Étape 2: Récupération des cléfs Client', + style: TextStyle(fontSize: 20)), + ), + const Text( + 'Pour pouvoir utiliser l\'application, il faut récupérer les clefs associées à l\'application créée juste avant.'), + const Text( + 'Normalement, vous devez voir apparaître une page avec les champs comme dans l\'image ci-dessous.'), + const Text('Sinon vous pouvez le retrouver avec le lien ci-dessous:'), + const SizedBox(height: 10), + const Link( + uri: 'https://streamlabs.com/dashboard#/settings/api-settings'), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24.0), + child: Image.asset('assets/images/client_app_keys.png'), + ), + const SizedBox(height: 20), + const Text( + 'Pour récupérer les clefs, il faut remplir le formulaire ci-dessous avec les valeurs correspondantes à ceux sur le site:'), + RowInput(label: 'Client ID', controller: _clientIdController), + RowInput(label: 'Client Secret', controller: _clientSecretController), + TextButton( + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + prefs.setString('client_id', _clientIdController.text.trim()); + prefs.setString( + 'client_secret', _clientSecretController.text.trim()); + showDialog( + context: context, + builder: (_) => AlertDialog( + title: const Text('Information'), + content: const Text( + 'Les informations ont été correctement enregistrée.'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('OK')) + ], + )); + }, + child: const Text('Appliquer les changements')), + const SizedBox(height: 20), + const Text( + 'Une fois les données enregistrées, vous pouvez passez à l\'étape suivante.'), + ]); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: FutureBuilder( + future: SharedPreferences.getInstance(), + builder: (BuildContext context, + AsyncSnapshot snapshot) { + if (snapshot.hasData) { + final prefs = snapshot.data!; + _clientIdController.text = + prefs.getString('client_id') ?? ''; + _clientSecretController.text = + prefs.getString('client_secret') ?? ''; + return buildContent(context); + } else { + return const Center(child: CircularProgressIndicator()); + } + })), + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + TextButton( + onPressed: () {}, child: const Text('Étape précédente')), + TextButton(onPressed: () {}, child: const Text('Étape suivante')) + ], + ), + ) + ], + ); + } +} diff --git a/lib/widgets/pages/tutorial.dart b/lib/widgets/pages/tutorial.dart index e76c732..99b5eba 100644 --- a/lib/widgets/pages/tutorial.dart +++ b/lib/widgets/pages/tutorial.dart @@ -1,4 +1,5 @@ import 'package:desktopapp/widgets/components/tutorials/step1.dart'; +import 'package:desktopapp/widgets/components/tutorials/step2.dart'; import 'package:flutter/material.dart'; class TutorialPage extends StatelessWidget { @@ -6,6 +7,6 @@ class TutorialPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold(body: const Step1()); + return Scaffold(body: Step2()); } } diff --git a/pubspec.lock b/pubspec.lock index 298215c..1fe2cce 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + flash: + dependency: "direct main" + description: + name: flash + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3+2" flutter: dependency: "direct main" description: flutter @@ -142,6 +163,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -149,6 +198,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" provider: dependency: transitive description: @@ -156,6 +212,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.2" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" sky_engine: dependency: transitive description: flutter @@ -273,6 +385,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+1" sdks: dart: ">=2.16.2 <3.0.0" flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index 102e685..d9f55a1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: cupertino_icons: ^1.0.2 flutter_bloc: ^8.0.1 url_launcher: ^6.0.20 + shared_preferences: ^2.0.13 + flash: ^2.0.3+2 dev_dependencies: flutter_test: @@ -64,6 +66,9 @@ flutter: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg + assets: + - assets/images/client_app_keys.png + # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware.