Repository navigation
iOS: preserve workspace groups in Recent Activity - #9960
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughRecent Activity sorting now preserves grouped workspaces as contiguous display blocks. Group metadata is resolved and normalized before sorting. The workspace list caches projections, renders the resulting items, and tests grouped, ungrouped, collapsed, invalid, and large workspace configurations. ChangesGrouped Recent Activity ordering
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant WorkspaceListView
participant WorkspaceListGroupedProjectionCache
participant MobileWorkspaceRecencyOrder
participant WorkspaceListTable
WorkspaceListView->>WorkspaceListGroupedProjectionCache: project workspaces, groups, and sort mode
WorkspaceListGroupedProjectionCache->>MobileWorkspaceRecencyOrder: groupedDisplayItems(workspaces, groups)
MobileWorkspaceRecencyOrder-->>WorkspaceListGroupedProjectionCache: atomic grouped and ungrouped items
WorkspaceListGroupedProjectionCache-->>WorkspaceListView: cached grouped projection
WorkspaceListView->>WorkspaceListTable: render grouped items and workspace lookup
Possibly related PRs
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (3 errors, 1 warning)
✅ Passed checks (21 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift (1)
344-348: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick winReplace the per-header workspace scan with one lookup.
Recent Activity now renders grouped sections.
groupedRowsthen callsworkspaces.first(where:)at line 905 for every group header. With 200 groups and 1,000 workspaces, this performs up to 200,000 comparisons on each list render.Build one workspace-ID-to-capabilities dictionary before
ForEach. Use that dictionary for the anchor lookup.Proposed fix
private func groupedRows( items: [MobileWorkspaceListItem] ) -> some View { let enablesReorder = enablesWorkspaceReorder let groupLookup = groupsByID + let capabilitiesByWorkspaceID = Dictionary( + workspaces.map { ($0.id, $0.actionCapabilities) }, + uniquingKeysWith: { first, _ in first } + ) ForEach(items, id: \.id) { item in switch item { case .groupHeader(let group, let hasUnread): - let anchorCapabilities = workspaces.first(where: { $0.id == group.anchorWorkspaceID })?.actionCapabilities ?? .none + let anchorCapabilities = capabilitiesByWorkspaceID[group.anchorWorkspaceID] ?? .noneAs per coding guidelines, production code must avoid repeated full scans for workloads around 1,000 records. As per path instructions,
.github/review-bot-rules/algorithmic-complexity.mdapplies this rule to scalable user data.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift` around lines 344 - 348, Update the grouped-row rendering path around rendersGroupedSections and groupedRows to build a single workspace-ID-to-capabilities dictionary before ForEach, then use that lookup for each group header’s anchor workspace instead of calling workspaces.first(where:). Preserve the existing grouping and anchor behavior while eliminating repeated full workspace scans.Sources: Coding guidelines, Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@Packages/iOS/CmuxMobileShellModel/Tests/CmuxMobileShellModelTests/MobileWorkspaceRecencyOrderTests.swift`:
- Around line 101-114: Remove the ContinuousClock().measure wrapper and the
duration-based 100 ms expectation from MobileWorkspaceRecencyOrderTests. Keep
the groupedDisplayItems invocation and the existing workspaces.count,
items.count, and unique-ID assertions intact; move any performance measurement
to a non-gating benchmark or performance harness if needed.
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift`:
- Around line 455-460: Move currentDisplayedGroupedListItems out of
WorkspaceListView.body and into the existing state owner as its derived
snapshot. Recompute it only when workspace, grouping, filter, selection, or sort
inputs change, and have the view reuse that stored value for table rows, unread
headers, and optimistic-order observation. Do not introduce a second mutable
cache or repeat the grouped projection during unrelated body evaluations.
---
Outside diff comments:
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift`:
- Around line 344-348: Update the grouped-row rendering path around
rendersGroupedSections and groupedRows to build a single
workspace-ID-to-capabilities dictionary before ForEach, then use that lookup for
each group header’s anchor workspace instead of calling
workspaces.first(where:). Preserve the existing grouping and anchor behavior
while eliminating repeated full workspace scans.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a4394d59-acc8-4aa4-bfbd-744e870104b3
📒 Files selected for processing (4)
Packages/iOS/CmuxMobileShellModel/Tests/CmuxMobileShellModelTests/MobileWorkspaceRecencyOrderTests.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+DragDrop.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+Table.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift
💤 Files with no reviewable changes (1)
- Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+DragDrop.swift
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift (1)
457-481: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAvoid filtering
workspacestwice per render during an active drag.
currentDisplayedGroupedListItemscomputesdisplayedGroupedWorkspaces, which reads the computed propertygroupedWorkspaces(anO(n)filter overworkspaces) once. WhenoptimisticGroupedState.optimisticOrderis non-nil,currentAuthoritativeGroupedListItemsreadsgroupedWorkspacesagain directly. This filter runs twice per body evaluation while a drag is active, and drag gestures trigger many render passes.Hoist
groupedWorkspacesinto a single localletat the top ofbodyand pass that value to both the displayed and authoritative branches instead of letting each branch re-read the computed property.As per path instructions,
.github/review-bot-rules/algorithmic-complexity.mdrequires avoiding "repeated sort/filter/map work in hot paths" for production code handling around 1,000 workspace records.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift` around lines 457 - 481, Hoist the computed groupedWorkspaces value into a single local let at the top of body, then reuse that local when constructing both displayedGroupedWorkspaces and currentAuthoritativeGroupedListItems. Update the displayed projection path and authoritativeGroupedProjectionCache.items call so an active drag does not re-read the groupedWorkspaces computed property during the same body evaluation.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swift`:
- Around line 457-481: Hoist the computed groupedWorkspaces value into a single
local let at the top of body, then reuse that local when constructing both
displayedGroupedWorkspaces and currentAuthoritativeGroupedListItems. Update the
displayed projection path and authoritativeGroupedProjectionCache.items call so
an active drag does not re-read the groupedWorkspaces computed property during
the same body evaluation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 86f64650-bcdf-4856-8c92-0e455520a2f9
📒 Files selected for processing (6)
Packages/iOS/CmuxMobileShellModel/Tests/CmuxMobileShellModelTests/MobileWorkspaceRecencyOrderTests.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListGroupedProjectionCache.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+Table.swiftPackages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView.swiftPackages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/WorkspaceListSortTests.swiftios/cmuxUITests/cmuxUITests.swift
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit fc90bea. Configure here.
Summary
Task
Fix iOS All Computers so Recent Activity no longer flattens workspace groups into ordinary workspace rows. Group headers and indented members must remain contiguous across computers, with stable recency ordering and no regressions to filters or single-computer views.
Testing
Note
Medium Risk
Changes core workspace list ordering and grouped projection in the mobile shell; behavior is heavily tested but mistakes could affect selection, collapse, and drag reconciliation.
Overview
All Computers + Recent Activity no longer flattens workspace groups into a single interleaved list. Grouped sections stay visible; each group moves as one display block ranked by its newest
lastActivityAt, with members still in Mac sidebar order (including timestamp-less members). Ungrouped rows rank on their own. Search, filters, and single-computer scope still use flat presentation where they did before.MobileWorkspaceRecencyOrderaddsgroupedDisplayItemsto build headers, indented members, and footers from those blocks while preserving pinned-first rules and stable tie-breaking.WorkspaceListViewwires recency into grouped rendering (rendersGroupedSectionsno longer turns off for recency), feeds the table from precomputedgroupedItems, and uses separate displayed vs authoritativeWorkspaceListGroupedProjectionCacheinstances so optimistic drag reconciliation does not thrash the on-screen projection.Also: Mac picker accessibility identifiers and connection status on the combined label;
.isSelectedon sidebar workspace rows; sort-picker schematic and preview fixtures for mixed-group UI/E2E coverage.Reviewed by Cursor Bugbot for commit 4f3529a. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Keeps workspace groups intact in All Computers > Recent Activity by treating each group as one block ranked by its newest member. Search and filters flatten only while active; clearing restores grouped sections; selection and accessibility remain stable.
Bug Fixes
groupedItems, and drag reconciliation uses authoritative grouped order keys..isSelectedfor visibility and accessibility.Performance
WorkspaceListGroupedProjectionCachewith separate displayed vs authoritative caches; reuses the grouped projection snapshot when optimism clears.workspacesByIDmap in grouped rows and appended group members in place.Written for commit d3e502c. Summary will update on new commits.
Summary by CodeRabbit