From f8838dc25805b06d69c912823de2f79247340673 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:17:39 +0100 Subject: [PATCH 01/37] feat(l10n): add descriptions for admin settings expansion tiles - Added Arabic and English descriptions for various admin settings sections - New descriptions include User Limits, App Status & Updates, Advertisements, Notifications, and Feed settings - Also added descriptions for Ad Platform Configuration, Feed Ad Settings, and Navigation Ad Settings - Updated existing entries to maintain consistency --- lib/l10n/arb/app_ar.arb | 34 +++++++++++++++++++++++++++++++++- lib/l10n/arb/app_en.arb | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index 70baa956..51154b94 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -2098,6 +2098,26 @@ "@userLimitsTitle": { "description": "عنوان قسم حدود المستخدم القابل للتوسيع." }, + "userLimitsDescription": "تحديد حدود للميزات والمحتوى الخاص بالمستخدم.", + "@userLimitsDescription": { + "description": "وصف قسم حدود المستخدم القابل للتوسيع." + }, + "appStatusAndUpdatesDescription": "التحكم في الحالة التشغيلية للتطبيق وإدارة متطلبات التحديث.", + "@appStatusAndUpdatesDescription": { + "description": "وصف قسم حالة التطبيق والتحديثات القابل للتوسيع." + }, + "advertisementsDescription": "إدارة جميع إعدادات الإعلانات، بما في ذلك الضوابط العالمية والمنصات والمواضع.", + "@advertisementsDescription": { + "description": "وصف قسم الإعلانات القابل للتوسيع." + }, + "notificationsDescription": "تكوين نظام الإشعارات الفورية، بما في ذلك المزودين وأنواع التسليم.", + "@notificationsDescription": { + "description": "وصف قسم الإشعارات القابل للتوسيع." + }, + "feedDescription": "التحكم في سلوك ومظهر موجز محتوى المستخدم.", + "@feedDescription": { + "description": "وصف قسم الموجز القابل للتوسيع." + }, "notificationSubscriptionBreakingOnlyDescription": "حد الاشتراكات التي ترسل تنبيهات فورية للأخبار العاجلة للعناوين المطابقة.", "@notificationSubscriptionBreakingOnlyDescription": { "description": "وصف لحد اشتراك إشعارات الأخبار العاجلة." @@ -2318,7 +2338,7 @@ "@commentStatus": { "description": "تسمية لحالة الإشراف على تعليق ضمن تفاعل." }, -"hasCommentFilterLabel": "تحتوي على تعليقات", + "hasCommentFilterLabel": "تحتوي على تعليقات", "@hasCommentFilterLabel": { "description": "تسمية لمفتاح تصفية التفاعلات بناءً على وجود تعليق." }, @@ -2858,5 +2878,17 @@ "example": "Breaking News Story" } } + }, + "adPlatformConfigurationDescription": "اختر مزود الإعلانات الأساسي وقم بتكوين معرفات الوحدات الإعلانية الخاصة به.", + "@adPlatformConfigurationDescription": { + "description": "وصف قسم تكوين منصة الإعلانات القابل للتوسيع." + }, + "feedAdSettingsDescription": "تحكم في رؤية الإعلانات ونوعها وتكرارها داخل موجز محتوى المستخدم.", + "@feedAdSettingsDescription": { + "description": "وصف قسم إعدادات إعلانات الموجز القابل للتوسيع." + }, + "navigationAdConfigDescription": "تكوين الإعلانات البينية التي تظهر أثناء تنقل المستخدم.", + "@navigationAdConfigDescription": { + "description": "وصف قسم إعدادات إعلانات التنقل القابل للتوسيع." } } \ No newline at end of file diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index f9940e7d..18365700 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -2094,6 +2094,26 @@ "@userLimitsTitle": { "description": "Title for the User Limits expansion tile." }, + "userLimitsDescription": "Define limits for user-specific features and content.", + "@userLimitsDescription": { + "description": "Description for the User Limits expansion tile." + }, + "appStatusAndUpdatesDescription": "Control the application's operational status and manage update requirements.", + "@appStatusAndUpdatesDescription": { + "description": "Description for the App Status & Updates expansion tile." + }, + "advertisementsDescription": "Manage all advertisement settings, including global controls, platforms, and placements.", + "@advertisementsDescription": { + "description": "Description for the Advertisements expansion tile." + }, + "notificationsDescription": "Configure the push notification system, including providers and delivery types.", + "@notificationsDescription": { + "description": "Description for the Notifications expansion tile." + }, + "feedDescription": "Control the behavior and appearance of the user's content feed.", + "@feedDescription": { + "description": "Description for the Feed expansion tile." + }, "notificationSubscriptionBreakingOnlyDescription": "Limit for subscriptions that send immediate alerts for matching headlines.", "@notificationSubscriptionBreakingOnlyDescription": { "description": "Description for the breaking news notification subscription limit." @@ -2854,5 +2874,17 @@ "example": "Breaking News Story" } } + }, + "adPlatformConfigurationDescription": "Select the primary ad provider and configure their respective ad unit IDs.", + "@adPlatformConfigurationDescription": { + "description": "Description for the Ad Platform Configuration expansion tile." + }, + "feedAdSettingsDescription": "Control ad visibility, type, and frequency within the user's content feed.", + "@feedAdSettingsDescription": { + "description": "Description for the Feed Ad Settings expansion tile." + }, + "navigationAdConfigDescription": "Configure interstitial ads that appear during user navigation.", + "@navigationAdConfigDescription": { + "description": "Description for the Navigation Ad Settings expansion tile." } } \ No newline at end of file From 9fa5c05c2121155e2ef50668ba449c6e57b7e5f1 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:18:00 +0100 Subject: [PATCH 02/37] build(l10n): sync --- lib/l10n/app_localizations.dart | 48 ++++++++++++++++++++++++++++++ lib/l10n/app_localizations_ar.dart | 31 +++++++++++++++++++ lib/l10n/app_localizations_en.dart | 32 ++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index ccac0c16..c20058ec 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -3116,6 +3116,36 @@ abstract class AppLocalizations { /// **'User Limits'** String get userLimitsTitle; + /// Description for the User Limits expansion tile. + /// + /// In en, this message translates to: + /// **'Define limits for user-specific features and content.'** + String get userLimitsDescription; + + /// Description for the App Status & Updates expansion tile. + /// + /// In en, this message translates to: + /// **'Control the application\'s operational status and manage update requirements.'** + String get appStatusAndUpdatesDescription; + + /// Description for the Advertisements expansion tile. + /// + /// In en, this message translates to: + /// **'Manage all advertisement settings, including global controls, platforms, and placements.'** + String get advertisementsDescription; + + /// Description for the Notifications expansion tile. + /// + /// In en, this message translates to: + /// **'Configure the push notification system, including providers and delivery types.'** + String get notificationsDescription; + + /// Description for the Feed expansion tile. + /// + /// In en, this message translates to: + /// **'Control the behavior and appearance of the user\'s content feed.'** + String get feedDescription; + /// Description for the breaking news notification subscription limit. /// /// In en, this message translates to: @@ -4135,6 +4165,24 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'{itemType} \"{itemName}\" deleted.'** String itemDeletedSnackbar(String itemType, String itemName); + + /// Description for the Ad Platform Configuration expansion tile. + /// + /// In en, this message translates to: + /// **'Select the primary ad provider and configure their respective ad unit IDs.'** + String get adPlatformConfigurationDescription; + + /// Description for the Feed Ad Settings expansion tile. + /// + /// In en, this message translates to: + /// **'Control ad visibility, type, and frequency within the user\'s content feed.'** + String get feedAdSettingsDescription; + + /// Description for the Navigation Ad Settings expansion tile. + /// + /// In en, this message translates to: + /// **'Configure interstitial ads that appear during user navigation.'** + String get navigationAdConfigDescription; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 74295f99..97648320 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -1672,6 +1672,25 @@ class AppLocalizationsAr extends AppLocalizations { @override String get userLimitsTitle => 'حدود المستخدم'; + @override + String get userLimitsDescription => + 'تحديد حدود للميزات والمحتوى الخاص بالمستخدم.'; + + @override + String get appStatusAndUpdatesDescription => + 'التحكم في الحالة التشغيلية للتطبيق وإدارة متطلبات التحديث.'; + + @override + String get advertisementsDescription => + 'إدارة جميع إعدادات الإعلانات، بما في ذلك الضوابط العالمية والمنصات والمواضع.'; + + @override + String get notificationsDescription => + 'تكوين نظام الإشعارات الفورية، بما في ذلك المزودين وأنواع التسليم.'; + + @override + String get feedDescription => 'التحكم في سلوك ومظهر موجز محتوى المستخدم.'; + @override String get notificationSubscriptionBreakingOnlyDescription => 'حد الاشتراكات التي ترسل تنبيهات فورية للأخبار العاجلة للعناوين المطابقة.'; @@ -2235,4 +2254,16 @@ class AppLocalizationsAr extends AppLocalizations { String itemDeletedSnackbar(String itemType, String itemName) { return 'تم حذف $itemType \"$itemName\".'; } + + @override + String get adPlatformConfigurationDescription => + 'اختر مزود الإعلانات الأساسي وقم بتكوين معرفات الوحدات الإعلانية الخاصة به.'; + + @override + String get feedAdSettingsDescription => + 'تحكم في رؤية الإعلانات ونوعها وتكرارها داخل موجز محتوى المستخدم.'; + + @override + String get navigationAdConfigDescription => + 'تكوين الإعلانات البينية التي تظهر أثناء تنقل المستخدم.'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index a6cf159b..66f4adf7 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -1675,6 +1675,26 @@ class AppLocalizationsEn extends AppLocalizations { @override String get userLimitsTitle => 'User Limits'; + @override + String get userLimitsDescription => + 'Define limits for user-specific features and content.'; + + @override + String get appStatusAndUpdatesDescription => + 'Control the application\'s operational status and manage update requirements.'; + + @override + String get advertisementsDescription => + 'Manage all advertisement settings, including global controls, platforms, and placements.'; + + @override + String get notificationsDescription => + 'Configure the push notification system, including providers and delivery types.'; + + @override + String get feedDescription => + 'Control the behavior and appearance of the user\'s content feed.'; + @override String get notificationSubscriptionBreakingOnlyDescription => 'Limit for subscriptions that send immediate alerts for matching headlines.'; @@ -2241,4 +2261,16 @@ class AppLocalizationsEn extends AppLocalizations { String itemDeletedSnackbar(String itemType, String itemName) { return '$itemType \"$itemName\" deleted.'; } + + @override + String get adPlatformConfigurationDescription => + 'Select the primary ad provider and configure their respective ad unit IDs.'; + + @override + String get feedAdSettingsDescription => + 'Control ad visibility, type, and frequency within the user\'s content feed.'; + + @override + String get navigationAdConfigDescription => + 'Configure interstitial ads that appear during user navigation.'; } From 15e263aa3f15f67bc7c3cd31bc2799c0c9b80e2b Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:18:19 +0100 Subject: [PATCH 03/37] feat(app_configuration): enhance features configuration tab design - Add descriptions to expansion tiles for better user guidance - Increase indentation of expansion tile children for visual hierarchy - Improve type safety by specifying bool type in onExpansionChanged callback --- .../view/tabs/features_configuration_tab.dart | 74 ++++++++++++------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/lib/app_configuration/view/tabs/features_configuration_tab.dart b/lib/app_configuration/view/tabs/features_configuration_tab.dart index 96fbf462..82c4e43e 100644 --- a/lib/app_configuration/view/tabs/features_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/features_configuration_tab.dart @@ -64,12 +64,20 @@ class _FeaturesConfigurationTabState extends State { return ExpansionTile( key: ValueKey('advertisementsTile_$expandedIndex'), title: Text(l10n.advertisementsTab), - onExpansionChanged: (isExpanded) { + subtitle: Text( + l10n.advertisementsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), + onExpansionChanged: (bool isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), @@ -108,12 +116,20 @@ class _FeaturesConfigurationTabState extends State { return ExpansionTile( key: ValueKey('pushNotificationsTile_$expandedIndex'), title: Text(l10n.notificationsTab), - onExpansionChanged: (isExpanded) { + subtitle: Text( + l10n.notificationsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), + onExpansionChanged: (bool isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), @@ -137,12 +153,20 @@ class _FeaturesConfigurationTabState extends State { return ExpansionTile( key: ValueKey('feedTile_$expandedIndex'), title: Text(l10n.feedTab), - onExpansionChanged: (isExpanded) { + subtitle: Text( + l10n.feedDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), + onExpansionChanged: (bool isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), @@ -150,6 +174,14 @@ class _FeaturesConfigurationTabState extends State { children: [ ExpansionTile( title: Text(l10n.feedItemClickBehaviorTitle), + subtitle: Text( + l10n.feedItemClickBehaviorDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -157,15 +189,6 @@ class _FeaturesConfigurationTabState extends State { ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.feedItemClickBehaviorDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), Align( alignment: AlignmentDirectional.centerStart, child: SegmentedButton( @@ -203,6 +226,14 @@ class _FeaturesConfigurationTabState extends State { const SizedBox(height: AppSpacing.lg), ExpansionTile( title: Text(l10n.feedDecoratorsTitle), + subtitle: Text( + l10n.feedDecoratorsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -210,15 +241,6 @@ class _FeaturesConfigurationTabState extends State { ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.feedDecoratorsDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), for (final decoratorType in FeedDecoratorType.values) Padding( padding: const EdgeInsets.only(bottom: AppSpacing.md), @@ -263,12 +285,12 @@ class _FeaturesConfigurationTabState extends State { ).colorScheme.onSurface.withOpacity(0.7), ), ), - onExpansionChanged: (isExpanded) { + onExpansionChanged: (bool isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), From 1fe308ccbc608d81602ac49e996be31715fcb2d5 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:18:38 +0100 Subject: [PATCH 04/37] feat(app_configuration): enhance system configuration tab with subtitles and spacing adjustments - Add descriptive subtitles to expansion tiles for better clarity - Increase indentation of expansion tile children for improved visual hierarchy - Utilize consistent styling for subtitles across different sections --- .../view/tabs/system_configuration_tab.dart | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/app_configuration/view/tabs/system_configuration_tab.dart b/lib/app_configuration/view/tabs/system_configuration_tab.dart index bb275f45..f5442ecd 100644 --- a/lib/app_configuration/view/tabs/system_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/system_configuration_tab.dart @@ -55,12 +55,20 @@ class _SystemConfigurationTabState extends State { return ExpansionTile( key: ValueKey('appStatusAndUpdatesTile_$expandedIndex'), title: Text(l10n.appStatusAndUpdatesTitle), + subtitle: Text( + l10n.appStatusAndUpdatesDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), onExpansionChanged: (isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), @@ -68,6 +76,14 @@ class _SystemConfigurationTabState extends State { children: [ ExpansionTile( title: Text(l10n.maintenanceModeTitle), + subtitle: Text( + l10n.maintenanceModeDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -99,6 +115,14 @@ class _SystemConfigurationTabState extends State { const SizedBox(height: AppSpacing.lg), ExpansionTile( title: Text(l10n.appUpdateManagementTitle), + subtitle: Text( + l10n.updateConfigDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -124,12 +148,20 @@ class _SystemConfigurationTabState extends State { return ExpansionTile( key: ValueKey('appUrlsTile_$expandedIndex'), title: Text(l10n.appUrlsTitle), + subtitle: Text( + l10n.appUrlsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), onExpansionChanged: (isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), From 06d10e817251fdc536aafecb3bc657048cacee07 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:19:04 +0100 Subject: [PATCH 05/37] refactor(app_configuration): improve user configuration tab layout and content - Update import statement for saved filter limits form - Add description subtitle to user limits and content limits sections - Increase indentation for expansion tile children - Replace SavedFilterLimitsSection with SavedFilterLimitsForm for both headline and source filter types --- .../view/tabs/user_configuration_tab.dart | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/app_configuration/view/tabs/user_configuration_tab.dart b/lib/app_configuration/view/tabs/user_configuration_tab.dart index 058d5ccb..54ada6d7 100644 --- a/lib/app_configuration/view/tabs/user_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/user_configuration_tab.dart @@ -1,6 +1,6 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/saved_filter_limits_section.dart'; +import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/saved_filter_limits_form.dart'; import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/user_limits_config_form.dart'; import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; import 'package:ui_kit/ui_kit.dart'; @@ -54,12 +54,20 @@ class _UserConfigurationTabState extends State { return ExpansionTile( key: ValueKey('userLimitsTile_$expandedIndex'), title: Text(l10n.userLimitsTitle), + subtitle: Text( + l10n.userLimitsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), onExpansionChanged: (isExpanded) { _expandedTileIndex.value = isExpanded ? tileIndex : null; }, initiallyExpanded: expandedIndex == tileIndex, childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, + start: AppSpacing.xxl, top: AppSpacing.md, bottom: AppSpacing.md, ), @@ -67,6 +75,14 @@ class _UserConfigurationTabState extends State { children: [ ExpansionTile( title: Text(l10n.userContentLimitsTitle), + subtitle: Text( + l10n.userContentLimitsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -81,20 +97,16 @@ class _UserConfigurationTabState extends State { ], ), const SizedBox(height: AppSpacing.lg), - ExpansionTile( - title: Text(l10n.savedFeedFilterLimitsTitle), - childrenPadding: const EdgeInsetsDirectional.only( - start: AppSpacing.lg, - top: AppSpacing.md, - bottom: AppSpacing.md, - ), - expandedCrossAxisAlignment: CrossAxisAlignment.start, - children: [ - SavedFilterLimitsSection( - remoteConfig: widget.remoteConfig, - onConfigChanged: widget.onConfigChanged, - ), - ], + SavedFilterLimitsForm( + remoteConfig: widget.remoteConfig, + onConfigChanged: widget.onConfigChanged, + filterType: SavedFilterType.headline, + ), + const SizedBox(height: AppSpacing.lg), + SavedFilterLimitsForm( + remoteConfig: widget.remoteConfig, + onConfigChanged: widget.onConfigChanged, + filterType: SavedFilterType.source, ), ], ); From c76cb938c22fc9fa76987ac89c47f3416b5664e5 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:19:18 +0100 Subject: [PATCH 06/37] refactor(app_configuration): wrap ad platform config in ExpansionTile - Add ExpansionTile to the ad platform configuration form - Move the title and description into the ExpansionTile - Adjust the layout of primary ad platform and ad unit identifiers sections - Improve readability and usability of the ad platform configuration form --- .../widgets/ad_platform_config_form.dart | 194 ++++++++++-------- 1 file changed, 107 insertions(+), 87 deletions(-) diff --git a/lib/app_configuration/widgets/ad_platform_config_form.dart b/lib/app_configuration/widgets/ad_platform_config_form.dart index ff776fd5..e860a446 100644 --- a/lib/app_configuration/widgets/ad_platform_config_form.dart +++ b/lib/app_configuration/widgets/ad_platform_config_form.dart @@ -146,8 +146,14 @@ class _AdPlatformConfigFormState extends State final l10n = AppLocalizationsX(context).l10n; final adConfig = widget.remoteConfig.features.ads; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, + return ExpansionTile( + title: Text(l10n.adPlatformConfigurationTitle), + subtitle: Text( + l10n.adPlatformConfigurationDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), children: [ ExpansionTile( title: Text(l10n.primaryAdPlatformTitle), @@ -158,52 +164,59 @@ class _AdPlatformConfigFormState extends State ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.primaryAdPlatformDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - textAlign: TextAlign.start, - ), - const SizedBox(height: AppSpacing.lg), - Align( - alignment: AlignmentDirectional.centerStart, - child: SegmentedButton( - style: SegmentedButton.styleFrom( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.zero, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + l10n.primaryAdPlatformDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), ), + textAlign: TextAlign.start, ), - segments: AdPlatformType.values - .where( - (type) => type != AdPlatformType.demo, - ) - .map( - (type) => ButtonSegment( - value: type, - label: Text(type.l10n(context)), - ), - ) - .toList(), - selected: {_selectedPlatform}, - onSelectionChanged: (newSelection) { - setState(() { - _selectedPlatform = newSelection.first; - _tabController.index = AdPlatformType.values.indexOf( - _selectedPlatform, - ); - }); - widget.onConfigChanged( - widget.remoteConfig.copyWith( - features: widget.remoteConfig.features.copyWith( - ads: adConfig.copyWith( - primaryAdPlatform: newSelection.first, - ), + const SizedBox(height: AppSpacing.lg), + Align( + alignment: AlignmentDirectional.centerStart, + child: SegmentedButton( + style: SegmentedButton.styleFrom( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, ), ), - ); - }, - ), + segments: AdPlatformType.values + .where( + (type) => type != AdPlatformType.demo, + ) + .map( + (type) => ButtonSegment( + value: type, + label: Text(type.l10n(context)), + ), + ) + .toList(), + selected: {_selectedPlatform}, + onSelectionChanged: (newSelection) { + setState(() { + _selectedPlatform = newSelection.first; + _tabController.index = AdPlatformType.values.indexOf( + _selectedPlatform, + ); + }); + widget.onConfigChanged( + widget.remoteConfig.copyWith( + features: widget.remoteConfig.features.copyWith( + ads: adConfig.copyWith( + primaryAdPlatform: newSelection.first, + ), + ), + ), + ); + }, + ), + ), + ], ), ], ), @@ -217,50 +230,57 @@ class _AdPlatformConfigFormState extends State ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Align( - alignment: AlignmentDirectional.centerStart, - child: SizedBox( - height: kTextTabBarHeight, - child: TabBar( - controller: _tabController, - tabAlignment: TabAlignment.start, - isScrollable: true, - tabs: AdPlatformType.values - .where( - (type) => type != AdPlatformType.demo, - ) - .map((platform) => Tab(text: platform.l10n(context))) - .toList(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: AlignmentDirectional.centerStart, + child: SizedBox( + height: kTextTabBarHeight, + child: TabBar( + controller: _tabController, + tabAlignment: TabAlignment.start, + isScrollable: true, + tabs: AdPlatformType.values + .where( + (type) => type != AdPlatformType.demo, + ) + .map((platform) => Tab(text: platform.l10n(context))) + .toList(), + ), + ), ), - ), - ), - const SizedBox(height: AppSpacing.lg), - Text( - l10n.adUnitIdentifiersDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - textAlign: TextAlign.start, - ), - const SizedBox(height: AppSpacing.lg), - SizedBox( - height: 300, // Adjust height as needed for the content - child: TabBarView( - controller: _tabController, - children: AdPlatformType.values - .where( - (type) => type != AdPlatformType.demo, - ) - .map( - (platform) => _buildAdUnitIdentifierFields( - context, - l10n, - platform, - adConfig, - ), - ) - .toList(), - ), + const SizedBox(height: AppSpacing.lg), + Text( + l10n.adUnitIdentifiersDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + textAlign: TextAlign.start, + ), + const SizedBox(height: AppSpacing.lg), + SizedBox( + height: 300, // Adjust height as needed for the content + child: TabBarView( + controller: _tabController, + children: AdPlatformType.values + .where( + (type) => type != AdPlatformType.demo, + ) + .map( + (platform) => _buildAdUnitIdentifierFields( + context, + l10n, + platform, + adConfig, + ), + ) + .toList(), + ), + ), + ], ), ], ), From 033df183d78a7372c424d851655e49373c2d26f4 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:19:24 +0100 Subject: [PATCH 07/37] refactor(app_configuration): remove unused imports and code - Remove unused import of 'package:ui_kit/ui_kit.dart' - Remove description text and spacing at the beginning of the form --- lib/app_configuration/widgets/app_urls_form.dart | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/app_configuration/widgets/app_urls_form.dart b/lib/app_configuration/widgets/app_urls_form.dart index 14a77375..851c3a42 100644 --- a/lib/app_configuration/widgets/app_urls_form.dart +++ b/lib/app_configuration/widgets/app_urls_form.dart @@ -2,7 +2,6 @@ import 'package:core/core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_news_app_web_dashboard_full_source_code/app_configuration/widgets/app_config_form_fields.dart'; import 'package:flutter_news_app_web_dashboard_full_source_code/l10n/l10n.dart'; -import 'package:ui_kit/ui_kit.dart'; /// {@template app_urls_form} /// A form widget for configuring application URLs. @@ -84,13 +83,6 @@ class _AppUrlsFormState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.appUrlsDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), AppConfigTextField( label: l10n.termsOfServiceUrlLabel, description: l10n.termsOfServiceUrlDescription, From 9486de88a3790f1dd6bb26d2f530b7f3955e7436 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:19:50 +0100 Subject: [PATCH 08/37] refactor(app_configuration): remove redundant padding - Removed Padding widgets around Text and SegmentedButton - Improved layout consistency in EngagementSettingsForm --- .../widgets/engagement_settings_form.dart | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/lib/app_configuration/widgets/engagement_settings_form.dart b/lib/app_configuration/widgets/engagement_settings_form.dart index 4a370020..0e69c908 100644 --- a/lib/app_configuration/widgets/engagement_settings_form.dart +++ b/lib/app_configuration/widgets/engagement_settings_form.dart @@ -46,41 +46,35 @@ class EngagementSettingsForm extends StatelessWidget { }, ), const SizedBox(height: AppSpacing.lg), - Padding( - padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), - child: Text( - l10n.engagementModeDescription, - style: Theme.of(context).textTheme.bodySmall, - ), + Text( + l10n.engagementModeDescription, + style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: AppSpacing.md), - Padding( - padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), - child: SegmentedButton( - segments: EngagementMode.values - .map( - (mode) => ButtonSegment( - value: mode, - label: Text(mode.l10n(context)), - ), - ) - .toList(), - selected: {engagementConfig.engagementMode}, - onSelectionChanged: (newSelection) { - final newConfig = communityConfig.copyWith( - engagement: engagementConfig.copyWith( - engagementMode: newSelection.first, + SegmentedButton( + segments: EngagementMode.values + .map( + (mode) => ButtonSegment( + value: mode, + label: Text(mode.l10n(context)), ), - ); - onConfigChanged( - remoteConfig.copyWith( - features: remoteConfig.features.copyWith( - community: newConfig, - ), + ) + .toList(), + selected: {engagementConfig.engagementMode}, + onSelectionChanged: (newSelection) { + final newConfig = communityConfig.copyWith( + engagement: engagementConfig.copyWith( + engagementMode: newSelection.first, + ), + ); + onConfigChanged( + remoteConfig.copyWith( + features: remoteConfig.features.copyWith( + community: newConfig, ), - ); - }, - ), + ), + ); + }, ), ], ); From 9baf8092ef1b77217738ef4f5b7275d48254ca09 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:20:04 +0100 Subject: [PATCH 09/37] feat(feed_ad_settings): add descriptive subtitle to ad settings form - Add a subtitle to the ExpansionTile in the FeedAdSettingsForm - Use localized string for the subtitle text - Apply styling to match the theme and improve readability --- lib/app_configuration/widgets/feed_ad_settings_form.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/app_configuration/widgets/feed_ad_settings_form.dart b/lib/app_configuration/widgets/feed_ad_settings_form.dart index d0c53081..98f36254 100644 --- a/lib/app_configuration/widgets/feed_ad_settings_form.dart +++ b/lib/app_configuration/widgets/feed_ad_settings_form.dart @@ -138,6 +138,12 @@ class _FeedAdSettingsFormState extends State return ExpansionTile( title: Text(l10n.feedAdSettingsTitle), + subtitle: Text( + l10n.feedAdSettingsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, From ab1aa2dbb4fdcb92dd3fb84cfb261a90c17bcd25 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:20:36 +0100 Subject: [PATCH 10/37] feat(app_configuration): add description to navigation ad settings - Add a subtitle with description to the navigation ad settings form - Use Theme text style for better consistency and readability - Adjust opacity for better visual harmony with the existing theme --- .../widgets/navigation_ad_settings_form.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/app_configuration/widgets/navigation_ad_settings_form.dart b/lib/app_configuration/widgets/navigation_ad_settings_form.dart index 93c22258..7704245e 100644 --- a/lib/app_configuration/widgets/navigation_ad_settings_form.dart +++ b/lib/app_configuration/widgets/navigation_ad_settings_form.dart @@ -115,6 +115,12 @@ class _NavigationAdSettingsFormState extends State return ExpansionTile( title: Text(l10n.navigationAdConfigTitle), + subtitle: Text( + l10n.navigationAdConfigDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, From 0c83289f01e09ff0eb2478385f109bf5fd6eeef7 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:20:49 +0100 Subject: [PATCH 11/37] refactor(app_configuration): move ExpansionTile description to subtitle - Remove separate Text widget for description in both ExpansionTile widgets - Add description as a subtitle to ExpansionTile, styled appropriately - Remove extra SizedBox for spacing --- .../push_notification_settings_form.dart | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/app_configuration/widgets/push_notification_settings_form.dart b/lib/app_configuration/widgets/push_notification_settings_form.dart index 38db1155..e7d083f5 100644 --- a/lib/app_configuration/widgets/push_notification_settings_form.dart +++ b/lib/app_configuration/widgets/push_notification_settings_form.dart @@ -61,6 +61,12 @@ class PushNotificationSettingsForm extends StatelessWidget { ) { return ExpansionTile( title: Text(l10n.pushNotificationPrimaryProviderTitle), + subtitle: Text( + l10n.pushNotificationPrimaryProviderDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -68,13 +74,6 @@ class PushNotificationSettingsForm extends StatelessWidget { ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.pushNotificationPrimaryProviderDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), Align( alignment: AlignmentDirectional.centerStart, child: SegmentedButton( @@ -111,6 +110,12 @@ class PushNotificationSettingsForm extends StatelessWidget { ) { return ExpansionTile( title: Text(l10n.pushNotificationDeliveryTypesTitle), + subtitle: Text( + l10n.pushNotificationDeliveryTypesDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -118,13 +123,6 @@ class PushNotificationSettingsForm extends StatelessWidget { ), expandedCrossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.pushNotificationDeliveryTypesDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), Column( children: PushNotificationSubscriptionDeliveryType.values .map( From c5a7735a56f8d341d27f9c83b0324e6c14f837ad Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:21:02 +0100 Subject: [PATCH 12/37] refactor(app_configuration): conditionally render reporting settings - Wrap headline, source, and comment reporting switches in a conditional check - Only display these options if reportingConfig.enabled is true - Simplify the layout by removing unnecessary Padding and Column widgets --- .../widgets/reporting_settings_form.dart | 111 +++++++++--------- 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/lib/app_configuration/widgets/reporting_settings_form.dart b/lib/app_configuration/widgets/reporting_settings_form.dart index 0add4b1b..0f93cd83 100644 --- a/lib/app_configuration/widgets/reporting_settings_form.dart +++ b/lib/app_configuration/widgets/reporting_settings_form.dart @@ -44,68 +44,63 @@ class ReportingSettingsForm extends StatelessWidget { ); }, ), - const SizedBox(height: AppSpacing.lg), - Padding( - padding: const EdgeInsetsDirectional.only(start: AppSpacing.lg), - child: Column( - children: [ - SwitchListTile( - title: Text(l10n.enableHeadlineReportingLabel), - value: reportingConfig.headlineReportingEnabled, - onChanged: (value) { - final newConfig = reportingConfig.copyWith( - headlineReportingEnabled: value, - ); - onConfigChanged( - remoteConfig.copyWith( - features: remoteConfig.features.copyWith( - community: communityConfig.copyWith( - reporting: newConfig, - ), - ), + if (reportingConfig.enabled) ...[ + const SizedBox(height: AppSpacing.lg), + SwitchListTile( + title: Text(l10n.enableHeadlineReportingLabel), + value: reportingConfig.headlineReportingEnabled, + onChanged: (value) { + final newConfig = reportingConfig.copyWith( + headlineReportingEnabled: value, + ); + onConfigChanged( + remoteConfig.copyWith( + features: remoteConfig.features.copyWith( + community: communityConfig.copyWith( + reporting: newConfig, ), - ); - }, - ), - SwitchListTile( - title: Text(l10n.enableSourceReportingLabel), - value: reportingConfig.sourceReportingEnabled, - onChanged: (value) { - final newConfig = reportingConfig.copyWith( - sourceReportingEnabled: value, - ); - onConfigChanged( - remoteConfig.copyWith( - features: remoteConfig.features.copyWith( - community: communityConfig.copyWith( - reporting: newConfig, - ), - ), + ), + ), + ); + }, + ), + SwitchListTile( + title: Text(l10n.enableSourceReportingLabel), + value: reportingConfig.sourceReportingEnabled, + onChanged: (value) { + final newConfig = reportingConfig.copyWith( + sourceReportingEnabled: value, + ); + onConfigChanged( + remoteConfig.copyWith( + features: remoteConfig.features.copyWith( + community: communityConfig.copyWith( + reporting: newConfig, ), - ); - }, - ), - SwitchListTile( - title: Text(l10n.enableCommentReportingLabel), - value: reportingConfig.commentReportingEnabled, - onChanged: (value) { - final newConfig = reportingConfig.copyWith( - commentReportingEnabled: value, - ); - onConfigChanged( - remoteConfig.copyWith( - features: remoteConfig.features.copyWith( - community: communityConfig.copyWith( - reporting: newConfig, - ), - ), + ), + ), + ); + }, + ), + SwitchListTile( + title: Text(l10n.enableCommentReportingLabel), + value: reportingConfig.commentReportingEnabled, + onChanged: (value) { + final newConfig = reportingConfig.copyWith( + commentReportingEnabled: value, + ); + onConfigChanged( + remoteConfig.copyWith( + features: remoteConfig.features.copyWith( + community: communityConfig.copyWith( + reporting: newConfig, ), - ); - }, - ), - ], + ), + ), + ); + }, ), - ), + ], ], ); } From 442d078818b00e224ad7600f9a1cc06d3ebb35e7 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:21:12 +0100 Subject: [PATCH 13/37] feat(app_configuration): add expandable tile to saved filter limits form - Replace Column widget with ExpansionTile for better user experience - Add title and description for headline and source filters - Adjust layout and spacing of existing widgets --- .../widgets/saved_filter_limits_form.dart | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/app_configuration/widgets/saved_filter_limits_form.dart b/lib/app_configuration/widgets/saved_filter_limits_form.dart index 46c47429..7e062790 100644 --- a/lib/app_configuration/widgets/saved_filter_limits_form.dart +++ b/lib/app_configuration/widgets/saved_filter_limits_form.dart @@ -201,11 +201,23 @@ class _SavedFilterLimitsFormState extends State final l10n = AppLocalizationsX(context).l10n; final isHeadlineFilter = widget.filterType == SavedFilterType.headline; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, + return ExpansionTile( + title: Text( + isHeadlineFilter + ? l10n.savedHeadlineFilterLimitsTitle + : l10n.savedSourceFilterLimitsTitle, + ), + subtitle: Text( + isHeadlineFilter + ? l10n.savedHeadlineFilterLimitsDescription + : l10n.savedSourceFilterLimitsDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), children: [ - Align( - alignment: AlignmentDirectional.centerStart, + Padding( + padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), child: SizedBox( height: kTextTabBarHeight, child: TabBar( @@ -218,7 +230,7 @@ class _SavedFilterLimitsFormState extends State ), ), ), - const SizedBox(height: AppSpacing.lg), + const SizedBox(height: AppSpacing.md), SizedBox( height: isHeadlineFilter ? 500 : 250, child: TabBarView( From d5764496847469a83cfa2a18eb56d564cee9adf4 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:21:29 +0100 Subject: [PATCH 14/37] refactor(app_configuration): remove user content limits description text - Remove the Text widget displaying the user content limits description - Remove the SizedBox creating space below the description text --- lib/app_configuration/widgets/user_limits_config_form.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/app_configuration/widgets/user_limits_config_form.dart b/lib/app_configuration/widgets/user_limits_config_form.dart index afb99d3d..7973dc40 100644 --- a/lib/app_configuration/widgets/user_limits_config_form.dart +++ b/lib/app_configuration/widgets/user_limits_config_form.dart @@ -109,13 +109,6 @@ class _UserLimitsConfigFormState extends State return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.userContentLimitsDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), - ), - ), - const SizedBox(height: AppSpacing.lg), Align( alignment: AlignmentDirectional.centerStart, child: SizedBox( From 200d8a08e0ede718b2317bfd5242af75a33a551a Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:21:42 +0100 Subject: [PATCH 15/37] style: format filter dialog code - Adjust indentation of code block in community_filter_dialog.dart - Improve readability and maintain consistency with surrounding code --- .../community_filter_dialog.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/community_management/widgets/community_filter_dialog/community_filter_dialog.dart b/lib/community_management/widgets/community_filter_dialog/community_filter_dialog.dart index cebf96fc..6b647d3e 100644 --- a/lib/community_management/widgets/community_filter_dialog/community_filter_dialog.dart +++ b/lib/community_management/widgets/community_filter_dialog/community_filter_dialog.dart @@ -254,13 +254,13 @@ class _CommunityFilterDialogState extends State { labelBuilder: (item) => item.l10n(context), onChanged: (item) { context.read().add( - EngagementsFilterChanged( - EngagementsFilter( - searchQuery: state.engagementsFilter.searchQuery, - selectedStatus: item, - ), - ), - ); + EngagementsFilterChanged( + EngagementsFilter( + searchQuery: state.engagementsFilter.searchQuery, + selectedStatus: item, + ), + ), + ); }, ), ]; From 829aff1d3b447d39a711e2eb46c2a3795ab14d21 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:40:49 +0100 Subject: [PATCH 16/37] feat(l10n): add descriptions for new feed decorator prompts - Add Arabic and English descriptions for new feed decorator prompts - Include descriptions for 'Link Account', 'Upgrade', 'Rate App', 'Enable Notifications', 'Suggested Topics', and 'Suggested Sources' feed decorators - Update both app_ar.arb and app_en.arb files --- lib/l10n/arb/app_ar.arb | 24 ++++++++++++++++++++++++ lib/l10n/arb/app_en.arb | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index 51154b94..24459c7b 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -2890,5 +2890,29 @@ "navigationAdConfigDescription": "تكوين الإعلانات البينية التي تظهر أثناء تنقل المستخدم.", "@navigationAdConfigDescription": { "description": "وصف قسم إعدادات إعلانات التنقل القابل للتوسيع." + }, + "feedDecoratorLinkAccountDescription": "يطالب المستخدمين الضيوف بإنشاء حساب كامل.", + "@feedDecoratorLinkAccountDescription": { + "description": "وصف لزينة 'ربط الحساب' في الموجز." + }, + "feedDecoratorUpgradeDescription": "يطالب المستخدمين العاديين بالترقية إلى اشتراك مميز.", + "@feedDecoratorUpgradeDescription": { + "description": "وصف لزينة 'الترقية' في الموجز." + }, + "feedDecoratorRateAppDescription": "يطالب المستخدمين بتقييم التطبيق في متجر التطبيقات.", + "@feedDecoratorRateAppDescription": { + "description": "وصف لزينة 'تقييم التطبيق' في الموجز." + }, + "feedDecoratorEnableNotificationsDescription": "يطالب المستخدمين بتمكين الإشعارات الفورية.", + "@feedDecoratorEnableNotificationsDescription": { + "description": "وصف لزينة 'تفعيل الإشعارات' في الموجز." + }, + "feedDecoratorSuggestedTopicsDescription": "يعرض مجموعة من المواضيع التي قد يهتم المستخدم بمتابعتها.", + "@feedDecoratorSuggestedTopicsDescription": { + "description": "وصف لزينة 'المواضيع المقترحة' في الموجز." + }, + "feedDecoratorSuggestedSourcesDescription": "يعرض مجموعة من المصادر التي قد يهتم المستخدم بمتابعتها.", + "@feedDecoratorSuggestedSourcesDescription": { + "description": "وصف لزينة 'المصادر المقترحة' في الموجز." } } \ No newline at end of file diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 18365700..61e01b3d 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -2886,5 +2886,29 @@ "navigationAdConfigDescription": "Configure interstitial ads that appear during user navigation.", "@navigationAdConfigDescription": { "description": "Description for the Navigation Ad Settings expansion tile." + }, + "feedDecoratorLinkAccountDescription": "Prompts guest users to create a full account.", + "@feedDecoratorLinkAccountDescription": { + "description": "Description for the 'Link Account' feed decorator." + }, + "feedDecoratorUpgradeDescription": "Prompts standard users to upgrade to a premium subscription.", + "@feedDecoratorUpgradeDescription": { + "description": "Description for the 'Upgrade' feed decorator." + }, + "feedDecoratorRateAppDescription": "Prompts users to rate the application in the app store.", + "@feedDecoratorRateAppDescription": { + "description": "Description for the 'Rate App' feed decorator." + }, + "feedDecoratorEnableNotificationsDescription": "Prompts users to enable push notifications.", + "@feedDecoratorEnableNotificationsDescription": { + "description": "Description for the 'Enable Notifications' feed decorator." + }, + "feedDecoratorSuggestedTopicsDescription": "Shows a collection of topics the user might be interested in following.", + "@feedDecoratorSuggestedTopicsDescription": { + "description": "Description for the 'Suggested Topics' feed decorator." + }, + "feedDecoratorSuggestedSourcesDescription": "Shows a collection of sources the user might be interested in following.", + "@feedDecoratorSuggestedSourcesDescription": { + "description": "Description for the 'Suggested Sources' feed decorator." } } \ No newline at end of file From 6c1877ea5760053c4b8baf4d780a8c005329ad7b Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:41:06 +0100 Subject: [PATCH 17/37] build(l10n): sync --- lib/l10n/app_localizations.dart | 36 ++++++++++++++++++++++++++++++ lib/l10n/app_localizations_ar.dart | 24 ++++++++++++++++++++ lib/l10n/app_localizations_en.dart | 24 ++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index c20058ec..8f7096c5 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -4183,6 +4183,42 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Configure interstitial ads that appear during user navigation.'** String get navigationAdConfigDescription; + + /// Description for the 'Link Account' feed decorator. + /// + /// In en, this message translates to: + /// **'Prompts guest users to create a full account.'** + String get feedDecoratorLinkAccountDescription; + + /// Description for the 'Upgrade' feed decorator. + /// + /// In en, this message translates to: + /// **'Prompts standard users to upgrade to a premium subscription.'** + String get feedDecoratorUpgradeDescription; + + /// Description for the 'Rate App' feed decorator. + /// + /// In en, this message translates to: + /// **'Prompts users to rate the application in the app store.'** + String get feedDecoratorRateAppDescription; + + /// Description for the 'Enable Notifications' feed decorator. + /// + /// In en, this message translates to: + /// **'Prompts users to enable push notifications.'** + String get feedDecoratorEnableNotificationsDescription; + + /// Description for the 'Suggested Topics' feed decorator. + /// + /// In en, this message translates to: + /// **'Shows a collection of topics the user might be interested in following.'** + String get feedDecoratorSuggestedTopicsDescription; + + /// Description for the 'Suggested Sources' feed decorator. + /// + /// In en, this message translates to: + /// **'Shows a collection of sources the user might be interested in following.'** + String get feedDecoratorSuggestedSourcesDescription; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 97648320..51731ec5 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -2266,4 +2266,28 @@ class AppLocalizationsAr extends AppLocalizations { @override String get navigationAdConfigDescription => 'تكوين الإعلانات البينية التي تظهر أثناء تنقل المستخدم.'; + + @override + String get feedDecoratorLinkAccountDescription => + 'يطالب المستخدمين الضيوف بإنشاء حساب كامل.'; + + @override + String get feedDecoratorUpgradeDescription => + 'يطالب المستخدمين العاديين بالترقية إلى اشتراك مميز.'; + + @override + String get feedDecoratorRateAppDescription => + 'يطالب المستخدمين بتقييم التطبيق في متجر التطبيقات.'; + + @override + String get feedDecoratorEnableNotificationsDescription => + 'يطالب المستخدمين بتمكين الإشعارات الفورية.'; + + @override + String get feedDecoratorSuggestedTopicsDescription => + 'يعرض مجموعة من المواضيع التي قد يهتم المستخدم بمتابعتها.'; + + @override + String get feedDecoratorSuggestedSourcesDescription => + 'يعرض مجموعة من المصادر التي قد يهتم المستخدم بمتابعتها.'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 66f4adf7..f4ad1d56 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -2273,4 +2273,28 @@ class AppLocalizationsEn extends AppLocalizations { @override String get navigationAdConfigDescription => 'Configure interstitial ads that appear during user navigation.'; + + @override + String get feedDecoratorLinkAccountDescription => + 'Prompts guest users to create a full account.'; + + @override + String get feedDecoratorUpgradeDescription => + 'Prompts standard users to upgrade to a premium subscription.'; + + @override + String get feedDecoratorRateAppDescription => + 'Prompts users to rate the application in the app store.'; + + @override + String get feedDecoratorEnableNotificationsDescription => + 'Prompts users to enable push notifications.'; + + @override + String get feedDecoratorSuggestedTopicsDescription => + 'Shows a collection of topics the user might be interested in following.'; + + @override + String get feedDecoratorSuggestedSourcesDescription => + 'Shows a collection of sources the user might be interested in following.'; } From 02f20490e40baa13dc7f0f39226decc9be2510ff Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:41:32 +0100 Subject: [PATCH 18/37] feat(app_configuration): add descriptions to feed decorator settings - Implement _getDecoratorDescription function to retrieve descriptions for each FeedDecoratorType - Add subtitle to ExpansionTile in FeaturesConfigurationTab to display decorator descriptions --- .../view/tabs/features_configuration_tab.dart | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/app_configuration/view/tabs/features_configuration_tab.dart b/lib/app_configuration/view/tabs/features_configuration_tab.dart index 82c4e43e..d7c489ce 100644 --- a/lib/app_configuration/view/tabs/features_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/features_configuration_tab.dart @@ -49,6 +49,27 @@ class _FeaturesConfigurationTabState extends State { super.dispose(); } + String _getDecoratorDescription( + BuildContext context, + FeedDecoratorType type, + ) { + final l10n = AppLocalizationsX(context).l10n; + switch (type) { + case FeedDecoratorType.linkAccount: + return l10n.feedDecoratorLinkAccountDescription; + case FeedDecoratorType.upgrade: + return l10n.feedDecoratorUpgradeDescription; + case FeedDecoratorType.rateApp: + return l10n.feedDecoratorRateAppDescription; + case FeedDecoratorType.enableNotifications: + return l10n.feedDecoratorEnableNotificationsDescription; + case FeedDecoratorType.suggestedTopics: + return l10n.feedDecoratorSuggestedTopicsDescription; + case FeedDecoratorType.suggestedSources: + return l10n.feedDecoratorSuggestedSourcesDescription; + } + } + @override Widget build(BuildContext context) { final l10n = AppLocalizationsX(context).l10n; @@ -246,6 +267,15 @@ class _FeaturesConfigurationTabState extends State { padding: const EdgeInsets.only(bottom: AppSpacing.md), child: ExpansionTile( title: Text(decoratorType.l10n(context)), + subtitle: Text( + _getDecoratorDescription(context, decoratorType), + style: Theme.of(context).textTheme.bodySmall + ?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.xl, top: AppSpacing.md, From 9549d28d6c31dea648cd65bd4ff29f87b159f86e Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:41:39 +0100 Subject: [PATCH 19/37] refactor(app_configuration): improve ad platform config form layout - Move description subtitles to ExpansionTile level for better visibility - Remove separate Text widgets for descriptions to clean up layout - Adjust spacing and alignment for a more consistent appearance --- .../widgets/ad_platform_config_form.dart | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/lib/app_configuration/widgets/ad_platform_config_form.dart b/lib/app_configuration/widgets/ad_platform_config_form.dart index e860a446..13713f0c 100644 --- a/lib/app_configuration/widgets/ad_platform_config_form.dart +++ b/lib/app_configuration/widgets/ad_platform_config_form.dart @@ -157,6 +157,12 @@ class _AdPlatformConfigFormState extends State children: [ ExpansionTile( title: Text(l10n.primaryAdPlatformTitle), + subtitle: Text( + l10n.primaryAdPlatformDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -167,16 +173,6 @@ class _AdPlatformConfigFormState extends State Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - l10n.primaryAdPlatformDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurface.withOpacity(0.7), - ), - textAlign: TextAlign.start, - ), - const SizedBox(height: AppSpacing.lg), Align( alignment: AlignmentDirectional.centerStart, child: SegmentedButton( @@ -223,6 +219,12 @@ class _AdPlatformConfigFormState extends State const SizedBox(height: AppSpacing.lg), ExpansionTile( title: Text(l10n.adUnitIdentifiersTitle), + subtitle: Text( + l10n.adUnitIdentifiersDescription, + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7), + ), + ), childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -251,16 +253,6 @@ class _AdPlatformConfigFormState extends State ), ), const SizedBox(height: AppSpacing.lg), - Text( - l10n.adUnitIdentifiersDescription, - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurface.withOpacity(0.7), - ), - textAlign: TextAlign.start, - ), - const SizedBox(height: AppSpacing.lg), SizedBox( height: 300, // Adjust height as needed for the content child: TabBarView( From c30a516aef2495558f5a6daef667cff63b317a63 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:42:07 +0100 Subject: [PATCH 20/37] refactor(app_configuration): disable initiallyExpanded property for ExpansionTile - Remove layout constraints check for mobile devices - Set initiallyExpanded property to false for all ExpansionTiles - Simplify the code structure for better maintainability --- .../widgets/app_review_settings_form.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/app_configuration/widgets/app_review_settings_form.dart b/lib/app_configuration/widgets/app_review_settings_form.dart index 5e724210..eb1dec43 100644 --- a/lib/app_configuration/widgets/app_review_settings_form.dart +++ b/lib/app_configuration/widgets/app_review_settings_form.dart @@ -109,10 +109,9 @@ class _AppReviewSettingsFormState extends State { ), child: LayoutBuilder( builder: (context, constraints) { - final isMobile = constraints.maxWidth < 600; return ExpansionTile( title: Text(l10n.internalPromptLogicTitle), - initiallyExpanded: !isMobile, + initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -174,10 +173,9 @@ class _AppReviewSettingsFormState extends State { ), child: LayoutBuilder( builder: (context, constraints) { - final isMobile = constraints.maxWidth < 600; return ExpansionTile( title: Text(l10n.eligiblePositiveInteractionsTitle), - initiallyExpanded: !isMobile, + initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, @@ -231,10 +229,9 @@ class _AppReviewSettingsFormState extends State { ), child: LayoutBuilder( builder: (context, constraints) { - final isMobile = constraints.maxWidth < 600; return ExpansionTile( title: Text(l10n.followUpActionsTitle), - initiallyExpanded: !isMobile, + initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, top: AppSpacing.md, From 77d6e0fcb8fef63c51f4025bc4e2320f6dc2e2a3 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:42:19 +0100 Subject: [PATCH 21/37] fix(app_configuration): display engagement mode options based on config - Wrap engagement mode widgets with a Padding and Column - Add conditional rendering based on engagementConfig.enabled - Adjust layout to improve spacing and alignment --- .../widgets/engagement_settings_form.dart | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/lib/app_configuration/widgets/engagement_settings_form.dart b/lib/app_configuration/widgets/engagement_settings_form.dart index 0e69c908..44553b4c 100644 --- a/lib/app_configuration/widgets/engagement_settings_form.dart +++ b/lib/app_configuration/widgets/engagement_settings_form.dart @@ -46,36 +46,45 @@ class EngagementSettingsForm extends StatelessWidget { }, ), const SizedBox(height: AppSpacing.lg), - Text( - l10n.engagementModeDescription, - style: Theme.of(context).textTheme.bodySmall, - ), - const SizedBox(height: AppSpacing.md), - SegmentedButton( - segments: EngagementMode.values - .map( - (mode) => ButtonSegment( - value: mode, - label: Text(mode.l10n(context)), + if (engagementConfig.enabled) + Padding( + padding: const EdgeInsets.symmetric(horizontal: AppSpacing.lg), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + l10n.engagementModeDescription, + style: Theme.of(context).textTheme.bodySmall, ), - ) - .toList(), - selected: {engagementConfig.engagementMode}, - onSelectionChanged: (newSelection) { - final newConfig = communityConfig.copyWith( - engagement: engagementConfig.copyWith( - engagementMode: newSelection.first, - ), - ); - onConfigChanged( - remoteConfig.copyWith( - features: remoteConfig.features.copyWith( - community: newConfig, + const SizedBox(height: AppSpacing.md), + SegmentedButton( + segments: EngagementMode.values + .map( + (mode) => ButtonSegment( + value: mode, + label: Text(mode.l10n(context)), + ), + ) + .toList(), + selected: {engagementConfig.engagementMode}, + onSelectionChanged: (newSelection) { + final newConfig = communityConfig.copyWith( + engagement: engagementConfig.copyWith( + engagementMode: newSelection.first, + ), + ); + onConfigChanged( + remoteConfig.copyWith( + features: remoteConfig.features.copyWith( + community: newConfig, + ), + ), + ); + }, ), - ), - ); - }, - ), + ], + ), + ), ], ); } From 04df17ed850b6c297fccc4f9cc00f7e76bc86d9b Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 13:42:31 +0100 Subject: [PATCH 22/37] style(app_configuration): add padding to user limits config form - Add horizontal padding of AppSpacing.lg and vertical padding of AppSpacing.sm to the SingleChildScrollView widget in the UserLimitsConfigForm --- lib/app_configuration/widgets/user_limits_config_form.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/app_configuration/widgets/user_limits_config_form.dart b/lib/app_configuration/widgets/user_limits_config_form.dart index 7973dc40..44099685 100644 --- a/lib/app_configuration/widgets/user_limits_config_form.dart +++ b/lib/app_configuration/widgets/user_limits_config_form.dart @@ -151,6 +151,10 @@ class _UserLimitsConfigFormState extends State UserLimitsConfig limits, ) { return SingleChildScrollView( + padding: const EdgeInsets.symmetric( + horizontal: AppSpacing.lg, + vertical: AppSpacing.sm, + ), child: Column( children: [ AppConfigIntField( From 6a99aa307b83ead275aacc7850d3f3342ca2a501 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:21:46 +0100 Subject: [PATCH 23/37] resx: Update localization descriptions and add new settings - Clarify feed item click behavior and community engagement descriptions - Simplify positive interaction type labels - Add descriptions for various advertisement and user interaction settings - Explain role-based visibility and prompt logic configurations --- lib/l10n/arb/app_ar.arb | 87 ++++++++++++++++++++++++++++++++++++++--- lib/l10n/arb/app_en.arb | 87 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 164 insertions(+), 10 deletions(-) diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index 24459c7b..81195a9d 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -2082,7 +2082,7 @@ "@feedItemClickBehaviorTitle": { "description": "عنوان إعداد سلوك النقر على عنصر الموجز." }, - "feedItemClickBehaviorDescription": "اختر المتصفح الذي يفتح عند نقر المستخدم على عنوان في الموجز.", + "feedItemClickBehaviorDescription": "قم بتعيين المتصفح الافتراضي لفتح العناوين. يمكن للمستخدمين تجاوز هذا الإعداد في إعدادات الموجز الخاصة بهم في التطبيق.", "@feedItemClickBehaviorDescription": { "description": "وصف إعداد سلوك النقر على عنصر الموجز." }, @@ -2154,7 +2154,7 @@ "@communityAndEngagementTitle": { "description": "عنوان قسم المجتمع والمشاركة القابل للتوسيع." }, - "communityAndEngagementDescription": "إدارة تفاعلات المستخدمين، والإبلاغ عن المحتوى، ونظام مراجعات التطبيق الداخلي.", + "communityAndEngagementDescription": "تكوين أدوات تفاعل المستخدمين والإبلاغ. لضمان المساءلة، هذه الميزات غير متاحة للمستخدمين الضيوف داخل تطبيق الجوال، بغض النظر عن الإعدادات المكونة هنا.", "@communityAndEngagementDescription": { "description": "وصف قسم المجتمع والمشاركة القابل للتوسيع." }, @@ -2274,15 +2274,15 @@ "@eligiblePositiveInteractionsTitle": { "description": "عنوان قسم التفاعلات الإيجابية المؤهلة." }, - "positiveInteractionTypeSaveItem": "حفظ عنصر محتوى (مثل عنوان رئيسي)", + "positiveInteractionTypeSaveItem": "حفظ عنصر محتوى", "@positiveInteractionTypeSaveItem": { "description": "تسمية نوع التفاعل الإيجابي 'حفظ عنصر'." }, - "positiveInteractionTypeFollowItem": "متابعة كيان (مثل موضوع أو مصدر أو بلد)", + "positiveInteractionTypeFollowItem": "متابعة كيان ", "@positiveInteractionTypeFollowItem": { "description": "تسمية نوع التفاعل الإيجابي 'متابعة عنصر'." }, - "positiveInteractionTypeShareContent": "مشاركة عنصر محتوى (مثل عنوان رئيسي)", + "positiveInteractionTypeShareContent": "مشاركة عنصر محتوى", "@positiveInteractionTypeShareContent": { "description": "تسمية نوع التفاعل الإيجابي 'مشاركة محتوى'." }, @@ -2914,5 +2914,82 @@ "feedDecoratorSuggestedSourcesDescription": "يعرض مجموعة من المصادر التي قد يهتم المستخدم بمتابعتها.", "@feedDecoratorSuggestedSourcesDescription": { "description": "وصف لزينة 'المصادر المقترحة' في الموجز." + }, + "enableGlobalAdsDescription": "ينشط أو يعطل عالميًا جميع الإعلانات داخل التطبيق.", + "@enableGlobalAdsDescription": { + "description": "وصف لمفتاح تفعيل الإعلانات العالمي." + }, + "enableFeedAdsDescription": "يتحكم في رؤية جميع الإعلانات داخل موجزات المحتوى.", + "@enableFeedAdsDescription": { + "description": "وصف لمفتاح تفعيل إعلانات الموجز." + }, + "visibleToRoleDescription": "عند التمكين، ستكون هذه الميزة نشطة للمستخدمين الذين لديهم دور '{roleName}'.", + "@visibleToRoleDescription": { + "description": "وصف عام لمفتاح الرؤية الخاص بدور معين.", + "placeholders": { + "roleName": { + "type": "String" + } + } + }, + "enableDecoratorDescription": "ينشط أو يعطل عالميًا هذه الزينة لجميع المستخدمين المؤهلين.", + "@enableDecoratorDescription": { + "description": "وصف لمفتاح تفعيل الزينة." + }, + "enableNavigationAdsDescription": "يتحكم في رؤية الإعلانات البينية التي تظهر أثناء تنقل المستخدم.", + "@enableNavigationAdsDescription": { + "description": "وصف لمفتاح تفعيل إعلانات التنقل." + }, + "enableHeadlineReportingDescription": "يسمح للمستخدمين بالإبلاغ عن العناوين الفردية لمشاكل مثل المعلومات المضللة أو العناوين المضللة.", + "@enableHeadlineReportingDescription": { + "description": "وصف لمفتاح الإبلاغ عن العناوين." + }, + "enableSourceReportingDescription": "يسمح للمستخدمين بالإبلاغ عن مصادر الأخبار بأكملها لمشاكل مثل الجودة المنخفضة أو التحيز.", + "@enableSourceReportingDescription": { + "description": "وصف لمفتاح الإبلاغ عن المصادر." + }, + "enableCommentReportingDescription": "يسمح للمستخدمين بالإبلاغ عن التعليقات الفردية للإشراف عليها.", + "@enableCommentReportingDescription": { + "description": "وصف لمفتاح الإبلاغ عن التعليقات." + }, + "pushNotificationDeliveryTypeBreakingOnlyDescription": "تفعيل للسماح للمستخدمين بالاشتراك في التنبيهات الفورية للأخبار العاجلة.", + "@pushNotificationDeliveryTypeBreakingOnlyDescription": { + "description": "وصف لمفتاح نوع التسليم 'الأخبار العاجلة'." + }, + "pushNotificationDeliveryTypeDailyDigestDescription": "تفعيل للسماح للمستخدمين بالاشتراك في ملخص يومي للأخبار ذات الصلة.", + "@pushNotificationDeliveryTypeDailyDigestDescription": { + "description": "وصف لمفتاح نوع التسليم 'الملخص اليومي'." + }, + "pushNotificationDeliveryTypeWeeklyRoundupDescription": "تفعيل للسماح للمستخدمين بالاشتراك في ملخص أسبوعي للأخبار ذات الصلة.", + "@pushNotificationDeliveryTypeWeeklyRoundupDescription": { + "description": "وصف لمفتاح نوع التسليم 'حصاد الأسبوع'." + }, + "positiveInteractionTypeSaveItemDescription": "يحتسب عندما يحفظ المستخدم عنوان رئيسي.", + "@positiveInteractionTypeSaveItemDescription": { + "description": "وصف لمفتاح نوع التفاعل الإيجابي 'حفظ عنصر'." + }, + "positiveInteractionTypeFollowItemDescription": "يحتسب عندما يتابع المستخدم موضوعًا أو مصدرًا أو بلدًا مثل لعنوان رئيسي.", + "@positiveInteractionTypeFollowItemDescription": { + "description": "وصف لمفتاح نوع التفاعل الإيجابي 'متابعة عنصر'." + }, + "positiveInteractionTypeShareContentDescription": "يحتسب عندما يشارك المستخدم عنوان رئيسي.", + "@positiveInteractionTypeShareContentDescription": { + "description": "وصف لمفتاح نوع التفاعل الإيجابي 'مشاركة محتوى'." + }, + "positiveInteractionTypeSaveFilterDescription": "يحتسب عندما ينشئ المستخدم مرشحًا محفوظًا.", + "@positiveInteractionTypeSaveFilterDescription": { + "description": "وصف لمفتاح نوع التفاعل الإيجابي 'حفظ مرشح'." + }, + "internalPromptLogicDescription": "تحديد الشروط التي تؤدي إلى ظهور موجه الاستمتاع، مثل عدد إجراءات المستخدم وفترات التهدئة.", + "@internalPromptLogicDescription": { + "description": "وصف لإعدادات منطق الموجه الداخلي." + }, + "eligiblePositiveInteractionsDescription": "اختر إجراءات المستخدم التي تُحتسب 'كتفاعلات إيجابية' لتشغيل موجه الاستمتاع.", + "@eligiblePositiveInteractionsDescription": { + "description": "وصف لإعدادات التفاعلات الإيجابية المؤهلة." + }, + "followUpActionsDescription": "تكوين ما يحدث بعد استجابة المستخدم لموجه الاستمتاع، مثل طلب مراجعة المتجر.", + "@followUpActionsDescription": { + "description": "وصف لإعدادات إجراءات المتابعة." } } \ No newline at end of file diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 61e01b3d..744c2065 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -2078,7 +2078,7 @@ "@feedItemClickBehaviorTitle": { "description": "Title for the feed item click behavior setting." }, - "feedItemClickBehaviorDescription": "Select which browser opens when a user taps on a headline in the feed.", + "feedItemClickBehaviorDescription": "Set the default browser for opening headlines. This can be overridden by users in their app's feed settings.", "@feedItemClickBehaviorDescription": { "description": "Description for the feed item click behavior setting." }, @@ -2150,7 +2150,7 @@ "@communityAndEngagementTitle": { "description": "Title for the Community & Engagement expansion tile." }, - "communityAndEngagementDescription": "Manage user interactions, content reporting, and the internal app reporting system.", + "communityAndEngagementDescription": "Configure user engagement and reporting tools. To ensure accountability, these features are unavailable for guest users within the mobile app, irrespective of the settings configured here.", "@communityAndEngagementDescription": { "description": "Description for the Community & Engagement expansion tile." }, @@ -2270,15 +2270,15 @@ "@eligiblePositiveInteractionsTitle": { "description": "Title for the expansion tile for eligible positive interactions." }, - "positiveInteractionTypeSaveItem": "Save a content item (e.g., a headline)", + "positiveInteractionTypeSaveItem": "Save a content item", "@positiveInteractionTypeSaveItem": { "description": "Label for the 'save item' positive interaction type." }, - "positiveInteractionTypeFollowItem": "Follow an entity (e.g., a topic, source, or country)", + "positiveInteractionTypeFollowItem": "Follow an entity", "@positiveInteractionTypeFollowItem": { "description": "Label for the 'follow item' positive interaction type." }, - "positiveInteractionTypeShareContent": "Share a content item (e.g., a headline)", + "positiveInteractionTypeShareContent": "Share a content item", "@positiveInteractionTypeShareContent": { "description": "Label for the 'share content' positive interaction type." }, @@ -2910,5 +2910,82 @@ "feedDecoratorSuggestedSourcesDescription": "Shows a collection of sources the user might be interested in following.", "@feedDecoratorSuggestedSourcesDescription": { "description": "Description for the 'Suggested Sources' feed decorator." + }, + "enableGlobalAdsDescription": "Globally activates or deactivates all advertisements within the application.", + "@enableGlobalAdsDescription": { + "description": "Description for the global ad enablement switch." + }, + "enableFeedAdsDescription": "Controls the visibility of all ads within content feeds.", + "@enableFeedAdsDescription": { + "description": "Description for the feed ad enablement switch." + }, + "visibleToRoleDescription": "When enabled, this feature will be active for users with the '{roleName}' role.", + "@visibleToRoleDescription": { + "description": "Generic description for a role-specific visibility switch.", + "placeholders": { + "roleName": { + "type": "String" + } + } + }, + "enableDecoratorDescription": "Globally activates or deactivates this decorator for all eligible users.", + "@enableDecoratorDescription": { + "description": "Description for the decorator enablement switch." + }, + "enableNavigationAdsDescription": "Controls the visibility of interstitial ads that appear during user navigation.", + "@enableNavigationAdsDescription": { + "description": "Description for the navigation ad enablement switch." + }, + "enableHeadlineReportingDescription": "Allows users to report individual headlines for issues like misinformation or clickbait.", + "@enableHeadlineReportingDescription": { + "description": "Description for the headline reporting switch." + }, + "enableSourceReportingDescription": "Allows users to report entire news sources for issues like low quality or bias.", + "@enableSourceReportingDescription": { + "description": "Description for the source reporting switch." + }, + "enableCommentReportingDescription": "Allows users to report individual comments for moderation.", + "@enableCommentReportingDescription": { + "description": "Description for the comment reporting switch." + }, + "pushNotificationDeliveryTypeBreakingOnlyDescription": "Enable to allow users to subscribe to immediate alerts for breaking news.", + "@pushNotificationDeliveryTypeBreakingOnlyDescription": { + "description": "Description for the 'Breaking News' delivery type switch." + }, + "pushNotificationDeliveryTypeDailyDigestDescription": "Enable to allow users to subscribe to a daily summary of relevant news.", + "@pushNotificationDeliveryTypeDailyDigestDescription": { + "description": "Description for the 'Daily Digest' delivery type switch." + }, + "pushNotificationDeliveryTypeWeeklyRoundupDescription": "Enable to allow users to subscribe to a weekly roundup of relevant news.", + "@pushNotificationDeliveryTypeWeeklyRoundupDescription": { + "description": "Description for the 'Weekly Roundup' delivery type switch." + }, + "positiveInteractionTypeSaveItemDescription": "Counts when a user bookmark a headline.", + "@positiveInteractionTypeSaveItemDescription": { + "description": "Description for the 'save item' positive interaction type switch." + }, + "positiveInteractionTypeFollowItemDescription": "Counts when a user follows a headline topic, source, or country.", + "@positiveInteractionTypeFollowItemDescription": { + "description": "Description for the 'follow item' positive interaction type switch." + }, + "positiveInteractionTypeShareContentDescription": "Counts when a user shares a headline.", + "@positiveInteractionTypeShareContentDescription": { + "description": "Description for the 'share content' positive interaction type switch." + }, + "positiveInteractionTypeSaveFilterDescription": "Counts when a user creates a saved filter.", + "@positiveInteractionTypeSaveFilterDescription": { + "description": "Description for the 'save filter' positive interaction type switch." + }, + "internalPromptLogicDescription": "Define the conditions that trigger the enjoyment prompt, such as the number of user actions and cooldown periods.", + "@internalPromptLogicDescription": { + "description": "Description for the internal prompt logic settings." + }, + "eligiblePositiveInteractionsDescription": "Select which user actions are counted as 'positive interactions' to trigger the enjoyment prompt.", + "@eligiblePositiveInteractionsDescription": { + "description": "Description for the eligible positive interactions settings." + }, + "followUpActionsDescription": "Configure what happens after a user responds to the enjoyment prompt, such as requesting a store review.", + "@followUpActionsDescription": { + "description": "Description for the follow-up actions settings." } } \ No newline at end of file From 3a0eab87e0fcc0b63bb349bfcc8586d22d8f2d60 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:22:15 +0100 Subject: [PATCH 24/37] build(l10n): sync --- lib/l10n/app_localizations.dart | 118 +++++++++++++++++++++++++++-- lib/l10n/app_localizations_ar.dart | 86 +++++++++++++++++++-- lib/l10n/app_localizations_en.dart | 86 +++++++++++++++++++-- 3 files changed, 269 insertions(+), 21 deletions(-) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 8f7096c5..86debcff 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -3095,7 +3095,7 @@ abstract class AppLocalizations { /// Description for the feed item click behavior setting. /// /// In en, this message translates to: - /// **'Select which browser opens when a user taps on a headline in the feed.'** + /// **'Set the default browser for opening headlines. This can be overridden by users in their app\'s feed settings.'** String get feedItemClickBehaviorDescription; /// Option for opening links in the app's internal browser. @@ -3203,7 +3203,7 @@ abstract class AppLocalizations { /// Description for the Community & Engagement expansion tile. /// /// In en, this message translates to: - /// **'Manage user interactions, content reporting, and the internal app reporting system.'** + /// **'Configure user engagement and reporting tools. To ensure accountability, these features are unavailable for guest users within the mobile app, irrespective of the settings configured here.'** String get communityAndEngagementDescription; /// Title for the User Engagement expansion tile. @@ -3383,19 +3383,19 @@ abstract class AppLocalizations { /// Label for the 'save item' positive interaction type. /// /// In en, this message translates to: - /// **'Save a content item (e.g., a headline)'** + /// **'Save a content item'** String get positiveInteractionTypeSaveItem; /// Label for the 'follow item' positive interaction type. /// /// In en, this message translates to: - /// **'Follow an entity (e.g., a topic, source, or country)'** + /// **'Follow an entity'** String get positiveInteractionTypeFollowItem; /// Label for the 'share content' positive interaction type. /// /// In en, this message translates to: - /// **'Share a content item (e.g., a headline)'** + /// **'Share a content item'** String get positiveInteractionTypeShareContent; /// Label for the 'save filter' positive interaction type. @@ -4219,6 +4219,114 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Shows a collection of sources the user might be interested in following.'** String get feedDecoratorSuggestedSourcesDescription; + + /// Description for the global ad enablement switch. + /// + /// In en, this message translates to: + /// **'Globally activates or deactivates all advertisements within the application.'** + String get enableGlobalAdsDescription; + + /// Description for the feed ad enablement switch. + /// + /// In en, this message translates to: + /// **'Controls the visibility of all ads within content feeds.'** + String get enableFeedAdsDescription; + + /// Generic description for a role-specific visibility switch. + /// + /// In en, this message translates to: + /// **'When enabled, this feature will be active for users with the \'{roleName}\' role.'** + String visibleToRoleDescription(String roleName); + + /// Description for the decorator enablement switch. + /// + /// In en, this message translates to: + /// **'Globally activates or deactivates this decorator for all eligible users.'** + String get enableDecoratorDescription; + + /// Description for the navigation ad enablement switch. + /// + /// In en, this message translates to: + /// **'Controls the visibility of interstitial ads that appear during user navigation.'** + String get enableNavigationAdsDescription; + + /// Description for the headline reporting switch. + /// + /// In en, this message translates to: + /// **'Allows users to report individual headlines for issues like misinformation or clickbait.'** + String get enableHeadlineReportingDescription; + + /// Description for the source reporting switch. + /// + /// In en, this message translates to: + /// **'Allows users to report entire news sources for issues like low quality or bias.'** + String get enableSourceReportingDescription; + + /// Description for the comment reporting switch. + /// + /// In en, this message translates to: + /// **'Allows users to report individual comments for moderation.'** + String get enableCommentReportingDescription; + + /// Description for the 'Breaking News' delivery type switch. + /// + /// In en, this message translates to: + /// **'Enable to allow users to subscribe to immediate alerts for breaking news.'** + String get pushNotificationDeliveryTypeBreakingOnlyDescription; + + /// Description for the 'Daily Digest' delivery type switch. + /// + /// In en, this message translates to: + /// **'Enable to allow users to subscribe to a daily summary of relevant news.'** + String get pushNotificationDeliveryTypeDailyDigestDescription; + + /// Description for the 'Weekly Roundup' delivery type switch. + /// + /// In en, this message translates to: + /// **'Enable to allow users to subscribe to a weekly roundup of relevant news.'** + String get pushNotificationDeliveryTypeWeeklyRoundupDescription; + + /// Description for the 'save item' positive interaction type switch. + /// + /// In en, this message translates to: + /// **'Counts when a user bookmark a headline.'** + String get positiveInteractionTypeSaveItemDescription; + + /// Description for the 'follow item' positive interaction type switch. + /// + /// In en, this message translates to: + /// **'Counts when a user follows a headline topic, source, or country.'** + String get positiveInteractionTypeFollowItemDescription; + + /// Description for the 'share content' positive interaction type switch. + /// + /// In en, this message translates to: + /// **'Counts when a user shares a headline.'** + String get positiveInteractionTypeShareContentDescription; + + /// Description for the 'save filter' positive interaction type switch. + /// + /// In en, this message translates to: + /// **'Counts when a user creates a saved filter.'** + String get positiveInteractionTypeSaveFilterDescription; + + /// Description for the internal prompt logic settings. + /// + /// In en, this message translates to: + /// **'Define the conditions that trigger the enjoyment prompt, such as the number of user actions and cooldown periods.'** + String get internalPromptLogicDescription; + + /// Description for the eligible positive interactions settings. + /// + /// In en, this message translates to: + /// **'Select which user actions are counted as \'positive interactions\' to trigger the enjoyment prompt.'** + String get eligiblePositiveInteractionsDescription; + + /// Description for the follow-up actions settings. + /// + /// In en, this message translates to: + /// **'Configure what happens after a user responds to the enjoyment prompt, such as requesting a store review.'** + String get followUpActionsDescription; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 51731ec5..cd4aae1d 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -1661,7 +1661,7 @@ class AppLocalizationsAr extends AppLocalizations { @override String get feedItemClickBehaviorDescription => - 'اختر المتصفح الذي يفتح عند نقر المستخدم على عنوان في الموجز.'; + 'قم بتعيين المتصفح الافتراضي لفتح العناوين. يمكن للمستخدمين تجاوز هذا الإعداد في إعدادات الموجز الخاصة بهم في التطبيق.'; @override String get feedItemClickBehaviorInternalNavigation => 'متصفح داخل التطبيق'; @@ -1725,7 +1725,7 @@ class AppLocalizationsAr extends AppLocalizations { @override String get communityAndEngagementDescription => - 'إدارة تفاعلات المستخدمين، والإبلاغ عن المحتوى، ونظام مراجعات التطبيق الداخلي.'; + 'تكوين أدوات تفاعل المستخدمين والإبلاغ. لضمان المساءلة، هذه الميزات غير متاحة للمستخدمين الضيوف داخل تطبيق الجوال، بغض النظر عن الإعدادات المكونة هنا.'; @override String get userEngagementTitle => 'مشاركة المستخدم'; @@ -1825,16 +1825,13 @@ class AppLocalizationsAr extends AppLocalizations { String get eligiblePositiveInteractionsTitle => 'التفاعلات الإيجابية المؤهلة'; @override - String get positiveInteractionTypeSaveItem => - 'حفظ عنصر محتوى (مثل عنوان رئيسي)'; + String get positiveInteractionTypeSaveItem => 'حفظ عنصر محتوى'; @override - String get positiveInteractionTypeFollowItem => - 'متابعة كيان (مثل موضوع أو مصدر أو بلد)'; + String get positiveInteractionTypeFollowItem => 'متابعة كيان '; @override - String get positiveInteractionTypeShareContent => - 'مشاركة عنصر محتوى (مثل عنوان رئيسي)'; + String get positiveInteractionTypeShareContent => 'مشاركة عنصر محتوى'; @override String get positiveInteractionTypeSaveFilter => 'إنشاء مرشح محفوظ'; @@ -2290,4 +2287,77 @@ class AppLocalizationsAr extends AppLocalizations { @override String get feedDecoratorSuggestedSourcesDescription => 'يعرض مجموعة من المصادر التي قد يهتم المستخدم بمتابعتها.'; + + @override + String get enableGlobalAdsDescription => + 'ينشط أو يعطل عالميًا جميع الإعلانات داخل التطبيق.'; + + @override + String get enableFeedAdsDescription => + 'يتحكم في رؤية جميع الإعلانات داخل موجزات المحتوى.'; + + @override + String visibleToRoleDescription(String roleName) { + return 'عند التمكين، ستكون هذه الميزة نشطة للمستخدمين الذين لديهم دور \'$roleName\'.'; + } + + @override + String get enableDecoratorDescription => + 'ينشط أو يعطل عالميًا هذه الزينة لجميع المستخدمين المؤهلين.'; + + @override + String get enableNavigationAdsDescription => + 'يتحكم في رؤية الإعلانات البينية التي تظهر أثناء تنقل المستخدم.'; + + @override + String get enableHeadlineReportingDescription => + 'يسمح للمستخدمين بالإبلاغ عن العناوين الفردية لمشاكل مثل المعلومات المضللة أو العناوين المضللة.'; + + @override + String get enableSourceReportingDescription => + 'يسمح للمستخدمين بالإبلاغ عن مصادر الأخبار بأكملها لمشاكل مثل الجودة المنخفضة أو التحيز.'; + + @override + String get enableCommentReportingDescription => + 'يسمح للمستخدمين بالإبلاغ عن التعليقات الفردية للإشراف عليها.'; + + @override + String get pushNotificationDeliveryTypeBreakingOnlyDescription => + 'تفعيل للسماح للمستخدمين بالاشتراك في التنبيهات الفورية للأخبار العاجلة.'; + + @override + String get pushNotificationDeliveryTypeDailyDigestDescription => + 'تفعيل للسماح للمستخدمين بالاشتراك في ملخص يومي للأخبار ذات الصلة.'; + + @override + String get pushNotificationDeliveryTypeWeeklyRoundupDescription => + 'تفعيل للسماح للمستخدمين بالاشتراك في ملخص أسبوعي للأخبار ذات الصلة.'; + + @override + String get positiveInteractionTypeSaveItemDescription => + 'يحتسب عندما يحفظ المستخدم عنوان رئيسي.'; + + @override + String get positiveInteractionTypeFollowItemDescription => + 'يحتسب عندما يتابع المستخدم موضوعًا أو مصدرًا أو بلدًا مثل لعنوان رئيسي.'; + + @override + String get positiveInteractionTypeShareContentDescription => + 'يحتسب عندما يشارك المستخدم عنوان رئيسي.'; + + @override + String get positiveInteractionTypeSaveFilterDescription => + 'يحتسب عندما ينشئ المستخدم مرشحًا محفوظًا.'; + + @override + String get internalPromptLogicDescription => + 'تحديد الشروط التي تؤدي إلى ظهور موجه الاستمتاع، مثل عدد إجراءات المستخدم وفترات التهدئة.'; + + @override + String get eligiblePositiveInteractionsDescription => + 'اختر إجراءات المستخدم التي تُحتسب \'كتفاعلات إيجابية\' لتشغيل موجه الاستمتاع.'; + + @override + String get followUpActionsDescription => + 'تكوين ما يحدث بعد استجابة المستخدم لموجه الاستمتاع، مثل طلب مراجعة المتجر.'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index f4ad1d56..8e2d83b7 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -1664,7 +1664,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get feedItemClickBehaviorDescription => - 'Select which browser opens when a user taps on a headline in the feed.'; + 'Set the default browser for opening headlines. This can be overridden by users in their app\'s feed settings.'; @override String get feedItemClickBehaviorInternalNavigation => 'In-App Browser'; @@ -1729,7 +1729,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get communityAndEngagementDescription => - 'Manage user interactions, content reporting, and the internal app reporting system.'; + 'Configure user engagement and reporting tools. To ensure accountability, these features are unavailable for guest users within the mobile app, irrespective of the settings configured here.'; @override String get userEngagementTitle => 'User Engagement'; @@ -1831,16 +1831,13 @@ class AppLocalizationsEn extends AppLocalizations { 'Eligible Positive Interactions'; @override - String get positiveInteractionTypeSaveItem => - 'Save a content item (e.g., a headline)'; + String get positiveInteractionTypeSaveItem => 'Save a content item'; @override - String get positiveInteractionTypeFollowItem => - 'Follow an entity (e.g., a topic, source, or country)'; + String get positiveInteractionTypeFollowItem => 'Follow an entity'; @override - String get positiveInteractionTypeShareContent => - 'Share a content item (e.g., a headline)'; + String get positiveInteractionTypeShareContent => 'Share a content item'; @override String get positiveInteractionTypeSaveFilter => 'Create a saved filter'; @@ -2297,4 +2294,77 @@ class AppLocalizationsEn extends AppLocalizations { @override String get feedDecoratorSuggestedSourcesDescription => 'Shows a collection of sources the user might be interested in following.'; + + @override + String get enableGlobalAdsDescription => + 'Globally activates or deactivates all advertisements within the application.'; + + @override + String get enableFeedAdsDescription => + 'Controls the visibility of all ads within content feeds.'; + + @override + String visibleToRoleDescription(String roleName) { + return 'When enabled, this feature will be active for users with the \'$roleName\' role.'; + } + + @override + String get enableDecoratorDescription => + 'Globally activates or deactivates this decorator for all eligible users.'; + + @override + String get enableNavigationAdsDescription => + 'Controls the visibility of interstitial ads that appear during user navigation.'; + + @override + String get enableHeadlineReportingDescription => + 'Allows users to report individual headlines for issues like misinformation or clickbait.'; + + @override + String get enableSourceReportingDescription => + 'Allows users to report entire news sources for issues like low quality or bias.'; + + @override + String get enableCommentReportingDescription => + 'Allows users to report individual comments for moderation.'; + + @override + String get pushNotificationDeliveryTypeBreakingOnlyDescription => + 'Enable to allow users to subscribe to immediate alerts for breaking news.'; + + @override + String get pushNotificationDeliveryTypeDailyDigestDescription => + 'Enable to allow users to subscribe to a daily summary of relevant news.'; + + @override + String get pushNotificationDeliveryTypeWeeklyRoundupDescription => + 'Enable to allow users to subscribe to a weekly roundup of relevant news.'; + + @override + String get positiveInteractionTypeSaveItemDescription => + 'Counts when a user bookmark a headline.'; + + @override + String get positiveInteractionTypeFollowItemDescription => + 'Counts when a user follows a headline topic, source, or country.'; + + @override + String get positiveInteractionTypeShareContentDescription => + 'Counts when a user shares a headline.'; + + @override + String get positiveInteractionTypeSaveFilterDescription => + 'Counts when a user creates a saved filter.'; + + @override + String get internalPromptLogicDescription => + 'Define the conditions that trigger the enjoyment prompt, such as the number of user actions and cooldown periods.'; + + @override + String get eligiblePositiveInteractionsDescription => + 'Select which user actions are counted as \'positive interactions\' to trigger the enjoyment prompt.'; + + @override + String get followUpActionsDescription => + 'Configure what happens after a user responds to the enjoyment prompt, such as requesting a store review.'; } From 0cdd422164aa28319a7611de592c2e61820b2152 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:22:27 +0100 Subject: [PATCH 25/37] feat(app_configuration): add description to global ads switch - Added a subtitle to the SwitchListTile in AdConfigForm - The subtitle provides a description for the global ads setting --- lib/app_configuration/widgets/ad_config_form.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/app_configuration/widgets/ad_config_form.dart b/lib/app_configuration/widgets/ad_config_form.dart index a74323e8..2e180641 100644 --- a/lib/app_configuration/widgets/ad_config_form.dart +++ b/lib/app_configuration/widgets/ad_config_form.dart @@ -32,6 +32,7 @@ class AdConfigForm extends StatelessWidget { children: [ SwitchListTile( title: Text(l10n.enableGlobalAdsLabel), + subtitle: Text(l10n.enableGlobalAdsDescription), value: ads.enabled, onChanged: (value) { onConfigChanged( From 22bf2179248b738d20538b9e805e6fa2808e3e28 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:22:56 +0100 Subject: [PATCH 26/37] feat(app_configuration): add subtitles to app review settings form - Add description subtitle to internal prompt logic section - Add description subtitle to eligible positive interactions section - Add description subtitle to follow-up actions section - Add l10n description to positive interaction type switch tiles --- .../widgets/app_review_settings_form.dart | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lib/app_configuration/widgets/app_review_settings_form.dart b/lib/app_configuration/widgets/app_review_settings_form.dart index eb1dec43..c1d006a6 100644 --- a/lib/app_configuration/widgets/app_review_settings_form.dart +++ b/lib/app_configuration/widgets/app_review_settings_form.dart @@ -111,6 +111,15 @@ class _AppReviewSettingsFormState extends State { builder: (context, constraints) { return ExpansionTile( title: Text(l10n.internalPromptLogicTitle), + subtitle: Text( + l10n.internalPromptLogicDescription, + style: Theme.of(context).textTheme.bodySmall + ?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, @@ -175,6 +184,15 @@ class _AppReviewSettingsFormState extends State { builder: (context, constraints) { return ExpansionTile( title: Text(l10n.eligiblePositiveInteractionsTitle), + subtitle: Text( + l10n.eligiblePositiveInteractionsDescription, + style: Theme.of(context).textTheme.bodySmall + ?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, @@ -185,6 +203,9 @@ class _AppReviewSettingsFormState extends State { children: [ ...PositiveInteractionType.values.map( (interactionType) => SwitchListTile( + subtitle: Text( + interactionType.l10nDescription(context), + ), title: Text(interactionType.l10n(context)), value: appReviewConfig .eligiblePositiveInteractions @@ -231,6 +252,15 @@ class _AppReviewSettingsFormState extends State { builder: (context, constraints) { return ExpansionTile( title: Text(l10n.followUpActionsTitle), + subtitle: Text( + l10n.followUpActionsDescription, + style: Theme.of(context).textTheme.bodySmall + ?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + ), initiallyExpanded: false, childrenPadding: const EdgeInsetsDirectional.only( start: AppSpacing.lg, @@ -314,3 +344,19 @@ extension on PositiveInteractionType { } } } + +extension on PositiveInteractionType { + String l10nDescription(BuildContext context) { + final l10n = AppLocalizationsX(context).l10n; + switch (this) { + case PositiveInteractionType.saveItem: + return l10n.positiveInteractionTypeSaveItemDescription; + case PositiveInteractionType.followItem: + return l10n.positiveInteractionTypeFollowItemDescription; + case PositiveInteractionType.shareContent: + return l10n.positiveInteractionTypeShareContentDescription; + case PositiveInteractionType.saveFilter: + return l10n.positiveInteractionTypeSaveFilterDescription; + } + } +} From 39a362337ce97d42cbd7a4049002e72de0e65354 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:24:04 +0100 Subject: [PATCH 27/37] feat(app_configuration): add descriptions to feed ad settings switches - Add subtitle to enableFeedAdsLabel switch - Add subtitle to visibleToRoleLabel switch --- lib/app_configuration/widgets/feed_ad_settings_form.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/app_configuration/widgets/feed_ad_settings_form.dart b/lib/app_configuration/widgets/feed_ad_settings_form.dart index 98f36254..1e6cfa75 100644 --- a/lib/app_configuration/widgets/feed_ad_settings_form.dart +++ b/lib/app_configuration/widgets/feed_ad_settings_form.dart @@ -153,6 +153,7 @@ class _FeedAdSettingsFormState extends State children: [ SwitchListTile( title: Text(l10n.enableFeedAdsLabel), + subtitle: Text(l10n.enableFeedAdsDescription), value: feedAdConfig.enabled, onChanged: (value) { widget.onConfigChanged( @@ -292,6 +293,7 @@ class _FeedAdSettingsFormState extends State children: [ SwitchListTile( title: Text(l10n.visibleToRoleLabel(role.l10n(context))), + subtitle: Text(l10n.visibleToRoleDescription(role.l10n(context))), value: roleConfig != null, onChanged: (value) { final newVisibleTo = Map.from( From 912fb366006609a2196e205530023413694bdd13 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:24:11 +0100 Subject: [PATCH 28/37] feat(feed_decorator): add description to enable switch - Add subtitle to SwitchListTile in FeedDecoratorForm - Improve user understanding of the enable decorator function --- lib/app_configuration/widgets/feed_decorator_form.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/app_configuration/widgets/feed_decorator_form.dart b/lib/app_configuration/widgets/feed_decorator_form.dart index 7d334fd7..ac9d24d2 100644 --- a/lib/app_configuration/widgets/feed_decorator_form.dart +++ b/lib/app_configuration/widgets/feed_decorator_form.dart @@ -156,6 +156,7 @@ class _FeedDecoratorFormState extends State children: [ SwitchListTile( title: Text(l10n.enabledLabel), + subtitle: Text(l10n.enableDecoratorDescription), value: decoratorConfig.enabled, onChanged: (value) { final newDecoratorConfig = decoratorConfig.copyWith(enabled: value); From 33a3ffaffe600b18fa63152a86b651a89302fb51 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:24:47 +0100 Subject: [PATCH 29/37] feat(app_configuration): add descriptions to navigation ad settings switches - Add subtitle to enableNavigationAdsLabel switch - Add subtitle to visibleToRoleLabel switch --- lib/app_configuration/widgets/navigation_ad_settings_form.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/app_configuration/widgets/navigation_ad_settings_form.dart b/lib/app_configuration/widgets/navigation_ad_settings_form.dart index 7704245e..05f54a24 100644 --- a/lib/app_configuration/widgets/navigation_ad_settings_form.dart +++ b/lib/app_configuration/widgets/navigation_ad_settings_form.dart @@ -130,6 +130,7 @@ class _NavigationAdSettingsFormState extends State children: [ SwitchListTile( title: Text(l10n.enableNavigationAdsLabel), + subtitle: Text(l10n.enableNavigationAdsDescription), value: navAdConfig.enabled, onChanged: (value) { widget.onConfigChanged( @@ -212,6 +213,7 @@ class _NavigationAdSettingsFormState extends State children: [ SwitchListTile( title: Text(l10n.visibleToRoleLabel(role.l10n(context))), + subtitle: Text(l10n.visibleToRoleDescription(role.l10n(context))), value: roleConfig != null, onChanged: (value) { final newVisibleTo = From 48dddbe49c45c06fcb1d5abc373445ad01a15774 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:25:15 +0100 Subject: [PATCH 30/37] feat(push-notification): add description to delivery type switcher - Implement _getDeliveryTypeDescription method to provide descriptions for different delivery types - Update _buildDeliveryTypesSection to include subtitle with delivery type description --- .../widgets/push_notification_settings_form.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/app_configuration/widgets/push_notification_settings_form.dart b/lib/app_configuration/widgets/push_notification_settings_form.dart index e7d083f5..c35089ac 100644 --- a/lib/app_configuration/widgets/push_notification_settings_form.dart +++ b/lib/app_configuration/widgets/push_notification_settings_form.dart @@ -103,6 +103,21 @@ class PushNotificationSettingsForm extends StatelessWidget { ); } + String _getDeliveryTypeDescription( + BuildContext context, + PushNotificationSubscriptionDeliveryType type, + ) { + final l10n = AppLocalizationsX(context).l10n; + switch (type) { + case PushNotificationSubscriptionDeliveryType.breakingOnly: + return l10n.pushNotificationDeliveryTypeBreakingOnlyDescription; + case PushNotificationSubscriptionDeliveryType.dailyDigest: + return l10n.pushNotificationDeliveryTypeDailyDigestDescription; + case PushNotificationSubscriptionDeliveryType.weeklyRoundup: + return l10n.pushNotificationDeliveryTypeWeeklyRoundupDescription; + } + } + Widget _buildDeliveryTypesSection( BuildContext context, AppLocalizations l10n, @@ -128,6 +143,7 @@ class PushNotificationSettingsForm extends StatelessWidget { .map( (type) => SwitchListTile( title: Text(type.l10n(context)), + subtitle: Text(_getDeliveryTypeDescription(context, type)), value: pushConfig.deliveryConfigs[type] ?? false, onChanged: (value) { final newDeliveryConfigs = From e319ec6c62963bc18d7c5bca076137df0b745e79 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:26:06 +0100 Subject: [PATCH 31/37] feat(app_configuration): add descriptions to reporting settings - Add subtitle descriptions for headline, source, and comment reporting settings - Improve clarity and user understanding of reporting options --- lib/app_configuration/widgets/reporting_settings_form.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/app_configuration/widgets/reporting_settings_form.dart b/lib/app_configuration/widgets/reporting_settings_form.dart index 0f93cd83..bf5139dd 100644 --- a/lib/app_configuration/widgets/reporting_settings_form.dart +++ b/lib/app_configuration/widgets/reporting_settings_form.dart @@ -48,6 +48,7 @@ class ReportingSettingsForm extends StatelessWidget { const SizedBox(height: AppSpacing.lg), SwitchListTile( title: Text(l10n.enableHeadlineReportingLabel), + subtitle: Text(l10n.enableHeadlineReportingDescription), value: reportingConfig.headlineReportingEnabled, onChanged: (value) { final newConfig = reportingConfig.copyWith( @@ -66,6 +67,7 @@ class ReportingSettingsForm extends StatelessWidget { ), SwitchListTile( title: Text(l10n.enableSourceReportingLabel), + subtitle: Text(l10n.enableSourceReportingDescription), value: reportingConfig.sourceReportingEnabled, onChanged: (value) { final newConfig = reportingConfig.copyWith( @@ -84,6 +86,7 @@ class ReportingSettingsForm extends StatelessWidget { ), SwitchListTile( title: Text(l10n.enableCommentReportingLabel), + subtitle: Text(l10n.enableCommentReportingDescription), value: reportingConfig.commentReportingEnabled, onChanged: (value) { final newConfig = reportingConfig.copyWith( From f2971ed0d0b137945e411f4c6e80d8a418ba0431 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:34:10 +0100 Subject: [PATCH 32/37] feat(app_configuration): add leading icons to expansion tiles - Add Icons.paid_outlined to advertisements tile - Add Icons.notifications_active_outlined to push notifications tile - Add Icons.dynamic_feed_outlined to feed tile - Add Icons.groups_outlined to community and engagement tile --- .../view/tabs/features_configuration_tab.dart | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/app_configuration/view/tabs/features_configuration_tab.dart b/lib/app_configuration/view/tabs/features_configuration_tab.dart index d7c489ce..f6f68a6d 100644 --- a/lib/app_configuration/view/tabs/features_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/features_configuration_tab.dart @@ -83,6 +83,12 @@ class _FeaturesConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 0; return ExpansionTile( + leading: Icon( + Icons.paid_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('advertisementsTile_$expandedIndex'), title: Text(l10n.advertisementsTab), subtitle: Text( @@ -135,6 +141,12 @@ class _FeaturesConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 1; return ExpansionTile( + leading: Icon( + Icons.notifications_active_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('pushNotificationsTile_$expandedIndex'), title: Text(l10n.notificationsTab), subtitle: Text( @@ -172,6 +184,12 @@ class _FeaturesConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 2; return ExpansionTile( + leading: Icon( + Icons.dynamic_feed_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('feedTile_$expandedIndex'), title: Text(l10n.feedTab), subtitle: Text( @@ -305,6 +323,12 @@ class _FeaturesConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 3; return ExpansionTile( + leading: Icon( + Icons.groups_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('communityTile_$expandedIndex'), title: Text(l10n.communityAndEngagementTitle), subtitle: Text( From 74e5ef1aa3a6c8160e128e3787dc14f96b4aa85a Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:34:16 +0100 Subject: [PATCH 33/37] feat(app_configuration): add icons to expansion tiles - Add system_update_alt_outlined icon to app status and updates tile - Add link_outlined icon to app URLs tile - Set icon color to onSurface with 70% opacity for both tiles --- .../view/tabs/system_configuration_tab.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/app_configuration/view/tabs/system_configuration_tab.dart b/lib/app_configuration/view/tabs/system_configuration_tab.dart index f5442ecd..d78fc200 100644 --- a/lib/app_configuration/view/tabs/system_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/system_configuration_tab.dart @@ -53,6 +53,12 @@ class _SystemConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 0; return ExpansionTile( + leading: Icon( + Icons.system_update_alt_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('appStatusAndUpdatesTile_$expandedIndex'), title: Text(l10n.appStatusAndUpdatesTitle), subtitle: Text( @@ -146,6 +152,12 @@ class _SystemConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 1; return ExpansionTile( + leading: Icon( + Icons.link_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('appUrlsTile_$expandedIndex'), title: Text(l10n.appUrlsTitle), subtitle: Text( From 1ad415ff224304d1c07a692bb958593593f27885 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:34:47 +0100 Subject: [PATCH 34/37] feat(app_configuration): add icon to user limits tile - Add Icons.manage_accounts_outlined to the leading of ExpansionTile - Set icon color to onSurface with 70% opacity --- lib/app_configuration/view/tabs/user_configuration_tab.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/app_configuration/view/tabs/user_configuration_tab.dart b/lib/app_configuration/view/tabs/user_configuration_tab.dart index 54ada6d7..6585163e 100644 --- a/lib/app_configuration/view/tabs/user_configuration_tab.dart +++ b/lib/app_configuration/view/tabs/user_configuration_tab.dart @@ -52,6 +52,12 @@ class _UserConfigurationTabState extends State { builder: (context, expandedIndex, child) { const tileIndex = 0; return ExpansionTile( + leading: Icon( + Icons.manage_accounts_outlined, + color: Theme.of(context).colorScheme.onSurface.withOpacity( + 0.7, + ), + ), key: ValueKey('userLimitsTile_$expandedIndex'), title: Text(l10n.userLimitsTitle), subtitle: Text( From 2e3b31727964dadf26421ebbdf683b15375ab531 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:46:13 +0100 Subject: [PATCH 35/37] feat(l10n): update app configuration translations and labels - Update Arabic translations for app configuration terms - Change "App Configuration" to "Remote Config" in English localization - Update related page titles and navigation item labels --- lib/l10n/app_localizations.dart | 4 ++-- lib/l10n/app_localizations_ar.dart | 4 ++-- lib/l10n/app_localizations_en.dart | 4 ++-- lib/l10n/arb/app_ar.arb | 4 ++-- lib/l10n/arb/app_en.arb | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 86debcff..6a898c19 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -269,7 +269,7 @@ abstract class AppLocalizations { /// Label for the app configuration navigation item /// /// In en, this message translates to: - /// **'App Configuration'** + /// **'Remote Config'** String get appConfiguration; /// Description for the App Configuration page @@ -287,7 +287,7 @@ abstract class AppLocalizations { /// Title for the App Configuration page /// /// In en, this message translates to: - /// **'App Configuration'** + /// **'Remote Configuration'** String get appConfigurationPageTitle; /// Tab title for Feed settings diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index cd4aae1d..6b697948 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -105,7 +105,7 @@ class AppLocalizationsAr extends AppLocalizations { String get source => 'المصدر'; @override - String get appConfiguration => 'إعدادات التطبيق'; + String get appConfiguration => 'التحكم المركزي'; @override String get appConfigurationPageDescription => @@ -115,7 +115,7 @@ class AppLocalizationsAr extends AppLocalizations { String get settings => 'الإعدادات'; @override - String get appConfigurationPageTitle => 'إعدادات التطبيق'; + String get appConfigurationPageTitle => 'التحكم المركزي'; @override String get feedTab => 'الموجز'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 8e2d83b7..4dd36941 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -104,7 +104,7 @@ class AppLocalizationsEn extends AppLocalizations { String get source => 'Source'; @override - String get appConfiguration => 'App Configuration'; + String get appConfiguration => 'Remote Config'; @override String get appConfigurationPageDescription => @@ -114,7 +114,7 @@ class AppLocalizationsEn extends AppLocalizations { String get settings => 'Settings'; @override - String get appConfigurationPageTitle => 'App Configuration'; + String get appConfigurationPageTitle => 'Remote Configuration'; @override String get feedTab => 'Feed'; diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index 81195a9d..f2aaa187 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -127,7 +127,7 @@ "@source": { "description": "تسمية المصدر" }, - "appConfiguration": "إعدادات التطبيق", + "appConfiguration": "التحكم المركزي", "@appConfiguration": { "description": "تسمية عنصر التنقل لإعدادات التطبيق" }, @@ -139,7 +139,7 @@ "@settings": { "description": "تسمية عنصر التنقل للإعدادات" }, - "appConfigurationPageTitle": "إعدادات التطبيق", + "appConfigurationPageTitle": "التحكم المركزي", "@appConfigurationPageTitle": { "description": "عنوان صفحة إعدادات التطبيق" }, diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 744c2065..1103f485 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -127,7 +127,7 @@ "@source": { "description": "Label for the a singular source" }, - "appConfiguration": "App Configuration", + "appConfiguration": "Remote Config", "@appConfiguration": { "description": "Label for the app configuration navigation item" }, @@ -139,7 +139,7 @@ "@settings": { "description": "Label for the settings navigation item" }, - "appConfigurationPageTitle": "App Configuration", + "appConfigurationPageTitle": "Remote Configuration", "@appConfigurationPageTitle": { "description": "Title for the App Configuration page" }, From e2e9abb33430f500d5325334085d473411f863ed Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:51:11 +0100 Subject: [PATCH 36/37] feat(l10n): update app config save success messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Arabic: "تم حفظ الإعدادات عن بعد بنجاح. ستعتمد تطبيقات الجوال هذه التغييرات عند تشغيلها التالي." - English: "Remote configuration saved successfully. Mobile clients will update on their next launch." These changes provide more accurate information about how mobile clients will apply the new configuration. --- lib/l10n/app_localizations.dart | 2 +- lib/l10n/app_localizations_ar.dart | 3 ++- lib/l10n/app_localizations_en.dart | 2 +- lib/l10n/arb/app_ar.arb | 2 +- lib/l10n/arb/app_en.arb | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 6a898c19..dd4abc09 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -389,7 +389,7 @@ abstract class AppLocalizations { /// Snackbar message for successful app configuration save /// /// In en, this message translates to: - /// **'App configuration saved successfully!'** + /// **'Remote configuration saved successfully. Mobile clients will update on their next launch.'** String get appConfigSaveSuccessMessage; /// Snackbar message for app configuration save error diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 6b697948..7a9c876b 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -172,7 +172,8 @@ class AppLocalizationsAr extends AppLocalizations { String get forceUpdateTab => 'تحديث إجباري'; @override - String get appConfigSaveSuccessMessage => 'تم حفظ إعدادات التطبيق بنجاح!'; + String get appConfigSaveSuccessMessage => + 'تم حفظ الإعدادات عن بعد بنجاح. ستعكس تطبيقات الجوال هذه التغييرات عند تشغيلها التالي.'; @override String appConfigSaveErrorMessage(String errorMessage) { diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 4dd36941..f7234eca 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -172,7 +172,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get appConfigSaveSuccessMessage => - 'App configuration saved successfully!'; + 'Remote configuration saved successfully. Mobile clients will update on their next launch.'; @override String appConfigSaveErrorMessage(String errorMessage) { diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index f2aaa187..e54bb86d 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -207,7 +207,7 @@ "@forceUpdateTab": { "description": "عنوان تبويب تحديث إجباري" }, - "appConfigSaveSuccessMessage": "تم حفظ إعدادات التطبيق بنجاح!", + "appConfigSaveSuccessMessage": "تم حفظ الإعدادات عن بعد بنجاح. ستعكس تطبيقات الجوال هذه التغييرات عند تشغيلها التالي.", "@appConfigSaveSuccessMessage": { "description": "رسالة شريط التنبيه لحفظ إعدادات التطبيق بنجاح" }, diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 1103f485..97d630c6 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -207,7 +207,7 @@ "@forceUpdateTab": { "description": "Tab title for Force Update" }, - "appConfigSaveSuccessMessage": "App configuration saved successfully!", + "appConfigSaveSuccessMessage": "Remote configuration saved successfully. Mobile clients will update on their next launch.", "@appConfigSaveSuccessMessage": { "description": "Snackbar message for successful app configuration save" }, From 7773304d76ebdc11aa9a5ac089c4d99b892e7d50 Mon Sep 17 00:00:00 2001 From: fulleni Date: Sat, 13 Dec 2025 14:52:54 +0100 Subject: [PATCH 37/37] chore: misc --- lib/l10n/app_localizations_ar.dart | 2 +- lib/l10n/arb/app_ar.arb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index 7a9c876b..cab4677f 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -115,7 +115,7 @@ class AppLocalizationsAr extends AppLocalizations { String get settings => 'الإعدادات'; @override - String get appConfigurationPageTitle => 'التحكم المركزي'; + String get appConfigurationPageTitle => 'التحكم المركزي عن بعد'; @override String get feedTab => 'الموجز'; diff --git a/lib/l10n/arb/app_ar.arb b/lib/l10n/arb/app_ar.arb index e54bb86d..6844f8ee 100644 --- a/lib/l10n/arb/app_ar.arb +++ b/lib/l10n/arb/app_ar.arb @@ -139,7 +139,7 @@ "@settings": { "description": "تسمية عنصر التنقل للإعدادات" }, - "appConfigurationPageTitle": "التحكم المركزي", + "appConfigurationPageTitle": "التحكم المركزي عن بعد", "@appConfigurationPageTitle": { "description": "عنوان صفحة إعدادات التطبيق" },