Implement newsgroup list loading in sidebar

This commit is contained in:
ChronosX88 2022-04-14 22:17:47 +03:00
parent 3b21f987d7
commit b6a8a9fa96
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
3 changed files with 151 additions and 85 deletions

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:wind/newsgroup_list_view.dart';
import 'package:wind/nntp_client.dart';
void main() {
@ -12,15 +13,6 @@ class MyApp extends StatelessWidget {
return MaterialApp(
title: 'Wind',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.indigo,
),
home: MyHomePage(title: 'Wind'),
@ -31,15 +23,6 @@ class MyApp extends StatelessWidget {
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
@ -47,11 +30,13 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
late NNTPClient nntpClient;
@override
void initState() {
super.initState();
var client = NNTPClient("localhost:1120");
nntpClient = NNTPClient("localhost:1120");
}
@override
@ -85,16 +70,9 @@ class _MyHomePageState extends State<MyHomePage> {
fontWeight: FontWeight.bold, fontSize: 20),
)),
Expanded(
child: ListView(children: [
ListTile(
title: Text(
"test.group",
),
subtitle: Text("Description of the group"),
onTap: () => {},
)
]),
)
child: Builder(
builder: (context) =>
NewsgroupListView(nntpClient))),
],
),
),
@ -112,18 +90,22 @@ class _MyHomePageState extends State<MyHomePage> {
class ThreadsListView extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ThreadsListViewState();
State<StatefulWidget> createState() => ThreadsListViewState();
}
class _ThreadsListViewState extends State<ThreadsListView> {
class ThreadsListViewState extends State<ThreadsListView> {
String currentGroup = "no group selected";
@override
Widget build(Object context) {
return Container(
width: 640,
child: ListView(
children: [
SizedBox(height: 10),
Card(
Widget build(BuildContext context) {
return Container(width: 640, child: Center(child: Text(currentGroup)));
}
}
class ThreadListItemView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
elevation: 5,
child: InkWell(
splashColor: Colors.indigo.withAlpha(30),
@ -135,8 +117,7 @@ class _ThreadsListViewState extends State<ThreadsListView> {
Container(
child: Text(
"A question for those who watched The Matrix in 1999.",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 21),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 21),
),
margin: EdgeInsets.only(top: 16, left: 16, right: 16),
),
@ -157,8 +138,7 @@ class _ThreadsListViewState extends State<ThreadsListView> {
),
],
),
margin: EdgeInsets.only(
top: 5, bottom: 2, left: 16, right: 16),
margin: EdgeInsets.only(top: 5, bottom: 2, left: 16, right: 16),
),
Container(
child: Text(
@ -168,8 +148,6 @@ class _ThreadsListViewState extends State<ThreadsListView> {
)
],
),
)),
],
));
}
}

View File

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:wind/nntp_client.dart';
class NewsgroupListView extends StatelessWidget {
final NNTPClient client;
NewsgroupListView(this.client);
@override
Widget build(BuildContext context) {
return FutureBuilder<List<GroupInfo>>(
future: _fetchList(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<GroupInfo> data = snapshot.data!;
return _newgroupListView(data);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
},
);
}
Future<List<GroupInfo>> _fetchList() async {
return await client.getNewsGroupList();
}
ListView _newgroupListView(List<GroupInfo> data) {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
style: ListTileStyle.drawer,
title: Text(data[index].name),
subtitle: Text(data[index].description),
onTap: () => {});
},
);
}
}

View File

@ -17,7 +17,7 @@ class NNTPClient {
return;
}
var command = commandQueue.removeFirst();
var resp = data as String;
var resp = data.toString();
var respLines = resp.split("\r\n");
respLines.removeWhere((element) => element == "");
var respCode = int.parse(respLines[0].split(" ")[0]);
@ -38,6 +38,44 @@ class NNTPClient {
var result = await cmd.response;
return result;
}
Future<List<GroupInfo>> getNewsGroupList() async {
List<GroupInfo> l = [];
var groupMap = {};
await _sendCommand("LIST", ["NEWSGROUPS"]).then((value) {
value.lines.removeAt(0);
value.lines.removeLast();
value.lines.forEach((element) {
var firstSpace = element.indexOf(" ");
var name = element.substring(0, firstSpace);
groupMap.addAll({
name: {"desc": element.substring(firstSpace + 1)}
});
});
});
await _sendCommand("LIST", ["ACTIVE"]).then((value) {
value.lines.removeAt(0);
value.lines.removeLast();
value.lines.forEach((element) {
var splitted = element.split(" ");
var name = splitted[0];
var high = splitted[1];
var low = splitted[2];
groupMap[name]["high"] = high;
groupMap[name]["low"] = low;
});
});
groupMap.forEach((key, value) {
l.add(GroupInfo(key, value["desc"], int.parse(value["low"]),
int.parse(value["high"])));
});
return l;
}
}
class _NNTPCommand {
@ -65,3 +103,12 @@ class _CommandResponse {
_CommandResponse(this.responseCode, this.lines);
}
class GroupInfo {
final String name;
final String description;
final int lowWater;
final int highWater;
GroupInfo(this.name, this.description, this.lowWater, this.highWater);
}