Fix new-stats Views card bottom row via dedicated stats/visits call#23098
Fix new-stats Views card bottom row via dedicated stats/visits call#23098adalpari wants to merge 6 commits into
Conversation
The Views card bottom row (Views, Visitors, Likes, Comments, Posts) was derived by summing the chart's per-bucket data points. For visitors this over-counts on long ranges (uniques counted once per bucket are summed) and could misreport the single-day total. Instead fill the bottom row with a dedicated stats/visits call tuned per range so visitor uniques de-duplicate server-side per bucket before summing: - Unit selection: day for <=31 days, month up to ~2 years, year beyond; single day uses unit=day quantity=1. - The dedicated call fires only when its unit/quantity differ from the chart's; otherwise the chart aggregates are reused to avoid redundant network requests. Falls back to chart aggregates if the call fails. Requires wordpress-rs with start_date/stat_fields support on StatsVisitsParams (bumped to 1434-e7e17e7). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generated by 🚫 Danger |
Project dependencies changeslist! Upgraded Dependencies
net.java.dev.jna:jna:5.19.1, (changed from 5.19.0)
rs.wordpress.api:android:1434-e7e17e7168b28116f3c7975ac8e20757259589cb, (changed from 0.5.0)
rs.wordpress.api:kotlin:1434-e7e17e7168b28116f3c7975ac8e20757259589cb, (changed from 0.5.0)tree +--- project :libs:fluxc
-| \--- rs.wordpress.api:android:0.5.0
-| +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-| +--- com.squareup.okhttp3:okhttp-tls:5.4.0
-| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-| | +--- com.squareup.okio:okio:3.17.0 (*)
-| | \--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-| +--- net.java.dev.jna:jna:5.19.0
-| +--- rs.wordpress.api:kotlin:0.5.0
-| | +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
-| | +--- com.squareup.okhttp3:okhttp-tls:5.4.0 (*)
-| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 -> 1.11.0 (*)
-| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-| \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+| \--- rs.wordpress.api:android:1434-e7e17e7168b28116f3c7975ac8e20757259589cb
+| +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+| +--- com.squareup.okhttp3:okhttp-tls:5.4.0
+| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+| | +--- com.squareup.okio:okio:3.17.0 (*)
+| | \--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+| +--- net.java.dev.jna:jna:5.19.1
+| +--- rs.wordpress.api:kotlin:1434-e7e17e7168b28116f3c7975ac8e20757259589cb
+| | +--- com.squareup.okhttp3:okhttp:5.4.0 (*)
+| | +--- com.squareup.okhttp3:okhttp-tls:5.4.0 (*)
+| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 -> 1.11.0 (*)
+| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 -> 2.3.21 (*)
-+--- rs.wordpress.api:android:0.5.0 (*)
++--- rs.wordpress.api:android:1434-e7e17e7168b28116f3c7975ac8e20757259589cb (*)
\--- com.automattic:encryptedlogging:1.1.1
- \--- net.java.dev.jna:jna:5.17.0 -> 5.19.0
+ \--- net.java.dev.jna:jna:5.17.0 -> 5.19.1 |
|
|
|
|
Address code-review findings on the new-stats Views card bottom row: - Always fire the dedicated bottom-stats call for every period instead of reusing the chart aggregates when the coarser unit matched the chart's. - Hide the bottom row when the dedicated call errors, throws, or returns an empty response, rather than falling back to chart aggregates or showing zeros. The bottom fetch now swallows exceptions (rethrowing cancellation) so it can't cancel the sibling chart fetches or fail the whole card. - Fix the >2-year (YEAR unit) previous-window skew: the previous window now mirrors the current window's exact day span for all units instead of being padded out to full calendar years, keeping the change comparison symmetric. Bottom aggregates are now nullable end-to-end (repository -> ViewModel -> UI state), and the card omits BottomStatsRow when they're absent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Split the Views card fetch so the chart (2 calls) and the bottom-stats row (2 dedicated calls) load from separate, independent requests instead of one blocking fetch of all four: - The chart no longer waits on the bottom-row calls, and each region updates on its own as it returns (own placeholder/spinner). - Either region can fail without hiding the other: a failed chart shows a compact retry while the bottom row stays; a failed bottom call hides only the row. - A successful-but-empty bottom response now shows a zero-valued row instead of hiding it (only errors hide the row). - Bottom totals use a dateless BottomStatsAggregates, dropping the unused date plumbing; the current-window logic is unified via currentPeriodWindow(). Reworks ViewsStatsCardUiState into Content(chart, bottomStats) with independent ChartUiState and BottomStatsUiState, and updates tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@adalpari Claude found some issues, and at least the first one sounds like it needs to be addressed. |
Keep the card dimmed until both the chart and the dedicated bottom-stats call finish, so a drill-down no longer un-dims the old period's totals as if they belonged to the new period. Also treat a period as loaded only when both regions succeed, so a transient bottom-stats failure retries on next visibility instead of hiding the row permanently. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Delete the private rememberShimmerBrush() copy in ViewsStatsCard and use the shared util helper, which honors LocalShimmerBrush so the Views card shimmer syncs with the other stats cards instead of spinning up its own infinite transitions. Extract unitAndQuantityFor() and previousWindowMirror() in StatsRepository so calculateBottomStatsRange and calculateCustomPeriodDates share the day/month threshold, the MONTHS.between + 1 quantity, and the exact day-span previous-window mirror. The bottom-row-only YEAR tier is gated behind an allowYear flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Yup, some of them are expected, and I'm fixing that in a subsequent PR because Claude was driving me crazy. I left a note in the PR description for that, but it seems like Claude kept going around it.
I've also done some of the suggested cleanups Thanks! |
nbradbury
left a comment
There was a problem hiding this comment.
Looks good! Feel free to
when the wp-rs dependency is updated.


Fixes CMM-2152.
NOTE: CI will fail until we merge the changes in WordPress-rs and target it.
Problem
On the new stats screen, the Views card bottom row (Views, Visitors, Likes, Comments, Posts) was derived by summing the chart's per-bucket data points. For Visitors this is wrong: uniques are counted once per bucket, so summing daily buckets over a long range over-counts them, and the single-day case could misreport the total.
Fix
Fill the bottom row with a dedicated
stats/visitscall tuned per range, so visitor uniques de-duplicate server-side per bucket before summing.dayfor ≤31 days,monthup to ~2 years (731d),yearbeyond. A single day usesunit=day&quantity=1.stats/visitscalls (current + previous) for every period, independently of the chart, restricted to the bottom-rowstat_fields.Views/Likes/Comments/Posts are additive, so their totals are unchanged; only Visitors is affected.
Known tradeoffs / follow-ups
0case and reduces over-counting via coarser units on long ranges, but does not fully de-duplicate visitors for multi-bucket ranges (e.g. Last 7 Days sums 7 daily buckets). Fine-grained per-range visitor de-duplication is intentionally deferred to a separate PR.Dependency
Requires wordpress-rs with
start_date/stat_fieldsonStatsVisitsParams.gradle/libs.versions.tomlis bumped to1434-e7e17e7168b28116f3c7975ac8e20757259589cb(wordpress-rs PR #1434).Testing
Note: there could be some incongruences with "Today's card" or between the chart and the bottom row for one day selections. I'll work on polishing that and be sure it's behaving like the web in a different PR as this one is big enough.
🤖 Generated with Claude Code