Keep per-kind facts on SourceKind and the Briefing's input in one place (review items 4, 5, 6, 7)
- SourceKind carries whether it feeds the Briefing, its fixed time window (Learning, Fun) and whether reading is picture-led (Fun); windowOf and the reader read from it. - AppState.briefingArticles is the one place that says only News sources feed the Briefing; generateBriefing and the Briefing tab use it. - articlesOf, hiddenCountOf and briefingArticles share one filter. - FeedService.fetchAll takes windowOf: like AppState.windowOf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
49982c5467
commit
246564f1d9
8 files changed
+80
-30
No files matched your search
+17
-12
@@ -82,22 +82,27 @@ class AppState extends ChangeNotifier {
|
||||
(settings.hidePaid && paywall.isPaid(a)) ||
|
||||
(settings.hideSponsored && paywall.isSponsored(a));
|
||||
|
||||
/// Articles from Sources whose kind passes [test] that the paid/sponsored
|
||||
/// filters show, or with [hidden], those they hide.
|
||||
Iterable<Article> _articlesWhere(bool Function(SourceKind kind) test,
|
||||
{bool hidden = false}) =>
|
||||
articles.where((a) => test(a.source.kind) && _isHidden(a) == hidden);
|
||||
|
||||
/// Articles from Sources of [kind] after the paid/sponsored filters. Today
|
||||
/// and the Briefing use News, the Learn tab the other kinds.
|
||||
List<Article> articlesOf(SourceKind kind) =>
|
||||
articles.where((a) => a.source.kind == kind && !_isHidden(a)).toList();
|
||||
/// uses News, the Learn tab the other kinds.
|
||||
List<Article> articlesOf(SourceKind kind) => _articlesWhere((k) => k == kind).toList();
|
||||
|
||||
/// Articles from Sources of [kind] that the paid/sponsored filters hide.
|
||||
int hiddenCountOf(SourceKind kind) =>
|
||||
articles.where((a) => a.source.kind == kind && _isHidden(a)).length;
|
||||
int hiddenCountOf(SourceKind kind) => _articlesWhere((k) => k == kind, hidden: true).length;
|
||||
|
||||
/// What the Briefing is made from: the shown articles of the kinds that
|
||||
/// feed it (News).
|
||||
List<Article> get briefingArticles => _articlesWhere((k) => k.feedsBriefing).toList();
|
||||
|
||||
/// How far back articles from Sources of [kind] reach. News follows the
|
||||
/// user's setting; the other kinds age slower.
|
||||
Duration windowOf(SourceKind kind) => switch (kind) {
|
||||
SourceKind.news => Duration(hours: settings.maxAgeHours),
|
||||
SourceKind.learning => const Duration(days: 14),
|
||||
SourceKind.fun => const Duration(days: 3),
|
||||
};
|
||||
Duration windowOf(SourceKind kind) =>
|
||||
kind.fixedWindow ?? Duration(hours: settings.maxAgeHours);
|
||||
|
||||
List<Source> get allSources => [..._curated, ...customSources];
|
||||
|
||||
@@ -119,7 +124,7 @@ class AppState extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
final result = await _feeds.fetchAll(
|
||||
enabledSources,
|
||||
maxAgeOf: (source) => windowOf(source.kind),
|
||||
windowOf: (source) => windowOf(source.kind),
|
||||
corsProxy: settings.corsProxy,
|
||||
);
|
||||
articles = result.articles;
|
||||
@@ -292,7 +297,7 @@ class AppState extends ChangeNotifier {
|
||||
Future<void> generateBriefing() async {
|
||||
final summarizer = _summarizer;
|
||||
if (summarizer == null || briefingLoading) return;
|
||||
final articles = articlesOf(SourceKind.news);
|
||||
final articles = briefingArticles;
|
||||
if (articles.isEmpty) {
|
||||
briefingError = 'No articles loaded yet. Pull to refresh the feed first.';
|
||||
notifyListeners();
|
||||
|
||||
Reference in new issue
Block a user