enum SourceLanguage { de('Deutsch', '🇩🇪'), en('English', '🇬🇧'); const SourceLanguage(this.label, this.flag); final String label; final String flag; } /// What a Source's articles are for; see GLOSSARY.md. Each kind has its own /// section in the app and its own time window. enum SourceKind { news('News'), learning('Learning'), fun('Fun'); const SourceKind(this.label); final String label; } /// A Source of any [kind]; see GLOSSARY.md. class Source { const Source({ required this.id, required this.name, required this.feedUrl, required this.homepage, required this.language, this.kind = SourceKind.news, this.description = '', this.enabledByDefault = false, this.isCustom = false, this.checkPaywallOnPage = false, }); final String id; final String name; final String feedUrl; final String homepage; final SourceLanguage language; final SourceKind kind; final String description; final bool enabledByDefault; final bool isCustom; /// Paid articles are only marked inside the page (schema.org), not in the /// feed, so each new article page is checked once. final bool checkPaywallOnPage; Map toJson() => { 'id': id, 'name': name, 'feedUrl': feedUrl, 'homepage': homepage, 'language': language.name, 'kind': kind.name, 'description': description, }; factory Source.custom(Map json) => Source( id: json['id'] as String, name: json['name'] as String, feedUrl: json['feedUrl'] as String, homepage: json['homepage'] as String? ?? '', language: SourceLanguage.values.byName(json['language'] as String? ?? 'en'), // Custom sources saved before kinds existed are News sources. kind: SourceKind.values.asNameMap()[json['kind']] ?? SourceKind.news, description: json['description'] as String? ?? '', isCustom: true, ); }