Skip to content

fix(widget): group category time by full path, matching the Activity view - #231

Open
TimeToBuildBob wants to merge 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/widget-category-grouping
Open

fix(widget): group category time by full path, matching the Activity view#231
TimeToBuildBob wants to merge 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/widget-category-grouping

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Fixes the per-category discrepancy @ErikBjare reported in #142 ("category time presented seems to diff from Activity view (total time matches though)").

Cause

parseCategories() aggregated by $category[0] — the top-level category only. So ["Work","Programming"] and ["Work","Planning"] both landed in one Work bucket. The total was unaffected (same events, same durations), which is exactly why totals matched while per-category rows did not.

The Activity view groups by the full category path: aw-webui builds cat_events with merge_events_by_keys(events, ["$category"]) and renders them with namefunc="e => e.data['$category'].join(' > ')" (SelectableVisualization.vue, top_categories).

Fix

Group by the full category path and label it the same way ("Work > Programming").

Tests

Adds CategoryTimeWidgetUpdaterTest (6 cases). Three of them fail against the old top-level rollup and pass with the fix:

  • parseCategories_keepsSubcategoriesSeparate
  • parseCategories_mergesRepeatsOfTheSamePath
  • parseCategories_sortsByDurationDescending

Verified locally with ./gradlew :mobile:testDebugUnitTest --tests 'net.activitywatch.android.widget.*'.

Not in this PR

  • NotifyWorker.parseCategorySeconds() has the same top-level rollup, but its keys are matched against configured alert categories, so changing it would alter alert behaviour. Worth a separate look.
  • @0xbrayo's widget preview request — separate change.

…view

The widget rolled every event up to its top-level category
($category[0]), so "Work > Programming" and "Work > Planning"
collapsed into a single "Work" row. Totals still matched the Activity
view because the sum is unchanged, but per-category times disagreed —
the symptom reported in ActivityWatch#142.

aw-webui builds cat_events with merge_events_by_keys(events,
["\$category"]) and labels them with \$category.join(" > ")
(SelectableVisualization.vue top_categories namefunc). Mirror that:
group by the full category path and label it the same way.

Adds unit tests for parseCategories; three of them fail against the
old top-level rollup.
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown

Greptile Summary

The PR aligns widget category aggregation with the Activity view by grouping events using their complete category path rather than only the top-level category.

  • Joins category path components into labels such as Work > Programming.
  • Keeps repeated occurrences of the same full path aggregated and sorted by duration.
  • Adds six unit tests covering separation, merging, totals, ordering, single-level categories, and empty results.

Confidence Score: 5/5

The PR appears safe to merge, with the full-path grouping behavior covered by focused regression tests.

The changed parser consistently aggregates and labels complete category paths while preserving total durations and existing duration ordering, and no reachable blocking or non-blocking defect remains.

Important Files Changed

Filename Overview
mobile/src/main/java/net/activitywatch/android/widget/CategoryTimeWidgetUpdater.kt Changes category aggregation to use full-path display labels; no actionable defect was established.
mobile/src/test/java/net/activitywatch/android/widget/CategoryTimeWidgetUpdaterTest.kt Adds focused regression coverage for full-path category aggregation and existing output behavior.

Reviews (1): Last reviewed commit: "fix(widget): group category time by full..." | Re-trigger Greptile

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

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.

1 participant