Skip to content

fix: harden cancellation and mobile remote controls - #105

Merged
D3SOX merged 2 commits into
masterfrom
fix-cancellation-cleanup-mobile-controls
Aug 12, 2026
Merged

fix: harden cancellation and mobile remote controls#105
D3SOX merged 2 commits into
masterfrom
fix-cancellation-cleanup-mobile-controls

Conversation

@D3SOX

@D3SOX D3SOX commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Cancelling an active gate could leave its provider task alive, retain the serialized queue slot, and leave incomplete download artifacts behind. Mobile remote-browser interactions could also move the pointer during taps and occasionally trigger the phone browser's native page zoom.

This change:

  • makes every browser-backed gate reject pending waits and abort direct transfers during teardown
  • bounds cancellation teardown, releases stale queue slots, and removes cancelled outputs plus .crdownload/.part artifacts
  • makes one-finger movement relative to the current remote pointer, keeps taps stationary, supports long-press right click and hold-drag zoom, and preserves two-finger panning
  • disables native page zoom across the Web UI while retaining normal scrolling

Validation:

  • bun test (140 passed)
  • bun x tsc --noEmit in webui
  • Biome checks for all changed files
  • git diff --check
  • targeted cancellation, cleanup, and mobile-control tests passed on the ARM Pi

Implemented with GPT-5 through the Codex desktop agent harness.

Summary by CodeRabbit

  • New Features

    • Cancelled downloads now stop promptly and remove associated temporary or incomplete files.
    • Closing download sessions safely cancels active transfers and pending browser waits.
    • Mobile remote controls now support smoother pointer movement, tap/hold clicks, panning, and incremental zooming.
    • Improved touch behavior, pointer accuracy, and guidance on the remote browser screen.
  • Bug Fixes

    • Prevented cancelled or timed-out downloads from leaving behind artifacts.
    • Improved cleanup and resource handling after interrupted downloads.
  • Tests

    • Added coverage for download cleanup, cancellation, touch controls, zooming, pointer movement, and interrupted transfers.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c52c431f-4158-4a3a-84b1-ff4a23e4eafc

📥 Commits

Reviewing files that changed from the base of the PR and between d9efd16 and 63f5622.

📒 Files selected for processing (6)
  • src/downloadgater.ts
  • src/hypeddit.ts
  • src/server.ts
  • webui/src/components/RemoteBrowserPanel.tsx
  • webui/src/components/remoteBrowser.test.ts
  • webui/src/components/remoteBrowser.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/downloadgater.ts
  • src/hypeddit.ts
  • src/server.ts
  • webui/src/components/RemoteBrowserPanel.tsx
  • webui/src/components/remoteBrowser.test.ts

📝 Walkthrough

Walkthrough

The PR adds cancellation-aware downloader teardown and cancelled-artifact cleanup. It also changes mobile remote controls to use relative pointer movement, button-only clicks, and long-press touch zoom.

Changes

Download cancellation

Layer / File(s) Summary
Cancelled artifact cleanup
src/downloadCleanup.ts, src/downloadCleanup.test.ts
Adds basename validation, known-file cleanup, optional incomplete-file sweeping, and tests for traversal rejection and preservation rules.
Downloader cancellation propagation
src/downloadgater.ts, src/droploud.ts, src/hypeddit.ts, src/mypresskit.ts, src/stillhype.ts
Downloaders reject pending waits or abort active transfers before browser closure. Cleanup clears callbacks, timers, progress indicators, and sessions.
Server cancellation teardown
src/server.ts
Cancelled jobs deduplicate artifact cleanup, bound teardown to ten seconds, clean timed-out jobs, and release queue slots after cleanup.
Cancellation behavior validation
src/gateCancellation.test.ts
Tests verify cancellation or transfer abort occurs before browser closure for supported downloaders.

Mobile remote control

Layer / File(s) Summary
Remote pointer contract
webui/src/components/remoteBrowser.ts
Adds normalized pointer types and helpers for clamped canvas coordinate conversion.
Relative gesture contract
webui/src/components/mobileRemoteControls.ts
Touch controls emit relative pointer deltas and button-only clicks. Long presses enter anchored zoom mode.
Remote panel touch integration
webui/src/components/RemoteBrowserPanel.tsx, webui/src/components/RemoteBrowserPanel.css, webui/src/layouts/Layout.astro
The panel stores normalized pointers, applies relative movement, handles touch zoom state, and updates touch behavior and guidance.
Gesture interaction tests
webui/src/components/remoteBrowser.test.ts
Tests cover taps, holds, relative movement, panning, zoom events, and zooming-state transitions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Server
  participant Downloader
  participant DownloadTask
  participant DownloadCleanup
  Server->>Downloader: close()
  Downloader->>DownloadTask: reject or abort active download
  DownloadTask-->>Server: task completion or cancellation
  Server->>DownloadCleanup: cleanup cancelled artifacts
  DownloadCleanup-->>Server: removed artifact names
Loading
sequenceDiagram
  participant TouchSession
  participant MobileRemoteControls
  participant RemoteBrowserPanel
  TouchSession->>MobileRemoteControls: touch movement or release
  MobileRemoteControls->>RemoteBrowserPanel: movePointerBy(deltaX, deltaY)
  MobileRemoteControls->>RemoteBrowserPanel: zoomBy(deltaY, anchorX, anchorY)
  MobileRemoteControls->>RemoteBrowserPanel: click(button)
Loading

Possibly related PRs

  • D3SOX/sc-gate-dl#85: Introduces downloader classes extended here with cancellation handling.
  • D3SOX/sc-gate-dl#89: Also changes server-side cancellation cleanup and active download teardown.
  • D3SOX/sc-gate-dl#104: Introduces the mobile remote-control gesture logic extended here with relative movement and touch zoom.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: cancellation hardening and mobile remote-control improvements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-cancellation-cleanup-mobile-controls

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hypeddit.ts (1)

771-779: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle failure from an already-running retry.

If cancellation starts after this callback begins, clearTimeout(retryTimer) cannot stop page.click(). Browser closure then rejects page.click() without a handler.

Catch and ignore this best-effort retry failure.

Proposed fix
 		const retryTimer = setTimeout(async () => {
 			if (!downloadGuid) {
-				await page.click(Selectors.DW_DOWNLOAD_BUTTON);
+				try {
+					await page.click(Selectors.DW_DOWNLOAD_BUTTON);
+				} catch {
+					// The page can close during cancellation.
+				}
 			}
 		}, 10_000);
🤖 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 `@src/hypeddit.ts` around lines 771 - 779, Handle rejection from the
asynchronous retry callback in the retryTimer setTimeout flow: wrap the
best-effort page.click(Selectors.DW_DOWNLOAD_BUTTON) operation in rejection
handling and ignore failures caused by cancellation or browser closure. Preserve
the existing downloadGuid check, logging, and retry timing.
🤖 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 `@src/downloadgater.ts`:
- Around line 699-702: Update the download flow around cancelPendingDownloadWait
and clickDownload so downloadCompletePromise has an attached rejection handler
before clickDownload can yield. Start both operations together and await them
with Promise.all(), preserving cancellation rejection behavior and preventing an
unhandled rejection while close() is pending.

In `@src/server.ts`:
- Around line 1191-1197: Update the cancellation-timeout flow around
runDownloadProcess(), cleanupCancelledJobDownloads(), and
jobQueue.releaseActive() so the shared download directory cannot be reused while
the cancelled task may still write. Keep the queue slot until task completion,
or, if releasing on timeout is unavoidable, schedule completion cleanup that is
isolated from artifacts created by the next job.

In `@webui/src/components/RemoteBrowserPanel.tsx`:
- Around line 672-682: Update currentRemotePointer in RemoteBrowserPanel to
store the pointer in canvas-relative or normalized remote coordinates instead of
viewport client coordinates. Recompute current client coordinates from the
latest canvas bounds immediately before clickRemote and movePointerBy dispatch,
preserving the pointer’s remote location across pan and zoom. Add panel-level
coverage verifying click and relative movement after both pan and zoom.

In `@webui/src/layouts/Layout.astro`:
- Around line 10-13: Update the viewport metadata in Layout.astro to remove
maximum-scale=1 and user-scalable=no, and remove the global html touch-action
restriction. Preserve gesture suppression only within .remote-browser-screen and
its viewport.

---

Outside diff comments:
In `@src/hypeddit.ts`:
- Around line 771-779: Handle rejection from the asynchronous retry callback in
the retryTimer setTimeout flow: wrap the best-effort
page.click(Selectors.DW_DOWNLOAD_BUTTON) operation in rejection handling and
ignore failures caused by cancellation or browser closure. Preserve the existing
downloadGuid check, logging, and retry timing.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4dbd98da-9241-4357-a9d1-c51ac601c329

📥 Commits

Reviewing files that changed from the base of the PR and between 4afd0bc and d9efd16.

📒 Files selected for processing (14)
  • src/downloadCleanup.test.ts
  • src/downloadCleanup.ts
  • src/downloadgater.ts
  • src/droploud.ts
  • src/gateCancellation.test.ts
  • src/hypeddit.ts
  • src/mypresskit.ts
  • src/server.ts
  • src/stillhype.ts
  • webui/src/components/RemoteBrowserPanel.css
  • webui/src/components/RemoteBrowserPanel.tsx
  • webui/src/components/mobileRemoteControls.ts
  • webui/src/components/remoteBrowser.test.ts
  • webui/src/layouts/Layout.astro

Comment thread src/downloadgater.ts
Comment thread src/server.ts Outdated
Comment thread webui/src/components/RemoteBrowserPanel.tsx
Comment thread webui/src/layouts/Layout.astro
@D3SOX
D3SOX merged commit 4c69ca5 into master Aug 12, 2026
2 checks passed
@D3SOX
D3SOX deleted the fix-cancellation-cleanup-mobile-controls branch August 12, 2026 04:53
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