-
Notifications
You must be signed in to change notification settings - Fork 0
Feat custom filters useres limits configuration #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
fulleni
merged 27 commits into
main
from
feat-custom-filters-useres-limits-configuration
Oct 13, 2025
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
79e7ccf
build(deps): update git dependencies to use version tags
fulleni 8477221
docs: add CHANGELOG.md file
fulleni b763f1b
chore(deps): remove empty line in pubspec.yaml
fulleni 74b0aa7
feat(ui): add user preset limits form
fulleni 6a67ad5
refactor(app-configuration): move user preset limits form to lib dire...
fulleni e753d38
feat(app_configuration): add user presets configuration tab
fulleni f5344d1
feat(app_configuration): add user presets configuration tab
fulleni 5908712
chore: changelog
fulleni 81f8091
feat(l10n): add user presets and filter limit translations
fulleni ff48e8d
fix(app_configuration): update preset tab label
fulleni 2c90f0e
fix(l10n): correct arb key for saved headlines filters limit description
fulleni 784b3c3
refactor(app_configuration): convert UserPresetLimitsForm to Stateful...
fulleni 880737d
feat(app_configuration): add user preset limits form and update expan...
fulleni f6e1593
fix(l10n): remove duplicate strings and correct order
fulleni 3b9c25b
chore: misc
fulleni e084fbd
refactor(app_configuration): remove user presets configuration tab
fulleni ad58d64
refactor(app_configuration): rename widget and update localization keys
fulleni a745f84
refactor(app_configuration): update saved headlines filter limits UI ...
fulleni 60bb031
refactor(l10n): remove unused arb entries and add new ones
fulleni 6a902e0
feat(app_configuration): add descriptions to limits sections
fulleni 7ddf14c
refactor(l10n): remove unused localization strings and fix descriptions
fulleni 1b94082
fix(localization): update saved headlines filter limit labels and des...
fulleni 7db311a
style: format
fulleni 2573bcb
refactor(app_configuration): remove user content limits description text
fulleni 3272453
refactor(app_configuration): implement dynamic tabbed interface for s...
fulleni 70965cb
fix(localization): correct Arabic translation for 'savedHeadlinesFilt...
fulleni 18aa371
docs(changelog): remove duplicate 1.0.0 release notes
fulleni File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| ##1.0.0 | ||
fulleni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - **BREAKING** feat!: migrated from date based versioning to semantic versioning. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
182 changes: 182 additions & 0 deletions
lib/app_configuration/widgets/saved_headlines_filters_limit_form.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| 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:flutter_news_app_web_dashboard_full_source_code/shared/extensions/app_user_role_l10n.dart'; | ||
| import 'package:ui_kit/ui_kit.dart'; | ||
|
|
||
| /// {@template saved_headlines_filters_limit_form} | ||
| /// A form for configuring saved headlines filter limits within the | ||
| /// [RemoteConfig]. | ||
| /// | ||
| /// This form provides fields to set the maximum number of saved filters | ||
| /// for guest, authenticated, and premium users. | ||
| /// {@endtemplate} | ||
| class SavedHeadlinesFiltersLimitForm extends StatefulWidget { | ||
| /// {@macro saved_headlines_filters_limit_form} | ||
| const SavedHeadlinesFiltersLimitForm({ | ||
| required this.remoteConfig, | ||
| required this.onConfigChanged, | ||
| super.key, | ||
| }); | ||
|
|
||
| /// The current [RemoteConfig] object. | ||
| final RemoteConfig remoteConfig; | ||
|
|
||
| /// Callback to notify parent of changes to the [RemoteConfig]. | ||
| final ValueChanged<RemoteConfig> onConfigChanged; | ||
|
|
||
| @override | ||
| State<SavedHeadlinesFiltersLimitForm> createState() => | ||
| _SavedHeadlinesFiltersLimitFormState(); | ||
| } | ||
|
|
||
| class _SavedHeadlinesFiltersLimitFormState | ||
| extends State<SavedHeadlinesFiltersLimitForm> | ||
| with SingleTickerProviderStateMixin { | ||
| late TabController _tabController; | ||
| late final Map<AppUserRole, TextEditingController> _controllers; | ||
|
|
||
| @override | ||
| void initState() { | ||
| super.initState(); | ||
| _tabController = TabController( | ||
| length: AppUserRole.values.length, | ||
| vsync: this, | ||
| ); | ||
| _initializeControllers(); | ||
| } | ||
|
|
||
| @override | ||
| void didUpdateWidget(covariant SavedHeadlinesFiltersLimitForm oldWidget) { | ||
| super.didUpdateWidget(oldWidget); | ||
| if (widget.remoteConfig.userPreferenceConfig != | ||
| oldWidget.remoteConfig.userPreferenceConfig) { | ||
| _updateControllerValues(); | ||
| } | ||
| } | ||
|
|
||
| void _initializeControllers() { | ||
| _controllers = { | ||
| for (final role in AppUserRole.values) | ||
| role: TextEditingController( | ||
| text: _getSavedFiltersLimit( | ||
| widget.remoteConfig.userPreferenceConfig, | ||
| role, | ||
| ).toString(), | ||
| )..selection = TextSelection.collapsed( | ||
| offset: _getSavedFiltersLimit( | ||
| widget.remoteConfig.userPreferenceConfig, | ||
| role, | ||
| ).toString().length, | ||
| ), | ||
| }; | ||
| } | ||
fulleni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| void _updateControllerValues() { | ||
| for (final role in AppUserRole.values) { | ||
| final newLimit = _getSavedFiltersLimit( | ||
| widget.remoteConfig.userPreferenceConfig, | ||
| role, | ||
| ).toString(); | ||
| if (_controllers[role]?.text != newLimit) { | ||
| _controllers[role]?.text = newLimit; | ||
| _controllers[role]?.selection = TextSelection.collapsed( | ||
| offset: newLimit.length, | ||
| ); | ||
| } | ||
| } | ||
| } | ||
fulleni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @override | ||
| void dispose() { | ||
| _tabController.dispose(); | ||
| for (final controller in _controllers.values) { | ||
| controller.dispose(); | ||
| } | ||
| super.dispose(); | ||
| } | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| final l10n = AppLocalizationsX(context).l10n; | ||
|
|
||
| return Column( | ||
| crossAxisAlignment: CrossAxisAlignment.start, | ||
| children: [ | ||
| Align( | ||
| alignment: AlignmentDirectional.centerStart, | ||
| child: SizedBox( | ||
| height: kTextTabBarHeight, | ||
| child: TabBar( | ||
| controller: _tabController, | ||
| tabAlignment: TabAlignment.start, | ||
| isScrollable: true, | ||
| tabs: AppUserRole.values | ||
| .map((role) => Tab(text: role.l10n(context))) | ||
| .toList(), | ||
| ), | ||
| ), | ||
| ), | ||
| const SizedBox(height: AppSpacing.lg), | ||
| SizedBox( | ||
| height: 120, | ||
| child: TabBarView( | ||
| controller: _tabController, | ||
| children: AppUserRole.values.map((role) { | ||
| final config = widget.remoteConfig.userPreferenceConfig; | ||
| return AppConfigIntField( | ||
| label: l10n.savedHeadlinesLimitLabel, | ||
| description: l10n.savedHeadlinesLimitDescription, | ||
| value: _getSavedFiltersLimit(config, role), | ||
| onChanged: (value) { | ||
| widget.onConfigChanged( | ||
| widget.remoteConfig.copyWith( | ||
| userPreferenceConfig: | ||
| _updateSavedFiltersLimit(config, value, role), | ||
| ), | ||
| ); | ||
| }, | ||
| controller: _controllers[role], | ||
| ); | ||
| }).toList(), | ||
| ), | ||
| ), | ||
| ], | ||
| ); | ||
| } | ||
|
|
||
| /// Retrieves the saved filters limit for a given [AppUserRole]. | ||
| /// | ||
| /// This helper method abstracts the logic for accessing the correct limit | ||
| /// from the [UserPreferenceConfig] based on the provided [role]. | ||
| int _getSavedFiltersLimit(UserPreferenceConfig config, AppUserRole role) { | ||
| switch (role) { | ||
| case AppUserRole.guestUser: | ||
| return config.guestSavedFiltersLimit; | ||
| case AppUserRole.standardUser: | ||
| return config.authenticatedSavedFiltersLimit; | ||
| case AppUserRole.premiumUser: | ||
| return config.premiumSavedFiltersLimit; | ||
| } | ||
| } | ||
|
|
||
| /// Updates the saved filters limit for a given [AppUserRole]. | ||
| /// | ||
| /// This helper method abstracts the logic for updating the correct limit | ||
| /// within the [UserPreferenceConfig] based on the provided [role] and [value]. | ||
| UserPreferenceConfig _updateSavedFiltersLimit( | ||
| UserPreferenceConfig config, | ||
| int value, | ||
| AppUserRole role, | ||
| ) { | ||
| switch (role) { | ||
| case AppUserRole.guestUser: | ||
| return config.copyWith(guestSavedFiltersLimit: value); | ||
| case AppUserRole.standardUser: | ||
| return config.copyWith(authenticatedSavedFiltersLimit: value); | ||
| case AppUserRole.premiumUser: | ||
| return config.copyWith(premiumSavedFiltersLimit: value); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.