1
0
Fork 0
mrtiboute/lib/widgets/components/tutorials/step3.dart

189 lines
6.6 KiB
Dart
Raw Normal View History

2022-03-31 21:34:28 +02:00
import 'dart:convert';
2022-03-30 23:37:04 +02:00
import 'dart:io';
2022-03-31 21:34:28 +02:00
import 'package:desktopapp/classes/routes.dart';
import 'package:desktopapp/utils/logger.dart';
import 'package:dio/dio.dart';
2022-03-30 23:37:04 +02:00
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
2022-03-31 21:34:28 +02:00
import 'package:url_launcher/url_launcher.dart';
2022-03-30 23:37:04 +02:00
class Step3 extends StatelessWidget {
2022-03-31 21:34:28 +02:00
const Step3({Key? key, required this.onPrevious}) : super(key: key);
final VoidCallback onPrevious;
2022-03-30 23:37:04 +02:00
Widget buildContent(BuildContext context, SharedPreferences prefs) {
return Column(children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 20),
2022-03-31 21:34:28 +02:00
child: Text('Étape 3: Autorisation de l\'application',
2022-03-30 23:37:04 +02:00
style: TextStyle(fontSize: 20)),
),
2022-03-31 21:34:28 +02:00
const Text(
'Pour terminer la configuration, il reste plus qu\'à se connecter à Streamlabs pour autoriser l\'application à créer des alertes.'),
const SizedBox(height: 10),
TextButton(
onPressed: () async {
waitAuthorization(context, prefs);
var clientId = prefs.getString('client_id');
await Future.delayed(const Duration(seconds: 1));
launch(
'https://streamlabs.com/api/v1.0/authorize?redirect_uri=http://localhost:1234/&client_id=$clientId&response_type=code&scope=alerts.create');
},
child: const Text('Cliquez ici pour vous connecter à Streamlabs')),
2022-03-30 23:37:04 +02:00
]);
}
2022-03-31 21:34:28 +02:00
Future<String?> waitAuthorizationCallback(SharedPreferences prefs) async {
var server = await HttpServer.bind(InternetAddress.loopbackIPv4, 1234);
Logger.log(LoggerType.info, this,
'Server started at ${server.address.address}:${server.port}');
2022-03-30 23:37:04 +02:00
var request = await server.first;
var uri = Uri.dataFromString(request.requestedUri.toString());
var query = uri.queryParameters;
var code = query['code'];
if (code != null) {
prefs.setString('code', code);
2022-03-31 21:34:28 +02:00
request.response
..headers.contentType = ContentType.text
..write('You can close tab now')
..close();
} else {
request.response
..headers.contentType = ContentType.text
..write('Internal error')
..close();
2022-03-30 23:37:04 +02:00
}
2022-03-31 21:34:28 +02:00
return code;
}
Future<void> waitAuthorization(
BuildContext context, SharedPreferences prefs) async {
var code = await waitAuthorizationCallback(prefs);
if (code != null) {
if (prefs.containsKey('credentials')) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Info'),
content: const Text(
'Connexion réussi. Appuyez sur OK pour acceder à l\'application.'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context)
.pushReplacementNamed(Routes.home.path);
},
child: const Text('OK'))
],
));
} else {
Dio dio = Dio(BaseOptions(
contentType: Headers.jsonContentType,
responseType: ResponseType.json,
validateStatus: (_) => true));
var data = jsonEncode({
'grant_type': 'authorization_code',
'client_id': prefs.getString('client_id'),
'client_secret': prefs.getString('client_secret'),
'redirect_uri': 'http://localhost:1234/',
'code': code,
});
var response =
await dio.post('https://streamlabs.com/api/v1.0/token', data: data);
if (response.statusCode == HttpStatus.ok) {
2022-03-31 22:04:57 +02:00
jsonDecode(response.data).forEach((key, value) =>
prefs.setString('credentials.$key', value.toString()));
2022-03-31 21:34:28 +02:00
Logger.log(LoggerType.info, this,
'Authorization success : ${response.data}');
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Info'),
content: const Text(
'Connexion réussi. Appuyez sur OK pour acceder à l\'application.'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context)
.pushReplacementNamed(Routes.home.path);
},
child: const Text('OK'))
],
));
} else {
Logger.log(LoggerType.error, this,
'Authorization error : ${response.data} with $data and ${response.requestOptions.headers}');
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Erreur'),
content: const Text('Impossible de se connecter.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'))
],
));
}
}
} else {
Logger.log(LoggerType.error, this,
'Authorization error : impossible to get code');
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('Erreur'),
content: const Text('Impossible de se connecter.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'))
],
));
}
2022-03-30 23:37:04 +02:00
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: FutureBuilder(
future: SharedPreferences.getInstance(),
builder: (BuildContext context,
AsyncSnapshot<SharedPreferences> snapshot) {
if (snapshot.hasData) {
final prefs = snapshot.data!;
return buildContent(context, prefs);
} else {
return const Center(child: CircularProgressIndicator());
}
})),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
2022-03-31 21:34:28 +02:00
onPressed: onPrevious, child: const Text('Étape précédente'))
2022-03-30 23:37:04 +02:00
],
),
)
],
);
}
}