From 7b215d5c6e67d5c80ba120f8542e66a6388d08cc Mon Sep 17 00:00:00 2001 From: Blake Leonard Date: Wed, 8 Mar 2023 13:02:43 -0500 Subject: [PATCH 1/4] fix: make the moxxmpp example work again Note: to do this, I could not use the ExampleTcpSocketWrapper. If I did, the app crashed on launch. I also added some functionality: the header bar turns green when connected, the FAB says what it does, and you can disconnect. Signed-off-by: Blake Leonard --- example/lib/main.dart | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 8107c6f..710257c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -55,21 +55,25 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { final XmppConnection connection = XmppConnection( - ExponentialBackoffReconnectionPolicy(), - ExampleTcpSocketWrapper(), + RandomBackoffReconnectionPolicy(1, 60), + AlwaysConnectedConnectivityManager(), + //ExampleTcpSocketWrapper(), // this causes the app to crash + TCPSocketWrapper(true), // Note: you probably want this to be false in a real app ); TextEditingController jidController = TextEditingController(); TextEditingController passwordController = TextEditingController(); + bool connected = false; + bool loading = false; _MyHomePageState() : super() { connection ..registerManagers([ StreamManagementManager(), - DiscoManager(), - RosterManager(), + DiscoManager([]), + RosterManager(TestingRosterStateManager("", [])), PingManager(), MessageManager(), - PresenceManager('http://moxxmpp.example'), + PresenceManager(), ]) ..registerFeatureNegotiators([ ResourceBindingNegotiator(), @@ -85,15 +89,24 @@ class _MyHomePageState extends State { } Future _buttonPressed() async { + if (connected) { + await connection.disconnect(); + setState(() {connected = false;}); + return; + } + setState(() {loading = true;}); connection.setConnectionSettings( ConnectionSettings( jid: JID.fromString(jidController.text), password: passwordController.text, useDirectTLS: true, allowPlainAuth: false, + // otherwise, connecting to some servers will + // cause an app to hang ), ); await connection.connect(); + setState(() {connected = true; loading = false;}); } @override @@ -101,18 +114,22 @@ class _MyHomePageState extends State { return Scaffold( appBar: AppBar( title: Text(widget.title), + backgroundColor: connected ? Colors.green : Colors.deepPurple[800], + foregroundColor: connected ? Colors.black : Colors.white, ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextField( + enabled: !loading, controller: jidController, decoration: InputDecoration( labelText: 'JID', ), ), TextField( + enabled: !loading, controller: passwordController, decoration: InputDecoration( labelText: 'Password', @@ -122,10 +139,13 @@ class _MyHomePageState extends State { ], ), ), - floatingActionButton: FloatingActionButton( + floatingActionButton: FloatingActionButton.extended( onPressed: _buttonPressed, + label: Text(connected ? 'Disconnect' : 'Connect'), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, tooltip: 'Connect', - child: const Icon(Icons.add), + icon: const Icon(Icons.power), ), ); } From 60c89e28d37925e7406501ded1ea53767b5eeb33 Mon Sep 17 00:00:00 2001 From: Blake Leonard Date: Wed, 8 Mar 2023 14:09:37 -0500 Subject: [PATCH 2/4] chore(example): switch to connectAwaitable That way it only acts connected when the credentials have been accepted. Also I had to correct the value of "allowPlainAuth" which should be true since a bug with it has been identified, and not yet fixed. Signed-off-by: Blake Leonard --- example/lib/main.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 710257c..051a75f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -87,7 +87,7 @@ class _MyHomePageState extends State { SaslScramNegotiator(8, '', '', ScramHashType.sha1), ]); } - + Future _buttonPressed() async { if (connected) { await connection.disconnect(); @@ -100,13 +100,22 @@ class _MyHomePageState extends State { jid: JID.fromString(jidController.text), password: passwordController.text, useDirectTLS: true, - allowPlainAuth: false, + allowPlainAuth: true, // otherwise, connecting to some servers will // cause an app to hang ), ); - await connection.connect(); - setState(() {connected = true; loading = false;}); + final result = await connection.connectAwaitable(); + setState(() {connected = result.success; loading = false;}); + if (result.error != null) { + print(result.error); + if (context.mounted) { + showDialog(context: context, builder: (_) => AlertDialog( + title: const Text('Error'), + content: Text(result.error.toString()), + )); + } + } } @override From 792ec4d731076a9ab34ef35a0cbc7750ba89561e Mon Sep 17 00:00:00 2001 From: Blake Leonard Date: Wed, 8 Mar 2023 15:07:55 -0500 Subject: [PATCH 3/4] chore(example): format and fix lint errors Signed-off-by: Blake Leonard --- example/lib/main.dart | 54 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 051a75f..9d1b4bb 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -11,19 +11,22 @@ class ExampleTcpSocketWrapper extends TCPSocketWrapper { Future> srvQuery(String domain, bool dnssec) async { final records = await MoxdnsPlugin.srvQuery(domain, false); return records - .map((record) => MoxSrvRecord( - record.priority, - record.weight, - record.target, - record.port, - ),) - .toList(); + .map( + (record) => MoxSrvRecord( + record.priority, + record.weight, + record.target, + record.port, + ), + ) + .toList(); } } void main() { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((record) { + // ignore: avoid_print print('${record.level.name}: ${record.time}: ${record.message}'); }); @@ -54,11 +57,13 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { + final logger = Logger('MyHomePage'); final XmppConnection connection = XmppConnection( RandomBackoffReconnectionPolicy(1, 60), AlwaysConnectedConnectivityManager(), //ExampleTcpSocketWrapper(), // this causes the app to crash - TCPSocketWrapper(true), // Note: you probably want this to be false in a real app + TCPSocketWrapper( + true), // Note: you probably want this to be false in a real app ); TextEditingController jidController = TextEditingController(); TextEditingController passwordController = TextEditingController(); @@ -91,29 +96,38 @@ class _MyHomePageState extends State { Future _buttonPressed() async { if (connected) { await connection.disconnect(); - setState(() {connected = false;}); + setState(() { + connected = false; + }); return; } - setState(() {loading = true;}); + setState(() { + loading = true; + }); connection.setConnectionSettings( ConnectionSettings( jid: JID.fromString(jidController.text), password: passwordController.text, useDirectTLS: true, allowPlainAuth: true, - // otherwise, connecting to some servers will - // cause an app to hang + // otherwise, connecting to some servers will + // cause an app to hang ), ); final result = await connection.connectAwaitable(); - setState(() {connected = result.success; loading = false;}); + setState(() { + connected = result.success; + loading = false; + }); if (result.error != null) { - print(result.error); + logger.severe(result.error); if (context.mounted) { - showDialog(context: context, builder: (_) => AlertDialog( - title: const Text('Error'), - content: Text(result.error.toString()), - )); + showDialog( + context: context, + builder: (_) => AlertDialog( + title: const Text('Error'), + content: Text(result.error.toString()), + )); } } } @@ -133,14 +147,14 @@ class _MyHomePageState extends State { TextField( enabled: !loading, controller: jidController, - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'JID', ), ), TextField( enabled: !loading, controller: passwordController, - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Password', ), obscureText: true, From 2cdc56c8825ac8e0e9f6ff220085efaf50b6a7a6 Mon Sep 17 00:00:00 2001 From: Blake Leonard Date: Fri, 10 Mar 2023 13:29:30 -0500 Subject: [PATCH 4/4] chore: format corrections, comment clarifications Signed-off-by: Blake Leonard --- example/lib/main.dart | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 9d1b4bb..3a3bb48 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -61,9 +61,10 @@ class _MyHomePageState extends State { final XmppConnection connection = XmppConnection( RandomBackoffReconnectionPolicy(1, 60), AlwaysConnectedConnectivityManager(), - //ExampleTcpSocketWrapper(), // this causes the app to crash - TCPSocketWrapper( - true), // Note: you probably want this to be false in a real app + // The below causes the app to crash. + //ExampleTcpSocketWrapper(), + // In a production app, the below should be false. + TCPSocketWrapper(true), ); TextEditingController jidController = TextEditingController(); TextEditingController passwordController = TextEditingController(); @@ -109,9 +110,11 @@ class _MyHomePageState extends State { jid: JID.fromString(jidController.text), password: passwordController.text, useDirectTLS: true, + // If `allowPlainAuth` is `false`, connecting to some + // servers will cause apps to hang, and never connect. + // The hang is a bug that will be fixed, so when it is, + // allowPlainAuth should be set to false. allowPlainAuth: true, - // otherwise, connecting to some servers will - // cause an app to hang ), ); final result = await connection.connectAwaitable(); @@ -123,11 +126,12 @@ class _MyHomePageState extends State { logger.severe(result.error); if (context.mounted) { showDialog( - context: context, - builder: (_) => AlertDialog( - title: const Text('Error'), - content: Text(result.error.toString()), - )); + context: context, + builder: (_) => AlertDialog( + title: const Text('Error'), + content: Text(result.error.toString()), + ), + ); } } }