~emersion/goguma-dev

Move network & bouncerNetwork state formatter to models v1 APPLIED

delthas: 2
 Move network & bouncerNetwork state formatter to models
 Add a network_details page

 6 files changed, 158 insertions(+), 29 deletions(-)
Pushed with minor edits, thanks!
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/goguma-dev/patches/31333/mbox | git am -3
Learn more about email & git

[PATCH 1/2] Move network & bouncerNetwork state formatter to models Export this patch

This will be shared with the network_details page.
---
 lib/models.dart        | 26 ++++++++++++++++++++++++++
 lib/page/settings.dart | 30 ++----------------------------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/lib/models.dart b/lib/models.dart
index 15c12af..95a3bd7 100644
--- a/lib/models.dart
+++ b/lib/models.dart
@@ -512,3 +512,29 @@ class MemberListModel extends ChangeNotifier {
		notifyListeners();
	}
}

String networkStateDescription(NetworkState state) {
	switch (state) {
		case NetworkState.offline:
			return 'Disconnected';
		case NetworkState.connecting:
			return 'Connecting…';
		case NetworkState.registering:
			return 'Logging in…';
		case NetworkState.synchronizing:
			return 'Synchronizing…';
		case NetworkState.online:
			return 'Connected';
	}
}

String bouncerNetworkStateDescription(BouncerNetworkState state) {
	switch (state) {
		case BouncerNetworkState.disconnected:
			return 'Bouncer disconnected from network';
		case BouncerNetworkState.connecting:
			return 'Bouncer connecting to network…';
		case BouncerNetworkState.connected:
			return 'Connected';
	}
}
diff --git a/lib/page/settings.dart b/lib/page/settings.dart
index 4d6a8e4..a70dd4b 100644
--- a/lib/page/settings.dart
+++ b/lib/page/settings.dart
@@ -148,12 +148,12 @@ class _NetworkItem extends AnimatedWidget {
	Widget build(BuildContext context) {
		String subtitle;
		if (network.bouncerNetwork != null && network.state == NetworkState.online) {
			subtitle = _bouncerNetworkStateDescription(network.bouncerNetwork!.state);
			subtitle = bouncerNetworkStateDescription(network.bouncerNetwork!.state);
			if (network.bouncerNetwork?.error?.isNotEmpty == true) {
				subtitle = '$subtitle - ${network.bouncerNetwork!.error}';
			}
		} else {
			subtitle = _networkStateDescription(network.state);
			subtitle = networkStateDescription(network.state);
		}

		return ListTile(
@@ -169,29 +169,3 @@ class _NetworkItem extends AnimatedWidget {
		);
	}
}

String _networkStateDescription(NetworkState state) {
	switch (state) {
	case NetworkState.offline:
		return 'Disconnected';
	case NetworkState.connecting:
		return 'Connecting…';
	case NetworkState.registering:
		return 'Logging in…';
	case NetworkState.synchronizing:
		return 'Synchronizing…';
	case NetworkState.online:
		return 'Connected';
	}
}

String _bouncerNetworkStateDescription(BouncerNetworkState state) {
	switch (state) {
	case BouncerNetworkState.disconnected:
		return 'Bouncer disconnected from network';
	case BouncerNetworkState.connecting:
		return 'Bouncer connecting to network…';
	case BouncerNetworkState.connected:
		return 'Connected';
	}
}

base-commit: 10a2a3232f0dbb959d17500cc75830f8b60b8257
-- 
2.17.1

[PATCH 2/2] Add a network_details page Export this patch

This page is intended to be the network counterpart of the
buffer_details page. It enables a user to review the main information
about a network (only name and state for now, perhaps some attributes in
the future).

The list of conversations opened with this network is also listed, with
links to open the corresponding conversation when tapped. Conversely,
the existing mentions of networks (in settings and buffer_details) were
linked to open this page.

This page also enables the user to run two actions:
- editing the network (this opens the edit_network page)
- deleting the network (this simply sends a DELNETWORK and pops the
  Navigator)
---
I have no strong opinions on the look&feel of the page. Let me know if  
there is anything to move around, I'll be happy to fix it.

 lib/app.dart                  |  14 +++++
 lib/page/buffer_details.dart  |   4 ++
 lib/page/network_details.dart | 110 ++++++++++++++++++++++++++++++++++
 lib/page/settings.dart        |   3 +-
 4 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 lib/page/network_details.dart

diff --git a/lib/app.dart b/lib/app.dart
index 43ca3b5..f406ddd 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -15,6 +15,7 @@ import 'page/buffer_list.dart';
import 'page/connect.dart';
import 'page/join.dart';
import 'page/edit_network.dart';
import 'page/network_details.dart';
import 'page/settings.dart';

const _themeMode = ThemeMode.system;
@@ -244,6 +245,19 @@ class AppState extends State<App> with WidgetsBindingObserver {
			var network = settings.arguments as BouncerNetworkModel?;
			builder = (context) => EditNetworkPage(network: network);
			break;
		case NetworkDetailsPage.routeName:
			var network = settings.arguments as NetworkModel;
			builder = (context) {
				var client = context.read<ClientProvider>().get(network);
				return MultiProvider(
					providers: [
						ChangeNotifierProvider<NetworkModel>.value(value: network),
						Provider<Client>.value(value: client),
					],
					child: NetworkDetailsPage(),
				);
			};
			break;
		default:
			throw Exception('Unknown route ${settings.name}');
		}
diff --git a/lib/page/buffer_details.dart b/lib/page/buffer_details.dart
index 1c38806..9c96fc5 100644
--- a/lib/page/buffer_details.dart
+++ b/lib/page/buffer_details.dart
@@ -7,6 +7,7 @@ import '../irc.dart';
import '../linkify.dart';
import '../models.dart';
import 'buffer.dart';
import 'network_details.dart';

class BufferDetailsPage extends StatefulWidget {
	static const routeName = '/buffer/details';
@@ -137,6 +138,9 @@ class BufferDetailsPageState extends State<BufferDetailsPage> {
		children.add(ListTile(
			title: Text(network.displayName),
			leading: Icon(Icons.hub),
			onTap: network.bouncerNetwork == null ? null : () {
				Navigator.pushNamed(context, NetworkDetailsPage.routeName, arguments: network);
			},
		));

		if (buffer.online == false) {
diff --git a/lib/page/network_details.dart b/lib/page/network_details.dart
new file mode 100644
index 0000000..8155686
--- /dev/null
+++ b/lib/page/network_details.dart
@@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../client.dart';
import '../irc.dart';
import '../models.dart';
import 'buffer.dart';
import 'edit_network.dart';

class NetworkDetailsPage extends StatefulWidget {
	static const routeName = '/network/details';

	const NetworkDetailsPage({ Key? key }) : super(key: key);

	@override
	NetworkDetailsPageState createState() => NetworkDetailsPageState();
}

class NetworkDetailsPageState extends State<NetworkDetailsPage> {
	@override
	Widget build(BuildContext context) {
		var network = context.watch<NetworkModel>();
		List<Widget> children = [];

		String status;
		if (network.bouncerNetwork != null && network.state == NetworkState.online) {
			status = bouncerNetworkStateDescription(network.bouncerNetwork!.state);
			if (network.bouncerNetwork?.error?.isNotEmpty == true) {
				status = '$status - ${network.bouncerNetwork!.error}';
			}
		} else {
			status = networkStateDescription(network.state);
		}
		children.add(Container(
			margin: const EdgeInsets.all(15),
			child: Text(status),
		));

		var buffers = context.watch<BufferListModel>().buffers.where((buffer) => buffer.network == network).toList();

		var channels = SliverList(delegate: SliverChildBuilderDelegate((context, index) {
				var buffer = buffers[index];
				return ListTile(
					leading: CircleAvatar(child: Text(_initials(buffer.name))),
					title: Text(buffer.name),
					onTap: () {
						Navigator.pushNamed(context, BufferPage.routeName, arguments: buffer);
					},
				);
			},
			childCount: buffers.length,
		));
		var s = buffers.length > 1 ? 's' : '';

		children.add(Divider());
		children.add(Container(
			margin: const EdgeInsets.all(15),
			child: Text('${buffers.length} conversation$s', style: TextStyle(fontWeight: FontWeight.bold)),
		));

		var client = context.read<Client>();
		return Scaffold(
			body: CustomScrollView(
				slivers: [
					SliverAppBar(
						pinned: true,
						snap: true,
						floating: true,
						expandedHeight: 128,
						flexibleSpace: FlexibleSpaceBar(
							title: Text(network.displayName),
							centerTitle: true,
						),
						actions: [
							IconButton(
								icon: Icon(Icons.edit),
								tooltip: 'Edit network',
								onPressed: () {
									Navigator.pushNamed(context, EditNetworkPage.routeName, arguments: network.bouncerNetwork!);
								},
							),
							IconButton(
								icon: Icon(Icons.delete_forever),
								tooltip: 'Delete network',
								onPressed: () {
									var msg = IrcMessage('BOUNCER', ['DELNETWORK', network.networkId.toString()]);
									client.send(msg);
									Navigator.pop(context);
								},
							),
						],
					),
					SliverList(delegate: SliverChildListDelegate(children)),
					channels,
				],
			),
		);
	}
}

String _initials(String name) {
	for (var r in name.runes) {
		var ch = String.fromCharCode(r);
		if (ch == '#') {
			continue;
		}
		return ch.toUpperCase();
	}
	return '';
}
diff --git a/lib/page/settings.dart b/lib/page/settings.dart
index a70dd4b..cd90544 100644
--- a/lib/page/settings.dart
+++ b/lib/page/settings.dart
@@ -11,6 +11,7 @@ import '../dialog/edit_profile.dart';
import '../irc.dart';
import '../models.dart';
import 'edit_network.dart';
import 'network_details.dart';

class SettingsPage extends StatefulWidget {
	static const routeName = '/settings';
@@ -164,7 +165,7 @@ class _NetworkItem extends AnimatedWidget {
				children: const [Icon(Icons.hub)],
			),
			onTap: network.bouncerNetwork == null ? null : () {
				Navigator.pushNamed(context, EditNetworkPage.routeName, arguments: network.bouncerNetwork!);
				Navigator.pushNamed(context, NetworkDetailsPage.routeName, arguments: network);
			},
		);
	}
-- 
2.17.1
Pushed with minor edits, thanks!