Skip to content

Conversation

@fulleni
Copy link
Member

@fulleni fulleni commented Oct 15, 2025

Status

READY

Description

This pull request delivers a comprehensive overhaul of the feed filtering system, focusing on user experience and code maintainability. It introduces a new 'Followed' filter for quick access to personalized content, refines the source filtering mechanism with a dedicated, more intuitive interface, and streamlines the overall filter state management. The changes aim to provide users with more powerful and flexible ways to discover content while improving the underlying architecture for future development.

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

Removes the `isFromFollowedItems` flag from the `HeadlineFilter` model. This property is being deprecated in favor of a more explicit state management approach within the `HeadlinesFeedBloc` for handling the new "Followed" filter.
Removes the `isUsingFollowedItems` flag from the `HeadlinesFilterState`. This property is being deprecated in favor of a more explicit state management approach within the `HeadlinesFeedBloc` for handling the new "Followed" filter.
Removes the `isUsingFollowedItems` property from the `FilterDataLoaded` event and deletes the `FollowedTopicsFilterToggled`, `FollowedSourcesFilterToggled`, and `FollowedCountriesFilterToggled` events.

This is part of a larger refactoring to replace the ambiguous "apply followed" flag with a more explicit and robust "Followed" filter managed by the `HeadlinesFeedBloc`.
…terBloc

Removes the event handlers and state modifications related to the `isUsingFollowedItems` flag from the `HeadlinesFilterBloc`. This simplifies the BLoC by removing the now-deprecated logic for applying followed items, paving the way for the new, more explicit "Followed" filter implementation.
Removes the `isUsingFollowedItems` flag and related logic from the `HeadlinesFilterPage`. This includes updating the `FilterDataLoaded` event dispatches and removing the logic that would disable filter tiles. This change simplifies the UI and aligns with the new, more explicit "Followed" filter strategy.
Removes the "Apply My Followed Topics" `IconButton` from the `TopicFilterPage`. This UI element is part of the deprecated filtering logic that is being replaced by a more explicit "Followed" filter on the main feed.
Removes the "Apply My Followed Sources" `IconButton` from the `SourceFilterPage`. This UI element is part of the deprecated filtering logic that is being replaced by a more explicit "Followed" filter on the main feed.
… page

Removes the "Apply My Followed Countries" `IconButton` from the `CountryFilterPage`. This UI element is part of the deprecated filtering logic that is being replaced by a more explicit "Followed" filter on the main feed.
Introduces the `FollowedFilterSelected` event to the `HeadlinesFeedBloc`. This event will be dispatched when a user selects the new "Followed" filter, triggering a feed refresh based on their followed topics, sources, and countries.
Adds a new event handler `_onFollowedFilterSelected` to the `HeadlinesFeedBloc`. This handler constructs a `HeadlineFilter` based on the user's followed topics, sources, and countries from the `AppBloc` state.

It then dispatches the existing `HeadlinesFeedFiltersApplied` event to trigger a full feed refresh, reusing the existing data loading and decoration pipeline. This provides a clean and robust implementation for the new "Followed" filter.
Updates the `SavedFiltersBar` to conditionally display a "Followed" filter chip. This chip is only visible if the user is following at least one topic, source, or country.

When selected, it dispatches the `FollowedFilterSelected` event to the `HeadlinesFeedBloc`, triggering a feed refresh to show content based on the user's followed items.
Documents the new "Followed" filter feature and the related refactoring that removed the `isUsingFollowedItems` flag.
- Add Arabic and English translations for "Followed" label
- Add new arb entries for saved filters bar
- Maintain existing translations for consistency
- Rename "Dynamic & Engaging Headlines Feed" to "Dynamic & Engaging Feed"
- Remove redundant "Display news in a beautiful, performant, infinitely scrolling feed"
- Change section title from "Advanced Content Filtering & Search" to "Powerful Filtering & Search"
- Add "Quick-Access Filter Bar" and "Advanced Filter Creation" details
- Remove "Followed Items" filter detail
- Rename "Saved & Quick-Access Filters" to "Saved Filters"
Introduces a new `SourceListFilterPage` to provide a dedicated UI for filtering the list of sources by headquarters and type. This page is a self-contained `StatefulWidget` that manages its own local state for the filter criteria.

This architectural change decouples the filter criteria UI from the source selection UI, paving the way for a cleaner implementation on the main `SourceFilterPage` and resolving the underlying cause of the source type selection bug.
Refactors the `SourceFilterPage` to improve user experience and fix a filtering bug. The UI for selecting headquarters and source types has been moved to a new, dedicated `SourceListFilterPage`.

- A new "Filter" icon in the `AppBar` now navigates to the `SourceListFilterPage`.
- The main page now only displays the list of sources, which is filtered based on the criteria returned from the new filter page.
- The complex and buggy local UI for `ChoiceChip` filters has been removed, simplifying the page's state management and resolving the issue where selecting a source type would incorrectly select all sources.
- Relocate source_list_filter_page.dart to maintain a consistent project structure
- Organize files under the lib directory for better codebase organization
- Place the file within the headlines-feed feature folder
- Move it to the view folder as it is likely a UI component
Updates the router to include a new route for the `SourceListFilterPage`. This route is nested under the main source filter page, allowing for navigation to the dedicated UI for filtering sources by headquarters and type.
Adds new English localization strings for the title and filter button tooltip on the new `SourceListFilterPage`.
Adds new Arabic localization strings for the title and filter button tooltip on the new `SourceListFilterPage`.
Refactors the `lib/router/routes.dart` file for better logical grouping and clarity.

- Adds the new `sourceListFilterName` constant for the dedicated source filter page.
- Reorganizes all route constants into logical groups (Authentication, Core App Shell, Global, Feed Sub-Routes, etc.) to improve readability and maintainability.
- Cleans up comments to remove outdated references, ensuring the file is easier to understand.
Introduces a new reusable `MultiSelectSearchPage` widget. This generic, stateful widget provides a standard UI for selecting multiple items from a long, searchable list.

This component will be used to improve the user experience for filtering by country on the source filter page, replacing the non-scalable horizontal `ChoiceChip` list with a more conventional and user-friendly vertical list with search functionality.
Refactors the `SourceListFilterPage` to provide a more scalable and user-friendly interface.

- Replaces the horizontal `ChoiceChip` list for countries with a `ListTile` that navigates to the new generic `MultiSelectSearchPage`. This provides a much better UX for long lists.
- Replaces the horizontal `ChoiceChip` list for source types with a vertical list of `CheckboxListTile` widgets, making all options immediately visible and accessible.
- Deletes the now-obsolete `_buildCountryCapsules` and `_buildSourceTypeCapsules` methods.
- Add new route for reusable multi-select search page
- Update Routes class with new multiSelectSearchName constant
- Implement builder function for multi-select search page
- Allow customization of title, items, and initial selections
- Add support for custom item builder function
- Add reusable, searchable multi-select page for filtering
- Implement saved feed filters with create, rename, and delete features
- Add horizontal filter bar to headlines feed for quick selection
- Improve source filter UI with vertical layout and navigation
- Fix bug where selecting source type would check all sources
- Pre-populate saved filters and settings for new anonymous users in demo
- Ensure saved filters are immediately visible on app start
- Update Headline Details page with fading scroll effect and new 'Continue Reading' button style
- Remove main feed's filter icon from AppBar in favor of new filter bar
- Refactor filter logic and remove ambiguous 'isUsingFollowedItems' flag
- Add 'Followed' filter for content from followed items
- Update existing filters to be using granular controls
Fixes a `_TypeError` that occurred when navigating to the generic `MultiSelectSearchPage`. The error was caused by an incorrect and overly strict type cast of the `itemBuilder` function within the `GoRouter` configuration.

The solution is to accept the `itemBuilder` as a generic `Function` in the router and then correctly invoke it within the `MultiSelectSearchPage` constructor. This change respects Dart's type system and allows strongly-typed functions (e.g., `(Country) => String`) to be passed without causing a runtime crash.
Fixes a `_TypeError` that occurred when popping the `MultiSelectSearchPage`. The error was caused by a type mismatch between the `Set<dynamic>` returned by the generic page and the `Future<Set<Country>>` expected by the calling page.

The solution is to change the expected return type of `pushNamed` to `Set<dynamic>` and then safely cast the resulting set to `Set<Country>` before updating the state. This ensures type safety and resolves the runtime crash.
Resolves an `invalid_override` error in `FilterSourceCriteriaChanged`. The `props` getter was returning a `List<Object?>` due to nullable properties, which is incompatible with the `List<Object>` required by the `Equatable` superclass.

The fix adjusts the `props` implementation to correctly handle nullable properties, ensuring it returns a `List<Object>` and satisfies the type contract.
@fulleni fulleni linked an issue Oct 15, 2025 that may be closed by this pull request
@gemini-code-assist
Copy link

Summary of Changes

Hello @fulleni, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a comprehensive overhaul of the feed filtering system, focusing on user experience and code maintainability. It introduces a new 'Followed' filter for quick access to personalized content, refines the source filtering mechanism with a dedicated, more intuitive interface, and streamlines the overall filter state management. The changes aim to provide users with more powerful and flexible ways to discover content while improving the underlying architecture for future development.

Highlights

  • Enhanced Feed Filtering UI: The feed filtering experience has been significantly improved with a new, dedicated 'Followed' filter in the quick-access bar and a redesigned source filter page for better usability and scalability.
  • Refactored Filter Logic: The underlying filter logic has been simplified by removing the ambiguous 'isUsingFollowedItems' flag, leading to clearer state management and more predictable filter behavior.
  • Reusable Multi-Select Search Page: A new generic and searchable multi-select page has been introduced, allowing for flexible selection of items (e.g., countries for source headquarters) and promoting code reusability across the application.
  • Improved Source Filtering: The source filter UI now uses a vertical layout and dedicated navigation for selecting headquarters countries and source types, replacing the previous horizontal scrolling capsules for a more user-friendly experience.
  • Bug Fix: Source Type Selection: A bug where selecting a source type would incorrectly check all sources has been corrected, ensuring accurate filtering based on user selections.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and well-executed refactoring of the feed filtering functionality. The removal of the isUsingFollowedItems flag greatly simplifies the logic and improves maintainability. The new source filter UI, which replaces horizontal scrolling with a dedicated, searchable multi-select page, is a major improvement in user experience and scalability. The introduction of the reusable MultiSelectSearchPage is a great example of good software engineering practice. Additionally, the new "Followed" quick filter is a valuable feature for users. The code is well-organized, and the changes are consistent across the codebase. I've included a few suggestions to further enhance type safety and robustness. Overall, this is an excellent update.

@fulleni fulleni merged commit 029f14b into main Oct 15, 2025
0 of 2 checks passed
@fulleni fulleni deleted the refactor/feed-filter-ui-enhancement branch October 15, 2025 11:53
@fulleni fulleni added this to the Foundation Edition milestone Nov 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: feed filter UI enhancement

2 participants