Rename NewsSource to Source now that it models every kind (review item 3)

The class and its file (lib/models/source.dart) follow the glossary term.
Persisted JSON keys are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
CedricandClaude Opus 5.5 committed 2026-10-16 16:03:25 +02:00
1 parent 1a3442ea02
commit a47ff28ed1
33 files changed
+119 -119

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@ import 'package:http/http.dart' as http;
import '../models/article.dart';
import '../models/briefing.dart';
import '../models/news_source.dart';
import '../models/source.dart';
import 'summarizer.dart';
/// Calls the Claude Messages API directly over HTTP (there is no official
+4 -4
View File
@@ -3,13 +3,13 @@ import 'package:html/parser.dart' as html_parser;
import 'package:xml/xml.dart';
import '../models/article.dart';
import '../models/news_source.dart';
import '../models/source.dart';
/// Parses RSS 2.0, RSS 1.0 (RDF) and Atom feeds into [Article]s.
class FeedParser {
static const excerptLength = 400;
static List<Article> parse(String body, NewsSource source) {
static List<Article> parse(String body, Source source) {
final doc = XmlDocument.parse(body);
final root = doc.rootElement;
if (root.name.local == 'feed') {
@@ -27,7 +27,7 @@ class FeedParser {
.toList();
}
static Article? _parseRssItem(XmlElement item, NewsSource source) {
static Article? _parseRssItem(XmlElement item, Source source) {
final title = htmlToText(_text(item, 'title'));
final link = _text(item, 'link').trim().isNotEmpty
? _text(item, 'link').trim()
@@ -53,7 +53,7 @@ class FeedParser {
);
}
static Article? _parseAtomEntry(XmlElement entry, NewsSource source) {
static Article? _parseAtomEntry(XmlElement entry, Source source) {
final title = htmlToText(_text(entry, 'title'));
final links = entry.childElements.where((e) => e.name.local == 'link');
final link = links
+4 -4
View File
@@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import '../models/article.dart';
import '../models/news_source.dart';
import '../models/source.dart';
import 'feed_parser.dart';
class FeedResult {
@@ -30,8 +30,8 @@ class FeedService {
/// [corsProxy] is only used on web, where browsers block cross-origin feed
/// requests. It is prepended to the feed URL, e.g. `https://proxy/?url=`.
Future<FeedResult> fetchAll(
List<NewsSource> sources, {
required Duration Function(NewsSource source) maxAgeOf,
List<Source> sources, {
required Duration Function(Source source) maxAgeOf,
String corsProxy = '',
}) async {
final errors = <String, String>{};
@@ -64,7 +64,7 @@ class FeedService {
return FeedResult(articles, errors);
}
Future<List<Article>> fetchSource(NewsSource source, {String corsProxy = ''}) async {
Future<List<Article>> fetchSource(Source source, {String corsProxy = ''}) async {
final url = kIsWeb && corsProxy.isNotEmpty
? '$corsProxy${Uri.encodeComponent(source.feedUrl)}'
: source.feedUrl;
+1 -1
View File
@@ -4,7 +4,7 @@ import 'package:http/http.dart' as http;
import '../models/article.dart';
import '../models/briefing.dart';
import '../models/news_source.dart';
import '../models/source.dart';
import 'summarizer.dart';
/// Delegates summarizing to an existing n8n workflow via a Webhook trigger.
+4 -4
View File
@@ -9,7 +9,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../models/app_settings.dart';
import '../models/briefing.dart';
import '../models/news_source.dart';
import '../models/source.dart';
/// Persists settings, source selection and the last briefing.
/// The Claude API key goes to the platform keystore, everything else to
@@ -81,15 +81,15 @@ class Storage {
Future<void> saveSeenSourceIds(Set<String> ids) =>
_prefs.setStringList('seen_sources', ids.toList());
List<NewsSource> loadCustomSources() {
List<Source> loadCustomSources() {
final raw = _prefs.getString('custom_sources');
if (raw == null) return [];
return (jsonDecode(raw) as List)
.map((j) => NewsSource.custom(j as Map<String, dynamic>))
.map((j) => Source.custom(j as Map<String, dynamic>))
.toList();
}
Future<void> saveCustomSources(List<NewsSource> sources) => _prefs.setString(
Future<void> saveCustomSources(List<Source> sources) => _prefs.setString(
'custom_sources', jsonEncode(sources.map((s) => s.toJson()).toList()));
/// Article URL -> whether its page said it's paid, and when that was checked.
+1 -1
View File
@@ -1,6 +1,6 @@
import '../models/article.dart';
import '../models/briefing.dart';
import '../models/news_source.dart';
import '../models/source.dart';
class SummarizerException implements Exception {
SummarizerException(this.message);