CMM-2133: Expandable referrers with children in new Stats#23066
Conversation
Referrer groups can contain child referrers (e.g. "Search Engines"), but the new stats Referrers card discarded them and rendered a flat list. Thread a children list (name, url, views) from the datasource through the repository, UI state and ViewModel, and render referrer groups with children as expand/collapse rows in both the card and the detail screen, following the UTM card pattern. Tapping a child opens its URL in a Chrome Custom Tab. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Remove the decorative right arrow from Most Viewed rows (shared by posts, referrers, clicks, search terms, video plays and file downloads) since it did not navigate anywhere. Move the expand/collapse dropdown arrow before the views count on referrer groups with children, and show a right arrow only on clickable URL child rows to signal they open a link. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Expanded child rows sat flush against their parent row in the referrers and UTM cards and detail screens. Add a small top margin so children are visually separated when a group is expanded. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
When a group had more than one child, the child rows were rendered flush against each other. Space them evenly in the referrers and UTM cards and detail screens. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The referrers endpoint returns only 10 items when max is unset. Send an explicit max=0 (which the server treats as unlimited) so it returns the full referrer list, matching how Posts & Pages behaves: the card still shows the first CARD_MAX_ITEMS entries while the detail screen shows all of them. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Extract the duplicated chevron, child row and expandable-children block from MostViewedCard and MostViewedDetailActivity into a shared MostViewedCommonComposables file, reusing StatsListRowContainer for the child row bar. Inject ActivityNavigator into NewStatsActivity and thread the child-click callback down instead of constructing the navigator in a composable and casting the context to Activity. Compute maxChildViews only when a group is expanded, and document the referrers max=0 semantics. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Generated by 🚫 Danger |
|
|
|
|
The detail screen renders rows in a LazyColumn, so the per-row expanded state held in a plain remember was discarded when a row scrolled off screen and reset to collapsed when it returned. Use rememberSaveable and key the list by item id so an expanded group stays expanded across scrolling. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## trunk #23066 +/- ##
========================================
Coverage 37.43% 37.44%
========================================
Files 2335 2337 +2
Lines 126326 126454 +128
Branches 17398 17422 +24
========================================
+ Hits 47296 47354 +58
- Misses 75156 75223 +67
- Partials 3874 3877 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The referrers card fetched the full (max=0) list and passed it to the detail screen through the launching Intent, and the detail LazyColumn was keyed by item.id (derived from name.hashCode()). On sites with many referrers this risked a TransactionTooLargeException, and empty/duplicate referrer names could collide into duplicate keys and crash the list. Bound the card request to REFERRERS_CARD_MAX and add fetchReferrersDetail (max=0) so the detail screen self-fetches its own unbounded list via a new MostViewedDetailViewModel (Loading/Error/Loaded), passing only the period through the Intent. Key the detail list by index instead of item.id. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Reset the expanded state when a row is reused for a different referrer, and add unit tests covering MostViewedDetailViewModel load/error/retry behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The referrers detail ViewModel surfaced raw exception messages to users; log the exception and show the localized stats_error_unknown string instead, and rethrow CancellationException. Make the referrers card's expand/collapse state survive configuration changes by keying each row on its item id and holding the expanded flag in rememberSaveable, so an expanded group stays expanded after rotation (matching the detail screen) while still resetting when the list reloads for a different referrer. CMM-2133 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
StatsRepositoryTest tripped detekt's LargeClass rule after the referrer tests were added. Extract them into a dedicated test class instead of baselining, keeping the referrer tests grouped in one place. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
@adalpari I've not tested this yet, but Claude had a couple of suggestions that I think are worth looking into.
|
I'm showing the icons coming in the JSON response, so I'm not sure there's a good way to correlate them... Anyway, can you show me a screenshot? I'm not actually seeing icons in these responses 🤔 |
Referrer ids are derived from name.hashCode(), which can collide on empty/duplicate names. Two colliding rows sharing a key() could misattribute the per-row rememberSaveable expanded state. Add the index to the key to guarantee uniqueness while keeping the item id so the saved state still resets when the referrer at a position changes after a period reload. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The card (MostViewedItemRow) and detail screen (DetailItemRow) each carried a near-identical ~80-line expandable-row body that differed only by the leading position number and the child indent. Consolidate them into a single MostViewedExpandableRow in MostViewedCommonComposables.kt, built on StatsListRowContainer and parameterized with position/child indent (mirroring the UtmExpandableRow pattern), so future changes to expand/collapse behavior live in one place. Also swap the clickable child row's ChevronRight for the standard AutoMirrored OpenInNew icon (with an "Open link" content description) to make it clearer the row opens an external URL. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
@nbradbury I've made some changes from Claude's suggestions and also used a more appropriate icon. Could you take another look?
|









Description
Adds expand/collapse support for child referrers in the new Stats "Referrers" card and its detail screen, and makes the detail screen show the full referrer list.
Referrer groups returned by the API can contain a list of child referrers (e.g. the "Search Engines" group nests "Google Search", etc.). Previously these were discarded and every group rendered as a flat row, and the detail screen only showed the same ~10 items as the card.
Changes:
childrenlist (name, url, views) from the datasource → repository → UI state → ViewModel. Groups with children now render an expand/collapse dropdown (following the UTM card pattern).ActivityNavigator.openInCustomTab).max = 10), while the referrers detail screen re-fetches the full list itself (max = 0, which the server treats as "all"). The detail screen now self-fetches via a newMostViewedDetailViewModel(with Loading/Error/Loaded states) instead of receiving the whole item list through the launching Intent — this keeps the card request small and avoids passing a large parcelable list across the process boundary (which riskedTransactionTooLargeExceptionon high-traffic sites). This matches Posts & Pages in that the card still shows the firstCARD_MAX_ITEMSentries.LazyColumnis keyed by index rather than by item id. Referrer ids are derived fromname.hashCode(), which is not guaranteed unique (empty or duplicate names collide), so keying by id could crash the list with a duplicate-key error — more likely now that the detail lists the full referrer set.MostViewedCommonComposables.kt(reusing the existingStatsListRowContainer), and bothNewStatsActivityandMostViewedDetailActivityinjectActivityNavigatorrather than constructing it in a composable.LazyColumn), the per-row expanded state usesrememberSaveableso an expanded group stays expanded when it scrolls off-screen and back.Testing instructions
Referrers card — expandable children:
Regression — shared Most Viewed cards: