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!
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 -3Learn more about email & git
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
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!