This commit is contained in:
Pato05 2024-02-10 18:13:27 +01:00
parent 8d44aebd7b
commit e827549c1d
No known key found for this signature in database
GPG Key ID: F53CA394104BA0CB
4 changed files with 185 additions and 1 deletions

View File

@ -1,9 +1,17 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/translations.i18n.dart';
import 'package:logging/logging.dart';
import 'package:network_info_plus/network_info_plus.dart';
import 'package:rxdart/rxdart.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:webview_flutter/webview_flutter.dart';
@ -209,6 +217,16 @@ class _LoginWidgetState extends State<LoginWidget> {
style: const TextStyle(fontSize: 16.0),
),
const SizedBox(height: 16.0),
ElevatedButton(
child:
Text('Login using other device'.i18n),
onPressed: () {
showDialog(
context: context,
builder: (context) =>
OtherDeviceLogin(_update));
}),
const SizedBox(height: 16.0),
//Email login dialog (Not working anymore)
// ElevatedButton(
// child: Text(
@ -407,6 +425,154 @@ class _LoginBrowserState extends State<LoginBrowser> {
}
}
class OtherDeviceLogin extends StatefulWidget {
final VoidCallback callback;
const OtherDeviceLogin(this.callback, {super.key});
@override
State<OtherDeviceLogin> createState() => _OtherDeviceLoginState();
}
class _OtherDeviceLoginState extends State<OtherDeviceLogin> {
late final HttpServer _server;
late final StreamSubscription _serverSubscription;
late final String? _deviceIP;
late final Future<void> _serverReady;
late int _code;
late Timer _codeTimer;
final _timerNotifier = ValueNotifier<double>(0.0);
bool step2 = false;
final _logger = Logger('OtherDeviceLogin');
void _generateCode() {
_code = Random.secure().nextInt(899999) + 100000;
}
Future<void> _initServer() async {
_server = await HttpServer.bind(InternetAddress.anyIPv4, 0);
_deviceIP = await NetworkInfo().getWifiIP();
_generateCode();
const tps = 30 * 1000 / 50;
_codeTimer = Timer.periodic(const Duration(milliseconds: 50), (timer) {
final a = timer.tick / tps;
_timerNotifier.value = a - a.truncate();
if (timer.tick % tps == 0) {
setState(() => _generateCode());
}
});
_serverSubscription = _server.listen((request) async {
final buffer = Uint8List(0);
final reqCompleter = Completer<void>();
final subs = request.listen(
(data) {
if (data.length + buffer.length > 8192) {
_logger.severe('Request too big!');
request.response.close();
}
buffer.addAll(data);
},
onDone: () {
reqCompleter.complete();
},
);
await reqCompleter.future;
subs.cancel();
try {
jsonDecode(utf8.decode(buffer));
} catch (e) {
_logger.severe('Error $e');
request.response.close();
}
});
}
@override
void initState() {
_serverReady = _initServer();
super.initState();
}
@override
void dispose() {
_server.close();
_serverSubscription.cancel();
_codeTimer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Login using other device'.i18n),
contentPadding: const EdgeInsets.only(top: 12),
content: step2
? Text('Please follow the on-screen instructions'.i18n,
style: Theme.of(context).textTheme.bodyLarge)
: FutureBuilder(
future: _serverReady,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const Row(children: [CircularProgressIndicator()]);
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ValueListenableBuilder(
valueListenable: _timerNotifier,
builder: (context, value, _) =>
LinearProgressIndicator(value: value),
),
Padding(
padding: const EdgeInsets.fromLTRB(24, 18, 24, 24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'On your other device, go to Freezer\'s settings > General > Login on other device, input the parameters below and follow the on-screen instructions.'
.i18n),
RichText(
textAlign: TextAlign.start,
text: TextSpan(
style:
Theme.of(context).textTheme.bodyMedium,
children: [
TextSpan(text: 'IP Address: '.i18n),
TextSpan(
text:
_deviceIP ?? 'Could not get IP!',
style: TextStyle(fontSize: 32.sp)),
const TextSpan(text: ':'),
TextSpan(
text: _server.port.toString(),
style: TextStyle(fontSize: 32.sp)),
])),
RichText(
text: TextSpan(
style:
Theme.of(context).textTheme.bodyMedium,
children: [
TextSpan(text: 'Code: '.i18n),
TextSpan(
text: '$_code',
style: TextStyle(fontSize: 32.sp)),
])),
],
),
)
]);
}),
actions: [
TextButton(
onPressed: () => Navigator.pop(context), child: Text('Cancel'.i18n))
],
);
}
}
// email login is removed cuz not working = USELESS
//class EmailLogin extends StatefulWidget {

View File

@ -12,6 +12,7 @@ import dynamic_color
import flutter_local_notifications
import isar_flutter_libs
import just_audio
import network_info_plus
import package_info_plus
import path_provider_foundation
import share_plus
@ -27,6 +28,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
NetworkInfoPlusPlugin.register(with: registry.registrar(forPlugin: "NetworkInfoPlusPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))

View File

@ -929,6 +929,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
network_info_plus:
dependency: "direct main"
description:
name: network_info_plus
sha256: "4601b815b1c6a46d84839f65cd774a7d999738471d910fae00d813e9e98b04e1"
url: "https://pub.dev"
source: hosted
version: "4.1.0+1"
network_info_plus_platform_interface:
dependency: transitive
description:
name: network_info_plus_platform_interface
sha256: "881f5029c5edaf19c616c201d3d8b366c5b1384afd5c1da5a49e4345de82fb8b"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
nm:
dependency: transitive
description:

View File

@ -96,7 +96,7 @@ dependencies:
flex_color_picker: ^3.3.0
webview_flutter:
^4.4.4
network_info_plus: ^4.1.0+1
#deezcryptor:
#path: deezcryptor/