feat(tasks): add conversation multi-select right sidebar #2442
feat(tasks): add conversation multi-select right sidebar #2442janburzinski wants to merge 4 commits into
Conversation
Greptile SummaryThis PR adds multi-select support to the sidebar conversations list, including shift-click range selection and a bulk-delete flow via a floating
Confidence Score: 4/5Safe to merge with awareness that shift-click can only expand (not contract) the selection range, and that bulk deletion clears the user's selection synchronously before async deletes resolve. The two main logic concerns — stale anchor index during live-sort re-ordering and range selection overwriting manual picks — were already flagged in prior review threads and addressed in this implementation. The remaining behavioural difference (shift-click accumulates rather than pivoting, so a second shift-click can never shrink the selection) is a deliberate design trade-off. The bulk delete clears selection synchronously before async deletions resolve, so a failed delete leaves the list correct but the selection lost. Neither rises to a blocking issue. use-multi-select.ts — the range-accumulation behaviour and anchor-snapshot ordering edge cases are worth a second look before this ships to users who rely heavily on keyboard-driven multi-select.
|
| Filename | Overview |
|---|---|
| apps/emdash-desktop/src/renderer/lib/hooks/use-multi-select.ts | New hook managing multi-select state with range selection; anchor-snapshot approach correctly avoids live-sort drift during a selection gesture, though the accumulation-only range model (can't contract a shift-click range) differs from standard OS behavior. |
| apps/emdash-desktop/src/renderer/features/tasks/conversations/sidebar-conversations-list.tsx | Integrates useMultiSelect into a virtualised row list; uses onCheckedChange + mousedown ref pattern to capture shift state correctly; bulk delete captures ID snapshot before modal open, avoiding stale-closure issues. |
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
apps/emdash-desktop/src/renderer/lib/hooks/use-multi-select.ts:41-49
**Shift-click can only expand selection, never contract it**
Range IDs are always added to the existing `Set` (`next.add`), so a second shift-click can never shrink a previously established range. In standard OS/spreadsheet behavior, shift-clicking closer to the anchor replaces the previous range with the smaller one. Here, if the user clicks A, shift-clicks E (selects A–E), then shift-clicks C, the expected result is A–C, but the actual result remains A–E. There is no way to shrink the selection via shift-click — the user must clear and start over. This is probably acceptable for a sidebar list, but worth being aware of if the behavior feels surprising during testing.
### Issue 2 of 2
apps/emdash-desktop/src/renderer/features/tasks/conversations/sidebar-conversations-list.tsx:291-294
**Selection cleared before async deletes resolve**
`clearSelection()` is called synchronously in `onSuccess`, immediately after dispatching all `deleteConversation` promises with `void`. If any deletion fails (network error, server rejection), the user's carefully assembled selection is already gone — they must re-select the conversations and retry manually. The existing single-delete path has the same pattern, but bulk deletes make losing the selection more costly. Consider clearing after all promises settle, or at minimum surfacing a toast on error so the user knows a retry is needed.
Reviews (3): Last reviewed commit: "fix(conversations): remove extra scroll ..." | Re-trigger Greptile
Description
Screenshot/Recording (if applicable)
https://streamable.com/vh10x6
Checklist
messages and, when possible, the PR title