fix(ui): restrict pause button to Downloading state (fixes #58) - #63
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughPause controls and bulk-pause logic were tightened so pause is shown and invoked only for downloads in the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR fixes issue #58 by restricting the Pause button in Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User presses Space / clicks Pause] --> B{Action source}
B -->|Per-row ActionCell| C{download.state}
B -->|Bulk handleToggleSelected| D[Filter visibleSelectedDownloads]
C -->|Downloading| E[Show Pause button → pause IPC]
C -->|Queued| F[No button shown ✅ fixed]
C -->|Paused| G[Show Resume button → resume IPC]
C -->|Error / Retry| H[Show Retry button → retry IPC]
C -->|Completed / other| I[No action button]
D --> J[state === Downloading → pauseMut]
D --> K[state === Paused → resumeMut]
D --> L[state === Queued → skip ✅ fixed]
D --> M[state === other → skip]
J & K --> N{tasks.length === 0?}
L & M --> N
N -->|Yes| O[Return early — no IPC calls]
N -->|No| P[Promise.allSettled tasks]
Reviews (1): Last reviewed commit: "fix(ui): restrict pause to Downloading s..." | Re-trigger Greptile |
| await waitFor(() => { | ||
| expect(mockInvoke).toHaveBeenCalledWith('download_pause', { id: 1 }); | ||
| expect(mockInvoke).toHaveBeenCalledWith('download_resume', { id: 2 }); | ||
| }); | ||
| expect(mockInvoke).not.toHaveBeenCalledWith('download_pause', { id: 3 }); |
There was a problem hiding this comment.
Negative assertion outside
waitFor
The not.toHaveBeenCalledWith check on line 485 runs synchronously after the waitFor resolves. In the current implementation this is safe — all three pause/resume calls are dispatched in the same Promise.allSettled batch, so id 3 would have been called before ids 1 and 2. However, if the implementation is ever changed to schedule calls asynchronously (e.g., debounced or queued), a late call for id 3 could slip past this assertion. Moving the negative check inside the same waitFor makes the intent explicit and future-proof.
| await waitFor(() => { | |
| expect(mockInvoke).toHaveBeenCalledWith('download_pause', { id: 1 }); | |
| expect(mockInvoke).toHaveBeenCalledWith('download_resume', { id: 2 }); | |
| }); | |
| expect(mockInvoke).not.toHaveBeenCalledWith('download_pause', { id: 3 }); | |
| await waitFor(() => { | |
| expect(mockInvoke).toHaveBeenCalledWith('download_pause', { id: 1 }); | |
| expect(mockInvoke).toHaveBeenCalledWith('download_resume', { id: 2 }); | |
| expect(mockInvoke).not.toHaveBeenCalledWith('download_pause', { id: 3 }); | |
| }); |
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)
src/views/DownloadsView/DownloadsTable.tsx (1)
145-181:⚠️ Potential issue | 🟠 MajorAdd accessible labels to icon-only action buttons.
Lines 145–181 render icon-only controls without
aria-label, so these actions are not reliably discoverable for assistive tech.🔧 Suggested fix
{download.state === 'Downloading' && ( <Button variant="ghost" size="icon" className="h-7 w-7" + aria-label={t('downloads.table.actions.pause', { defaultValue: 'Pause' })} onClick={(e) => { e.stopPropagation(); actions.pause(download.id); }} > <Pause className="size-3.5" /> </Button> )} {download.state === 'Paused' && ( <Button variant="ghost" size="icon" className="h-7 w-7" + aria-label={t('downloads.table.actions.resume', { defaultValue: 'Resume' })} onClick={(e) => { e.stopPropagation(); actions.resume(download.id); }} > <Play className="size-3.5" /> </Button> )} {(download.state === 'Error' || download.state === 'Retry') && ( <Button variant="ghost" size="icon" className="h-7 w-7" + aria-label={t('downloads.table.actions.retry', { defaultValue: 'Retry' })} onClick={(e) => { e.stopPropagation(); actions.start(download.id); }} > <RotateCcw className="size-3.5" /> </Button> )}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/views/DownloadsView/DownloadsTable.tsx` around lines 145 - 181, The icon-only action Buttons for Pause, Play and RotateCcw lack accessible labels; update each Button (the ones rendering when download.state === 'Downloading', 'Paused', and when download.state === 'Error' || 'Retry') to include a descriptive aria-label (e.g., "Pause download", "Resume download", "Retry download") and include contextual text like the download name or id (e.g., `aria-label={`Pause download ${download.name || download.id}`}`) so assistive tech can announce the action; keep the existing onClick handlers (actions.pause, actions.resume, actions.start) and leave the icons (Pause, Play, RotateCcw) as visual-only content.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/views/DownloadsView/DownloadsTable.tsx`:
- Around line 145-181: The icon-only action Buttons for Pause, Play and
RotateCcw lack accessible labels; update each Button (the ones rendering when
download.state === 'Downloading', 'Paused', and when download.state === 'Error'
|| 'Retry') to include a descriptive aria-label (e.g., "Pause download", "Resume
download", "Retry download") and include contextual text like the download name
or id (e.g., `aria-label={`Pause download ${download.name || download.id}`}`) so
assistive tech can announce the action; keep the existing onClick handlers
(actions.pause, actions.resume, actions.start) and leave the icons (Pause, Play,
RotateCcw) as visual-only content.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bcffe3dc-abeb-4331-9e8b-549dc4d8c6fc
📒 Files selected for processing (5)
CHANGELOG.mdsrc/views/DownloadsView/DownloadsTable.tsxsrc/views/DownloadsView/DownloadsView.tsxsrc/views/DownloadsView/__tests__/DownloadsTable.test.tsxsrc/views/DownloadsView/__tests__/DownloadsView.test.tsx
Summary
Downloadingstate (wasDownloading || Queued), aligning UI with the domain state machine that only allowsDownloading → PausedhandleToggleSelected) similarly restricted to only pauseDownloadingdownloads, preventing silent IPC errors forQueuedselectionsQueueddownloadsTest plan
npx vitest run— 336/336 pass, 0 failnpm run lint— 0 warnings, 0 errorsDownloadingQueuedDownloadingare paused,Queuedare skippedCloses #58
Summary by cubic
Restricts the Pause action to only Downloading items and updates the Space bulk toggle to ignore Queued, preventing invalid IPC calls. Adds i18n-backed aria-labels for action buttons and fixes #58.
pause,resume, andretrylabels toen/frand set aria-labels on action buttons.Written for commit b168ae5. Summary will update on new commits.
Summary by CodeRabbit
Bug Fixes
Accessibility
Tests
Localization