feat(search): collapse language/quality variants in global search - #1215
feat(search): collapse language/quality variants in global search#12154gray wants to merge 2 commits into
Conversation
Global search for a popular title returns dozens of near-duplicate
cards — one per language/quality/provider tag ("DE| The Pitt",
"4K-TR - The Pitt (2025) (US)", "|ALB| The Pitt"). A new "Group similar
titles" toggle (default on, persisted) collapses variants sharing a
normalized title and content type into a single card with a "×N" badge.
- groupResultsByVariant() keys on normalizeTitleKeys(title).base + type
(from PR #1211), so a movie and a series with the same name never
merge; the collapsed card shows the cleanest member title
- clicking a multi-variant card expands it inline to reveal every
version (the raw titles show the language); clicking again collapses;
a single-variant group opens directly
- composes with the existing "group by playlist" toggle: variants
collapse within each playlist section, or globally in the flat list
- ContentCardComponent gains an optional countBadge input
- SEARCH_VIEW.GROUP_SIMILAR_TITLES added to all 18 locales
The version picker (choose language up front) stays a follow-up; this
change removes the visual flood without a new picker component.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba69d4b75d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| <!-- Variant group: collapsed card (+ expanded members) or a single card --> | ||
| <ng-template #variantTpl let-vg> | ||
| @if (vg.items.length > 1) { |
There was a problem hiding this comment.
Keep loading pages when collapsed results do not overflow
When grouping collapses the first 100 results into only a handful of cards—the primary scenario advertised by this change—the results container may not become scrollable. SearchLayoutComponent emits nearEnd only from onSearchContentScroll, so no scroll event occurs and hasMoreGlobalResults() is never consumed; results after the first page remain hidden unless the user disables grouping or expands enough groups to create scrolling. Automatically request another page while the grouped viewport is underfilled, or provide an explicit load-more action.
Useful? React with 👍 / 👎.
| const expanded = new Set(this.expandedVariantKeys()); | ||
| if (expanded.has(group.key)) { | ||
| expanded.delete(group.key); | ||
| } else { | ||
| expanded.add(group.key); |
There was a problem hiding this comment.
Scope expansion state to each playlist section
With “group by playlist” enabled, separately computed groups for the same normalized title and type receive the same group.key. Because this shared set stores only that key, expanding a title in one playlist also expands the matching title in every other playlist section. Include the playlist identity in the expansion key for the playlist-grouped rendering path while retaining the current global key for the flat path.
Useful? React with 👍 / 👎.
Greptile SummaryThis PR adds a "Group similar titles" toggle to the global search results that collapses language/quality/provider variants of the same title into a single card with a ×N badge, reducing a flood of near-duplicate cards to a handful while letting the user expand any group inline.
Confidence Score: 5/5Safe to merge — all four previously flagged issues are properly resolved and no new defects were found. All four issues raised in the prior review (year-split for remakes, poster-preferring representative, per-playlist expansion key scoping, and pagination auto-fill) are correctly addressed. The request-version guard in searchGlobal prevents stale appends, the isLoadingMoreGlobalResults flag serializes concurrent auto-fill calls, the null-year bucket gets its own distinct key suffix, and buildGroup tracks displayTitle and representative independently. The unit suite covers corpus scenarios with 155/155 passing tests and build/typecheck are clean. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "fix(search): address variant-grouping re..." | Re-trigger Greptile |
- auto-load further pages when grouping collapses a page into too few
cards to scroll (the scroll-driven pager would otherwise never fire and
later results stayed hidden); bounded by card threshold and page count
- scope variant-group keys per playlist so expanding a title in one
playlist section no longer expands it in every other section
- split a bucket by year when it holds two or more distinct years so
remakes ("Dune (1984)" vs "Dune (2021)") no longer collapse into one
card; a single/absent year still keeps variants together
- pick a representative that has a poster, skipping leading posterless
clones so the collapsed card shows real artwork when any member has it
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks — addressed all four findings in ab3e2fc:
New tests cover year-splitting, poster preference, key-prefix scoping, per-playlist expansion independence, and the auto-fill backfill. |
|
@greptileai please re-review — commit ab3e2fc addresses all four earlier findings (pagination auto-fill, per-playlist expansion keys, year-split for remakes, poster-preferring representative). |
What
PR-2 of the tag-extraction track (builds on #1211). Global search for a popular title floods the grid with near-duplicate cards — one per language/quality/provider tag. A new "Group similar titles" toggle (default on, persisted) collapses variants that share a normalized title and content type into a single card with a
×Nbadge.Behaviour
groupResultsByVariant()keys onnormalizeTitleKeys(title).base + type(from feat(matching): strip appended language/quality tags in title normalization #1211), so a movie and a series with the same name never merge; the collapsed card shows the cleanest member title (e.g.The Pitt, notDE| The Pitt).For the Fallout / The Pitt corpora this turns ~100–126 cards into a handful. The upfront language picker stays a follow-up — this change removes the visual flood without a new picker component.
Changes
global-search-grouping.util.ts(+ spec) — grouping logic extracted so the (baselined) component stays thin.ContentCardComponentgains an optionalcountBadgeinput (×Npill).SearchResultsComponent:groupSimilartoggle,flatVariantGroups/playlistSectionscomputeds, inline expand/collapse state; template rendered via sharedng-templates for both branches.SEARCH_VIEW.GROUP_SIMILAR_TITLESadded to all 18 locales.Validation
portal-xtream-feature155/155 (new util spec + 5 component grouping tests),components105/105.typecheck:ciclean;nx build webclean (AOT templates + all locale JSON); lint clean on touched projects.🤖 Generated with Claude Code