feat: check every subscription in the background and add the posts page
This commit is contained in:
parent
953ae798eb
commit
1b426ccd8b
15 changed files with 688 additions and 58 deletions
|
|
@ -286,6 +286,51 @@ class MewsDatabase extends _$MewsDatabase {
|
|||
return statement.write(const FeedEntriesCompanion(readAt: Value(null)));
|
||||
}
|
||||
|
||||
/// Every stored post with the site it came from, for the posts page.
|
||||
Future<List<RiverEntry>> riverEntries({
|
||||
EntrySort sort = EntrySort.date,
|
||||
bool unreadOnly = false,
|
||||
int limit = 200,
|
||||
}) async {
|
||||
final site = alias(subscriptions, 'site');
|
||||
final query = select(feedEntries).join([
|
||||
leftOuterJoin(site, site.url.equalsExp(feedEntries.siteUrl)),
|
||||
]);
|
||||
if (unreadOnly) query.where(feedEntries.readAt.isNull());
|
||||
|
||||
// A site without a title sorts under its address, so the order never
|
||||
// depends on a null.
|
||||
final sourceName = coalesce([site.title, feedEntries.siteUrl]);
|
||||
query.orderBy(switch (sort) {
|
||||
EntrySort.date => [
|
||||
OrderingTerm.desc(feedEntries.date),
|
||||
OrderingTerm.asc(feedEntries.url),
|
||||
],
|
||||
EntrySort.source => [
|
||||
OrderingTerm.asc(sourceName),
|
||||
OrderingTerm.desc(feedEntries.date),
|
||||
],
|
||||
EntrySort.unread => [
|
||||
// Unread first, whichever way the database orders nulls.
|
||||
OrderingTerm.desc(feedEntries.readAt.isNull()),
|
||||
OrderingTerm.desc(feedEntries.date),
|
||||
],
|
||||
});
|
||||
query.limit(limit);
|
||||
|
||||
return (await query.get()).map((row) {
|
||||
final entry = row.readTable(feedEntries);
|
||||
return RiverEntry(
|
||||
siteUrl: entry.siteUrl,
|
||||
siteTitle: row.readTableOrNull(site)?.title,
|
||||
url: entry.url,
|
||||
title: entry.title,
|
||||
date: entry.date,
|
||||
readAt: entry.readAt,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/// How many posts are unread, for one site or across all of them.
|
||||
Future<int> unreadCount({String? siteUrl}) async {
|
||||
final total = feedEntries.url.count();
|
||||
|
|
@ -371,3 +416,43 @@ class MewsDatabase extends _$MewsDatabase {
|
|||
Future<void> saveCachedPage(CachedPagesCompanion entry) =>
|
||||
into(cachedPages).insert(entry, mode: InsertMode.insertOrReplace);
|
||||
}
|
||||
|
||||
/// How the posts page is ordered.
|
||||
enum EntrySort {
|
||||
date,
|
||||
source,
|
||||
unread;
|
||||
|
||||
/// Reads the order from an address, falling back to the default rather than
|
||||
/// refusing a value the reader may have typed.
|
||||
static EntrySort parse(String? name) => switch (name) {
|
||||
'source' => EntrySort.source,
|
||||
'unread' => EntrySort.unread,
|
||||
_ => EntrySort.date,
|
||||
};
|
||||
}
|
||||
|
||||
/// One post together with the site that published it.
|
||||
class RiverEntry {
|
||||
const RiverEntry({
|
||||
required this.siteUrl,
|
||||
required this.siteTitle,
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.date,
|
||||
required this.readAt,
|
||||
});
|
||||
|
||||
final String siteUrl;
|
||||
final String? siteTitle;
|
||||
final String url;
|
||||
final String title;
|
||||
final DateTime date;
|
||||
final DateTime? readAt;
|
||||
|
||||
bool get unread => readAt == null;
|
||||
|
||||
/// The site as the reader knows it: its title, or its address until one is
|
||||
/// recorded.
|
||||
String get siteName => siteTitle ?? siteUrl;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue