Skip to content

feat(mobile): unify session filtering across the live and history pages - #5631

Merged
iscekic merged 5 commits into
mainfrom
feat/mobile-live-session-filters
Aug 28, 2026
Merged

feat(mobile): unify session filtering across the live and history pages#5631
iscekic merged 5 commits into
mainfrom
feat/mobile-live-session-filters

Conversation

@iscekic

@iscekic iscekic commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Both session-list pages get one shared filtering UI. The pages stay separate — each keeps its own list, its own persisted filter record, and its own screen.

Live sessions All sessions (history)
Filter by repository new already had it
Filter by origin new already had it
Search new (in-memory) already had it (server-side)
Persisted filters new (own key) already had it
Count badge on the filter button new new
Sort control removed

How

  • Shared SessionFilterButton — the sliders icon plus a count badge while filters are applied. The count is spoken as the button's accessibilityValue, so it needs no new translated string.
  • Live filtering is client-side. The live set is already fully loaded, so repository, origin, and free-text search all match in memory — no refetch, no extra query, and search needs no debounce.
  • Live filter options are built from the live rows themselves, so the picker never offers a repository or an origin with nothing running.
  • Origin buckets on the live page reuse the history vocabulary (cloud agent / extension / CLI / Slack / GitHub / Linear / other), derived by inverting expandPlatformFilter rather than duplicating the mapping.
  • PersistenceusePersistedAgentSessionFilters now takes its SecureStore key as a parameter. The live page uses LIVE_SESSION_FILTERS_KEY; history keeps SESSION_FILTERS_KEY. Separate records, because the pages filter separate lists.
  • Sort removed. Both pages order by creation time (SESSION_LIST_SORT). Home and the Share gate are unaffected — they already pass updated_at explicitly.
  • No-match state on the live page distinguishes search from filters and offers the matching clear action.

Follow-on cleanup

Dropping the sort control let a few things collapse:

  • AgentSessionFilters loses sortBy, so clearAgentSessionNarrowingFilters is gone and clearBroadly takes a plain clear callback instead of a filter transform.
  • AgentSessionListContent and useAgentSessionListData no longer thread a sortBy prop, and the SectionList no longer remounts on sort change.
  • sortBy / sortLastUpdated / sortCreated are removed from all 88 locales.
  • PLATFORM_FILTERS and ProjectFilterOption move to session-list-helpers so pure modules can read them without pulling in React Native.

Legacy persisted records that still carry sortBy parse fine — the field is ignored.

Tests

  • live-session-filters.test.ts — bucket folding, option building, AND-combined filtering, title and repository search, whitespace-only query, unknown-origin and no-repository rows.
  • session-list-screen.mounted.test.tsx — filter button visibility and badge count, repository filtering, search narrowing, search-header visibility, clearable no-match state.
  • agent-session-filters.test.ts — filter counting, legacy sortBy tolerance.
  • pnpm format && pnpm typecheck && pnpm lint && pnpm check:unused clean. pnpm test 6402 passed. Root pnpm typecheck clean.

The live Agents list showed every running session with no way to narrow it.
Add the same filter affordance the history screen uses: a filter button in the
header, removable chips, and the shared filter modal.

- Filter by repository and by origin bucket (cloud agent, extension, CLI,
  Slack, GitHub, Linear, other).
- Build both option sets from the live rows themselves, so the picker never
  offers a value with nothing running.
- Filter in memory. The live set is already fully loaded, so no refetch.
- Show a clearable no-match empty state when a filter hides every row.
- Reuse the existing translations. No new i18n keys.

The filter modal now hides its sort section when no sort is given, and takes
the platform rows to offer. `PLATFORM_FILTERS` and `ProjectFilterOption` move
to `session-list-helpers` so pure modules can read them without pulling in
React Native.
@iscekic iscekic self-assigned this Aug 28, 2026
Comment thread apps/mobile/src/components/agents/live-session-filters.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental commit 7b7aa5d fixes the prior sign-out cleanup, filter-load flash, and no-match CTA issues; no new findings on current HEAD.

Files Reviewed (10 files)
  • apps/mobile/src/lib/auth/auth-context.tsx
  • apps/mobile/src/lib/auth/auth-context.test.tsx
  • apps/mobile/src/components/agents/use-live-session-query.ts
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-history-screen.tsx
  • apps/mobile/src/components/agents/session-history-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-search-state.ts
  • apps/mobile/src/components/agents/session-search-state.test.ts
  • apps/mobile/src/components/agents/use-session-search-input.ts
Previous Review Summaries (3 snapshots, latest commit d09783e)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit d09783e)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/lib/storage-keys.ts 14 LIVE_SESSION_FILTERS_KEY is not deleted on sign-out
apps/mobile/src/components/agents/use-live-session-query.ts 26 Persisted live filters apply only after a default unfiltered paint

SUGGESTION

File Line Issue
apps/mobile/src/components/agents/session-list-screen.tsx 228 No-match CTA says "Clear search" but always clears filters too
Files Reviewed (18 files)
  • apps/mobile/src/lib/storage-keys.ts - 1 issue
  • apps/mobile/src/components/agents/use-live-session-query.ts - 1 issue
  • apps/mobile/src/components/agents/session-list-screen.tsx - 1 issue
  • apps/mobile/src/components/agents/live-session-filters.ts
  • apps/mobile/src/components/agents/live-session-filters.test.ts
  • apps/mobile/src/components/agents/platform-filter-modal.tsx
  • apps/mobile/src/components/agents/session-filter-button.tsx
  • apps/mobile/src/components/agents/session-history-screen.tsx
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-header-actions.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx
  • apps/mobile/src/components/agents/session-search-state.ts
  • apps/mobile/src/components/agents/session-search-state.test.ts
  • apps/mobile/src/components/agents/use-agent-session-list-data.ts
  • apps/mobile/src/lib/agent-session-filters.ts
  • apps/mobile/src/lib/agent-session-filters.test.ts
  • apps/mobile/src/lib/agent-session-sort.ts
  • apps/mobile/src/lib/hooks/use-persisted-agent-session-filters.ts

Fix these issues in Kilo Cloud

Previous review (commit 7db57e8)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 file)
  • apps/mobile/src/components/agents/live-session-filters.ts

Previous review (commit 05e662d)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
apps/mobile/src/components/agents/live-session-filters.ts 61 .toSorted() is not implemented on Hermes and will crash the live Agents tab
Files Reviewed (6 files)
  • apps/mobile/src/components/agents/live-session-filters.ts - 1 issue
  • apps/mobile/src/components/agents/live-session-filters.test.ts
  • apps/mobile/src/components/agents/platform-filter-modal.tsx
  • apps/mobile/src/components/agents/session-list-helpers.ts
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-screen.mounted.test.tsx

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 102.4K · Output: 12.9K · Cached: 319.5K

Review guidance: REVIEW.md from base branch main

Hermes does not implement Array.prototype.toSorted. The map already copies,
so sort() mutates nothing shared.
Both session-list pages now share one filtering UI. The pages stay separate:
each keeps its own list, its own persisted filter record, and its own screen.

- Add a count badge to the filter button while filters are applied. The count
  is spoken as the button's accessibility value, so no new string is needed.
- Persist the live page's filters under their own SecureStore key.
- Add search to the live page. The live set is in memory, so it matches the
  title and the repository locally, with no debounce and no refetch.
- Remove the sort control. Both pages order by creation time; Home and the
  Share gate keep `updated_at`, which they already pass explicitly.

`AgentSessionFilters` loses `sortBy`, so `clearBroadly` takes a plain clear
callback instead of a filter transform. The persisted-filters hook now takes
its storage key as a parameter. Sort strings are dropped from all 88 locales.
@iscekic iscekic changed the title feat(mobile): filter the live sessions list by repository and origin feat(mobile): unify session filtering across the live and history pages Aug 28, 2026
scripts/lint-all.sh runs a stricter type-aware config than the mobile
package's own lint script. Use vi.fn().mockResolvedValue so the mocks trip
neither prefer-await-to-then nor require-await.
Comment thread apps/mobile/src/lib/storage-keys.ts
Comment thread apps/mobile/src/components/agents/use-live-session-query.ts
Comment thread apps/mobile/src/components/agents/session-list-screen.tsx Outdated
- Delete the live filter record on sign-out. Without it, User A's repository
  and origin filters loaded for User B and hid B's running sessions.
- Hold the live skeletons until the stored filter record resolves. The list
  painted unfiltered first, then dropped rows when the record arrived.
- Make the no-match CTA do exactly what its label says. It read "Clear search"
  while also dropping the persisted filters. Both pages now clear only the one
  the label names, which leaves `clearBroadly` with no caller.
@iscekic iscekic added the human-ready The PR is ready for human review. label Aug 28, 2026
@iscekic
iscekic merged commit 0360afc into main Aug 28, 2026
23 checks passed
@iscekic
iscekic deleted the feat/mobile-live-session-filters branch August 28, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants