Add feed filter options

This commit is contained in:
Lea 2023-01-23 10:45:52 +01:00
parent 9801b20a61
commit 27915caf5f
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
2 changed files with 139 additions and 7 deletions

View file

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:feet/widgets/centered_page_hint.dart'; import 'package:feet/widgets/centered_page_hint.dart';
import 'package:feet/widgets/filter_menu.dart';
import 'package:feet/widgets/homepage_post.dart'; import 'package:feet/widgets/homepage_post.dart';
import 'package:feet/widgets/login_prompt.dart'; import 'package:feet/widgets/login_prompt.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -83,9 +84,15 @@ class _MyHomePageState extends State<MyHomePage> {
var _fetched = false; var _fetched = false;
var _fetchedCount = 0; var _fetchedCount = 0;
var _knownPostsSize = -1; var _knownPostsSize = -1;
List<int> _feedFilter = [];
Future<void> refresh() async { Future<void> refresh() async {
widget.api.cache.clear(); widget.api.cache.clear();
setState(() {
_fetchedCount = 0;
_knownPostsSize = -1;
_feedFilter = [];
});
print("Starting refresh"); print("Starting refresh");
@ -97,10 +104,8 @@ class _MyHomePageState extends State<MyHomePage> {
.sinceId(0) .sinceId(0)
.execute(); .execute();
while ( while ((data['items'] as List<dynamic>).isNotEmpty &&
(data['items'] as List<dynamic>).isNotEmpty && _fetchedCount < FETCH_MAX_POSTS) {
_fetchedCount < FETCH_MAX_POSTS
) {
print("Fetching more items"); print("Fetching more items");
var ids = widget.api.cache.items var ids = widget.api.cache.items
@ -134,7 +139,10 @@ class _MyHomePageState extends State<MyHomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var loggedIn = widget.api.loggedIn(); var loggedIn = widget.api.loggedIn();
var posts = widget.api.cache.items.getAll().values; var posts = widget.api.cache.items.getAll().values.where(
(element) => _feedFilter.isEmpty || _feedFilter.contains(element.feedId)
);
var savedPosts = posts.where((element) => element.isSaved); var savedPosts = posts.where((element) => element.isSaved);
var unreadPosts = posts.where((element) => !element.isRead); var unreadPosts = posts.where((element) => !element.isRead);
@ -173,7 +181,8 @@ class _MyHomePageState extends State<MyHomePage> {
text: "Nothing here yet. Try saving some posts!"), text: "Nothing here yet. Try saving some posts!"),
]; ];
// I'm aware that this is stupid, but I'm sick and tired and really don't care as long as it works // I'm aware that this is stupid, but I'm sick and tired and
// really don't care as long as it works
if (!loggedIn) { if (!loggedIn) {
Timer.periodic(const Duration(seconds: 1), (timer) { Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() { setState(() {
@ -248,7 +257,33 @@ class _MyHomePageState extends State<MyHomePage> {
), ),
); );
}, },
) ),
PopupMenuItem(
value: "filter",
child: Text(
_feedFilter.isEmpty
? "Filter..."
: "Filter (${_feedFilter.length}/${widget.api.cache.feeds.size})"
),
onTap: () {
Future.delayed(
Duration.zero,
() => showDialog(
context: context,
barrierDismissible: false,
builder: (context) => FilterMenu(
api: widget.api,
initData: _feedFilter,
onConfirm: (items) {
setState(() {
_feedFilter = items;
});
},
),
),
);
},
),
]), ]),
], ],
), ),

View file

@ -0,0 +1,97 @@
import 'package:feet/api/api.dart';
import 'package:flutter/material.dart';
class FilterMenu extends StatefulWidget {
final FeverAPI api;
final List<int> initData;
final void Function(List<int> items) onConfirm;
const FilterMenu({
super.key,
required this.api,
required this.initData,
required this.onConfirm,
});
@override
State<FilterMenu> createState() => _FilterMenuState();
}
class _FilterMenuState extends State<FilterMenu> {
final Map<int, bool> _checked = {};
@override
void initState() {
super.initState();
for (var feed in widget.api.cache.feeds.getAll().values) {
_checked[feed.id] = widget.initData.contains(feed.id);
}
}
@override
Widget build(BuildContext context) {
int selected = _checked.values.where((e) => e == true).length;
return SimpleDialog(
title: const Text("Filter"),
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 4.0),
child: Text(
selected == 0
? "All feeds will be shown"
: "$selected out of ${_checked.length} feeds will be shown",
),
),
Container(
width: 300,
height: 280,
padding: const EdgeInsets.all(8.0),
child: ListView(
children: widget.api.cache.feeds
.getAll()
.values
.map((feed) => Row(
children: [
Checkbox(
value: _checked[feed.id] ?? false,
onChanged: (value) {
setState(() {
_checked[feed.id] = value ?? true;
});
},
),
Text(feed.title),
],
))
.toList(),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextButton(
onPressed: () {
List<int> items = _checked.keys
.where((element) => _checked[element]!)
.toList();
widget.onConfirm(items);
Navigator.of(context).pop();
},
child: const Text("Done"),
),
TextButton(
onPressed: () {
setState(() {
_checked.forEach((key, value) {
_checked[key] = false;
});
});
},
child: const Text("Reset")),
],
)
],
);
}
}