fetch all posts instead of only the initial 50

This commit is contained in:
Lea 2023-01-23 08:47:10 +01:00
parent 1a09ba2ba9
commit 2303df7abe
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
4 changed files with 71 additions and 7 deletions

View file

@ -103,6 +103,7 @@ class APIRequestBuilder {
return this;
}
/// Mark single item as read, unread, saved, unsaved
APIRequestBuilder markItem(Item item, ItemMarkType markAs) {
_addArg('mark=item');
_addArg('as=${markAs.name}');
@ -112,6 +113,22 @@ class APIRequestBuilder {
return this;
}
/// Use the `since_id` argument with the highest id of locally cached items to
/// request 50 additional items. Repeat until the items array in the response
/// is empty.
APIRequestBuilder sinceId(int id) {
_addArg('since_id=$id');
return this;
}
/// Use the `max_id` argument with the lowest id of locally cached items (or
/// 0 initially) to request 50 previous items. Repeat until the items array
/// in the response is empty.
APIRequestBuilder maxId(int id) {
_addArg('max_id=$id');
return this;
}
/// Executes the API request and returns the JSON data
Future<Map<String, dynamic>> fetch() async {
if (api.apiKey == null || api.apiUrl == null) {
@ -126,7 +143,7 @@ class APIRequestBuilder {
}
/// Executes the API request and populates the local cache with the response data
Future<void> execute() async {
Future<Map<String, dynamic>> execute() async {
final data = await fetch();
if (data.containsKey('groups')) {
@ -185,6 +202,8 @@ class APIRequestBuilder {
}
api.cache.items.set(_markedItem!.id, _markedItem!);
}
return data;
}
}

View file

@ -42,6 +42,8 @@ class ObjectCache<K, T> {
void set(K key, T value) {
_items[key] = value;
}
int get size => _items.length;
}
class ItemCache extends ObjectCache<int, Item> {

View file

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:feet/pages/login.dart';
import 'package:feet/widgets/centered_page_hint.dart';
import 'package:feet/widgets/homepage_post.dart';
import 'package:feet/widgets/login_prompt.dart';
@ -10,6 +9,10 @@ import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'api/api.dart';
// Limit the maximum amount of posts to fetch so we don't wait forever when
// fetching a large list
const FETCH_MAX_POSTS = 1000;
void main() {
runApp(MyApp());
}
@ -78,9 +81,47 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
var _index = 0;
var _fetched = false;
var _fetchedCount = 0;
var _knownPostsSize = -1;
Future<void> refresh() =>
widget.api.request().withFeeds().withGroups().withItems().execute();
Future<void> refresh() async {
widget.api.cache.clear();
print("Starting refresh");
var data = await widget.api
.request()
.withFeeds()
.withGroups()
.withItems()
.sinceId(0)
.execute();
while (
(data['items'] as List<dynamic>).isNotEmpty &&
_fetchedCount < FETCH_MAX_POSTS
) {
print("Fetching more items");
var ids = widget.api.cache.items
.getAll()
.values
.map((value) => value.id)
.toList()
..sort((a, b) => b - a);
setState(() {
_fetchedCount = ids.length;
_knownPostsSize = data['total_items'] ?? -1;
});
data =
await widget.api.request().withItems().sinceId(ids.first).execute();
print(
"Item cache size is now ${widget.api.cache.items.size} ${ids.first} ${ids.last}");
}
}
@override
void initState() {
@ -233,8 +274,10 @@ class _MyHomePageState extends State<MyHomePage> {
body: loggedIn
? (_fetched
? pages[_index]
: const CenteredPageHint(
icon: Icons.downloading, text: "Fetching your feeds..."))
: CenteredPageHint(
icon: Icons.downloading,
text:
"Fetching your feeds...\n${_fetchedCount > 0 && _knownPostsSize > -1 ? "$_fetchedCount / $_knownPostsSize" : ""}"))
: Center(child: LoginPrompt(api: widget.api)),
);
}

View file

@ -15,7 +15,7 @@ class CenteredPageHint extends StatelessWidget {
padding: const EdgeInsets.all(12.0),
child: Icon(icon, size: 48),
),
Text(text),
Text(text, textAlign: TextAlign.center),
],
),
);