From b2ddfddef02b6e6a76f8816192bb43cb2831a62d Mon Sep 17 00:00:00 2001 From: Piero512 Date: Fri, 12 Mar 2021 08:07:59 -0500 Subject: [PATCH] Add discover page and button --- lib/pages/discover_page.dart | 83 ++++++++++++++++++++++++++ lib/screens/configurations_screen.dart | 42 +++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 lib/pages/discover_page.dart diff --git a/lib/pages/discover_page.dart b/lib/pages/discover_page.dart new file mode 100644 index 0000000..da2994d --- /dev/null +++ b/lib/pages/discover_page.dart @@ -0,0 +1,83 @@ +import 'dart:async'; + +import 'package:bonsoir/bonsoir.dart'; +import 'package:flutter/material.dart'; +import 'package:rutorrentflutter/api/api_conf.dart'; + +class DiscoverPage extends StatefulWidget { + @override + _DiscoverPageState createState() => _DiscoverPageState(); +} + +class _DiscoverPageState extends State { + final BonsoirDiscovery zeroconfService = + BonsoirDiscovery(type: "_rutorrent_mobile._tcp"); + final List urls = []; + StreamSubscription zeroconfSub; + + @override + void dispose() { + zeroconfSub?.cancel(); + if (zeroconfService.isReady && !zeroconfService.isStopped) { + zeroconfService.stop(); + } + super.dispose(); + } + + static buildURL(ResolvedBonsoirService resolved) { + // TODO: Enable password authentication + var protocol = resolved.attributes["protocol"]; + var port = resolved.port; + if (port == 80) { + return "http://${resolved.ip}/"; + } else if (port == 443) { + return "https://${resolved.ip}/"; + } else { + if (protocol != null) { + return "$protocol://${resolved.ip}:${resolved.port}/"; + } else { + return "http://${resolved.ip}:${resolved.port}"; + } + } + } + + void setupListener() { + zeroconfSub = zeroconfService.eventStream.listen((event) { + if (event.isServiceResolved && + event.type == BonsoirDiscoveryEventType.DISCOVERY_SERVICE_RESOLVED) { + var resolved = event.service as ResolvedBonsoirService; + setState(() { + urls.add(resolved); + }); + } + }); + zeroconfService.start(); + } + + @override + void initState() { + zeroconfService.ready.then((_) => setupListener()); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Dialog( + child: Container( + child: ListView.builder( + itemBuilder: (context, index) => ListTile( + title: Text(urls[index].name), + subtitle: Text("IP address: ${urls[index].ip}"), + onTap: () { + var api = Api(); + api.setUrl(buildURL(urls[index])); + api.setUsername(""); + api.setPassword(""); + Navigator.of(context).pop(api); + }, + ), + itemCount: urls.length, + )), + ); + } +} diff --git a/lib/screens/configurations_screen.dart b/lib/screens/configurations_screen.dart index 5c95564..b2a6cf0 100644 --- a/lib/screens/configurations_screen.dart +++ b/lib/screens/configurations_screen.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import 'package:rutorrentflutter/components/data_input.dart'; import 'package:rutorrentflutter/components/password_input.dart'; import 'package:rutorrentflutter/models/mode.dart'; +import 'package:rutorrentflutter/pages/discover_page.dart'; import 'package:rutorrentflutter/screens/main_screen.dart'; import 'package:modal_progress_hud/modal_progress_hud.dart'; import 'package:rutorrentflutter/utilities/preferences.dart'; @@ -215,6 +216,47 @@ class _ConfigurationsScreenState extends State { passwordFocus: passwordFocus, ), ), + Padding( + padding: + const EdgeInsets.symmetric(vertical: 16, horizontal: 32), + child: Container( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5.0), + side: + BorderSide(color: Theme.of(context).primaryColor), + ), + primary: Provider.of(context).isLightMode + ? Colors.white + : Colors.black, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 28, vertical: 16), + child: Text( + 'Discover ruTorrent servers in LAN', + style: TextStyle( + color: Theme.of(context).primaryColor, + fontSize: 18), + ), + ), + onPressed: () async { + var received = await showDialog( + context: context, builder: (ctx) => DiscoverPage()); + if (received != null) { + Api api = Provider.of(context, + listen: false); // One call to provider + api.setUrl(api.url); + api.setUsername(api.username); + api.setPassword(api.password); + _validateConfigurationDetails(api); + } + }, + ), + ), + ), Padding( padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 32),