50 lines
1.8 KiB
Dart
50 lines
1.8 KiB
Dart
import 'package:signals/signals.dart';
|
|
|
|
import '../../database/database.dart';
|
|
import '../../mews/document.dart';
|
|
|
|
/// Which sites the reader subscribes to (spec 6). The posts themselves live in
|
|
/// the database, so an unread post survives a restart; only the set of
|
|
/// addresses is held here, because that is what the chrome watches.
|
|
class SubscriptionsController {
|
|
SubscriptionsController(this._db);
|
|
|
|
final MewsDatabase _db;
|
|
|
|
final subscribedUrls = signal(<String>{});
|
|
|
|
Future<void> load() async {
|
|
final rows = await _db.allSubscriptions();
|
|
subscribedUrls.value = rows.map((row) => row.url).toSet();
|
|
}
|
|
|
|
bool isSubscribed(String url) => subscribedUrls.value.contains(url);
|
|
|
|
Future<void> toggle(MewsPage page) async {
|
|
if (isSubscribed(page.url)) {
|
|
await remove(page.url);
|
|
return;
|
|
}
|
|
await _db.addSubscription(page.url, page.title, page.atomFeedHref);
|
|
subscribedUrls.value = {...subscribedUrls.value, page.url};
|
|
// The posts already on the page are the site's back catalogue, not news,
|
|
// so they are stored read and only later posts are flagged.
|
|
await _db.addEntries(page.url, page.entries, read: true);
|
|
}
|
|
|
|
Future<void> remove(String siteUrl) async {
|
|
await _db.removeSubscription(siteUrl);
|
|
subscribedUrls.value = {...subscribedUrls.value}..remove(siteUrl);
|
|
}
|
|
|
|
/// Records the posts on a subscribed page the reader just opened, and
|
|
/// returns the ones that are new. Does nothing for a site not subscribed to.
|
|
Future<List<MewsEntry>> refreshSite(MewsPage page) async {
|
|
if (!isSubscribed(page.url)) return const [];
|
|
await _db.describeSubscription(page.url,
|
|
title: page.title, atomHref: page.atomFeedHref);
|
|
final fresh = await _db.addEntries(page.url, page.entries);
|
|
await _db.touchSubscription(page.url, DateTime.now());
|
|
return fresh;
|
|
}
|
|
}
|