mirror of
https://github.com/ChronosX88/wind.git
synced 2024-12-04 18:12:18 +00:00
Implement thread list update feature
This commit is contained in:
parent
a0e45d81ff
commit
cf15aae5ac
@ -93,6 +93,20 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
// Here we take the value from the MyHomePage object that was created by
|
// Here we take the value from the MyHomePage object that was created by
|
||||||
// the App.build method, and use it to set our appbar title.
|
// the App.build method, and use it to set our appbar title.
|
||||||
title: Text(widget.title),
|
title: Text(widget.title),
|
||||||
|
actions: [
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Обновление списка тредов...')),
|
||||||
|
);
|
||||||
|
Provider.of<ThreadListModel>(context, listen: false).update();
|
||||||
|
},
|
||||||
|
label: const Text("Обновить"),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
primary: Theme.of(context).colorScheme.onPrimary),
|
||||||
|
icon: Icon(Icons.sync))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -6,6 +6,8 @@ class ThreadListModel extends ChangeNotifier {
|
|||||||
String currentGroup = "";
|
String currentGroup = "";
|
||||||
NNTPClient? client;
|
NNTPClient? client;
|
||||||
Map<String, Map<int, List<ThreadItem>>> threads = {};
|
Map<String, Map<int, List<ThreadItem>>> threads = {};
|
||||||
|
int _pageNum = -1;
|
||||||
|
List<ThreadItem> _curItems = [];
|
||||||
|
|
||||||
Future<void> selectNewsgroup(String name) async {
|
Future<void> selectNewsgroup(String name) async {
|
||||||
if (currentGroup == name) return;
|
if (currentGroup == name) return;
|
||||||
@ -13,27 +15,29 @@ class ThreadListModel extends ChangeNotifier {
|
|||||||
currentGroup = name;
|
currentGroup = name;
|
||||||
await client!.selectGroup(name);
|
await client!.selectGroup(name);
|
||||||
threads.putIfAbsent(name, () => {});
|
threads.putIfAbsent(name, () => {});
|
||||||
|
_curItems.clear();
|
||||||
|
_pageNum = -1;
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ThreadItem>> getNewThreads(
|
Future<List<ThreadItem>> getNewThreads(bool clearCache) async {
|
||||||
int perPage, int pageNum, bool clearCache) async {
|
|
||||||
if (currentGroup == "") return [];
|
if (currentGroup == "") return [];
|
||||||
List<ThreadItem> items = [];
|
|
||||||
|
_pageNum += 1;
|
||||||
|
|
||||||
if (clearCache) {
|
if (clearCache) {
|
||||||
threads[currentGroup]?.clear();
|
threads[currentGroup]?.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threads[currentGroup]!.containsKey(pageNum)) {
|
if (threads[currentGroup]!.containsKey(_pageNum)) {
|
||||||
items.addAll(threads[currentGroup]![pageNum]!);
|
_curItems.addAll(threads[currentGroup]![_pageNum]!);
|
||||||
} else {
|
} else {
|
||||||
var resp = await client!.getNewThreads(perPage, pageNum);
|
var resp = await client!.getNewThreads(10, _pageNum);
|
||||||
resp.forEach((pair) {
|
resp.forEach((pair) {
|
||||||
var number = pair.item1;
|
var number = pair.item1;
|
||||||
var msg = pair.item2;
|
var msg = pair.item2;
|
||||||
items.add(ThreadItem(
|
_curItems.add(ThreadItem(
|
||||||
msg.getHeaderValue("Message-Id")!,
|
msg.getHeaderValue("Message-Id")!,
|
||||||
number,
|
number,
|
||||||
msg.getHeaderValue("Subject")!,
|
msg.getHeaderValue("Subject")!,
|
||||||
@ -42,9 +46,18 @@ class ThreadListModel extends ChangeNotifier {
|
|||||||
msg.decodeTextPlainPart()!));
|
msg.decodeTextPlainPart()!));
|
||||||
});
|
});
|
||||||
|
|
||||||
threads[currentGroup]![pageNum] = items;
|
if (resp.isEmpty) _pageNum -= 1;
|
||||||
|
|
||||||
|
threads[currentGroup]![_pageNum] = List.from(_curItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return _curItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
_curItems.clear();
|
||||||
|
_pageNum = -1;
|
||||||
|
threads[currentGroup]!.clear();
|
||||||
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wind/thread_list_model.dart';
|
import 'package:wind/thread_list_model.dart';
|
||||||
import 'package:wind/thread_screen.dart';
|
|
||||||
|
|
||||||
class ThreadListView extends StatefulWidget {
|
class ThreadListView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -9,8 +8,6 @@ class ThreadListView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ThreadListViewState extends State<ThreadListView> {
|
class ThreadListViewState extends State<ThreadListView> {
|
||||||
List<ThreadItem> _items = [];
|
|
||||||
int _pageNum = 0;
|
|
||||||
String _curGroup = "";
|
String _curGroup = "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -24,16 +21,13 @@ class ThreadListViewState extends State<ThreadListView> {
|
|||||||
if (snapshot.hasData &&
|
if (snapshot.hasData &&
|
||||||
snapshot.connectionState != ConnectionState.waiting) {
|
snapshot.connectionState != ConnectionState.waiting) {
|
||||||
List<ThreadItem> data = List.from(snapshot.data!);
|
List<ThreadItem> data = List.from(snapshot.data!);
|
||||||
_items.addAll(data);
|
if (data.isNotEmpty && data.last.number != -100500)
|
||||||
if (_items.isNotEmpty &&
|
data.add(ThreadItem("", -100500, "", "", "",
|
||||||
_items.last.number != -100500 &&
|
|
||||||
data.isNotEmpty)
|
|
||||||
_items.add(ThreadItem("", -100500, "", "", "",
|
|
||||||
"")); // magic item (for button "load more")
|
"")); // magic item (for button "load more")
|
||||||
return _curGroup != ""
|
return _curGroup != ""
|
||||||
? _threadView()
|
? _threadView(data)
|
||||||
: Center(
|
: Center(
|
||||||
child: Text("Newsgroup is not selected",
|
child: Text("Новостная группа не выбрана",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold, fontSize: 16)));
|
fontWeight: FontWeight.bold, fontSize: 16)));
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
@ -46,22 +40,18 @@ class ThreadListViewState extends State<ThreadListView> {
|
|||||||
|
|
||||||
Future<List<ThreadItem>> _fetchThreadList(BuildContext context) async {
|
Future<List<ThreadItem>> _fetchThreadList(BuildContext context) async {
|
||||||
var model = context.read<ThreadListModel>();
|
var model = context.read<ThreadListModel>();
|
||||||
if (model.currentGroup != _curGroup) {
|
_curGroup = model.currentGroup;
|
||||||
_items.clear();
|
return await model.getNewThreads(false);
|
||||||
_curGroup = model.currentGroup;
|
|
||||||
_pageNum = 0;
|
|
||||||
}
|
|
||||||
return await model.getNewThreads(10, _pageNum, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _threadView() {
|
Widget _threadView(List<ThreadItem> items) {
|
||||||
return _items.isNotEmpty
|
return items.isNotEmpty
|
||||||
? Scrollbar(
|
? Scrollbar(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
key: PageStorageKey("threadList"),
|
key: PageStorageKey("threadList"),
|
||||||
itemCount: _items.length,
|
itemCount: items.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (_items[index].number == -100500) {
|
if (items[index].number == -100500) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 100,
|
height: 100,
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
@ -72,19 +62,18 @@ class ThreadListViewState extends State<ThreadListView> {
|
|||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_pageNum += 1;
|
items.removeLast();
|
||||||
_items.removeLast();
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text('Load more'),
|
child: Text('Загрузить больше'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
return ThreadListItemView(item: _items[index]);
|
return ThreadListItemView(item: items[index]);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
: Center(
|
: Center(
|
||||||
child: Text("This newsgroup is empty",
|
child: Text("Эта новостная группа пуста",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)));
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user