diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8526f3d3..05998827 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
# Upcoming
+- **feat**: Added a comprehensive **Community & Engagement System**. This major feature introduces the foundational data models, fixtures and tests for user reactions, comments, a multi-entity reporting system, and a smart app review funnel. The entire system is remotely configurable via a new unified `CommunityConfig` model and extends `UserLimitsConfig` to support role-based limits for comments and reports.
+- **BREAKING** refactor!: Overhauled data models and configuration to align with the new identity pivot toward news aggregator. This major refactor introduces a more scalable remote configuration structure, standardizes enums and models for broader use (e.g., `FeedItem` settings), and simplifies ad, notification, and headline data structures for improved clarity and maintainability.
- **feat**: Introduce data models to support a filter-based push notification system. This includes `SavedHeadlineFilter`, `SavedSourceFilter`, and related configuration models, providing the architectural foundation for clients to implement notification subscriptions.
- **BREAKING** refactor!: Rework `UserPreferenceConfig` to support the new notification system with a more scalable, role-based map structure for all user limits.
- **test**: Add comprehensive unit tests for all new and refactored models.
diff --git a/README.md b/README.md
index 534fd001..7a9ac88b 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,27 @@ Provides data structures for persisting all user-specific configurations, from a
+
+💬 Community & Engagement System
+
+---
+
+### 💬 Reactions, Comments & Reporting
+
+Provides a complete suite of models for building a rich community interaction layer. This includes individualized reactions, a robust commenting system with a built-in moderation workflow, and a flexible reporting system for headlines, sources, and comments.
+
+> **Your Advantage:** Foster a vibrant and safe user community, maintain high content quality through effective moderation, and gather direct user feedback on your content.
+
+---
+
+### ⭐ Smart App Review Funnel
+
+Implements the data structures for a strategic, two-layer review funnel. This system intelligently prompts engaged users for public reviews while channeling critical feedback from dissatisfied users into private channels.
+
+> **Your Advantage:** Maximize positive app store ratings and improve your app's reputation by proactively managing user feedback and preventing negative public reviews.
+
+
+
🔔 Notification & Alerting System
diff --git a/lib/src/enums/comment_report_reason.dart b/lib/src/enums/comment_report_reason.dart
new file mode 100644
index 00000000..492c1788
--- /dev/null
+++ b/lib/src/enums/comment_report_reason.dart
@@ -0,0 +1,19 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template comment_report_reason}
+/// Defines the specific reasons a user can provide for reporting a comment.
+/// {@endtemplate}
+@JsonEnum()
+enum CommentReportReason {
+ /// The comment is unsolicited advertising or promotion.
+ @JsonValue('spamOrAdvertising')
+ spamOrAdvertising,
+
+ /// The comment contains abusive language, personal attacks, or bullying.
+ @JsonValue('harassmentOrBullying')
+ harassmentOrBullying,
+
+ /// The comment targets certain groups with hateful language.
+ @JsonValue('hateSpeech')
+ hateSpeech,
+}
diff --git a/lib/src/enums/comment_status.dart b/lib/src/enums/comment_status.dart
new file mode 100644
index 00000000..95fb5a5f
--- /dev/null
+++ b/lib/src/enums/comment_status.dart
@@ -0,0 +1,27 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template comment_status}
+/// Defines the lifecycle status of a user-submitted comment.
+/// {@endtemplate}
+@JsonEnum()
+enum CommentStatus {
+ /// The comment has been submitted and is awaiting moderation.
+ @JsonValue('pendingReview')
+ pendingReview,
+
+ /// The comment has been approved by a moderator and is publicly visible.
+ @JsonValue('approved')
+ approved,
+
+ /// The comment has been rejected by a moderator and is not visible.
+ @JsonValue('rejected')
+ rejected,
+
+ /// The comment has been automatically flagged by an AI moderation service.
+ @JsonValue('flaggedByAI')
+ flaggedByAI,
+
+ /// The comment has been hidden by the user who posted it.
+ @JsonValue('hiddenByUser')
+ hiddenByUser,
+}
diff --git a/lib/src/enums/engageable_type.dart b/lib/src/enums/engageable_type.dart
new file mode 100644
index 00000000..a3f53842
--- /dev/null
+++ b/lib/src/enums/engageable_type.dart
@@ -0,0 +1,12 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template engageable_type}
+/// Defines the types of entities that can be engaged with (reacted to or
+/// commented on).
+/// {@endtemplate}
+@JsonEnum()
+enum EngageableType {
+ /// The engagement is for a news headline.
+ @JsonValue('headline')
+ headline,
+}
diff --git a/lib/src/enums/engagement_mode.dart b/lib/src/enums/engagement_mode.dart
new file mode 100644
index 00000000..ef483c7f
--- /dev/null
+++ b/lib/src/enums/engagement_mode.dart
@@ -0,0 +1,15 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template engagement_mode}
+/// Defines the engagement features available to users.
+/// {@endtemplate}
+@JsonEnum()
+enum EngagementMode {
+ /// Users can only react to headlines.
+ @JsonValue('reactionsOnly')
+ reactionsOnly,
+
+ /// Users can both react and comment on headlines.
+ @JsonValue('reactionsAndComments')
+ reactionsAndComments,
+}
diff --git a/lib/src/enums/enums.dart b/lib/src/enums/enums.dart
index f917dbae..832ba937 100644
--- a/lib/src/enums/enums.dart
+++ b/lib/src/enums/enums.dart
@@ -6,16 +6,25 @@ export 'app_font_weight.dart';
export 'app_text_scale_factor.dart';
export 'app_user_role.dart';
export 'banner_ad_shape.dart';
+export 'comment_report_reason.dart';
+export 'comment_status.dart';
export 'content_status.dart';
export 'content_type.dart';
export 'dashboard_user_role.dart';
export 'device_platform.dart';
+export 'engageable_type.dart';
+export 'engagement_mode.dart';
export 'feed_decorator_category.dart';
export 'feed_decorator_type.dart';
export 'feed_item_click_behavior.dart';
export 'feed_item_density.dart';
export 'feed_item_image_style.dart';
+export 'headline_report_reason.dart';
export 'push_notification_provider.dart';
export 'push_notification_subscription_delivery_type.dart';
+export 'reaction_type.dart';
+export 'report_status.dart';
+export 'reportable_entity.dart';
export 'sort_order.dart';
+export 'source_report_reason.dart';
export 'source_type.dart';
diff --git a/lib/src/enums/headline_report_reason.dart b/lib/src/enums/headline_report_reason.dart
new file mode 100644
index 00000000..462d1311
--- /dev/null
+++ b/lib/src/enums/headline_report_reason.dart
@@ -0,0 +1,32 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template headline_report_reason}
+/// Defines the specific reasons a user can provide for reporting a headline.
+/// {@endtemplate}
+@JsonEnum()
+enum HeadlineReportReason {
+ /// The content is factually incorrect or considered fake news.
+ @JsonValue('misinformationOrFakeNews')
+ misinformationOrFakeNews,
+
+ /// The headline is clickbait or does not reflect the article's content.
+ @JsonValue('clickbaitTitle')
+ clickbaitTitle,
+
+ /// The content contains hate speech, graphic violence, or other inappropriate
+ /// material.
+ @JsonValue('offensiveOrHateSpeech')
+ offensiveOrHateSpeech,
+
+ /// The link leads to advertising, phishing, or fraudulent content.
+ @JsonValue('spamOrScam')
+ spamOrScam,
+
+ /// The article URL does not work.
+ @JsonValue('brokenLink')
+ brokenLink,
+
+ /// The content requires a subscription that was not disclosed.
+ @JsonValue('paywalled')
+ paywalled,
+}
diff --git a/lib/src/enums/reaction_type.dart b/lib/src/enums/reaction_type.dart
new file mode 100644
index 00000000..0015529c
--- /dev/null
+++ b/lib/src/enums/reaction_type.dart
@@ -0,0 +1,38 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template reaction_type}
+/// Defines the types of reactions a user can have to a headline.
+/// {@endtemplate}
+@JsonEnum()
+enum ReactionType {
+ /// Represents a "like" or "thumbs up" reaction.
+ /// General positive approval.
+ @JsonValue('like')
+ like,
+
+ /// Represents an "insightful" or "lightbulb" reaction.
+ /// Signals the article provided new information or a valuable perspective.
+ @JsonValue('insightful')
+ insightful,
+
+ /// Represents an "amusing" or "funny" reaction.
+ /// For lighthearted or humorous content.
+ @JsonValue('amusing')
+ amusing,
+
+ /// Represents a "sad" reaction.
+ /// For news that evokes empathy or sadness.
+ @JsonValue('sad')
+ sad,
+
+ /// Represents an "angry" or "outrageous" reaction.
+ /// For news that provokes a strong negative emotional response.
+ @JsonValue('angry')
+ angry,
+
+ /// Represents a "skeptical" or "questionable" reaction.
+ /// Signals that the user questions the validity, bias, or sourcing of the
+ /// article without formally reporting it.
+ @JsonValue('skeptical')
+ skeptical,
+}
diff --git a/lib/src/enums/report_status.dart b/lib/src/enums/report_status.dart
new file mode 100644
index 00000000..6e0bd3bf
--- /dev/null
+++ b/lib/src/enums/report_status.dart
@@ -0,0 +1,19 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template report_status}
+/// Defines the moderation workflow status for a user-submitted report.
+/// {@endtemplate}
+@JsonEnum()
+enum ReportStatus {
+ /// The report has been submitted by a user and is awaiting review.
+ @JsonValue('submitted')
+ submitted,
+
+ /// A moderator is actively reviewing the report.
+ @JsonValue('inReview')
+ inReview,
+
+ /// The report has been reviewed and a decision has been made.
+ @JsonValue('resolved')
+ resolved,
+}
diff --git a/lib/src/enums/reportable_entity.dart b/lib/src/enums/reportable_entity.dart
new file mode 100644
index 00000000..5417e589
--- /dev/null
+++ b/lib/src/enums/reportable_entity.dart
@@ -0,0 +1,22 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template reportable_entity}
+/// Defines the types of entities that can be reported by users.
+///
+/// This enum acts as a discriminator in the `Report` model to identify
+/// what kind of content the report refers to.
+/// {@endtemplate}
+@JsonEnum()
+enum ReportableEntity {
+ /// The report is for a news headline.
+ @JsonValue('headline')
+ headline,
+
+ /// The report is for a news source.
+ @JsonValue('source')
+ source,
+
+ /// The report is for a user engagement (mainly for engagements with comments).
+ @JsonValue('engagement')
+ engagement,
+}
diff --git a/lib/src/enums/source_report_reason.dart b/lib/src/enums/source_report_reason.dart
new file mode 100644
index 00000000..8c1aa169
--- /dev/null
+++ b/lib/src/enums/source_report_reason.dart
@@ -0,0 +1,30 @@
+import 'package:json_annotation/json_annotation.dart';
+
+/// {@template source_report_reason}
+/// Defines the specific reasons a user can provide for reporting a news source.
+///
+/// These reasons are designed to be actionable and can provide data to
+/// influence other systems, like an automated content scraper's scoring.
+/// {@endtemplate}
+@JsonEnum()
+enum SourceReportReason {
+ /// The source consistently produces poor, biased, or unreliable content.
+ @JsonValue('lowQualityJournalism')
+ lowQualityJournalism,
+
+ /// The source's website is unusable due to excessive ads or popups.
+ @JsonValue('highAdDensity')
+ highAdDensity,
+
+ /// The source often requires a subscription to view content.
+ @JsonValue('frequentPaywalls')
+ frequentPaywalls,
+
+ /// The source is pretending to be another entity.
+ @JsonValue('impersonation')
+ impersonation,
+
+ /// The source has a pattern of publishing fake news or misinformation.
+ @JsonValue('spreadsMisinformation')
+ spreadsMisinformation,
+}
diff --git a/lib/src/fixtures/engagements.dart b/lib/src/fixtures/engagements.dart
new file mode 100644
index 00000000..55d1c4f3
--- /dev/null
+++ b/lib/src/fixtures/engagements.dart
@@ -0,0 +1,152 @@
+import 'package:core/core.dart';
+
+/// Generates a list of predefined engagements for fixture data.
+///
+/// This function can be configured to generate data in either English or
+/// Arabic. It pairs reactions with comments to create realistic engagement
+/// scenarios.
+List getEngagementsFixturesData({
+ String languageCode = 'en',
+ DateTime? now,
+}) {
+ final engagements = [];
+ final users = usersFixturesData.take(10).toList();
+ final headlines = getHeadlinesFixturesData(
+ languageCode: languageCode,
+ ).take(100).toList();
+ final reactions = reactionsFixturesData;
+ final comments = getHeadlineCommentsFixturesData(
+ languageCode: languageCode,
+ now: now,
+ );
+ final referenceTime = now ?? DateTime.now();
+
+ for (var i = 0; i < 10; i++) {
+ for (var j = 0; j < 10; j++) {
+ final index = i * 10 + j;
+ final user = users[i];
+ final headline = headlines[index];
+ final reaction = reactions[index];
+ // Pair every other reaction with a comment for variety
+ final comment = index.isEven ? comments[index] : null;
+
+ engagements.add(
+ Engagement(
+ id: _engagementIds[index],
+ userId: user.id,
+ entityId: headline.id,
+ entityType: EngageableType.headline,
+ reaction: reaction,
+ comment: comment,
+ createdAt: referenceTime.subtract(Duration(days: i, hours: j)),
+ updatedAt: referenceTime.subtract(Duration(days: i, hours: j)),
+ ),
+ );
+ }
+ }
+
+ return engagements;
+}
+
+const _engagementIds = [
+ kEngagementId1,
+ kEngagementId2,
+ kEngagementId3,
+ kEngagementId4,
+ kEngagementId5,
+ kEngagementId6,
+ kEngagementId7,
+ kEngagementId8,
+ kEngagementId9,
+ kEngagementId10,
+ kEngagementId11,
+ kEngagementId12,
+ kEngagementId13,
+ kEngagementId14,
+ kEngagementId15,
+ kEngagementId16,
+ kEngagementId17,
+ kEngagementId18,
+ kEngagementId19,
+ kEngagementId20,
+ kEngagementId21,
+ kEngagementId22,
+ kEngagementId23,
+ kEngagementId24,
+ kEngagementId25,
+ kEngagementId26,
+ kEngagementId27,
+ kEngagementId28,
+ kEngagementId29,
+ kEngagementId30,
+ kEngagementId31,
+ kEngagementId32,
+ kEngagementId33,
+ kEngagementId34,
+ kEngagementId35,
+ kEngagementId36,
+ kEngagementId37,
+ kEngagementId38,
+ kEngagementId39,
+ kEngagementId40,
+ kEngagementId41,
+ kEngagementId42,
+ kEngagementId43,
+ kEngagementId44,
+ kEngagementId45,
+ kEngagementId46,
+ kEngagementId47,
+ kEngagementId48,
+ kEngagementId49,
+ kEngagementId50,
+ kEngagementId51,
+ kEngagementId52,
+ kEngagementId53,
+ kEngagementId54,
+ kEngagementId55,
+ kEngagementId56,
+ kEngagementId57,
+ kEngagementId58,
+ kEngagementId59,
+ kEngagementId60,
+ kEngagementId61,
+ kEngagementId62,
+ kEngagementId63,
+ kEngagementId64,
+ kEngagementId65,
+ kEngagementId66,
+ kEngagementId67,
+ kEngagementId68,
+ kEngagementId69,
+ kEngagementId70,
+ kEngagementId71,
+ kEngagementId72,
+ kEngagementId73,
+ kEngagementId74,
+ kEngagementId75,
+ kEngagementId76,
+ kEngagementId77,
+ kEngagementId78,
+ kEngagementId79,
+ kEngagementId80,
+ kEngagementId81,
+ kEngagementId82,
+ kEngagementId83,
+ kEngagementId84,
+ kEngagementId85,
+ kEngagementId86,
+ kEngagementId87,
+ kEngagementId88,
+ kEngagementId89,
+ kEngagementId90,
+ kEngagementId91,
+ kEngagementId92,
+ kEngagementId93,
+ kEngagementId94,
+ kEngagementId95,
+ kEngagementId96,
+ kEngagementId97,
+ kEngagementId98,
+ kEngagementId99,
+ kEngagementId100,
+];
diff --git a/lib/src/fixtures/fixture_ids.dart b/lib/src/fixtures/fixture_ids.dart
index 32886ae5..c480101e 100644
--- a/lib/src/fixtures/fixture_ids.dart
+++ b/lib/src/fixtures/fixture_ids.dart
@@ -1066,3 +1066,117 @@ const String kInAppNotificationId18 = 'in_app_notification_18';
const String kInAppNotificationId19 = 'in_app_notification_19';
const String kInAppNotificationId20 = 'in_app_notification_20';
const String kInAppNotificationId21 = 'in_app_notification_21';
+
+/// Content Reports Fixture IDs.
+const String kReportId1 = 'rep0000000000000000000001';
+const String kReportId2 = 'rep0000000000000000000002';
+const String kReportId3 = 'rep0000000000000000000003';
+const String kReportId4 = 'rep0000000000000000000004';
+const String kReportId5 = 'rep0000000000000000000005';
+const String kReportId6 = 'rep0000000000000000000006';
+const String kReportId7 = 'rep0000000000000000000007';
+const String kReportId8 = 'rep0000000000000000000008';
+const String kReportId9 = 'rep0000000000000000000009';
+const String kReportId10 = 'rep0000000000000000000010';
+
+/// Engagement Fixture IDs
+const String kEngagementId1 = 'eng0000000000000000000001';
+const String kEngagementId2 = 'eng0000000000000000000002';
+const String kEngagementId3 = 'eng0000000000000000000003';
+const String kEngagementId4 = 'eng0000000000000000000004';
+const String kEngagementId5 = 'eng0000000000000000000005';
+const String kEngagementId6 = 'eng0000000000000000000006';
+const String kEngagementId7 = 'eng0000000000000000000007';
+const String kEngagementId8 = 'eng0000000000000000000008';
+const String kEngagementId9 = 'eng0000000000000000000009';
+const String kEngagementId10 = 'eng0000000000000000000010';
+const String kEngagementId11 = 'eng0000000000000000000011';
+const String kEngagementId12 = 'eng0000000000000000000012';
+const String kEngagementId13 = 'eng0000000000000000000013';
+const String kEngagementId14 = 'eng0000000000000000000014';
+const String kEngagementId15 = 'eng0000000000000000000015';
+const String kEngagementId16 = 'eng0000000000000000000016';
+const String kEngagementId17 = 'eng0000000000000000000017';
+const String kEngagementId18 = 'eng0000000000000000000018';
+const String kEngagementId19 = 'eng0000000000000000000019';
+const String kEngagementId20 = 'eng0000000000000000000020';
+const String kEngagementId21 = 'eng0000000000000000000021';
+const String kEngagementId22 = 'eng0000000000000000000022';
+const String kEngagementId23 = 'eng0000000000000000000023';
+const String kEngagementId24 = 'eng0000000000000000000024';
+const String kEngagementId25 = 'eng0000000000000000000025';
+const String kEngagementId26 = 'eng0000000000000000000026';
+const String kEngagementId27 = 'eng0000000000000000000027';
+const String kEngagementId28 = 'eng0000000000000000000028';
+const String kEngagementId29 = 'eng0000000000000000000029';
+const String kEngagementId30 = 'eng0000000000000000000030';
+const String kEngagementId31 = 'eng0000000000000000000031';
+const String kEngagementId32 = 'eng0000000000000000000032';
+const String kEngagementId33 = 'eng0000000000000000000033';
+const String kEngagementId34 = 'eng0000000000000000000034';
+const String kEngagementId35 = 'eng0000000000000000000035';
+const String kEngagementId36 = 'eng0000000000000000000036';
+const String kEngagementId37 = 'eng0000000000000000000037';
+const String kEngagementId38 = 'eng0000000000000000000038';
+const String kEngagementId39 = 'eng0000000000000000000039';
+const String kEngagementId40 = 'eng0000000000000000000040';
+const String kEngagementId41 = 'eng0000000000000000000041';
+const String kEngagementId42 = 'eng0000000000000000000042';
+const String kEngagementId43 = 'eng0000000000000000000043';
+const String kEngagementId44 = 'eng0000000000000000000044';
+const String kEngagementId45 = 'eng0000000000000000000045';
+const String kEngagementId46 = 'eng0000000000000000000046';
+const String kEngagementId47 = 'eng0000000000000000000047';
+const String kEngagementId48 = 'eng0000000000000000000048';
+const String kEngagementId49 = 'eng0000000000000000000049';
+const String kEngagementId50 = 'eng0000000000000000000050';
+const String kEngagementId51 = 'eng0000000000000000000051';
+const String kEngagementId52 = 'eng0000000000000000000052';
+const String kEngagementId53 = 'eng0000000000000000000053';
+const String kEngagementId54 = 'eng0000000000000000000054';
+const String kEngagementId55 = 'eng0000000000000000000055';
+const String kEngagementId56 = 'eng0000000000000000000056';
+const String kEngagementId57 = 'eng0000000000000000000057';
+const String kEngagementId58 = 'eng0000000000000000000058';
+const String kEngagementId59 = 'eng0000000000000000000059';
+const String kEngagementId60 = 'eng0000000000000000000060';
+const String kEngagementId61 = 'eng0000000000000000000061';
+const String kEngagementId62 = 'eng0000000000000000000062';
+const String kEngagementId63 = 'eng0000000000000000000063';
+const String kEngagementId64 = 'eng0000000000000000000064';
+const String kEngagementId65 = 'eng0000000000000000000065';
+const String kEngagementId66 = 'eng0000000000000000000066';
+const String kEngagementId67 = 'eng0000000000000000000067';
+const String kEngagementId68 = 'eng0000000000000000000068';
+const String kEngagementId69 = 'eng0000000000000000000069';
+const String kEngagementId70 = 'eng0000000000000000000070';
+const String kEngagementId71 = 'eng0000000000000000000071';
+const String kEngagementId72 = 'eng0000000000000000000072';
+const String kEngagementId73 = 'eng0000000000000000000073';
+const String kEngagementId74 = 'eng0000000000000000000074';
+const String kEngagementId75 = 'eng0000000000000000000075';
+const String kEngagementId76 = 'eng0000000000000000000076';
+const String kEngagementId77 = 'eng0000000000000000000077';
+const String kEngagementId78 = 'eng0000000000000000000078';
+const String kEngagementId79 = 'eng0000000000000000000079';
+const String kEngagementId80 = 'eng0000000000000000000080';
+const String kEngagementId81 = 'eng0000000000000000000081';
+const String kEngagementId82 = 'eng0000000000000000000082';
+const String kEngagementId83 = 'eng0000000000000000000083';
+const String kEngagementId84 = 'eng0000000000000000000084';
+const String kEngagementId85 = 'eng0000000000000000000085';
+const String kEngagementId86 = 'eng0000000000000000000086';
+const String kEngagementId87 = 'eng0000000000000000000087';
+const String kEngagementId88 = 'eng0000000000000000000088';
+const String kEngagementId89 = 'eng0000000000000000000089';
+const String kEngagementId90 = 'eng0000000000000000000090';
+const String kEngagementId91 = 'eng0000000000000000000091';
+const String kEngagementId92 = 'eng0000000000000000000092';
+const String kEngagementId93 = 'eng0000000000000000000093';
+const String kEngagementId94 = 'eng0000000000000000000094';
+const String kEngagementId95 = 'eng0000000000000000000095';
+const String kEngagementId96 = 'eng0000000000000000000096';
+const String kEngagementId97 = 'eng0000000000000000000097';
+const String kEngagementId98 = 'eng0000000000000000000098';
+const String kEngagementId99 = 'eng0000000000000000000099';
+const String kEngagementId100 = 'eng0000000000000000000100';
diff --git a/lib/src/fixtures/fixtures.dart b/lib/src/fixtures/fixtures.dart
index 99029356..3ab9ce27 100644
--- a/lib/src/fixtures/fixtures.dart
+++ b/lib/src/fixtures/fixtures.dart
@@ -1,11 +1,15 @@
export 'app_settings.dart';
export 'countries.dart';
export 'dashboard_summary.dart';
+export 'engagements.dart';
export 'fixture_ids.dart';
+export 'headline_comments.dart';
+export 'headline_reactions.dart';
export 'headlines.dart';
export 'in_app_notifications.dart';
export 'languages.dart';
export 'remote_configs.dart';
+export 'reports.dart';
export 'saved_headline_filters.dart';
export 'saved_source_filters.dart';
export 'sources.dart';
diff --git a/lib/src/fixtures/headline_comments.dart b/lib/src/fixtures/headline_comments.dart
new file mode 100644
index 00000000..939c1aae
--- /dev/null
+++ b/lib/src/fixtures/headline_comments.dart
@@ -0,0 +1,76 @@
+import 'package:core/core.dart';
+
+/// A list of predefined comments for fixture data.
+///
+/// This function can be configured to generate comments in either English or
+/// Arabic. It creates 10 comments for each of the first 10 users, with each
+/// comment targeting a unique headline.
+List getHeadlineCommentsFixturesData({
+ String languageCode = 'en',
+ DateTime? now,
+}) {
+ final comments = [];
+ final users = usersFixturesData.take(10).toList();
+
+ // Ensure only approved languages are used, default to 'en'.
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+ final language = languagesFixturesData.firstWhere(
+ (lang) => lang.code == resolvedLanguageCode,
+ orElse: () => languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
+ );
+
+ final commentContentsByLang = >{
+ 'en': [
+ 'This is a really insightful article. It completely changed my perspective.',
+ "I'm not sure I agree with the author's conclusion, but it's a well-argued piece.",
+ 'Finally, someone is talking about this! More people need to read this.',
+ 'A bit simplistic, but a good introduction to the topic for beginners.',
+ 'The data presented here is fascinating. I wonder what the long-term implications are.',
+ 'This is exactly what I was looking for. Thank you for sharing!',
+ 'I have a few questions about the methodology used in this study.',
+ 'This made me laugh out loud. Great writing!',
+ "A powerful and moving story. It's important to hear these voices.",
+ 'I think there are some key facts missing from this analysis.',
+ ],
+ 'ar': [
+ 'هذا مقال ثاقب حقًا. لقد غير وجهة نظري تمامًا.',
+ 'لست متأكدًا من أنني أتفق مع استنتاج المؤلف، لكنها قطعة جيدة الحجة.',
+ 'أخيرًا، هناك من يتحدث عن هذا! المزيد من الناس بحاجة إلى قراءة هذا.',
+ 'مبسط بعض الشيء، لكنه مقدمة جيدة للمبتدئين.',
+ 'البيانات المقدمة هنا رائعة. أتساءل ما هي الآثار طويلة المدى.',
+ 'هذا هو بالضبط ما كنت أبحث عنه. شكرًا لك على المشاركة!',
+ 'لدي بعض الأسئلة حول المنهجية المستخدمة في هذه الدراسة.',
+ 'هذا جعلني أضحك بصوت عال. كتابة رائعة!',
+ 'قصة قوية ومؤثرة. من المهم سماع هذه الأصوات.',
+ 'أعتقد أن هناك بعض الحقائق الأساسية المفقودة من هذا التحليل.',
+ ],
+ };
+
+ final commentContents = commentContentsByLang[resolvedLanguageCode]!;
+
+ for (var i = 0; i < users.length; i++) {
+ for (var j = 0; j < 10; j++) {
+ final commentIndex = i * 10 + j;
+
+ // Vary the status for realism
+ var status = CommentStatus.approved;
+ if (commentIndex % 15 == 0) {
+ status = CommentStatus.pendingReview;
+ } else if (commentIndex % 25 == 0) {
+ status = CommentStatus.rejected;
+ }
+
+ comments.add(
+ Comment(
+ language: language,
+ content: commentContents[j],
+ status: status,
+ ),
+ );
+ }
+ }
+
+ return comments;
+}
diff --git a/lib/src/fixtures/headline_reactions.dart b/lib/src/fixtures/headline_reactions.dart
new file mode 100644
index 00000000..f58a3fe8
--- /dev/null
+++ b/lib/src/fixtures/headline_reactions.dart
@@ -0,0 +1,17 @@
+import 'package:core/core.dart';
+
+/// A list of predefined reactions for fixture data.
+/// This creates a list of reactions with varying types.
+final List reactionsFixturesData = () {
+ final reactions = [];
+ const reactionTypes = ReactionType.values;
+
+ // Create 100 reactions, cycling through the available reaction types.
+ for (var i = 0; i < 100; i++) {
+ reactions.add(
+ Reaction(reactionType: reactionTypes[i % reactionTypes.length]),
+ );
+ }
+
+ return reactions;
+}();
diff --git a/lib/src/fixtures/headlines.dart b/lib/src/fixtures/headlines.dart
index 721179eb..a5e16df5 100644
--- a/lib/src/fixtures/headlines.dart
+++ b/lib/src/fixtures/headlines.dart
@@ -1,1511 +1,186 @@
import 'package:core/src/enums/enums.dart';
import 'package:core/src/fixtures/countries.dart';
import 'package:core/src/fixtures/fixture_ids.dart';
-import 'package:core/src/fixtures/sources.dart';
-import 'package:core/src/fixtures/topics.dart';
+import 'package:core/src/fixtures/sources.dart' as source_fixtures;
+import 'package:core/src/fixtures/topics.dart' as topic_fixtures;
import 'package:core/src/models/entities/headline.dart';
-/// A list of predefined headlines for fixture data.
-final headlinesFixturesData = [
- Headline(
- id: kHeadlineId1,
- isBreaking: false,
- title: 'AI Breakthrough: New Model Achieves Human-Level Performance',
- url: 'https://example.com/news/ai-breakthrough-1',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId1/800/600',
- source: sourcesFixturesData[0], // TechCrunch
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(minutes: 15)),
- updatedAt: DateTime.now().subtract(const Duration(minutes: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId2,
- isBreaking: false,
- title: 'Local Team Wins Championship in Thrilling Final',
- url: 'https://example.com/news/sports-championship-2',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId2/800/600',
- source: sourcesFixturesData[1], // BBC News
- eventCountry: countriesFixturesData[1], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(minutes: 15)),
- updatedAt: DateTime.now().subtract(const Duration(minutes: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId3,
- isBreaking: false,
- title: 'Global Leaders Meet to Discuss Climate Change Policies',
- url: 'https://example.com/news/politics-climate-3',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId3/800/600',
- source: sourcesFixturesData[2], // The New York Times
- eventCountry: countriesFixturesData[2], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(minutes: 15)),
- updatedAt: DateTime.now().subtract(const Duration(minutes: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId4,
- isBreaking: true,
- title: 'New Planet Discovered in Distant Galaxy',
- url: 'https://example.com/news/science-planet-4',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId4/800/600',
- source: sourcesFixturesData[3], // The Guardian
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(minutes: 15)),
- updatedAt: DateTime.now().subtract(const Duration(minutes: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId5,
- isBreaking: false,
- title: 'Breakthrough in Cancer Research Offers New Hope',
- url: 'https://example.com/news/health-cancer-5',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId5/800/600',
- source: sourcesFixturesData[4], // CNN
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(minutes: 15)),
- updatedAt: DateTime.now().subtract(const Duration(minutes: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId6,
- isBreaking: false,
- title: 'Blockbuster Movie Breaks Box Office Records',
- url: 'https://example.com/news/entertainment-movie-6',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId6/800/600',
- source: sourcesFixturesData[5], // Reuters
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 1)),
- updatedAt: DateTime.now().subtract(const Duration(days: 1)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId7,
- isBreaking: false,
- title: 'Stock Market Reaches All-Time High Amid Economic Boom',
- url: 'https://example.com/news/business-market-7',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId7/800/600',
- source: sourcesFixturesData[6], // Al Jazeera English
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 1)),
- updatedAt: DateTime.now().subtract(const Duration(days: 1)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId8,
- isBreaking: false,
- title: 'New Travel Restrictions Lifted for Popular Destinations',
- url: 'https://example.com/news/travel-restrictions-8',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId8/800/600',
- source: sourcesFixturesData[7], // Xinhua News Agency
- eventCountry: countriesFixturesData[7], // China
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 1)),
- updatedAt: DateTime.now().subtract(const Duration(days: 1)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId9,
- isBreaking: false,
- title: 'Michelin Star Chef Opens New Restaurant in City Center',
- url: 'https://example.com/news/food-restaurant-9',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId9/800/600',
- source: sourcesFixturesData[8], // The Times of India
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 1)),
- updatedAt: DateTime.now().subtract(const Duration(days: 1)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId10,
- isBreaking: false,
- title: 'Innovative Teaching Methods Boost Student Engagement',
- url: 'https://example.com/news/education-methods-10',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId10/800/600',
- source: sourcesFixturesData[9], // Folha de S.Paulo
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[9], // Education
- createdAt: DateTime.now().subtract(const Duration(days: 1)),
- updatedAt: DateTime.now().subtract(const Duration(days: 1)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId11,
- isBreaking: false,
- title: 'Cybersecurity Firms Warn of New Global Threat',
- url: 'https://example.com/news/cybersecurity-threat-11',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId11/800/600',
- source: sourcesFixturesData[0], // TechCrunch
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 2)),
- updatedAt: DateTime.now().subtract(const Duration(days: 2)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId12,
- isBreaking: false,
- title: 'Olympics Committee Announces Host City for 2032 Games',
- url: 'https://example.com/news/sports-olympics-12',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId12/800/600',
- source: sourcesFixturesData[1], // BBC News
- eventCountry: countriesFixturesData[1], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 2)),
- updatedAt: DateTime.now().subtract(const Duration(days: 2)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId13,
- isBreaking: false,
- title: 'New Bill Aims to Reform Healthcare System',
- url: 'https://example.com/news/politics-healthcare-13',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId13/800/600',
- source: sourcesFixturesData[2], // The New York Times
- eventCountry: countriesFixturesData[2], // Canada
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 2)),
- updatedAt: DateTime.now().subtract(const Duration(days: 2)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId14,
- isBreaking: false,
- title: 'Archaeologists Uncover Ancient City Ruins',
- url: 'https://example.com/news/science-archaeology-14',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId14/800/600',
- source: sourcesFixturesData[3], // The Guardian
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(days: 2)),
- updatedAt: DateTime.now().subtract(const Duration(days: 2)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId15,
- isBreaking: false,
- title: 'Dietary Guidelines Updated for Public Health',
- url: 'https://example.com/news/health-diet-15',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId15/800/600',
- source: sourcesFixturesData[4], // CNN
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 2)),
- updatedAt: DateTime.now().subtract(const Duration(days: 2)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId16,
- isBreaking: false,
- title: 'Music Festival Announces Star-Studded Lineup',
- url: 'https://example.com/news/entertainment-music-16',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId16/800/600',
- source: sourcesFixturesData[5], // Reuters
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 3)),
- updatedAt: DateTime.now().subtract(const Duration(days: 3)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId17,
- isBreaking: false,
- title: 'Tech Giant Acquires Startup in Multi-Billion Dollar Deal',
- url: 'https://example.com/news/business-acquisition-17',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId17/800/600',
- source: sourcesFixturesData[6], // Al Jazeera English
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 3)),
- updatedAt: DateTime.now().subtract(const Duration(days: 3)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId18,
- isBreaking: false,
- title: 'Space Tourism Takes Off: First Commercial Flights Announced',
- url: 'https://example.com/news/travel-space-18',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId18/800/600',
- source: sourcesFixturesData[7], // Xinhua News Agency
- eventCountry: countriesFixturesData[7], // China
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 3)),
- updatedAt: DateTime.now().subtract(const Duration(days: 3)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId19,
- isBreaking: false,
- title: 'Future of Food: Lab-Grown Meat Gains Popularity',
- url: 'https://example.com/news/food-lab-meat-19',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId19/800/600',
- source: sourcesFixturesData[8], // The Times of India
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 3)),
- updatedAt: DateTime.now().subtract(const Duration(days: 3)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId20,
- isBreaking: false,
- title: 'Online Learning Platforms See Surge in Enrollment',
- url: 'https://example.com/news/education-online-20',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId20/800/600',
- source: sourcesFixturesData[9], // Folha de S.Paulo
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[9], // Education
- createdAt: DateTime.now().subtract(const Duration(days: 3)),
- updatedAt: DateTime.now().subtract(const Duration(days: 3)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId21,
- isBreaking: false,
- title: 'Quantum Computing Achieves New Milestone',
- url: 'https://example.com/news/tech-quantum-21',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId21/800/600',
- source: sourcesFixturesData[0], // TechCrunch
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 4)),
- updatedAt: DateTime.now().subtract(const Duration(days: 4)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId22,
- isBreaking: false,
- title: 'World Cup Qualifiers: Unexpected Upsets Shake Rankings',
- url: 'https://example.com/news/sports-worldcup-22',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId22/800/600',
- source: sourcesFixturesData[1], // BBC News
- eventCountry: countriesFixturesData[1], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 4)),
- updatedAt: DateTime.now().subtract(const Duration(days: 4)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId23,
- isBreaking: false,
- title: 'Election Results: New Government Takes Power',
- url: 'https://example.com/news/politics-election-23',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId23/800/600',
- source: sourcesFixturesData[2], // The New York Times
- eventCountry: countriesFixturesData[2], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 4)),
- updatedAt: DateTime.now().subtract(const Duration(days: 4)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId24,
- isBreaking: false,
- title: 'Breakthrough in Fusion Energy Research Announced',
- url: 'https://example.com/news/science-fusion-24',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId24/800/600',
- source: sourcesFixturesData[3], // The Guardian
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(days: 4)),
- updatedAt: DateTime.now().subtract(const Duration(days: 4)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId25,
- isBreaking: false,
- title: 'Mental Health Awareness Campaign Launched Globally',
- url: 'https://example.com/news/health-mental-25',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId25/800/600',
- source: sourcesFixturesData[4], // CNN
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 4)),
- updatedAt: DateTime.now().subtract(const Duration(days: 4)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId26,
- isBreaking: false,
- title: 'Gaming Industry Sees Record Growth in Virtual Reality',
- url: 'https://example.com/news/entertainment-vr-26',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId26/800/600',
- source: sourcesFixturesData[5], // Reuters
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 5)),
- updatedAt: DateTime.now().subtract(const Duration(days: 5)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId27,
- isBreaking: false,
- title: 'Global Supply Chain Disruptions Impacting Consumer Goods',
- url: 'https://example.com/news/business-supplychain-27',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId27/800/600',
- source: sourcesFixturesData[6], // Al Jazeera English
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 5)),
- updatedAt: DateTime.now().subtract(const Duration(days: 5)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId28,
- isBreaking: false,
- title: 'Arctic Expedition Discovers New Marine Species',
- url: 'https://example.com/news/travel-arctic-28',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId28/800/600',
- source: sourcesFixturesData[7], // Xinhua News Agency
- eventCountry: countriesFixturesData[7], // China
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 5)),
- updatedAt: DateTime.now().subtract(const Duration(days: 5)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId29,
- isBreaking: false,
- title: 'Rise of Plant-Based Cuisine: New Restaurants Open',
- url: 'https://example.com/news/food-plantbased-29',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId29/800/600',
- source: sourcesFixturesData[8], // The Times of India
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 5)),
- updatedAt: DateTime.now().subtract(const Duration(days: 5)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId30,
- isBreaking: false,
- title: 'Education Technology Transforms Classrooms',
- url: 'https://example.com/news/education-edtech-30',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId30/800/600',
- source: sourcesFixturesData[9], // Folha de S.Paulo
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[9], // Education
- createdAt: DateTime.now().subtract(const Duration(days: 5)),
- updatedAt: DateTime.now().subtract(const Duration(days: 5)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId31,
- isBreaking: false,
- title: 'SpaceX Launches New Satellite Constellation',
- url: 'https://example.com/news/tech-spacex-31',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId31/800/600',
- source: sourcesFixturesData[0], // TechCrunch
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 6)),
- updatedAt: DateTime.now().subtract(const Duration(days: 6)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId32,
- isBreaking: false,
- title: 'Football Legend Announces Retirement',
- url: 'https://example.com/news/sports-retirement-32',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId32/800/600',
- source: sourcesFixturesData[1], // BBC News
- eventCountry: countriesFixturesData[1], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 6)),
- updatedAt: DateTime.now().subtract(const Duration(days: 6)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId33,
- isBreaking: false,
- title: 'G7 Summit Concludes with Joint Statement on Global Economy',
- url: 'https://example.com/news/politics-g7-33',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId33/800/600',
- source: sourcesFixturesData[2], // The New York Times
- eventCountry: countriesFixturesData[2], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 6)),
- updatedAt: DateTime.now().subtract(const Duration(days: 6)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId34,
- isBreaking: false,
- title: "Breakthrough in Alzheimer's Research Offers New Treatment Path",
- url: 'https://example.com/news/science-alzheimers-34',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId34/800/600',
- source: sourcesFixturesData[3], // The Guardian
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 6)),
- updatedAt: DateTime.now().subtract(const Duration(days: 6)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId35,
- isBreaking: false,
- title: 'Global Vaccination Campaign Reaches Billions',
- url: 'https://example.com/news/health-vaccine-35',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId35/800/600',
- source: sourcesFixturesData[4], // CNN
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 6)),
- updatedAt: DateTime.now().subtract(const Duration(days: 6)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId36,
- isBreaking: false,
- title: 'Streaming Wars Intensify with New Platform Launches',
- url: 'https://example.com/news/entertainment-streaming-36',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId36/800/600',
- source: sourcesFixturesData[5], // Reuters
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 7)),
- updatedAt: DateTime.now().subtract(const Duration(days: 7)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId37,
- isBreaking: false,
- title: 'Cryptocurrency Market Experiences Major Volatility',
- url: 'https://example.com/news/business-crypto-37',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId37/800/600',
- source: sourcesFixturesData[6], // Al Jazeera English
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 7)),
- updatedAt: DateTime.now().subtract(const Duration(days: 7)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId38,
- isBreaking: false,
- title: 'Sustainable Tourism Initiatives Gain Momentum',
- url: 'https://example.com/news/travel-sustainable-38',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId38/800/600',
- source: sourcesFixturesData[7], // Xinhua News Agency
- eventCountry: countriesFixturesData[7], // China
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 7)),
- updatedAt: DateTime.now().subtract(const Duration(days: 7)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId39,
- isBreaking: false,
- title: 'Food Security Summit Addresses Global Hunger',
- url: 'https://example.com/news/food-security-39',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId39/800/600',
- source: sourcesFixturesData[8], // The Times of India
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 7)),
- updatedAt: DateTime.now().subtract(const Duration(days: 7)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId40,
- isBreaking: false,
- title: 'Robotics in Education: New Tools for Learning',
- url: 'https://example.com/news/education-robotics-40',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId40/800/600',
- source: sourcesFixturesData[9], // Folha de S.Paulo
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[9], // Education
- createdAt: DateTime.now().subtract(const Duration(days: 7)),
- updatedAt: DateTime.now().subtract(const Duration(days: 7)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId41,
- isBreaking: false,
- title: 'AI Ethics Debate Intensifies Among Tech Leaders',
- url: 'https://example.com/news/tech-ethics-41',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId41/800/600',
- source: sourcesFixturesData[0], // TechCrunch
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 8)),
- updatedAt: DateTime.now().subtract(const Duration(days: 8)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId42,
- isBreaking: false,
- title: 'Esports Industry Sees Massive Investment Boom',
- url: 'https://example.com/news/sports-esports-42',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId42/800/600',
- source: sourcesFixturesData[1], // BBC News
- eventCountry: countriesFixturesData[1], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 8)),
- updatedAt: DateTime.now().subtract(const Duration(days: 8)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId43,
- isBreaking: false,
- title: 'International Sanctions Imposed on Rogue State',
- url: 'https://example.com/news/politics-sanctions-43',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId43/800/600',
- source: sourcesFixturesData[2], // The New York Times
- eventCountry: countriesFixturesData[2], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 8)),
- updatedAt: DateTime.now().subtract(const Duration(days: 8)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId44,
- isBreaking: false,
- title: 'New Species of Deep-Sea Creature Discovered',
- url: 'https://example.com/news/science-deepsea-44',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId44/800/600',
- source: sourcesFixturesData[3], // The Guardian
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(days: 8)),
- updatedAt: DateTime.now().subtract(const Duration(days: 8)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId45,
- isBreaking: false,
- title: 'Global Health Crisis: New Pandemic Preparedness Plan',
- url: 'https://example.com/news/health-pandemic-45',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId45/800/600',
- source: sourcesFixturesData[4], // CNN
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 8)),
- updatedAt: DateTime.now().subtract(const Duration(days: 8)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId46,
- isBreaking: false,
- title: 'Hollywood Strikes Continue: Impact on Film Production',
- url: 'https://example.com/news/entertainment-strikes-46',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId46/800/600',
- source: sourcesFixturesData[5], // Reuters
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 9)),
- updatedAt: DateTime.now().subtract(const Duration(days: 9)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId47,
- isBreaking: false,
- title: 'Emerging Markets Show Strong Economic Resilience',
- url: 'https://example.com/news/business-emerging-47',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId47/800/600',
- source: sourcesFixturesData[6], // Al Jazeera English
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 9)),
- updatedAt: DateTime.now().subtract(const Duration(days: 9)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId48,
- isBreaking: false,
- title: 'Adventure Tourism Booms in Remote Regions',
- url: 'https://example.com/news/travel-adventure-48',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId48/800/600',
- source: sourcesFixturesData[7], // Xinhua News Agency
- eventCountry: countriesFixturesData[7], // China
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 9)),
- updatedAt: DateTime.now().subtract(const Duration(days: 9)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId49,
- isBreaking: false,
- title: 'The Rise of Sustainable Food Packaging',
- url: 'https://example.com/news/food-packaging-49',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId49/800/600',
- source: sourcesFixturesData[8], // The Times of India
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 9)),
- updatedAt: DateTime.now().subtract(const Duration(days: 9)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId50,
- isBreaking: false,
- title: 'Personalized Learning: Tailoring Education to Individual Needs',
- url: 'https://example.com/news/education-personalized-50',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId50/800/600',
- source: sourcesFixturesData[9], // Folha de S.Paulo
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[9], // Education
- createdAt: DateTime.now().subtract(const Duration(days: 9)),
- updatedAt: DateTime.now().subtract(const Duration(days: 9)),
- status: ContentStatus.active,
- ),
+/// Generates a list of predefined headlines for fixture data.
+///
+/// This function can be configured to generate headlines in either English or
+/// Arabic.
+List getHeadlinesFixturesData({
+ String languageCode = 'en',
+ DateTime? now,
+}) {
+ // Ensure only approved languages are used, default to 'en'.
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+ final referenceTime = now ?? DateTime.now();
- // --- Headlines for New Sources (5 per source) ---
+ final sources = source_fixtures.getSourcesFixturesData(
+ languageCode: resolvedLanguageCode,
+ );
+ final topics = topic_fixtures.getTopicsFixturesData(
+ languageCode: resolvedLanguageCode,
+ );
- // --- Local News Outlets (kSourceId11 - kSourceId20) ---
- Headline(
- id: kHeadlineId51,
- isBreaking: false,
- title: 'City Council Approves New Downtown Development Plan',
- url: 'https://example.com/news/sf-downtown-plan',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId51/800/600', // San Francisco Chronicle
- source: sourcesFixturesData[10], // San Francisco Chronicle
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 10)),
- updatedAt: DateTime.now().subtract(const Duration(days: 10)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId52,
- isBreaking: false,
- title: 'Tech Startups Flourish in the Bay Area',
- url: 'https://example.com/news/sf-tech-boom',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId52/800/600', // San Francisco Chronicle
- source: sourcesFixturesData[10], // San Francisco Chronicle
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 10)),
- updatedAt: DateTime.now().subtract(const Duration(days: 10)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId53,
- isBreaking: false,
- title: 'Golden Gate Bridge Retrofit Project Begins',
- url: 'https://example.com/news/ggb-retrofit',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId53/800/600', // San Francisco Chronicle
- source: sourcesFixturesData[10], // San Francisco Chronicle
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 11)),
- updatedAt: DateTime.now().subtract(const Duration(days: 11)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId54,
- isBreaking: false,
- title: 'Local Chef Wins Prestigious Culinary Award',
- url: 'https://example.com/news/sf-chef-award',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId54/800/600', // San Francisco Chronicle
- source: sourcesFixturesData[10], // San Francisco Chronicle
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 11)),
- updatedAt: DateTime.now().subtract(const Duration(days: 11)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId55,
- isBreaking: false,
- title: 'Warriors Secure Victory in Season Opener',
- url: 'https://example.com/news/warriors-win',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId55/800/600', // San Francisco Chronicle
- source: sourcesFixturesData[10], // San Francisco Chronicle
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 12)),
- updatedAt: DateTime.now().subtract(const Duration(days: 12)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId56,
- isBreaking: false,
- title: 'Manchester United Announces New Stadium Expansion Plans',
- url: 'https://example.com/news/mu-stadium-expansion',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId56/800/600', // Manchester Evening News
- source: sourcesFixturesData[11], // Manchester Evening News
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 12)),
- updatedAt: DateTime.now().subtract(const Duration(days: 12)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId57,
- isBreaking: false,
- title: 'New Tram Line Opens in Greater Manchester',
- url: 'https://example.com/news/manchester-tram-line',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId57/800/600', // Manchester Evening News
- source: sourcesFixturesData[11], // Manchester Evening News
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 13)),
- updatedAt: DateTime.now().subtract(const Duration(days: 13)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId58,
- isBreaking: false,
- title: 'Manchester Tech Hub Attracts Global Talent',
- url: 'https://example.com/news/manchester-tech-hub',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId58/800/600', // Manchester Evening News
- source: sourcesFixturesData[11], // Manchester Evening News
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 13)),
- updatedAt: DateTime.now().subtract(const Duration(days: 13)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId59,
- isBreaking: false,
- title: 'Coronation Street Filming Causes Local Buzz',
- url: 'https://example.com/news/corrie-filming',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId59/800/600', // Manchester Evening News
- source: sourcesFixturesData[11], // Manchester Evening News
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 14)),
- updatedAt: DateTime.now().subtract(const Duration(days: 14)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId60,
- isBreaking: false,
- title: 'Council Debates Clean Air Zone Implementation',
- url: 'https://example.com/news/manc-caz-debate',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId60/800/600', // Manchester Evening News
- source: sourcesFixturesData[11], // Manchester Evening News
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 14)),
- updatedAt: DateTime.now().subtract(const Duration(days: 14)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId61,
- isBreaking: false,
- title: 'Sydney Opera House Announces New Season Lineup',
- url: 'https://example.com/news/sydney-opera-season',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId61/800/600', // The Sydney Morning Herald
- source: sourcesFixturesData[12], // The Sydney Morning Herald
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 15)),
- updatedAt: DateTime.now().subtract(const Duration(days: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId62,
- isBreaking: false,
- title: 'Housing Prices in Sydney Continue to Climb',
- url: 'https://example.com/news/sydney-housing-prices',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId62/800/600', // The Sydney Morning Herald
- source: sourcesFixturesData[12], // The Sydney Morning Herald
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 15)),
- updatedAt: DateTime.now().subtract(const Duration(days: 15)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId63,
- isBreaking: false,
- title: 'NSW Government Unveils New Infrastructure Projects',
- url: 'https://example.com/news/nsw-infrastructure',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId63/800/600', // The Sydney Morning Herald
- source: sourcesFixturesData[12], // The Sydney Morning Herald
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 16)),
- updatedAt: DateTime.now().subtract(const Duration(days: 16)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId64,
- isBreaking: false,
- title: 'Swans Triumph in AFL Derby Match',
- url: 'https://example.com/news/swans-afl-win',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId64/800/600', // The Sydney Morning Herald
- source: sourcesFixturesData[12], // The Sydney Morning Herald
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 16)),
- updatedAt: DateTime.now().subtract(const Duration(days: 16)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId65,
- isBreaking: false,
- title: 'Bondi Beach Erosion Concerns Prompt Action',
- url: 'https://example.com/news/bondi-erosion',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId65/800/600', // The Sydney Morning Herald
- source: sourcesFixturesData[12], // The Sydney Morning Herald
- eventCountry: countriesFixturesData[3], // Australia
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(days: 17)),
- updatedAt: DateTime.now().subtract(const Duration(days: 17)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId66,
- isBreaking: false,
- title: 'Paris Metro Expansion: New Stations Opened',
- url: 'https://example.com/news/paris-metro-expansion',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId66/800/600', // Le Parisien
- source: sourcesFixturesData[13], // Le Parisien
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 17)),
- updatedAt: DateTime.now().subtract(const Duration(days: 17)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId67,
- isBreaking: false,
- title: 'Louvre Museum Unveils New Egyptian Antiquities Wing',
- url: 'https://example.com/news/louvre-egyptian-wing',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId67/800/600', // Le Parisien
- source: sourcesFixturesData[13], // Le Parisien
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 18)),
- updatedAt: DateTime.now().subtract(const Duration(days: 18)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId68,
- isBreaking: false,
- title: 'Paris Saint-Germain Secures Ligue 1 Title',
- url: 'https://example.com/news/psg-ligue1-title',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId68/800/600', // Le Parisien
- source: sourcesFixturesData[13], // Le Parisien
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 18)),
- updatedAt: DateTime.now().subtract(const Duration(days: 18)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId69,
- isBreaking: false,
- title: 'Mayor of Paris Announces New Green Initiatives',
- url: 'https://example.com/news/paris-green-initiatives',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId69/800/600', // Le Parisien
- source: sourcesFixturesData[13], // Le Parisien
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 19)),
- updatedAt: DateTime.now().subtract(const Duration(days: 19)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId70,
- isBreaking: false,
- title: 'Paris Fashion Week Highlights New Trends',
- url: 'https://example.com/news/paris-fashion-week',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId70/800/600', // Le Parisien
- source: sourcesFixturesData[13], // Le Parisien
- eventCountry: countriesFixturesData[5], // France
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 19)),
- updatedAt: DateTime.now().subtract(const Duration(days: 19)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId71,
- isBreaking: false,
- title: 'Toronto Raptors Make Key Trade Ahead of Deadline',
- url: 'https://example.com/news/raptors-trade',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId71/800/600', // The Toronto Star
- source: sourcesFixturesData[14], // The Toronto Star
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 20)),
- updatedAt: DateTime.now().subtract(const Duration(days: 20)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId72,
- isBreaking: false,
- title: 'TTC Announces Service Changes for Summer',
- url: 'https://example.com/news/ttc-summer-changes',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId72/800/600', // The Toronto Star
- source: sourcesFixturesData[14], // The Toronto Star
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 20)),
- updatedAt: DateTime.now().subtract(const Duration(days: 20)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId73,
- isBreaking: false,
- title: 'Toronto International Film Festival (TIFF) Lineup Revealed',
- url: 'https://example.com/news/tiff-lineup',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId73/800/600', // The Toronto Star
- source: sourcesFixturesData[14], // The Toronto Star
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 21)),
- updatedAt: DateTime.now().subtract(const Duration(days: 21)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId74,
- isBreaking: false,
- title: 'City of Toronto Grapples with Housing Affordability',
- url: 'https://example.com/news/toronto-housing-crisis',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId74/800/600', // The Toronto Star
- source: sourcesFixturesData[14], // The Toronto Star
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 21)),
- updatedAt: DateTime.now().subtract(const Duration(days: 21)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId75,
- isBreaking: false,
- title: 'New Waterfront Development Project Approved',
- url: 'https://example.com/news/toronto-waterfront-project',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId75/800/600', // The Toronto Star
- source: sourcesFixturesData[14], // The Toronto Star
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 22)),
- updatedAt: DateTime.now().subtract(const Duration(days: 22)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId76,
- isBreaking: false,
- title: 'Berlin Philharmonic Announces New Conductor',
- url: 'https://example.com/news/berlin-phil-conductor',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId76/800/600', // Berliner Morgenpost
- source: sourcesFixturesData[15], // Berliner Morgenpost
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 22)),
- updatedAt: DateTime.now().subtract(const Duration(days: 22)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId77,
- isBreaking: false,
- title: 'Remnants of Berlin Wall Unearthed During Construction',
- url: 'https://example.com/news/berlin-wall-discovery',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId77/800/600', // Berliner Morgenpost
- source: sourcesFixturesData[15], // Berliner Morgenpost
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[3], // Science
- createdAt: DateTime.now().subtract(const Duration(days: 23)),
- updatedAt: DateTime.now().subtract(const Duration(days: 23)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId78,
- isBreaking: false,
- title: 'Hertha BSC Faces Relegation Battle',
- url: 'https://example.com/news/hertha-bsc-relegation',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId78/800/600', // Berliner Morgenpost
- source: sourcesFixturesData[15], // Berliner Morgenpost
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 23)),
- updatedAt: DateTime.now().subtract(const Duration(days: 23)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId79,
- isBreaking: false,
- title: 'Berlin Senate Approves Rent Control Measures',
- url: 'https://example.com/news/berlin-rent-control',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId79/800/600', // Berliner Morgenpost
- source: sourcesFixturesData[15], // Berliner Morgenpost
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 24)),
- updatedAt: DateTime.now().subtract(const Duration(days: 24)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId80,
- isBreaking: false,
- title: 'Brandenburg Airport Reports Record Passenger Numbers',
- url: 'https://example.com/news/ber-airport-record',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId80/800/600', // Berliner Morgenpost
- source: sourcesFixturesData[15], // Berliner Morgenpost
- eventCountry: countriesFixturesData[4], // Germany
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 24)),
- updatedAt: DateTime.now().subtract(const Duration(days: 24)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId81,
- isBreaking: false,
- title: 'Tokyo Government Tackles Aging Population Issues',
- url: 'https://example.com/news/tokyo-aging-population',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId81/800/600', // The Asahi Shimbun (Tokyo)
- source: sourcesFixturesData[16], // The Asahi Shimbun (Tokyo)
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 25)),
- updatedAt: DateTime.now().subtract(const Duration(days: 25)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId82,
- isBreaking: false,
- title: 'New Shinkansen Line to Connect Tokyo and Tsuruga',
- url: 'https://example.com/news/shinkansen-extension',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId82/800/600', // The Asahi Shimbun (Tokyo)
- source: sourcesFixturesData[16], // The Asahi Shimbun (Tokyo)
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 25)),
- updatedAt: DateTime.now().subtract(const Duration(days: 25)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId83,
- isBreaking: false,
- title: 'Yomiuri Giants Clinch Central League Pennant',
- url: 'https://example.com/news/giants-win-pennant',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId83/800/600', // The Asahi Shimbun (Tokyo)
- source: sourcesFixturesData[16], // The Asahi Shimbun (Tokyo)
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 26)),
- updatedAt: DateTime.now().subtract(const Duration(days: 26)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId84,
- isBreaking: false,
- title: 'Studio Ghibli Announces New Film Project',
- url: 'https://example.com/news/ghibli-new-film',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId84/800/600', // The Asahi Shimbun (Tokyo)
- source: sourcesFixturesData[16], // The Asahi Shimbun (Tokyo)
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 26)),
- updatedAt: DateTime.now().subtract(const Duration(days: 26)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId85,
- isBreaking: false,
- title: "Tokyo's Tsukiji Outer Market Thrives After Relocation",
- url: 'https://example.com/news/tsukiji-market-thrives',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId85/800/600', // The Asahi Shimbun (Tokyo)
- source: sourcesFixturesData[16], // The Asahi Shimbun (Tokyo)
- eventCountry: countriesFixturesData[6], // Japan
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 27)),
- updatedAt: DateTime.now().subtract(const Duration(days: 27)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId86,
- isBreaking: false,
- title: 'Mumbai Metro Expands with New Aqua Line',
- url: 'https://example.com/news/mumbai-metro-aqua-line',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId86/800/600', // Hindustan Times (Mumbai)
- source: sourcesFixturesData[17], // Hindustan Times (Mumbai)
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 27)),
- updatedAt: DateTime.now().subtract(const Duration(days: 27)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId87,
- isBreaking: false,
- title: 'Bollywood Film Shoots Bring Stars to Mumbai Streets',
- url: 'https://example.com/news/bollywood-mumbai-shoots',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId87/800/600', // Hindustan Times (Mumbai)
- source: sourcesFixturesData[17], // Hindustan Times (Mumbai)
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 28)),
- updatedAt: DateTime.now().subtract(const Duration(days: 28)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId88,
- isBreaking: false,
- title: 'Mumbai Indians Gear Up for IPL Season',
- url: 'https://example.com/news/mumbai-indians-ipl',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId88/800/600', // Hindustan Times (Mumbai)
- source: sourcesFixturesData[17], // Hindustan Times (Mumbai)
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 28)),
- updatedAt: DateTime.now().subtract(const Duration(days: 28)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId89,
- isBreaking: false,
- title: 'BMC Tackles Monsoon Preparedness in Mumbai',
- url: 'https://example.com/news/bmc-monsoon-prep',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId89/800/600', // Hindustan Times (Mumbai)
- source: sourcesFixturesData[17], // Hindustan Times (Mumbai)
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 29)),
- updatedAt: DateTime.now().subtract(const Duration(days: 29)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId90,
- isBreaking: false,
- title: "Mumbai's Financial District Sees New Investments",
- url: 'https://example.com/news/mumbai-bkc-investments',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId90/800/600', // Hindustan Times (Mumbai)
- source: sourcesFixturesData[17], // Hindustan Times (Mumbai)
- eventCountry: countriesFixturesData[8], // India
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 29)),
- updatedAt: DateTime.now().subtract(const Duration(days: 29)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId91,
- isBreaking: false,
- title: 'Rio Carnival Preparations in Full Swing',
- url: 'https://example.com/news/rio-carnival-prep',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId91/800/600', // O Globo (Rio de Janeiro)
- source: sourcesFixturesData[18], // O Globo (Rio de Janeiro)
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 30)),
- updatedAt: DateTime.now().subtract(const Duration(days: 30)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId92,
- isBreaking: false,
- title: 'Flamengo Wins Key Match at Maracanã Stadium',
- url: 'https://example.com/news/flamengo-maracana-win',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId92/800/600', // O Globo (Rio de Janeiro)
- source: sourcesFixturesData[18], // O Globo (Rio de Janeiro)
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 30)),
- updatedAt: DateTime.now().subtract(const Duration(days: 30)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId93,
- isBreaking: false,
- title: 'Security Boosted in Rio Ahead of Major Summit',
- url: 'https://example.com/news/rio-security-boost',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId93/800/600', // O Globo (Rio de Janeiro)
- source: sourcesFixturesData[18], // O Globo (Rio de Janeiro)
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 31)),
- updatedAt: DateTime.now().subtract(const Duration(days: 31)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId94,
- isBreaking: false,
- title: 'Sugarloaf Mountain Cable Car Undergoes Modernization',
- url: 'https://example.com/news/sugarloaf-cable-car-update',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId94/800/600', // O Globo (Rio de Janeiro)
- source: sourcesFixturesData[18], // O Globo (Rio de Janeiro)
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 31)),
- updatedAt: DateTime.now().subtract(const Duration(days: 31)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId95,
- isBreaking: false,
- title: "Bossa Nova Festival Celebrates Rio's Musical Heritage",
- url: 'https://example.com/news/bossa-nova-festival',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId95/800/600', // O Globo (Rio de Janeiro)
- source: sourcesFixturesData[18], // O Globo (Rio de Janeiro)
- eventCountry: countriesFixturesData[9], // Brazil
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 32)),
- updatedAt: DateTime.now().subtract(const Duration(days: 32)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId96,
- isBreaking: false,
- title: 'Sagrada Família Nears Completion After 140 Years',
- url: 'https://example.com/news/sagrada-familia-completion',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId96/800/600', // La Vanguardia (Barcelona)
- source: sourcesFixturesData[19], // La Vanguardia (Barcelona)
- eventCountry: countriesFixturesData[10], // Spain
- topic: topicsFixturesData[5], // Entertainment
- createdAt: DateTime.now().subtract(const Duration(days: 32)),
- updatedAt: DateTime.now().subtract(const Duration(days: 32)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId97,
- isBreaking: false,
- title: 'FC Barcelona Presents New Kit at Camp Nou',
- url: 'https://example.com/news/fcb-new-kit',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId97/800/600', // La Vanguardia (Barcelona)
- source: sourcesFixturesData[19], // La Vanguardia (Barcelona)
- eventCountry: countriesFixturesData[10], // Spain
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 33)),
- updatedAt: DateTime.now().subtract(const Duration(days: 33)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId98,
- isBreaking: false,
- title: 'Catalan Government Discusses Tourism Strategy',
- url: 'https://example.com/news/catalan-tourism-strategy',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId98/800/600', // La Vanguardia (Barcelona)
- source: sourcesFixturesData[19], // La Vanguardia (Barcelona)
- eventCountry: countriesFixturesData[10], // Spain
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 33)),
- updatedAt: DateTime.now().subtract(const Duration(days: 33)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId99,
- isBreaking: false,
- title: "Barcelona's Tech Scene Booms with New Hub",
- url: 'https://example.com/news/barcelona-tech-hub',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId99/800/600', // La Vanguardia (Barcelona)
- source: sourcesFixturesData[19], // La Vanguardia (Barcelona)
- eventCountry: countriesFixturesData[10], // Spain
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 34)),
- updatedAt: DateTime.now().subtract(const Duration(days: 34)),
- status: ContentStatus.active,
- ),
- Headline(
- id: kHeadlineId100,
- isBreaking: false,
- title: 'La Boqueria Market: A Taste of Barcelona',
- url: 'https://example.com/news/la-boqueria-feature',
- imageUrl:
- 'https://picsum.photos/seed/kHeadlineId100/800/600', // La Vanguardia (Barcelona)
- source: sourcesFixturesData[19], // La Vanguardia (Barcelona)
- eventCountry: countriesFixturesData[10], // Spain
- topic: topicsFixturesData[8], // Food
- createdAt: DateTime.now().subtract(const Duration(days: 34)),
- updatedAt: DateTime.now().subtract(const Duration(days: 34)),
- status: ContentStatus.active,
- ),
+ final headlines = [];
+ for (var i = 0; i < _headlineIds.length; i++) {
+ final id = _headlineIds[i];
+ final title =
+ _titlesByLang[resolvedLanguageCode]![i % _titlesByLang['en']!.length];
+ final source = sources[i % sources.length];
+ final topic = topics[i % topics.length];
+ final country = countriesFixturesData[i % countriesFixturesData.length];
- // --- National News Outlets (kSourceId21 - kSourceId30) ---
- // ... (Headlines for kSourceId21 to kSourceId30 would follow the same pattern)
- // To keep the response size manageable, I will add a placeholder comment here.
- // In a real implementation, 50 headlines for these 10 sources would be added.
- // Example for USA Today:
- Headline(
- id: kHeadlineId101,
- isBreaking: false,
- title: 'National Parks See Record Visitor Numbers',
- url: 'https://example.com/news/national-parks-visitors',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId101/800/600',
- source: sourcesFixturesData[20], // USA Today
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[7], // Travel
- createdAt: DateTime.now().subtract(const Duration(days: 35)),
- updatedAt: DateTime.now().subtract(const Duration(days: 35)),
- status: ContentStatus.active,
- ),
- // ... 4 more for USA Today
+ headlines.add(
+ Headline(
+ id: id,
+ isBreaking: i % 10 == 3, // Make some headlines breaking
+ title: title,
+ url: 'https://example.com/news/${id.substring(0, 8)}',
+ imageUrl: 'https://picsum.photos/seed/$id/800/600',
+ source: source,
+ eventCountry: country,
+ topic: topic,
+ createdAt: referenceTime.subtract(Duration(minutes: i * 15)),
+ updatedAt: referenceTime.subtract(Duration(minutes: i * 15)),
+ status: ContentStatus.active,
+ ),
+ );
+ }
+ return headlines;
+}
- // Example for The Globe and Mail:
- Headline(
- id: kHeadlineId106,
- isBreaking: false,
- title: 'Canadian Government Announces New Federal Budget',
- url: 'https://example.com/news/canada-federal-budget',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId106/800/600',
- source: sourcesFixturesData[21], // The Globe and Mail
- eventCountry: countriesFixturesData[1], // Canada
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 36)),
- updatedAt: DateTime.now().subtract(const Duration(days: 36)),
- status: ContentStatus.active,
- ),
- // ... 4 more for The Globe and Mail
-
- // --- International News Outlets (kSourceId31 - kSourceId40) ---
- // ... (Headlines for kSourceId31 to kSourceId40 would follow the same pattern)
- // Example for CNN International:
- Headline(
- id: kHeadlineId151,
- isBreaking: false,
- title: 'Global Supply Chain Issues Persist',
- url: 'https://example.com/news/global-supply-chain',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId151/800/600',
- source: sourcesFixturesData[30], // CNN International
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 45)),
- updatedAt: DateTime.now().subtract(const Duration(days: 45)),
- status: ContentStatus.active,
- ),
- // ... 4 more for CNN International
-
- // --- Specialized Publishers (kSourceId41 - kSourceId50) ---
- // Example for ESPN:
- Headline(
- id: kHeadlineId201,
- isBreaking: false,
- title: 'World Cup Finals: An Unforgettable Match',
- url: 'https://example.com/news/world-cup-final',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId201/800/600',
- source: sourcesFixturesData[40], // ESPN
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[1], // Sports
- createdAt: DateTime.now().subtract(const Duration(days: 55)),
- updatedAt: DateTime.now().subtract(const Duration(days: 55)),
- status: ContentStatus.active,
- ),
- // ... 4 more for ESPN
-
- // --- Blogs (kSourceId51 - kSourceId60) ---
- // Example for Stratechery:
- Headline(
- id: kHeadlineId251,
- isBreaking: false,
- title: 'The Future of Content and Aggregation',
- url: 'https://example.com/news/stratechery-content-ai',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId251/800/600',
- source: sourcesFixturesData[50], // Stratechery by Ben Thompson
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 65)),
- updatedAt: DateTime.now().subtract(const Duration(days: 65)),
- status: ContentStatus.active,
- ),
- // ... 4 more for Stratechery
-
- // --- Government Sources (kSourceId61 - kSourceId70) ---
- // Example for WhiteHouse.gov:
- Headline(
- id: kHeadlineId301,
- isBreaking: false,
- title: 'President Signs Executive Order on Cybersecurity',
- url: 'https://example.com/news/wh-cyber-order',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId301/800/600',
- source: sourcesFixturesData[60], // WhiteHouse.gov
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[2], // Politics
- createdAt: DateTime.now().subtract(const Duration(days: 75)),
- updatedAt: DateTime.now().subtract(const Duration(days: 75)),
- status: ContentStatus.active,
- ),
- // ... 4 more for WhiteHouse.gov
-
- // --- Aggregators (kSourceId71 - kSourceId80) ---
- // Example for Google News:
- Headline(
- id: kHeadlineId351,
- isBreaking: false,
- title: 'This Week in Tech: A Google News Roundup',
- url: 'https://example.com/news/gnews-tech-roundup',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId351/800/600',
- source: sourcesFixturesData[70], // Google News
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[0], // Technology
- createdAt: DateTime.now().subtract(const Duration(days: 85)),
- updatedAt: DateTime.now().subtract(const Duration(days: 85)),
- status: ContentStatus.active,
- ),
- // ... 4 more for Google News
-
- // --- Other (kSourceId81 - kSourceId90) ---
- // Example for PR Newswire:
- Headline(
- id: kHeadlineId401,
- isBreaking: false,
- title: 'Global Tech Corp Announces Record Quarterly Earnings',
- url: 'https://example.com/news/prn-earnings',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId401/800/600',
- source: sourcesFixturesData[80], // PR Newswire
- eventCountry: countriesFixturesData[0], // United States
- topic: topicsFixturesData[6], // Business
- createdAt: DateTime.now().subtract(const Duration(days: 95)),
- updatedAt: DateTime.now().subtract(const Duration(days: 95)),
- status: ContentStatus.active,
- ),
- // Example for The Lancet:
- Headline(
- id: kHeadlineId411,
- isBreaking: false,
- title: 'Phase 3 Trial Results for New Diabetes Drug Published',
- url: 'https://example.com/news/lancet-diabetes-drug',
- imageUrl: 'https://picsum.photos/seed/kHeadlineId411/800/600',
- source: sourcesFixturesData[82], // The Lancet
- eventCountry: countriesFixturesData[2], // United Kingdom
- topic: topicsFixturesData[4], // Health
- createdAt: DateTime.now().subtract(const Duration(days: 100)),
- updatedAt: DateTime.now().subtract(const Duration(days: 100)),
- status: ContentStatus.active,
- ),
+const List _headlineIds = [
+ kHeadlineId1, kHeadlineId2, kHeadlineId3, kHeadlineId4, kHeadlineId5,
+ kHeadlineId6, kHeadlineId7, kHeadlineId8, kHeadlineId9, kHeadlineId10,
+ kHeadlineId11, kHeadlineId12, kHeadlineId13, kHeadlineId14, kHeadlineId15,
+ kHeadlineId16, kHeadlineId17, kHeadlineId18, kHeadlineId19, kHeadlineId20,
+ kHeadlineId21, kHeadlineId22, kHeadlineId23, kHeadlineId24, kHeadlineId25,
+ kHeadlineId26, kHeadlineId27, kHeadlineId28, kHeadlineId29, kHeadlineId30,
+ kHeadlineId31, kHeadlineId32, kHeadlineId33, kHeadlineId34, kHeadlineId35,
+ kHeadlineId36, kHeadlineId37, kHeadlineId38, kHeadlineId39, kHeadlineId40,
+ kHeadlineId41, kHeadlineId42, kHeadlineId43, kHeadlineId44, kHeadlineId45,
+ kHeadlineId46, kHeadlineId47, kHeadlineId48, kHeadlineId49, kHeadlineId50,
+ kHeadlineId51, kHeadlineId52, kHeadlineId53, kHeadlineId54, kHeadlineId55,
+ kHeadlineId56, kHeadlineId57, kHeadlineId58, kHeadlineId59, kHeadlineId60,
+ kHeadlineId61, kHeadlineId62, kHeadlineId63, kHeadlineId64, kHeadlineId65,
+ kHeadlineId66, kHeadlineId67, kHeadlineId68, kHeadlineId69, kHeadlineId70,
+ kHeadlineId71, kHeadlineId72, kHeadlineId73, kHeadlineId74, kHeadlineId75,
+ kHeadlineId76, kHeadlineId77, kHeadlineId78, kHeadlineId79, kHeadlineId80,
+ kHeadlineId81, kHeadlineId82, kHeadlineId83, kHeadlineId84, kHeadlineId85,
+ kHeadlineId86, kHeadlineId87, kHeadlineId88, kHeadlineId89, kHeadlineId90,
+ kHeadlineId91, kHeadlineId92, kHeadlineId93, kHeadlineId94, kHeadlineId95,
+ kHeadlineId96, kHeadlineId97, kHeadlineId98, kHeadlineId99, kHeadlineId100,
+ // Add more IDs if needed, up to kHeadlineId450
];
+
+final Map> _titlesByLang = {
+ 'en': [
+ 'AI Breakthrough: New Model Achieves Human-Level Performance',
+ 'Local Team Wins Championship in Thrilling Final',
+ 'Global Leaders Meet to Discuss Climate Change Policies',
+ 'New Planet Discovered in Distant Galaxy',
+ 'Breakthrough in Cancer Research Offers New Hope',
+ 'Blockbuster Movie Breaks Box Office Records',
+ 'Stock Market Reaches All-Time High Amid Economic Boom',
+ 'New Travel Restrictions Lifted for Popular Destinations',
+ 'Michelin Star Chef Opens New Restaurant in City Center',
+ 'Innovative Teaching Methods Boost Student Engagement',
+ 'Cybersecurity Firms Warn of New Global Threat',
+ 'Olympics Committee Announces Host City for 2032 Games',
+ 'New Bill Aims to Reform Healthcare System',
+ 'Archaeologists Uncover Ancient City Ruins',
+ 'Dietary Guidelines Updated for Public Health',
+ 'Music Festival Announces Star-Studded Lineup',
+ 'Tech Giant Acquires Startup in Multi-Billion Dollar Deal',
+ 'Space Tourism Takes Off: First Commercial Flights Announced',
+ 'Future of Food: Lab-Grown Meat Gains Popularity',
+ 'Online Learning Platforms See Surge in Enrollment',
+ 'Quantum Computing Achieves New Milestone',
+ 'World Cup Qualifiers: Unexpected Upsets Shake Rankings',
+ 'Election Results: New Government Takes Power',
+ 'Breakthrough in Fusion Energy Research Announced',
+ 'Mental Health Awareness Campaign Launched Globally',
+ 'Gaming Industry Sees Record Growth in Virtual Reality',
+ 'Global Supply Chain Disruptions Impacting Consumer Goods',
+ 'Arctic Expedition Discovers New Marine Species',
+ 'Rise of Plant-Based Cuisine: New Restaurants Open',
+ 'Education Technology Transforms Classrooms',
+ 'SpaceX Launches New Satellite Constellation',
+ 'Football Legend Announces Retirement',
+ 'G7 Summit Concludes with Joint Statement on Global Economy',
+ "Breakthrough in Alzheimer's Research Offers New Treatment Path",
+ 'Global Vaccination Campaign Reaches Billions',
+ 'Streaming Wars Intensify with New Platform Launches',
+ 'Cryptocurrency Market Experiences Major Volatility',
+ 'Sustainable Tourism Initiatives Gain Momentum',
+ 'Food Security Summit Addresses Global Hunger',
+ 'Robotics in Education: New Tools for Learning',
+ 'AI Ethics Debate Intensifies Among Tech Leaders',
+ 'Esports Industry Sees Massive Investment Boom',
+ 'International Sanctions Imposed on Rogue State',
+ 'New Species of Deep-Sea Creature Discovered',
+ 'Global Health Crisis: New Pandemic Preparedness Plan',
+ 'Hollywood Strikes Continue: Impact on Film Production',
+ 'Emerging Markets Show Strong Economic Resilience',
+ 'Adventure Tourism Booms in Remote Regions',
+ 'The Rise of Sustainable Food Packaging',
+ 'Personalized Learning: Tailoring Education to Individual Needs',
+ ],
+ 'ar': [
+ 'إنجاز في الذكاء الاصطناعي: نموذج جديد يحقق أداءً على المستوى البشري',
+ 'الفريق المحلي يفوز بالبطولة في نهائي مثير',
+ 'قادة العالم يجتمعون لمناقشة سياسات تغير المناخ',
+ 'اكتشاف كوكب جديد في مجرة بعيدة',
+ 'تقدم في أبحاث السرطان يقدم أملاً جديدًا',
+ 'فيلم ضخم يحطم الأرقام القياسية في شباك التذاكر',
+ 'سوق الأسهم يصل إلى أعلى مستوى له على الإطلاق وسط ازدهار اقتصادي',
+ 'رفع قيود السفر الجديدة عن وجهات شهيرة',
+ 'شيف حائز على نجمة ميشلان يفتتح مطعمًا جديدًا في وسط المدينة',
+ 'طرق التدريس المبتكرة تعزز مشاركة الطلاب',
+ 'شركات الأمن السيبراني تحذر من تهديد عالمي جديد',
+ 'اللجنة الأولمبية تعلن عن المدينة المضيفة لألعاب 2032',
+ 'مشروع قانون جديد يهدف إلى إصلاح نظام الرعاية الصحية',
+ 'علماء الآثار يكشفون عن أطلال مدينة قديمة',
+ 'تحديث المبادئ التوجيهية الغذائية للصحة العامة',
+ 'مهرجان موسيقي يعلن عن قائمة نجوم مرصعة بالنجوم',
+ 'عملاق التكنولوجيا يستحوذ على شركة ناشئة في صفقة بمليارات الدولارات',
+ 'السياحة الفضائية تنطلق: الإعلان عن أولى الرحلات التجارية',
+ 'مستقبل الغذاء: اللحوم المزروعة في المختبر تكتسب شعبية',
+ 'منصات التعلم عبر الإنترنت تشهد طفرة في التسجيل',
+ 'الحوسبة الكمومية تحقق إنجازًا جديدًا',
+ 'تصفيات كأس العالم: مفاجآت غير متوقعة تهز التصنيفات',
+ 'نتائج الانتخابات: حكومة جديدة تتولى السلطة',
+ 'الإعلان عن تقدم كبير في أبحاث طاقة الاندماج',
+ 'إطلاق حملة توعية بالصحة النفسية على مستوى العالم',
+ 'صناعة الألعاب تشهد نموًا قياسيًا في الواقع الافتراضي',
+ 'اضطرابات سلسلة التوريد العالمية تؤثر على السلع الاستهلاكية',
+ 'بعثة استكشافية في القطب الشمالي تكتشف أنواعًا بحرية جديدة',
+ 'صعود المطبخ النباتي: افتتاح مطاعم جديدة',
+ 'تكنولوجيا التعليم تغير الفصول الدراسية',
+ 'سبيس إكس تطلق كوكبة أقمار صناعية جديدة',
+ 'أسطورة كرة القدم يعلن اعتزاله',
+ 'قمة مجموعة السبع تختتم ببيان مشترك حول الاقتصاد العالمي',
+ 'تقدم في أبحاث الزهايمر يقدم مسارًا علاجيًا جديدًا',
+ 'حملة التطعيم العالمية تصل إلى المليارات',
+ 'حروب البث تشتد مع إطلاق منصات جديدة',
+ 'سوق العملات المشفرة يشهد تقلبات كبيرة',
+ 'مبادرات السياحة المستدامة تكتسب زخمًا',
+ 'قمة الأمن الغذائي تتناول الجوع العالمي',
+ 'الروبوتات في التعليم: أدوات جديدة للتعلم',
+ 'جدل أخلاقيات الذكاء الاصطناعي يشتد بين قادة التكنولوجيا',
+ 'صناعة الرياضات الإلكترونية تشهد طفرة استثمارية هائلة',
+ 'فرض عقوبات دولية على دولة مارقة',
+ 'اكتشاف أنواع جديدة من مخلوقات أعماق البحار',
+ 'أزمة صحية عالمية: خطة جديدة للتأهب للأوبئة',
+ 'إضرابات هوليوود مستمرة: التأثير على إنتاج الأفلام',
+ 'الأسواق الناشئة تظهر مرونة اقتصادية قوية',
+ 'ازدهار سياحة المغامرات في المناطق النائية',
+ 'صعود أغلفة المواد الغذائية المستدامة',
+ 'التعلم المخصص: تكييف التعليم مع الاحتياجات الفردية',
+ ],
+};
diff --git a/lib/src/fixtures/in_app_notifications.dart b/lib/src/fixtures/in_app_notifications.dart
index 3cefa960..00686ac2 100644
--- a/lib/src/fixtures/in_app_notifications.dart
+++ b/lib/src/fixtures/in_app_notifications.dart
@@ -17,10 +17,10 @@ List _generateAdminNotifications() {
21,
(index) => 'in_app_notification_${index + 1}',
);
- final headlineIds = headlinesFixturesData.map((e) => e.id).toList();
+ final headlineIds = getHeadlinesFixturesData().map((e) => e.id).toList();
return List.generate(21, (index) {
- final headline = headlinesFixturesData[index % headlineIds.length];
+ final headline = getHeadlinesFixturesData()[index % headlineIds.length];
final notificationId = notificationIds[index];
final isRead = index > 3;
diff --git a/lib/src/fixtures/remote_configs.dart b/lib/src/fixtures/remote_configs.dart
index 46b642cb..63d59759 100644
--- a/lib/src/fixtures/remote_configs.dart
+++ b/lib/src/fixtures/remote_configs.dart
@@ -65,6 +65,21 @@ final remoteConfigsFixturesData = [
AppUserRole.standardUser: SavedFilterLimits(total: 10, pinned: 5),
AppUserRole.premiumUser: SavedFilterLimits(total: 25, pinned: 10),
},
+ reactionsPerDay: {
+ AppUserRole.guestUser: 20,
+ AppUserRole.standardUser: 100,
+ AppUserRole.premiumUser: 500,
+ },
+ commentsPerDay: {
+ AppUserRole.guestUser: 0,
+ AppUserRole.standardUser: 10,
+ AppUserRole.premiumUser: 50,
+ },
+ reportsPerDay: {
+ AppUserRole.guestUser: 1,
+ AppUserRole.standardUser: 5,
+ AppUserRole.premiumUser: 20,
+ },
),
),
features: const FeaturesConfig(
@@ -199,6 +214,23 @@ final remoteConfigsFixturesData = [
PushNotificationSubscriptionDeliveryType.weeklyRoundup: true,
},
),
+ community: CommunityConfig(
+ engagement: EngagementConfig(
+ enabled: true,
+ engagementMode: EngagementMode.reactionsAndComments,
+ ),
+ reporting: ReportingConfig(
+ headlineReportingEnabled: true,
+ sourceReportingEnabled: true,
+ commentReportingEnabled: true,
+ ),
+ appReview: AppReviewConfig(
+ // User must perform 5 positive actions (e.g., save headline)
+ // to become eligible for the review prompt.
+ positiveInteractionThreshold: 5,
+ initialPromptCooldownDays: 14,
+ ),
+ ),
),
),
];
diff --git a/lib/src/fixtures/reports.dart b/lib/src/fixtures/reports.dart
new file mode 100644
index 00000000..656f3217
--- /dev/null
+++ b/lib/src/fixtures/reports.dart
@@ -0,0 +1,93 @@
+import 'package:core/core.dart';
+
+/// Generates a list of predefined reports for fixture data.
+///
+/// This creates 1 report for each of the first 10 users, targeting a mix of
+/// headlines, sources, and comments.
+///
+/// The optional [now] parameter allows for creating deterministic timestamps,
+/// which is essential for testing.
+List getReportsFixturesData({DateTime? now}) {
+ final reports = [];
+ final referenceTime = now ?? DateTime.now();
+ final users = usersFixturesData.take(10).toList();
+ final headlines = getHeadlinesFixturesData(
+ now: referenceTime,
+ ).take(10).toList();
+ final engagementsWithComments = getEngagementsFixturesData(
+ now: referenceTime,
+ ).where((e) => e.comment != null).toList();
+ final reportIds = [
+ kReportId1,
+ kReportId2,
+ kReportId3,
+ kReportId4,
+ kReportId5,
+ kReportId6,
+ kReportId7,
+ kReportId8,
+ kReportId9,
+ kReportId10,
+ ];
+ const headlineReasons = HeadlineReportReason.values;
+ const sourceReasons = SourceReportReason.values;
+ const commentReasons = CommentReportReason.values;
+
+ for (var i = 0; i < users.length; i++) {
+ final user = users[i];
+ final headline = headlines[i];
+ var status = ReportStatus.submitted;
+ if (i % 3 == 0) {
+ status = ReportStatus.inReview;
+ } else if (i % 5 == 0) {
+ status = ReportStatus.resolved;
+ }
+
+ // Create a mix of report types
+ if (i < 5) {
+ // Report on Headlines
+ reports.add(
+ Report(
+ id: reportIds[i],
+ reporterUserId: user.id,
+ entityType: ReportableEntity.headline,
+ entityId: headline.id,
+ reason: headlineReasons[i % headlineReasons.length].name,
+ additionalComments: 'This headline seems misleading.',
+ status: status,
+ createdAt: referenceTime.subtract(Duration(days: i)),
+ ),
+ );
+ } else if (i < 8) {
+ // Report on Sources
+ reports.add(
+ Report(
+ id: reportIds[i],
+ reporterUserId: user.id,
+ entityType: ReportableEntity.source,
+ entityId: getSourcesFixturesData()[i].id,
+ reason: sourceReasons[i % sourceReasons.length].name,
+ additionalComments: 'This source has too many ads.',
+ status: status,
+ createdAt: referenceTime.subtract(Duration(days: i)),
+ ),
+ );
+ } else {
+ // Report on Comments
+ reports.add(
+ Report(
+ id: reportIds[i],
+ reporterUserId: user.id,
+ entityType: ReportableEntity.engagement,
+ entityId: engagementsWithComments[i].id,
+ reason: commentReasons[i % commentReasons.length].name,
+ additionalComments: 'This comment is spam.',
+ status: status,
+ createdAt: referenceTime.subtract(Duration(days: i)),
+ ),
+ );
+ }
+ }
+
+ return reports;
+}
diff --git a/lib/src/fixtures/saved_headline_filters.dart b/lib/src/fixtures/saved_headline_filters.dart
index d90c14c2..5a22c653 100644
--- a/lib/src/fixtures/saved_headline_filters.dart
+++ b/lib/src/fixtures/saved_headline_filters.dart
@@ -1,33 +1,47 @@
import 'package:core/core.dart';
-/// A list of predefined saved headline filters for fixture data.
-final savedHeadlineFiltersFixturesData = [
- SavedHeadlineFilter(
- id: kSavedHeadlineFilterId1,
- userId: kAdminUserId,
- name: 'US Tech News',
- isPinned: true,
- deliveryTypes: const {
- PushNotificationSubscriptionDeliveryType.breakingOnly,
- },
- criteria: HeadlineFilterCriteria(
- topics: [topicsFixturesData[0]], // Technology
- sources: const [],
- countries: [countriesFixturesData[0]], // United States
+/// Generates a list of predefined saved headline filters for fixture data.
+List getSavedHeadlineFiltersFixturesData({
+ String languageCode = 'en',
+}) {
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+ final topics = getTopicsFixturesData(languageCode: resolvedLanguageCode);
+
+ final namesByLang = {
+ 'en': ['US Tech News', 'Global Business'],
+ 'ar': ['أخبار التكنولوجيا الأمريكية', 'أعمال عالمية'],
+ };
+
+ return [
+ SavedHeadlineFilter(
+ id: kSavedHeadlineFilterId1,
+ userId: kAdminUserId,
+ name: namesByLang[resolvedLanguageCode]![0],
+ isPinned: true,
+ deliveryTypes: const {
+ PushNotificationSubscriptionDeliveryType.breakingOnly,
+ },
+ criteria: HeadlineFilterCriteria(
+ topics: [topics[0]], // Technology
+ sources: const [],
+ countries: [countriesFixturesData[0]], // United States
+ ),
),
- ),
- SavedHeadlineFilter(
- id: kSavedHeadlineFilterId2,
- userId: kUser1Id,
- name: 'Global Business',
- isPinned: false,
- deliveryTypes: const {
- PushNotificationSubscriptionDeliveryType.breakingOnly,
- },
- criteria: HeadlineFilterCriteria(
- topics: [topicsFixturesData[6]], // Business
- sources: const [],
- countries: const [],
+ SavedHeadlineFilter(
+ id: kSavedHeadlineFilterId2,
+ userId: kUser1Id,
+ name: namesByLang[resolvedLanguageCode]![1],
+ isPinned: false,
+ deliveryTypes: const {
+ PushNotificationSubscriptionDeliveryType.breakingOnly,
+ },
+ criteria: HeadlineFilterCriteria(
+ topics: [topics[6]], // Business
+ sources: const [],
+ countries: const [],
+ ),
),
- ),
-];
+ ];
+}
diff --git a/lib/src/fixtures/saved_source_filters.dart b/lib/src/fixtures/saved_source_filters.dart
index 3458301a..b8dcc307 100644
--- a/lib/src/fixtures/saved_source_filters.dart
+++ b/lib/src/fixtures/saved_source_filters.dart
@@ -1,27 +1,40 @@
import 'package:core/core.dart';
-/// A list of predefined saved source filters for fixture data.
-final savedSourceFiltersFixturesData = [
- SavedSourceFilter(
- id: kSavedSourceFilterId1,
- userId: kAdminUserId,
- name: 'UK News Agencies',
- isPinned: true,
- criteria: SourceFilterCriteria(
- sourceTypes: const [SourceType.newsAgency],
- languages: const [],
- countries: [countriesFixturesData[1]], // United Kingdom
+/// Generates a list of predefined saved source filters for fixture data.
+List getSavedSourceFiltersFixturesData({
+ String languageCode = 'en',
+}) {
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+
+ final namesByLang = {
+ 'en': ['UK News Agencies', 'German Tech Blogs'],
+ 'ar': ['وكالات الأنباء البريطانية', 'مدونات التكنولوجيا الألمانية'],
+ };
+
+ return [
+ SavedSourceFilter(
+ id: kSavedSourceFilterId1,
+ userId: kAdminUserId,
+ name: namesByLang[resolvedLanguageCode]![0],
+ isPinned: true,
+ criteria: SourceFilterCriteria(
+ sourceTypes: const [SourceType.newsAgency],
+ languages: const [],
+ countries: [countriesFixturesData[1]], // United Kingdom
+ ),
),
- ),
- SavedSourceFilter(
- id: kSavedSourceFilterId2,
- userId: kUser1Id,
- name: 'German Tech Blogs',
- isPinned: false,
- criteria: SourceFilterCriteria(
- sourceTypes: const [SourceType.blog, SourceType.specializedPublisher],
- languages: [languagesFixturesData.firstWhere((l) => l.code == 'de')],
- countries: [countriesFixturesData[4]], // Germany
+ SavedSourceFilter(
+ id: kSavedSourceFilterId2,
+ userId: kUser1Id,
+ name: namesByLang[resolvedLanguageCode]![1],
+ isPinned: false,
+ criteria: SourceFilterCriteria(
+ sourceTypes: const [SourceType.blog, SourceType.specializedPublisher],
+ languages: [languagesFixturesData.firstWhere((l) => l.code == 'de')],
+ countries: [countriesFixturesData[4]], // Germany
+ ),
),
- ),
-];
+ ];
+}
diff --git a/lib/src/fixtures/sources.dart b/lib/src/fixtures/sources.dart
index ea562d9e..c3605455 100644
--- a/lib/src/fixtures/sources.dart
+++ b/lib/src/fixtures/sources.dart
@@ -4,1179 +4,887 @@ import 'package:core/src/fixtures/fixture_ids.dart';
import 'package:core/src/fixtures/languages.dart';
import 'package:core/src/models/entities/source.dart';
-/// A list of predefined sources for fixture data.
-final sourcesFixturesData = [
- Source(
- id: kSourceId1,
- name: 'TechCrunch',
- description: 'Leading online publisher of technology news.',
- url: 'https://techcrunch.com',
- logoUrl: 'https://api.companyenrich.com/logo/techcrunch.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-01-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId2,
- name: 'BBC News',
- description: 'Breaking news, sport, TV, radio and a whole lot more.',
- url: 'https://www.bbc.com/news',
- logoUrl: 'https://api.companyenrich.com/logo/bbc.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-01-02T11:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-02T11:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId3,
- name: 'The New York Times',
- description: 'Breaking News, World News & Multimedia.',
- url: 'https://www.nytimes.com',
- logoUrl: 'https://api.companyenrich.com/logo/nytimes.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-01-03T12:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-03T12:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId4,
- name: 'The Guardian',
- description:
- 'Latest news, sport, business, comment and reviews from the Guardian.',
- url: 'https://www.theguardian.com',
- logoUrl: 'https://api.companyenrich.com/logo/theguardian.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-01-04T13:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-04T13:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId5,
- name: 'CNN',
- description: 'Breaking News, Latest News and Videos.',
- url: 'https://edition.cnn.com',
- logoUrl: 'https://api.companyenrich.com/logo/cnn.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-01-05T14:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-05T14:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId6,
- name: 'Reuters',
- description: 'Business, financial, national and international news.',
- url: 'https://www.reuters.com',
- logoUrl: 'https://api.companyenrich.com/logo/reuters.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-01-06T15:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-06T15:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId7,
- name: 'Al Jazeera English',
- description:
- 'News, analysis, and opinion from the Middle East and around the world.',
- url: 'https://www.aljazeera.com',
- logoUrl: 'https://api.companyenrich.com/logo/aljazeera.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters:
- countriesFixturesData[0], // United States (assuming for simplicity, actual is Qatar)
- createdAt: DateTime.parse('2023-01-07T16:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-07T16:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId8,
- name: 'Xinhua News Agency',
- description: "Official press agency of the People's Republic of China.",
- url: 'http://www.xinhuanet.com/english/',
- logoUrl: 'https://api.companyenrich.com/logo/xinhuanet.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[7], // China
- createdAt: DateTime.parse('2023-01-08T17:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-08T17:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId9,
- name: 'The Times of India',
- description: 'Latest and Breaking News from India.',
- url: 'https://timesofindia.indiatimes.com/',
- logoUrl: 'https://api.companyenrich.com/logo/indiatimes.com',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[8], // India
- createdAt: DateTime.parse('2023-01-09T18:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-09T18:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId10,
- name: 'Folha de S.Paulo',
- description: 'Brazilian daily newspaper.',
- url: 'https://www.folha.uol.com.br/',
- logoUrl: 'https://api.companyenrich.com/logo/uol.com.br',
- sourceType: SourceType.newsAgency,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'pt'),
- headquarters: countriesFixturesData[9], // Brazil
- createdAt: DateTime.parse('2023-01-10T19:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-10T19:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId11,
- name: 'San Francisco Chronicle',
- description: 'News from the San Francisco Bay Area.',
- url: 'https://www.sfchronicle.com',
- logoUrl: 'https://api.companyenrich.com/logo/sfchronicle.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-02-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId12,
- name: 'Manchester Evening News',
- description: 'Covering Greater Manchester, UK.',
- url: 'https://www.manchestereveningnews.co.uk',
- logoUrl: 'https://api.companyenrich.com/logo/manchestereveningnews.co.uk',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-02-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId13,
- name: 'The Sydney Morning Herald',
- description: 'Independent journalism for Sydney, Australia.',
- url: 'https://www.smh.com.au',
- logoUrl: 'https://api.companyenrich.com/logo/smh.com.au',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[3], // Australia
- createdAt: DateTime.parse('2023-02-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId14,
- name: 'Le Parisien',
- description: 'Local news for Paris and the Île-de-France region.',
- url: 'https://www.leparisien.fr',
- logoUrl: 'https://api.companyenrich.com/logo/leparisien.fr',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'fr'),
- headquarters: countriesFixturesData[5], // France
- createdAt: DateTime.parse('2023-02-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId15,
- name: 'The Toronto Star',
- description: 'News and stories for Toronto, Canada.',
- url: 'https://www.thestar.com',
- logoUrl: 'https://api.companyenrich.com/logo/thestar.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[1], // Canada
- createdAt: DateTime.parse('2023-02-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId16,
- name: 'Berliner Morgenpost',
- description: 'Daily news for Berlin, Germany.',
- url: 'https://www.morgenpost.de',
- logoUrl: 'https://api.companyenrich.com/logo/morgenpost.de',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'de'),
- headquarters: countriesFixturesData[4], // Germany
- createdAt: DateTime.parse('2023-02-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId17,
- name: 'The Asahi Shimbun (Tokyo)',
- description: 'Local and national news from a Tokyo perspective.',
- url: 'https://www.asahi.com/area/tokyo/',
- logoUrl: 'https://api.companyenrich.com/logo/asahi.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'ja'),
- headquarters: countriesFixturesData[6], // Japan
- createdAt: DateTime.parse('2023-02-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId18,
- name: 'Hindustan Times (Mumbai)',
- description: 'Latest news from Mumbai, India.',
- url: 'https://www.hindustantimes.com/mumbai-news',
- logoUrl: 'https://api.companyenrich.com/logo/hindustantimes.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[8], // India
- createdAt: DateTime.parse('2023-02-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId19,
- name: 'O Globo (Rio de Janeiro)',
- description: 'News from Rio de Janeiro, Brazil.',
- url: 'https://oglobo.globo.com/rio/',
- logoUrl: 'https://api.companyenrich.com/logo/globo.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'pt'),
- headquarters: countriesFixturesData[9], // Brazil
- createdAt: DateTime.parse('2023-02-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId20,
- name: 'La Vanguardia (Barcelona)',
- description: 'News from Barcelona and Catalonia, Spain.',
- url: 'https://www.lavanguardia.com/local/barcelona',
- logoUrl: 'https://api.companyenrich.com/logo/lavanguardia.com',
- sourceType: SourceType.localNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'es'),
- headquarters: countriesFixturesData[10], // Spain
- createdAt: DateTime.parse('2023-02-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-02-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId21,
- name: 'USA Today',
- description: 'National news from across the United States.',
- url: 'https://www.usatoday.com',
- logoUrl: 'https://api.companyenrich.com/logo/usatoday.com',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-03-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId22,
- name: 'The Globe and Mail',
- description: "Canada's national newspaper.",
- url: 'https://www.theglobeandmail.com',
- logoUrl: 'https://api.companyenrich.com/logo/theglobeandmail.com',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[1], // Canada
- createdAt: DateTime.parse('2023-03-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId23,
- name: 'The Australian',
- description: 'National news of Australia.',
- url: 'https://www.theaustralian.com.au',
- logoUrl: 'https://api.companyenrich.com/logo/theaustralian.com.au',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[3], // Australia
- createdAt: DateTime.parse('2023-03-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId24,
- name: 'Le Monde',
- description: 'French national daily newspaper.',
- url: 'https://www.lemonde.fr',
- logoUrl: 'https://api.companyenrich.com/logo/lemonde.fr',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'fr'),
- headquarters: countriesFixturesData[5], // France
- createdAt: DateTime.parse('2023-03-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId25,
- name: 'Frankfurter Allgemeine Zeitung',
- description: 'German national newspaper.',
- url: 'https://www.faz.net',
- logoUrl: 'https://api.companyenrich.com/logo/faz.net',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'de'),
- headquarters: countriesFixturesData[4], // Germany
- createdAt: DateTime.parse('2023-03-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId26,
- name: 'The Yomiuri Shimbun',
- description: 'Japanese national newspaper.',
- url: 'https://www.yomiuri.co.jp',
- logoUrl: 'https://api.companyenrich.com/logo/yomiuri.co.jp',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'ja'),
- headquarters: countriesFixturesData[6], // Japan
- createdAt: DateTime.parse('2023-03-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId27,
- name: "People's Daily",
- description: 'Official newspaper of the Central Committee of the CCP.',
- url: 'http://en.people.cn',
- logoUrl: 'https://api.companyenrich.com/logo/people.cn',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[7], // China
- createdAt: DateTime.parse('2023-03-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId28,
- name: 'O Estado de S. Paulo',
- description: 'Brazilian national newspaper.',
- url: 'https://www.estadao.com.br',
- logoUrl: 'https://api.companyenrich.com/logo/estadao.com.br',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'pt'),
- headquarters: countriesFixturesData[9], // Brazil
- createdAt: DateTime.parse('2023-03-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId29,
- name: 'El País',
- description: 'Spanish national daily newspaper.',
- url: 'https://elpais.com',
- logoUrl: 'https://api.companyenrich.com/logo/elpais.com',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'es'),
- headquarters: countriesFixturesData[10], // Spain
- createdAt: DateTime.parse('2023-03-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId30,
- name: 'Corriere della Sera',
- description: 'Italian national daily newspaper.',
- url: 'https://www.corriere.it',
- logoUrl: 'https://api.companyenrich.com/logo/corriere.it',
- sourceType: SourceType.nationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'it'),
- headquarters: countriesFixturesData[11], // Italy
- createdAt: DateTime.parse('2023-03-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-03-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId31,
- name: 'CNN International',
- description: 'Global news coverage from CNN.',
- url: 'https://edition.cnn.com',
- logoUrl: 'https://api.companyenrich.com/logo/cnn.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-04-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId32,
- name: 'BBC World News',
- description: 'International news from the BBC.',
- url: 'https://www.bbc.com/news/world',
- logoUrl: 'https://api.companyenrich.com/logo/bbc.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-04-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId33,
- name: 'The Economist',
- description: 'In-depth analysis of international news and business.',
- url: 'https://www.economist.com',
- logoUrl: 'https://api.companyenrich.com/logo/economist.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-04-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId34,
- name: 'France 24',
- description: 'French perspective on international current events.',
- url: 'https://www.france24.com/en/',
- logoUrl: 'https://api.companyenrich.com/logo/france24.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[5], // France
- createdAt: DateTime.parse('2023-04-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId35,
- name: 'Deutsche Welle',
- description: "Germany's international broadcaster.",
- url: 'https://www.dw.com/en/',
- logoUrl: 'https://api.companyenrich.com/logo/dw.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[4], // Germany
- createdAt: DateTime.parse('2023-04-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId36,
- name: 'The Wall Street Journal',
- description: 'Global business and financial news.',
- url: 'https://www.wsj.com',
- logoUrl: 'https://api.companyenrich.com/logo/wsj.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-04-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId37,
- name: 'Associated Press (AP)',
- description: 'Global news network.',
- url: 'https://apnews.com',
- logoUrl: 'https://api.companyenrich.com/logo/apnews.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-04-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId38,
- name: 'Agence France-Presse (AFP)',
- description: 'International news agency based in Paris.',
- url: 'https://www.afp.com/en',
- logoUrl: 'https://api.companyenrich.com/logo/afp.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[5], // France
- createdAt: DateTime.parse('2023-04-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId39,
- name: 'RT',
- description: 'Russian state-funded international television network.',
- url: 'https://www.rt.com',
- logoUrl: 'https://api.companyenrich.com/logo/rt.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[12], // Russia
- createdAt: DateTime.parse('2023-04-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId40,
- name: 'CGTN',
- description: 'Chinese state-funded international television network.',
- url: 'https://www.cgtn.com',
- logoUrl: 'https://api.companyenrich.com/logo/cgtn.com',
- sourceType: SourceType.internationalNewsOutlet,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[7], // China
- createdAt: DateTime.parse('2023-04-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-04-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId41,
- name: 'ESPN',
- description: 'The worldwide leader in sports.',
- url: 'https://www.espn.com',
- logoUrl: 'https://api.companyenrich.com/logo/espn.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId42,
- name: 'Nature',
- description: 'International journal of science.',
- url: 'https://www.nature.com',
- logoUrl: 'https://api.companyenrich.com/logo/nature.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-05-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId43,
- name: 'The Hollywood Reporter',
- description: 'The definitive voice of the entertainment industry.',
- url: 'https://www.hollywoodreporter.com',
- logoUrl: 'https://api.companyenrich.com/logo/hollywoodreporter.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId44,
- name: 'Vogue',
- description: 'Fashion, beauty, and lifestyle.',
- url: 'https://www.vogue.com',
- logoUrl: 'https://api.companyenrich.com/logo/vogue.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId45,
- name: 'National Geographic',
- description: 'Science, exploration, and adventure.',
- url: 'https://www.nationalgeographic.com',
- logoUrl: 'https://api.companyenrich.com/logo/nationalgeographic.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId46,
- name: 'Wired',
- description: 'How technology is changing every aspect of our lives.',
- url: 'https://www.wired.com',
- logoUrl: 'https://api.companyenrich.com/logo/wired.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId47,
- name: 'Bon Appétit',
- description: 'Food and cooking magazine.',
- url: 'https://www.bonappetit.com',
- logoUrl: 'https://api.companyenrich.com/logo/bonappetit.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId48,
- name: 'Architectural Digest',
- description: 'The international design authority.',
- url: 'https://www.architecturaldigest.com',
- logoUrl: 'https://api.companyenrich.com/logo/architecturaldigest.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId49,
- name: 'Car and Driver',
- description: 'Automotive news and reviews.',
- url: 'https://www.caranddriver.com',
- logoUrl: 'https://api.companyenrich.com/logo/caranddriver.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-05-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId50,
- name: 'PC Gamer',
- description: 'Global authority on PC games.',
- url: 'https://www.pcgamer.com',
- logoUrl: 'https://api.companyenrich.com/logo/pcgamer.com',
- sourceType: SourceType.specializedPublisher,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-05-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-05-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId51,
- name: 'Stratechery by Ben Thompson',
- description: 'Analysis of the strategy and business of technology.',
- url: 'https://stratechery.com',
- logoUrl: 'https://api.companyenrich.com/logo/stratechery.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId52,
- name: 'Daring Fireball',
- description: 'By John Gruber. On technology and Apple.',
- url: 'https://daringfireball.net',
- logoUrl: 'https://api.companyenrich.com/logo/daringfireball.net',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId53,
- name: 'Wait But Why',
- description: 'A popular long-form, stick-figure-illustrated blog.',
- url: 'https://waitbutwhy.com',
- logoUrl: 'https://api.companyenrich.com/logo/waitbutwhy.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId54,
- name: 'Smitten Kitchen',
- description: 'A home cooking blog from a tiny kitchen in New York City.',
- url: 'https://smittenkitchen.com',
- logoUrl: 'https://api.companyenrich.com/logo/smittenkitchen.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId55,
- name: 'The Verge',
- description: 'A technology news and media network operated by Vox Media.',
- url: 'https://www.theverge.com',
- logoUrl: 'https://api.companyenrich.com/logo/theverge.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId56,
- name: 'Gizmodo',
- description: 'A design, technology, science and science fiction website.',
- url: 'https://gizmodo.com',
- logoUrl: 'https://api.companyenrich.com/logo/gizmodo.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId57,
- name: 'Kotaku',
- description: 'A video game website and blog.',
- url: 'https://kotaku.com',
- logoUrl: 'https://api.companyenrich.com/logo/kotaku.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId58,
- name: 'Lifehacker',
- description: 'A weblog about life hacks and software.',
- url: 'https://lifehacker.com',
- logoUrl: 'https://api.companyenrich.com/logo/lifehacker.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId59,
- name: 'Mashable',
- description: 'A global, multi-platform media and entertainment company.',
- url: 'https://mashable.com',
- logoUrl: 'https://api.companyenrich.com/logo/mashable.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId60,
- name: 'Engadget',
- description: 'A multilingual technology blog network.',
- url: 'https://www.engadget.com',
- logoUrl: 'https://api.companyenrich.com/logo/engadget.com',
- sourceType: SourceType.blog,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-06-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-06-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId61,
- name: 'WhiteHouse.gov',
- description: 'Official website of the White House.',
- url: 'https://www.whitehouse.gov',
- logoUrl: 'https://api.companyenrich.com/logo/whitehouse.gov',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-07-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId62,
- name: 'GOV.UK',
- description: 'The official website for UK government services.',
- url: 'https://www.gov.uk',
- logoUrl: 'https://api.companyenrich.com/logo/gov.uk',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-07-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId63,
- name: 'Canada.ca',
- description: 'Official website of the Government of Canada.',
- url: 'https://www.canada.ca/en.html',
- logoUrl: 'https://api.companyenrich.com/logo/canada.ca',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[1], // Canada
- createdAt: DateTime.parse('2023-07-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId64,
- name: 'Australia.gov.au',
- description: 'Official website of the Australian Government.',
- url: 'https://www.australia.gov.au',
- logoUrl: 'https://api.companyenrich.com/logo/australia.gov.au',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[3], // Australia
- createdAt: DateTime.parse('2023-07-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId65,
- name: 'Bundesregierung.de',
- description: 'Official website of the German Federal Government.',
- url: 'https://www.bundesregierung.de/breg-de',
- logoUrl: 'https://api.companyenrich.com/logo/bundesregierung.de',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'de'),
- headquarters: countriesFixturesData[4], // Germany
- createdAt: DateTime.parse('2023-07-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId66,
- name: 'Gouvernement.fr',
- description: 'Official website of the French Government.',
- url: 'https://www.gouvernement.fr',
- logoUrl: 'https://api.companyenrich.com/logo/gouvernement.fr',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'fr'),
- headquarters: countriesFixturesData[5], // France
- createdAt: DateTime.parse('2023-07-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId67,
- name: 'Kantei.go.jp',
- description: 'Official website of the Prime Minister of Japan.',
- url: 'https://japan.kantei.go.jp',
- logoUrl: 'https://api.companyenrich.com/logo/kantei.go.jp',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[6], // Japan
- createdAt: DateTime.parse('2023-07-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId68,
- name: 'India.gov.in',
- description: 'National Portal of India.',
- url: 'https://www.india.gov.in',
- logoUrl: 'https://api.companyenrich.com/logo/india.gov.in',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[8], // India
- createdAt: DateTime.parse('2023-07-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId69,
- name: 'Gov.br',
- description: 'Official website of the Brazilian Government.',
- url: 'https://www.gov.br/pt-br',
- logoUrl: 'https://api.companyenrich.com/logo/gov.br',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'pt'),
- headquarters: countriesFixturesData[9], // Brazil
- createdAt: DateTime.parse('2023-07-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId70,
- name: 'English.gov.cn',
- description: 'Official web portal of the Chinese Government.',
- url: 'http://english.gov.cn',
- logoUrl: 'https://api.companyenrich.com/logo/gov.cn',
- sourceType: SourceType.governmentSource,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[7], // China
- createdAt: DateTime.parse('2023-07-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-07-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId71,
- name: 'Google News',
- description: 'A news aggregator service developed by Google.',
- url: 'https://news.google.com',
- logoUrl: 'https://api.companyenrich.com/logo/google.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId72,
- name: 'Apple News',
- description: 'A news aggregator app by Apple Inc.',
- url: 'https://www.apple.com/apple-news/',
- logoUrl: 'https://api.companyenrich.com/logo/apple.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId73,
- name: 'Feedly',
- description: 'A news aggregator application for various web browsers.',
- url: 'https://feedly.com',
- logoUrl: 'https://api.companyenrich.com/logo/feedly.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId74,
- name: 'Flipboard',
- description: 'A social-network aggregation, magazine-format mobile app.',
- url: 'https://flipboard.com',
- logoUrl: 'https://api.companyenrich.com/logo/flipboard.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId75,
- name: 'SmartNews',
- description: 'A mobile app for discovering news.',
- url: 'https://www.smartnews.com',
- logoUrl: 'https://api.companyenrich.com/logo/smartnews.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[6], // Japan
- createdAt: DateTime.parse('2023-08-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId76,
- name: 'Inoreader',
- description: 'A web-based content and RSS feed reader.',
- url: 'https://www.inoreader.com',
- logoUrl: 'https://api.companyenrich.com/logo/inoreader.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[13], // Bulgaria
- createdAt: DateTime.parse('2023-08-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId77,
- name: 'The Old Reader',
- description: 'A simple, web-based RSS reader.',
- url: 'https://theoldreader.com',
- logoUrl: 'https://api.companyenrich.com/logo/theoldreader.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId78,
- name: 'NewsBlur',
- description: 'A personal news reader.',
- url: 'https://newsblur.com',
- logoUrl: 'https://api.companyenrich.com/logo/newsblur.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId79,
- name: 'Pocket',
- description: 'An application for managing a reading list of articles.',
- url: 'https://getpocket.com',
- logoUrl: 'https://api.companyenrich.com/logo/getpocket.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId80,
- name: 'Digg',
- description: 'A news aggregator with a curated front page.',
- url: 'https://digg.com',
- logoUrl: 'https://api.companyenrich.com/logo/digg.com',
- sourceType: SourceType.aggregator,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-08-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-08-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId81,
- name: 'PR Newswire',
- description: 'A distributor of press releases.',
- url: 'https://www.prnewswire.com',
- logoUrl: 'https://api.companyenrich.com/logo/prnewswire.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId82,
- name: 'arXiv',
- description: 'An open-access archive for scholarly articles.',
- url: 'https://arxiv.org',
- logoUrl: 'https://api.companyenrich.com/logo/arxiv.org',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-02T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-02T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId83,
- name: 'The Lancet',
- description: 'A weekly peer-reviewed general medical journal.',
- url: 'https://www.thelancet.com',
- logoUrl: 'https://api.companyenrich.com/logo/thelancet.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[2], // United Kingdom
- createdAt: DateTime.parse('2023-09-03T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-03T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId84,
- name: 'Google AI Blog',
- description: 'The latest news from Google AI.',
- url: 'https://ai.googleblog.com',
- logoUrl: 'https://api.companyenrich.com/logo/googleblog.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-04T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-04T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId85,
- name: 'Microsoft PressPass',
- description: 'Official news and information from Microsoft.',
- url: 'https://news.microsoft.com',
- logoUrl: 'https://api.companyenrich.com/logo/microsoft.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-05T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-05T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId86,
- name: 'JSTOR',
- description: 'A digital library of academic journals, books, and sources.',
- url: 'https://www.jstor.org',
- logoUrl: 'https://api.companyenrich.com/logo/jstor.org',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-06T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-06T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId87,
- name: 'Business Wire',
- description: 'A company that disseminates press releases.',
- url: 'https://www.businesswire.com',
- logoUrl: 'https://api.companyenrich.com/logo/businesswire.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-07T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-07T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId88,
- name: 'PLOS ONE',
- description: 'A peer-reviewed open access scientific journal.',
- url: 'https://journals.plos.org/plosone/',
- logoUrl: 'https://api.companyenrich.com/logo/plos.org',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-08T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-08T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId89,
- name: 'Apple Newsroom',
- description: 'Official press releases from Apple.',
- url: 'https://www.apple.com/newsroom/',
- logoUrl: 'https://api.companyenrich.com/logo/apple.com',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-09T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-09T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Source(
- id: kSourceId90,
- name: 'The New England Journal of Medicine',
- description: 'A weekly medical journal.',
- url: 'https://www.nejm.org',
- logoUrl: 'https://api.companyenrich.com/logo/nejm.org',
- sourceType: SourceType.other,
- language: languagesFixturesData.firstWhere((lang) => lang.code == 'en'),
- headquarters: countriesFixturesData[0], // United States
- createdAt: DateTime.parse('2023-09-10T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-09-10T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
+/// Generates a list of predefined sources for fixture data.
+///
+/// This function can be configured to generate sources in either English or
+/// Arabic.
+List getSourcesFixturesData({String languageCode = 'en'}) {
+ // Ensure only approved languages are used, default to 'en'.
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+
+ final sources = [];
+ for (var i = 0; i < _sourceIds.length; i++) {
+ final id = _sourceIds[i];
+ final name = _namesByLang[resolvedLanguageCode]![i];
+ final description = _descriptionsByLang[resolvedLanguageCode]![i];
+ final url = _urls[i];
+ final logoUrl = 'https://api.companyenrich.com/logo/${url.split('/')[2]}';
+ final sourceType = _sourceTypes[i];
+ final language = languagesFixturesData.firstWhere(
+ (lang) => lang.code == _langCodes[i],
+ );
+ final headquarters = countriesFixturesData[_countryIndexes[i]];
+
+ sources.add(
+ Source(
+ id: id,
+ name: name,
+ description: description,
+ url: url,
+ logoUrl: logoUrl,
+ sourceType: sourceType,
+ language: language,
+ headquarters: headquarters,
+ createdAt: DateTime.parse(
+ '2023-01-01T10:00:00.000Z',
+ ).add(Duration(days: i)),
+ updatedAt: DateTime.parse(
+ '2023-01-01T10:00:00.000Z',
+ ).add(Duration(days: i)),
+ status: ContentStatus.active,
+ ),
+ );
+ }
+ return sources;
+}
+
+const _sourceIds = [
+ kSourceId1,
+ kSourceId2,
+ kSourceId3,
+ kSourceId4,
+ kSourceId5,
+ kSourceId6,
+ kSourceId7,
+ kSourceId8,
+ kSourceId9,
+ kSourceId10,
+ kSourceId11,
+ kSourceId12,
+ kSourceId13,
+ kSourceId14,
+ kSourceId15,
+ kSourceId16,
+ kSourceId17,
+ kSourceId18,
+ kSourceId19,
+ kSourceId20,
+ kSourceId21,
+ kSourceId22,
+ kSourceId23,
+ kSourceId24,
+ kSourceId25,
+ kSourceId26,
+ kSourceId27,
+ kSourceId28,
+ kSourceId29,
+ kSourceId30,
+ kSourceId31,
+ kSourceId32,
+ kSourceId33,
+ kSourceId34,
+ kSourceId35,
+ kSourceId36,
+ kSourceId37,
+ kSourceId38,
+ kSourceId39,
+ kSourceId40,
+ kSourceId41,
+ kSourceId42,
+ kSourceId43,
+ kSourceId44,
+ kSourceId45,
+ kSourceId46,
+ kSourceId47,
+ kSourceId48,
+ kSourceId49,
+ kSourceId50,
+ kSourceId51,
+ kSourceId52,
+ kSourceId53,
+ kSourceId54,
+ kSourceId55,
+ kSourceId56,
+ kSourceId57,
+ kSourceId58,
+ kSourceId59,
+ kSourceId60,
+ kSourceId61,
+ kSourceId62,
+ kSourceId63,
+ kSourceId64,
+ kSourceId65,
+ kSourceId66,
+ kSourceId67,
+ kSourceId68,
+ kSourceId69,
+ kSourceId70,
+ kSourceId71,
+ kSourceId72,
+ kSourceId73,
+ kSourceId74,
+ kSourceId75,
+ kSourceId76,
+ kSourceId77,
+ kSourceId78,
+ kSourceId79,
+ kSourceId80,
+ kSourceId81,
+ kSourceId82,
+ kSourceId83,
+ kSourceId84,
+ kSourceId85,
+ kSourceId86,
+ kSourceId87,
+ kSourceId88,
+ kSourceId89,
+ kSourceId90,
+];
+
+final Map> _namesByLang = {
+ 'en': [
+ 'TechCrunch',
+ 'BBC News',
+ 'The New York Times',
+ 'The Guardian',
+ 'CNN',
+ 'Reuters',
+ 'Al Jazeera English',
+ 'Xinhua News Agency',
+ 'The Times of India',
+ 'Folha de S.Paulo',
+ 'San Francisco Chronicle',
+ 'Manchester Evening News',
+ 'The Sydney Morning Herald',
+ 'Le Parisien',
+ 'The Toronto Star',
+ 'Berliner Morgenpost',
+ 'The Asahi Shimbun (Tokyo)',
+ 'Hindustan Times (Mumbai)',
+ 'O Globo (Rio de Janeiro)',
+ 'La Vanguardia (Barcelona)',
+ 'USA Today',
+ 'The Globe and Mail',
+ 'The Australian',
+ 'Le Monde',
+ 'Frankfurter Allgemeine Zeitung',
+ 'The Yomiuri Shimbun',
+ "People's Daily",
+ 'O Estado de S. Paulo',
+ 'El País',
+ 'Corriere della Sera',
+ 'CNN International',
+ 'BBC World News',
+ 'The Economist',
+ 'France 24',
+ 'Deutsche Welle',
+ 'The Wall Street Journal',
+ 'Associated Press (AP)',
+ 'Agence France-Presse (AFP)',
+ 'RT',
+ 'CGTN',
+ 'ESPN',
+ 'Nature',
+ 'The Hollywood Reporter',
+ 'Vogue',
+ 'National Geographic',
+ 'Wired',
+ 'Bon Appétit',
+ 'Architectural Digest',
+ 'Car and Driver',
+ 'PC Gamer',
+ 'Stratechery by Ben Thompson',
+ 'Daring Fireball',
+ 'Wait But Why',
+ 'Smitten Kitchen',
+ 'The Verge',
+ 'Gizmodo',
+ 'Kotaku',
+ 'Lifehacker',
+ 'Mashable',
+ 'Engadget',
+ 'WhiteHouse.gov',
+ 'GOV.UK',
+ 'Canada.ca',
+ 'Australia.gov.au',
+ 'Bundesregierung.de',
+ 'Gouvernement.fr',
+ 'Kantei.go.jp',
+ 'India.gov.in',
+ 'Gov.br',
+ 'English.gov.cn',
+ 'Google News',
+ 'Apple News',
+ 'Feedly',
+ 'Flipboard',
+ 'SmartNews',
+ 'Inoreader',
+ 'The Old Reader',
+ 'NewsBlur',
+ 'Pocket',
+ 'Digg',
+ 'PR Newswire',
+ 'arXiv',
+ 'The Lancet',
+ 'Google AI Blog',
+ 'Microsoft PressPass',
+ 'JSTOR',
+ 'Business Wire',
+ 'PLOS ONE',
+ 'Apple Newsroom',
+ 'The New England Journal of Medicine',
+ ],
+ 'ar': [
+ 'تك كرانش',
+ 'بي بي سي نيوز',
+ 'نيويورك تايمز',
+ 'الجارديان',
+ 'سي إن إن',
+ 'رويترز',
+ 'الجزيرة الإنجليزية',
+ 'وكالة أنباء شينخوا',
+ 'تايمز أوف إنديا',
+ 'فولها دي ساو باولو',
+ 'سان فرانسيسكو كرونيكل',
+ 'مانشستر إيفننغ نيوز',
+ 'سيدني مورنينغ هيرالد',
+ 'لو باريزيان',
+ 'تورنتو ستار',
+ 'برلينر مورغنبوست',
+ 'أساهي شيمبون (طوكيو)',
+ 'هندوستان تايمز (مومباي)',
+ 'أو جلوبو (ريو دي جانيرو)',
+ 'لا فانجارديا (برشلونة)',
+ 'يو إس إيه توداي',
+ 'ذا جلوب آند ميل',
+ 'ذي أستراليان',
+ 'لوموند',
+ 'فرانكفورتر ألجماينه تسايتונג',
+ 'يomiuri Shimbun',
+ 'صحيفة الشعب اليومية',
+ 'أو إستาดو دي ساو باولو',
+ 'إل باييس',
+ 'كورييري ديلا سيرا',
+ 'سي إن إن الدولية',
+ 'بي بي سي وورلد نيوز',
+ 'ذي إيكونوميست',
+ 'فرانس 24',
+ 'دويتشه فيله',
+ 'وول ستريت جورنال',
+ 'أسوشيتد برس (AP)',
+ 'وكالة فرانس برس (AFP)',
+ 'آر تي',
+ 'سي جي تي إن',
+ 'إي إس بي إن',
+ 'نيتشر',
+ 'هوليوود ريبورتر',
+ 'فوغ',
+ 'ناشيونال جيوغرافيك',
+ 'وايرد',
+ 'بون أبيتيت',
+ 'أركيتكتشرال دايجست',
+ 'كار آند درايفر',
+ 'بي سي جيمر',
+ 'סטרטכרי بقلم بن طومسون',
+ 'دارينج فايربول',
+ 'ويت بات واي',
+ 'สมิตเทน คิทเช่น',
+ 'ذا فيرج',
+ 'جيزمودو',
+ 'كوتاكو',
+ 'لايف هاكر',
+ 'ماشابل',
+ 'إنガジェット',
+ 'WhiteHouse.gov',
+ 'GOV.UK',
+ 'Canada.ca',
+ 'Australia.gov.au',
+ 'Bundesregierung.de',
+ 'Gouvernement.fr',
+ 'Kantei.go.jp',
+ 'India.gov.in',
+ 'Gov.br',
+ 'English.gov.cn',
+ 'أخبار جوجل',
+ 'أخبار أبل',
+ 'فيدلي',
+ 'فليبورد',
+ 'سمارت نيوز',
+ 'إينوريدر',
+ 'ذا أولد ريدر',
+ 'نيوز بلور',
+ 'بوكيت',
+ 'ديغ',
+ 'بي آر نيوزواير',
+ 'أرخايف',
+ 'ذا لانسيت',
+ 'مدونة جوجل للذكاء الاصطناعي',
+ 'مايكروسوفت بريس باس',
+ 'جيستور',
+ 'بزنس واير',
+ 'بلوس ون',
+ 'غرفة أخبار أبل',
+ 'مجلة نيو إنجلاند الطبية',
+ ],
+};
+
+final Map> _descriptionsByLang = {
+ 'en': [
+ 'Leading online publisher of technology news.',
+ 'Breaking news, sport, TV, radio and a whole lot more.',
+ 'Breaking News, World News & Multimedia.',
+ 'Latest news, sport, business, comment and reviews from the Guardian.',
+ 'Breaking News, Latest News and Videos.',
+ 'Business, financial, national and international news.',
+ 'News, analysis, and opinion from the Middle East and around the world.',
+ "Official press agency of the People's Republic of China.",
+ 'Latest and Breaking News from India.',
+ 'Brazilian daily newspaper.',
+ 'News from the San Francisco Bay Area.',
+ 'Covering Greater Manchester, UK.',
+ 'Independent journalism for Sydney, Australia.',
+ 'Local news for Paris and the Île-de-France region.',
+ 'News and stories for Toronto, Canada.',
+ 'Daily news for Berlin, Germany.',
+ 'Local and national news from a Tokyo perspective.',
+ 'Latest news from Mumbai, India.',
+ 'News from Rio de Janeiro, Brazil.',
+ 'News from Barcelona and Catalonia, Spain.',
+ 'National news from across the United States.',
+ "Canada's national newspaper.",
+ 'National news of Australia.',
+ 'French national daily newspaper.',
+ 'German national newspaper.',
+ 'Japanese national newspaper.',
+ 'Official newspaper of the Central Committee of the CCP.',
+ 'Brazilian national newspaper.',
+ 'Spanish national daily newspaper.',
+ 'Italian national daily newspaper.',
+ 'Global news coverage from CNN.',
+ 'International news from the BBC.',
+ 'In-depth analysis of international news and business.',
+ 'French perspective on international current events.',
+ "Germany's international broadcaster.",
+ 'Global business and financial news.',
+ 'Global news network.',
+ 'International news agency based in Paris.',
+ 'Russian state-funded international television network.',
+ 'Chinese state-funded international television network.',
+ 'The worldwide leader in sports.',
+ 'International journal of science.',
+ 'The definitive voice of the entertainment industry.',
+ 'Fashion, beauty, and lifestyle.',
+ 'Science, exploration, and adventure.',
+ 'How technology is changing every aspect of our lives.',
+ 'Food and cooking magazine.',
+ 'The international design authority.',
+ 'Automotive news and reviews.',
+ 'Global authority on PC games.',
+ 'Analysis of the strategy and business of technology.',
+ 'By John Gruber. On technology and Apple.',
+ 'A popular long-form, stick-figure-illustrated blog.',
+ 'A home cooking blog from a tiny kitchen in New York City.',
+ 'A technology news and media network operated by Vox Media.',
+ 'A design, technology, science and science fiction website.',
+ 'A video game website and blog.',
+ 'A weblog about life hacks and software.',
+ 'A global, multi-platform media and entertainment company.',
+ 'A multilingual technology blog network.',
+ 'Official website of the White House.',
+ 'The official website for UK government services.',
+ 'Official website of the Government of Canada.',
+ 'Official website of the Australian Government.',
+ 'Official website of the German Federal Government.',
+ 'Official website of the French Government.',
+ 'Official website of the Prime Minister of Japan.',
+ 'National Portal of India.',
+ 'Official website of the Brazilian Government.',
+ 'Official web portal of the Chinese Government.',
+ 'A news aggregator service developed by Google.',
+ 'A news aggregator app by Apple Inc.',
+ 'A news aggregator application for various web browsers.',
+ 'A social-network aggregation, magazine-format mobile app.',
+ 'A mobile app for discovering news.',
+ 'A web-based content and RSS feed reader.',
+ 'A simple, web-based RSS reader.',
+ 'A personal news reader.',
+ 'An application for managing a reading list of articles.',
+ 'A news aggregator with a curated front page.',
+ 'A distributor of press releases.',
+ 'An open-access archive for scholarly articles.',
+ 'A weekly peer-reviewed general medical journal.',
+ 'The latest news from Google AI.',
+ 'Official news and information from Microsoft.',
+ 'A digital library of academic journals, books, and sources.',
+ 'A company that disseminates press releases.',
+ 'A peer-reviewed open access scientific journal.',
+ 'Official press releases from Apple.',
+ 'A weekly medical journal.',
+ ],
+ 'ar': [
+ 'الناشر الرائد عبر الإنترنت لأخبار التكنولوجيا.',
+ 'الأخبار العاجلة والرياضة والتلفزيون والراديو والكثير.',
+ 'الأخبار العاجلة والأخبار العالمية والوسائط المتعددة.',
+ 'آخر الأخبار والرياضة والأعمال والتعليقات والمراجعات من الجارديان.',
+ 'الأخبار العاجلة وآخر الأخبار ومقاطع الفيديو.',
+ 'الأعمال والأخبار المالية والوطنية والدولية.',
+ 'الأخبار والتحليلات والآراء من الشرق الأوسط وحول العالم.',
+ 'وكالة الأنباء الرسمية لجمهورية الصين الشعبية.',
+ 'آخر الأخبار العاجلة من الهند.',
+ 'صحيفة يومية برازيلية.',
+ 'أخبار من منطقة خليج سان فرانسيسكو.',
+ 'تغطية مانشستر الكبرى، المملكة المتحدة.',
+ 'صحافة مستقلة لسيدني، أستراليا.',
+ 'الأخبار المحلية لباريس ومنطقة إيل دو فرانس.',
+ 'الأخبار والقصص لتورنتو، كندا.',
+ 'الأخبار اليومية لبرلين، ألمانيا.',
+ 'الأخبار المحلية والوطنية من منظور طوكيو.',
+ 'آخر الأخبار من مومباي، الهند.',
+ 'أخبار من ريو دي جانيرو، البرازيل.',
+ 'أخبار من برشلونة وكاتالونيا، إسبانيا.',
+ 'الأخبار الوطنية من جميع أنحاء الولايات المتحدة.',
+ 'الصحيفة الوطنية الكندية.',
+ 'الأخبار الوطنية لأستراليا.',
+ 'صحيفة يومية وطنية فرنسية.',
+ 'صحيفة وطنية ألمانية.',
+ 'صحيفة وطنية يابانية.',
+ 'الصحيفة الرسمية للجنة المركزية للحزب الشيوعي الصيني.',
+ 'صحيفة وطنية برازيلية.',
+ 'صحيفة يومية وطنية إسبانية.',
+ 'صحيفة يومية وطنية إيطالية.',
+ 'تغطية إخبارية عالمية من CNN.',
+ 'الأخبار الدولية من بي بي سي.',
+ 'تحليل متعمق للأخبار الدولية والأعمال.',
+ 'منظور فرنسي للأحداث الجارية الدولية.',
+ 'المذيع الدولي لألمانيا.',
+ 'الأخبار التجارية والمالية العالمية.',
+ 'شبكة أخبار عالمية.',
+ 'وكالة أنباء دولية مقرها باريس.',
+ 'شبكة تلفزيونية دولية ممولة من الدولة الروسية.',
+ 'شبكة تلفزيونية دولية ممولة من الدولة الصينية.',
+ 'الشركة الرائدة عالميًا في مجال الرياضة.',
+ 'مجلة دولية للعلوم.',
+ 'الصوت النهائي لصناعة الترفيه.',
+ 'الموضة والجمال وأسلوب الحياة.',
+ 'العلوم والاستكشاف والمغامرة.',
+ 'كيف تغير التكنولوجيا كل جانب من جوانب حياتنا.',
+ 'مجلة طعام وطبخ.',
+ 'السلطة الدولية للتصميم.',
+ 'أخبار ومراجعات السيارات.',
+ 'السلطة العالمية في ألعاب الكمبيوتر.',
+ 'تحليل استراتيجية وأعمال التكنولوجيا.',
+ 'بقلم جون غروبر. عن التكنولوجيا وأبل.',
+ 'مدونة شهيرة طويلة ومصورة بشخصيات كرتونية.',
+ 'مدونة طبخ منزلية من مطبخ صغير في مدينة نيويورك.',
+ 'شبكة أخبار ووسائط تكنولوجية تديرها Vox Media.',
+ 'موقع للتصميم والتكنولوجيا والعلوم والخيال العلمي.',
+ 'موقع ومدونة لألعاب الفيديو.',
+ 'مدونة حول حيل الحياة والبرامج.',
+ 'شركة إعلام وترفيه عالمية متعددة المنصات.',
+ 'شبكة مدونات تكنولوجية متعددة اللغات.',
+ 'الموقع الرسمي للبيت الأبيض.',
+ 'الموقع الرسمي لخدمات حكومة المملكة المتحدة.',
+ 'الموقع الرسمي لحكومة كندا.',
+ 'الموقع الرسمي للحكومة الأسترالية.',
+ 'الموقع الرسمي للحكومة الفيدرالية الألمانية.',
+ 'الموقع الرسمي للحكومة الفرنسية.',
+ 'الموقع الرسمي لرئيس وزراء اليابان.',
+ 'البوابة الوطنية للهند.',
+ 'الموقع الرسمي للحكومة البرازيلية.',
+ 'البوابة الإلكترونية الرسمية للحكومة الصينية.',
+ 'خدمة تجميع الأخبار التي طورتها جوجل.',
+ 'تطبيق مجمع أخبار من شركة أبل.',
+ 'تطبيق مجمع أخبار لمختلف متصفحات الويب.',
+ 'تطبيق جوال لتجميع الشبكات الاجتماعية بتنسيق مجلة.',
+ 'تطبيق جوال لاكتشاف الأخبار.',
+ 'قارئ محتوى وخلاصة RSS على شبكة الإنترنت.',
+ 'قارئ RSS بسيط على شبكة الإنترنت.',
+ 'قارئ أخبار شخصي.',
+ 'تطبيق لإدارة قائمة قراءة المقالات.',
+ 'مجمع أخبار بصفحة أمامية منسقة.',
+ 'موزع للبيانات الصحفية.',
+ 'أرشيف مفتوح الوصول للمقالات العلمية.',
+ 'مجلة طبية عامة أسبوعية محكمة.',
+ 'آخر الأخبار من Google AI.',
+ 'الأخبار والمعلومات الرسمية من مايكروسوفت.',
+ 'مكتبة رقمية للمجلات الأكاديمية والكتب والمصادر.',
+ 'شركة تنشر البيانات الصحفية.',
+ 'مجلة علمية مفتوحة الوصول ومحكمة.',
+ 'البيانات الصحفية الرسمية من Apple.',
+ 'مجلة طبية أسبوعية.',
+ ],
+};
+
+const _urls = [
+ 'https://techcrunch.com',
+ 'https://www.bbc.com/news',
+ 'https://www.nytimes.com',
+ 'https://www.theguardian.com',
+ 'https://edition.cnn.com',
+ 'https://www.reuters.com',
+ 'https://www.aljazeera.com',
+ 'http://www.xinhuanet.com/english/',
+ 'https://timesofindia.indiatimes.com/',
+ 'https://www.folha.uol.com.br/',
+ 'https://www.sfchronicle.com',
+ 'https://www.manchestereveningnews.co.uk',
+ 'https://www.smh.com.au',
+ 'https://www.leparisien.fr',
+ 'https://www.thestar.com',
+ 'https://www.morgenpost.de',
+ 'https://www.asahi.com/area/tokyo/',
+ 'https://www.hindustantimes.com/mumbai-news',
+ 'https://oglobo.globo.com/rio/',
+ 'https://www.lavanguardia.com/local/barcelona',
+ 'https://www.usatoday.com',
+ 'https://www.theglobeandmail.com',
+ 'https://www.theaustralian.com.au',
+ 'https://www.lemonde.fr',
+ 'https://www.faz.net',
+ 'https://www.yomiuri.co.jp',
+ 'http://en.people.cn',
+ 'https://www.estadao.com.br',
+ 'https://elpais.com',
+ 'https://www.corriere.it',
+ 'https://edition.cnn.com',
+ 'https://www.bbc.com/news/world',
+ 'https://www.economist.com',
+ 'https://www.france24.com/en/',
+ 'https://www.dw.com/en/',
+ 'https://www.wsj.com',
+ 'https://apnews.com',
+ 'https://www.afp.com/en',
+ 'https://www.rt.com',
+ 'https://www.cgtn.com',
+ 'https://www.espn.com',
+ 'https://www.nature.com',
+ 'https://www.hollywoodreporter.com',
+ 'https://www.vogue.com',
+ 'https://www.nationalgeographic.com',
+ 'https://www.wired.com',
+ 'https://www.bonappetit.com',
+ 'https://www.architecturaldigest.com',
+ 'https://www.caranddriver.com',
+ 'https://www.pcgamer.com',
+ 'https://stratechery.com',
+ 'https://daringfireball.net',
+ 'https://waitbutwhy.com',
+ 'https://smittenkitchen.com',
+ 'https://www.theverge.com',
+ 'https://gizmodo.com',
+ 'https://kotaku.com',
+ 'https://lifehacker.com',
+ 'https://mashable.com',
+ 'https://www.engadget.com',
+ 'https://www.whitehouse.gov',
+ 'https://www.gov.uk',
+ 'https://www.canada.ca/en.html',
+ 'https://www.australia.gov.au',
+ 'https://www.bundesregierung.de/breg-de',
+ 'https://www.gouvernement.fr',
+ 'https://japan.kantei.go.jp',
+ 'https://www.india.gov.in',
+ 'https://www.gov.br/pt-br',
+ 'http://english.gov.cn',
+ 'https://news.google.com',
+ 'https://www.apple.com/apple-news/',
+ 'https://feedly.com',
+ 'https://flipboard.com',
+ 'https://www.smartnews.com',
+ 'https://www.inoreader.com',
+ 'https://theoldreader.com',
+ 'https://newsblur.com',
+ 'https://getpocket.com',
+ 'https://digg.com',
+ 'https://www.prnewswire.com',
+ 'https://arxiv.org',
+ 'https://www.thelancet.com',
+ 'https://ai.googleblog.com',
+ 'https://news.microsoft.com',
+ 'https://www.jstor.org',
+ 'https://www.businesswire.com',
+ 'https://journals.plos.org/plosone/',
+ 'https://www.apple.com/newsroom/',
+ 'https://www.nejm.org',
+];
+
+const _sourceTypes = [
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.newsAgency,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.localNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.nationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.internationalNewsOutlet,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.specializedPublisher,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.blog,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.governmentSource,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.aggregator,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+ SourceType.other,
+];
+
+const _langCodes = [
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'pt',
+ 'en',
+ 'en',
+ 'en',
+ 'fr',
+ 'en',
+ 'de',
+ 'ja',
+ 'en',
+ 'pt',
+ 'es',
+ 'en',
+ 'en',
+ 'en',
+ 'fr',
+ 'de',
+ 'ja',
+ 'en',
+ 'pt',
+ 'es',
+ 'it',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'de',
+ 'en',
+ 'en',
+ 'fr',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'de',
+ 'fr',
+ 'en',
+ 'en',
+ 'pt',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+ 'en',
+];
+
+const _countryIndexes = [
+ 0,
+ 2,
+ 0,
+ 2,
+ 0,
+ 0,
+ 0,
+ 7,
+ 8,
+ 9,
+ 0,
+ 2,
+ 3,
+ 5,
+ 1,
+ 4,
+ 6,
+ 8,
+ 9,
+ 10,
+ 0,
+ 1,
+ 3,
+ 5,
+ 4,
+ 6,
+ 7,
+ 9,
+ 10,
+ 11,
+ 0,
+ 2,
+ 2,
+ 5,
+ 4,
+ 0,
+ 0,
+ 5,
+ 12,
+ 7,
+ 0,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2,
+ 1,
+ 3,
+ 4,
+ 5,
+ 6,
+ 8,
+ 9,
+ 7,
+ 0,
+ 0,
+ 0,
+ 0,
+ 6,
+ 13,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2,
];
diff --git a/lib/src/fixtures/topics.dart b/lib/src/fixtures/topics.dart
index 331b55d1..82ea603d 100644
--- a/lib/src/fixtures/topics.dart
+++ b/lib/src/fixtures/topics.dart
@@ -2,96 +2,113 @@ import 'package:core/src/enums/enums.dart';
import 'package:core/src/fixtures/fixture_ids.dart';
import 'package:core/src/models/entities/topic.dart';
-/// A list of predefined topics for fixture data.
-final topicsFixturesData = [
- Topic(
- id: kTopicId1,
- name: 'Technology',
- description: 'News and updates from the world of technology.',
- iconUrl: 'https://example.com/icons/tech.png',
- createdAt: DateTime.parse('2023-01-01T10:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-01T10:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId2,
- name: 'Sports',
- description: 'Latest scores, highlights, and news from sports.',
- iconUrl: 'https://example.com/icons/sports.png',
- createdAt: DateTime.parse('2023-01-02T11:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-02T11:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId3,
- name: 'Politics',
- description: 'Updates on political events and government policies.',
- iconUrl: 'https://example.com/icons/politics.png',
- createdAt: DateTime.parse('2023-01-03T12:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-03T12:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId4,
- name: 'Science',
- description: 'Discoveries and breakthroughs in scientific research.',
- iconUrl: 'https://example.com/icons/science.png',
- createdAt: DateTime.parse('2023-01-04T13:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-04T13:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId5,
- name: 'Health',
- description: 'Information and advice on health and wellness.',
- iconUrl: 'https://example.com/icons/health.png',
- createdAt: DateTime.parse('2023-01-05T14:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-05T14:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId6,
- name: 'Entertainment',
- description: 'News from movies, music, and pop culture.',
- iconUrl: 'https://example.com/icons/entertainment.png',
- createdAt: DateTime.parse('2023-01-06T15:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-06T15:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId7,
- name: 'Business',
- description: 'Financial markets, economy, and corporate news.',
- iconUrl: 'https://example.com/icons/business.png',
- createdAt: DateTime.parse('2023-01-07T16:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-07T16:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId8,
- name: 'Travel',
- description: 'Guides, tips, and news for travelers.',
- iconUrl: 'https://example.com/icons/travel.png',
- createdAt: DateTime.parse('2023-01-08T17:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-08T17:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId9,
- name: 'Food',
- description: 'Recipes, culinary trends, and food industry news.',
- iconUrl: 'https://example.com/icons/food.png',
- createdAt: DateTime.parse('2023-01-09T18:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-09T18:00:00.000Z'),
- status: ContentStatus.active,
- ),
- Topic(
- id: kTopicId10,
- name: 'Education',
- description: 'Developments in education and learning.',
- iconUrl: 'https://example.com/icons/education.png',
- createdAt: DateTime.parse('2023-01-10T19:00:00.000Z'),
- updatedAt: DateTime.parse('2023-01-10T19:00:00.000Z'),
- status: ContentStatus.active,
- ),
+/// Generates a list of predefined topics for fixture data.
+///
+/// This function can be configured to generate topics in either English or
+/// Arabic.
+List getTopicsFixturesData({String languageCode = 'en'}) {
+ // Ensure only approved languages are used, default to 'en'.
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+
+ final topics = [];
+ for (var i = 0; i < _topicIds.length; i++) {
+ topics.add(
+ Topic(
+ id: _topicIds[i],
+ name: _namesByLang[resolvedLanguageCode]![i],
+ description: _descriptionsByLang[resolvedLanguageCode]![i],
+ iconUrl: 'https://example.com/icons/${_iconNames[i]}.png',
+ createdAt: DateTime.parse(
+ '2023-01-01T10:00:00.000Z',
+ ).add(Duration(days: i)),
+ updatedAt: DateTime.parse(
+ '2023-01-01T10:00:00.000Z',
+ ).add(Duration(days: i)),
+ status: ContentStatus.active,
+ ),
+ );
+ }
+ return topics;
+}
+
+const _topicIds = [
+ kTopicId1,
+ kTopicId2,
+ kTopicId3,
+ kTopicId4,
+ kTopicId5,
+ kTopicId6,
+ kTopicId7,
+ kTopicId8,
+ kTopicId9,
+ kTopicId10,
+];
+
+const _iconNames = [
+ 'tech',
+ 'sports',
+ 'politics',
+ 'science',
+ 'health',
+ 'entertainment',
+ 'business',
+ 'travel',
+ 'food',
+ 'education',
];
+
+final Map> _namesByLang = {
+ 'en': [
+ 'Technology',
+ 'Sports',
+ 'Politics',
+ 'Science',
+ 'Health',
+ 'Entertainment',
+ 'Business',
+ 'Travel',
+ 'Food',
+ 'Education',
+ ],
+ 'ar': [
+ 'التكنولوجيا',
+ 'الرياضة',
+ 'السياسة',
+ 'العلوم',
+ 'الصحة',
+ 'الترفيه',
+ 'الأعمال',
+ 'السفر',
+ 'الطعام',
+ 'التعليم',
+ ],
+};
+
+final Map> _descriptionsByLang = {
+ 'en': [
+ 'News and updates from the world of technology.',
+ 'Latest scores, highlights, and news from sports.',
+ 'Updates on political events and government policies.',
+ 'Discoveries and breakthroughs in scientific research.',
+ 'Information and advice on health and wellness.',
+ 'News from movies, music, and pop culture.',
+ 'Financial markets, economy, and corporate news.',
+ 'Guides, tips, and news for travelers.',
+ 'Recipes, culinary trends, and food industry news.',
+ 'Developments in education and learning.',
+ ],
+ 'ar': [
+ 'أخبار وتحديثات من عالم التكنولوجيا.',
+ 'آخر النتائج والأهداف والأخبار من عالم الرياضة.',
+ 'تحديثات حول الأحداث السياسية والسياسات الحكومية.',
+ 'اكتشافات وإنجازات في البحث العلمي.',
+ 'معلومات ونصائح حول الصحة والعافية.',
+ 'أخبار من الأفلام والموسيقى وثقافة البوب.',
+ 'الأسواق المالية والاقتصاد وأخبار الشركات.',
+ 'أدلة ونصائح وأخبار للمسافرين.',
+ 'وصفات واتجاهات الطهي وأخبار صناعة المواد الغذائية.',
+ 'التطورات في التعليم والتعلم.',
+ ],
+};
diff --git a/lib/src/fixtures/user_content_preferences.dart b/lib/src/fixtures/user_content_preferences.dart
index 48f6c701..787b3f31 100644
--- a/lib/src/fixtures/user_content_preferences.dart
+++ b/lib/src/fixtures/user_content_preferences.dart
@@ -1,101 +1,117 @@
import 'package:core/core.dart';
-/// User Content Preferences Demo Data
-final List userContentPreferencesFixturesData = [
- UserContentPreferences(
- id: kAdminUserId,
- followedCountries: const [],
- followedSources: [
- sourcesFixturesData[0], // TechCrunch
- sourcesFixturesData[1], // BBC News
- sourcesFixturesData[10], // San Francisco Chronicle
- sourcesFixturesData[40], // ESPN
- ],
- followedTopics: [
- topicsFixturesData[0], // Technology
- topicsFixturesData[1], // Sports
- topicsFixturesData[6], // Business
- topicsFixturesData[7], // Travel
- ],
- savedHeadlines: [headlinesFixturesData[0], headlinesFixturesData[10]],
- savedHeadlineFilters: savedHeadlineFiltersFixturesData
- .map((e) => e.copyWith(userId: kAdminUserId))
- .toList(),
- savedSourceFilters: savedSourceFiltersFixturesData
- .map((e) => e.copyWith(userId: kAdminUserId))
- .toList(),
- ),
- UserContentPreferences(
- id: kUser1Id, // Publisher (Premium)
- followedCountries: const [],
- followedSources: [
- sourcesFixturesData[0], // TechCrunch
- sourcesFixturesData[1], // BBC News
- ],
- followedTopics: [
- topicsFixturesData[0], // Technology
- topicsFixturesData[6], // Business
- ],
- savedHeadlines: [headlinesFixturesData[2], headlinesFixturesData[3]],
- savedHeadlineFilters: savedHeadlineFiltersFixturesData
- .map((e) => e.copyWith(userId: kUser1Id))
- .toList(),
- savedSourceFilters: savedSourceFiltersFixturesData
- .map((e) => e.copyWith(userId: kUser1Id))
- .toList(),
- ),
- UserContentPreferences(
- id: kUser2Id, // Publisher (Standard)
- followedCountries: const [],
- followedSources: [
- sourcesFixturesData[3], // The Guardian
- sourcesFixturesData[4], // CNN
- ],
- followedTopics: [
- topicsFixturesData[2], // Politics
- topicsFixturesData[4], // Health
- ],
- savedHeadlines: [headlinesFixturesData[4], headlinesFixturesData[5]],
- savedHeadlineFilters: savedHeadlineFiltersFixturesData
- .map((e) => e.copyWith(userId: kUser2Id))
- .toList(),
- savedSourceFilters: savedSourceFiltersFixturesData
- .map((e) => e.copyWith(userId: kUser2Id))
- .toList(),
- ),
- // Add preferences for users 3-10
- ...List.generate(8, (index) {
- final userId = [
- kUser3Id,
- kUser4Id,
- kUser5Id,
- kUser6Id,
- kUser7Id,
- kUser8Id,
- kUser9Id,
- kUser10Id,
- ][index];
- return UserContentPreferences(
- id: userId,
+/// Generates a list of predefined user content preferences for fixture data.
+///
+/// This function can be configured to generate preferences in either English or
+/// Arabic, which affects the nested fixture data like topics and sources.
+List getUserContentPreferencesFixturesData({
+ String languageCode = 'en',
+}) {
+ // Ensure only approved languages are used, default to 'en'.
+ final resolvedLanguageCode = ['en', 'ar'].contains(languageCode)
+ ? languageCode
+ : 'en';
+
+ // Get language-specific fixtures
+ final sources = getSourcesFixturesData(languageCode: resolvedLanguageCode);
+ final topics = getTopicsFixturesData(languageCode: resolvedLanguageCode);
+ final headlines = getHeadlinesFixturesData(
+ languageCode: resolvedLanguageCode,
+ );
+ final savedHeadlineFilters = getSavedHeadlineFiltersFixturesData(
+ languageCode: resolvedLanguageCode,
+ );
+ final savedSourceFilters = getSavedSourceFiltersFixturesData(
+ languageCode: resolvedLanguageCode,
+ );
+
+ return [
+ UserContentPreferences(
+ id: kAdminUserId,
followedCountries: const [],
followedSources: [
- sourcesFixturesData[index % 10],
- sourcesFixturesData[(index + 1) % 10],
+ sources[0], // TechCrunch
+ sources[1], // BBC News
+ sources[10], // San Francisco Chronicle
+ sources[40], // ESPN
],
followedTopics: [
- topicsFixturesData[index % 5],
- topicsFixturesData[(index + 1) % 5],
+ topics[0], // Technology
+ topics[1], // Sports
+ topics[6], // Business
+ topics[7], // Travel
+ ],
+ savedHeadlines: [headlines[0], headlines[10]],
+ savedHeadlineFilters: savedHeadlineFilters
+ .map((e) => e.copyWith(userId: kAdminUserId))
+ .toList(),
+ savedSourceFilters: savedSourceFilters
+ .map((e) => e.copyWith(userId: kAdminUserId))
+ .toList(),
+ ),
+ UserContentPreferences(
+ id: kUser1Id, // Publisher (Premium)
+ followedCountries: const [],
+ followedSources: [
+ sources[0], // TechCrunch
+ sources[1], // BBC News
],
- savedHeadlines: [
- headlinesFixturesData[index * 2],
- headlinesFixturesData[index * 2 + 1],
+ followedTopics: [
+ topics[0], // Technology
+ topics[6], // Business
+ ],
+ savedHeadlines: [headlines[2], headlines[3]],
+ savedHeadlineFilters: savedHeadlineFilters
+ .map((e) => e.copyWith(userId: kUser1Id))
+ .toList(),
+ savedSourceFilters: savedSourceFilters
+ .map((e) => e.copyWith(userId: kUser1Id))
+ .toList(),
+ ),
+ UserContentPreferences(
+ id: kUser2Id, // Publisher (Standard)
+ followedCountries: const [],
+ followedSources: [
+ sources[3], // The Guardian
+ sources[4], // CNN
+ ],
+ followedTopics: [
+ topics[2], // Politics
+ topics[4], // Health
],
- savedHeadlineFilters: savedHeadlineFiltersFixturesData
- .map((e) => e.copyWith(userId: userId))
+ savedHeadlines: [headlines[4], headlines[5]],
+ savedHeadlineFilters: savedHeadlineFilters
+ .map((e) => e.copyWith(userId: kUser2Id))
.toList(),
- savedSourceFilters: savedSourceFiltersFixturesData
- .map((e) => e.copyWith(userId: userId))
+ savedSourceFilters: savedSourceFilters
+ .map((e) => e.copyWith(userId: kUser2Id))
.toList(),
- );
- }),
-];
+ ),
+ // Add preferences for users 3-10
+ ...List.generate(8, (index) {
+ final userId = [
+ kUser3Id,
+ kUser4Id,
+ kUser5Id,
+ kUser6Id,
+ kUser7Id,
+ kUser8Id,
+ kUser9Id,
+ kUser10Id,
+ ][index];
+ return UserContentPreferences(
+ id: userId,
+ followedCountries: const [],
+ followedSources: [sources[index % 10], sources[(index + 1) % 10]],
+ followedTopics: [topics[index % 5], topics[(index + 1) % 5]],
+ savedHeadlines: [headlines[index * 2], headlines[index * 2 + 1]],
+ savedHeadlineFilters: savedHeadlineFilters
+ .map((e) => e.copyWith(userId: userId))
+ .toList(),
+ savedSourceFilters: savedSourceFilters
+ .map((e) => e.copyWith(userId: userId))
+ .toList(),
+ );
+ }),
+ ];
+}
diff --git a/lib/src/models/config/app_review_config.dart b/lib/src/models/config/app_review_config.dart
new file mode 100644
index 00000000..c440c39b
--- /dev/null
+++ b/lib/src/models/config/app_review_config.dart
@@ -0,0 +1,75 @@
+import 'package:equatable/equatable.dart';
+import 'package:json_annotation/json_annotation.dart';
+import 'package:meta/meta.dart';
+
+part 'app_review_config.g.dart';
+
+/// {@template app_review_config}
+/// Defines the remote configuration for the two-layer App Review Funnel.
+///
+/// This system strategically prompts engaged users for feedback to maximize
+/// positive public reviews while capturing constructive criticism privately.
+///
+/// ### How It Works
+///
+/// 1. **Trigger**: A user becomes eligible to see the prompt after reaching
+/// the [positiveInteractionThreshold] of positive actions (e.g., saves).
+///
+/// 2. **Prompt**: The `FeedDecoratorType.rateApp` decorator asks the user
+/// "Are you enjoying the app?". The display logic is managed by the user's
+/// `UserFeedDecoratorStatus` for `rateApp`, which respects the
+/// [initialPromptCooldownDays].
+///
+/// 3. **Action**:
+/// - **On "Yes"**: The client sets `isCompleted` to `true` on the user's
+/// `UserFeedDecoratorStatus` for `rateApp` and immediately triggers the
+/// native OS in-app review dialog if applicable ie the app is hosted in
+/// google play or apple store. The prompt will not be shown again.
+/// - **On "No"**: The client only updates the `lastShownAt` timestamp on
+/// the status object. The prompt will not be shown again until the
+/// cooldown period has passed. No public review is requested.
+/// {@endtemplate}
+@immutable
+@JsonSerializable(explicitToJson: true, includeIfNull: true, checked: true)
+class AppReviewConfig extends Equatable {
+ /// {@macro app_review_config}
+ const AppReviewConfig({
+ required this.positiveInteractionThreshold,
+ required this.initialPromptCooldownDays,
+ });
+
+ /// Creates a [AppReviewConfig] from JSON data.
+ factory AppReviewConfig.fromJson(Map json) =>
+ _$AppReviewConfigFromJson(json);
+
+ /// The number of positive interactions (e.g., saving a headline) required
+ /// to trigger the initial review prompt.
+ final int positiveInteractionThreshold;
+
+ /// The number of days to wait before showing the initial prompt again if the
+ /// user dismisses it.
+ final int initialPromptCooldownDays;
+
+ /// Converts this [AppReviewConfig] instance to JSON data.
+ Map toJson() => _$AppReviewConfigToJson(this);
+
+ @override
+ List