Skip to content

feat(web): add copy path option to content tab context menu#933

Open
lenisko wants to merge 2 commits intoautobrr:developfrom
lenisko:lenisko-copy-path
Open

feat(web): add copy path option to content tab context menu#933
lenisko wants to merge 2 commits intoautobrr:developfrom
lenisko:lenisko-copy-path

Conversation

@lenisko
Copy link
Copy Markdown

@lenisko lenisko commented Jan 1, 2026

  • add copy path option to content tab context menu
  • added missing "File/Dir" on mobile view "Rename" labels

Couldn't decide if we should name it Copy Path or Copy Save Path but in my opinion shorter wins so leaving it as it is.

Solves #910

Summary by CodeRabbit

  • New Features

    • Added "Copy Path" to torrent file/folder context menus to copy full paths (including configured save location).
  • Improvements

    • Context menu labels clarified to "Rename File" and "Rename Folder".
    • Added toast notifications for copy success and failure.
    • Improved handling of save-path formatting so copied paths work across platforms.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 1, 2026

Walkthrough

Added an optional savePath prop to torrent file-list components and threaded it through subcomponents; implemented "Copy Path" context-menu actions that build a full path via a new joinPath utility and copy it to the clipboard with toast success/error handling. Rename labels were clarified.

Changes

Cohort / File(s) Summary
Torrent file UI
web/src/components/torrents/TorrentDetailsPanel.tsx, web/src/components/torrents/TorrentFileTree.tsx, web/src/components/torrents/details/TorrentFileTable.tsx
Added optional savePath?: string prop to public component props and threaded it through TreeNode/FolderRow/FileRow/TorrentFileTable. Added "Copy Path" context menu items that construct full paths and call clipboard util; adjusted rename menu labels to "Rename File"/"Rename Folder".
Utilities
web/src/lib/utils.ts
Added export function joinPath(basePath: string, relativePath: string): string to detect separator, trim trailing separators, and join paths cross-platform.
Helpers / imports
web/src/components/torrents/...
Added imports and usage of copyTextToClipboard, joinPath, toast, and a Copy icon; wired success/error toasts for copy actions.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant FileRow as File/Folder Row (UI)
  participant Tree as TorrentFileTree / Table
  participant Utils as joinPath()
  participant Clipboard as copyTextToClipboard()
  participant Toast as toast()

  rect rgba(40,120,200,0.06)
    User->>FileRow: Right-click -> Select "Copy Path"
    FileRow->>Tree: request item id/path + savePath
    Tree->>Utils: joinPath(savePath, itemPath)
    Utils-->>Tree: fullPath
    Tree->>Clipboard: copyTextToClipboard(fullPath)
    alt copy success
      Clipboard-->>Toast: success toast("Copied path")
      Toast-->>User: show success
    else copy failure
      Clipboard-->>Toast: error toast("Could not copy")
      Toast-->>User: show error
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #650: Modifies the same TorrentFileTree code paths and UX around file-tree rendering and path handling.
  • #760: Alters TorrentDetailsPanel and file-list components, also adding savePath propagation and path-related UI changes.
  • #556: Adds/adjusts torrent path display and copy behavior in torrent details UI, overlapping with this PR's copy-path implementation.

Suggested labels

enhancement, web, torrent

Suggested reviewers

  • s0up4200

Poem

🐰 I hopped through folders, found the trail,
A savePath stitched to every tail.
Click "Copy Path" — a carrot cheer,🥕
Full paths carried far and near.✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a 'Copy Path' feature to the content tab context menu.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7163573 and 70c734e.

📒 Files selected for processing (2)
  • web/src/components/torrents/TorrentFileTree.tsx
  • web/src/components/torrents/details/TorrentFileTable.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/components/torrents/TorrentFileTree.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: finevan
Repo: autobrr/qui PR: 677
File: web/src/components/torrents/AddTorrentDialog.tsx:496-504
Timestamp: 2025-12-03T18:11:08.682Z
Learning: In the AddTorrentDialog component (web/src/components/torrents/AddTorrentDialog.tsx), temporary path settings (useDownloadPath/downloadPath) should be applied per-torrent rather than updating global instance preferences. The UI/UX is designed to suggest that these options apply to the individual torrent being added.
📚 Learning: 2025-12-03T18:11:08.682Z
Learnt from: finevan
Repo: autobrr/qui PR: 677
File: web/src/components/torrents/AddTorrentDialog.tsx:496-504
Timestamp: 2025-12-03T18:11:08.682Z
Learning: In the AddTorrentDialog component (web/src/components/torrents/AddTorrentDialog.tsx), temporary path settings (useDownloadPath/downloadPath) should be applied per-torrent rather than updating global instance preferences. The UI/UX is designed to suggest that these options apply to the individual torrent being added.

Applied to files:

  • web/src/components/torrents/details/TorrentFileTable.tsx
🔇 Additional comments (3)
web/src/components/torrents/details/TorrentFileTable.tsx (3)

13-17: LGTM! Imports properly support the new Copy Path feature.

The new imports (copyTextToClipboard, joinPath, Copy icon, and toast) are all utilized correctly in the Copy Path implementation.


26-26: LGTM! The savePath prop is properly integrated.

The optional savePath prop enables full path construction while maintaining backward compatibility through the fallback to node.id when not provided.

Also applies to: 173-173


424-437: Excellent implementation! Previous feedback has been addressed.

The Copy Path feature now includes success feedback with a toast notification. The implementation correctly:

  • Constructs the full path using joinPath when savePath is available
  • Handles errors gracefully with error toast
  • Provides differentiated success messages for files vs. folders (an improvement over the generic suggestion)

The previous concern about missing success confirmation has been fully resolved.


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.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
web/src/lib/utils.ts (1)

312-317: Function works correctly for its intended use case.

The joinPath implementation appropriately detects Windows vs Unix separators and handles path joining. One minor edge case to consider: if relativePath starts with a separator, the result would have a double separator (e.g., /base//relative). However, given that relativePath values come from torrent file listings (which use consistent forward slashes) and basePath from save_path (platform-normalized), this scenario is unlikely in practice.

Optional: Defensive handling for edge cases

If you want to be extra defensive, consider normalizing the relativePath:

 export function joinPath(basePath: string, relativePath: string): string {
   if (!basePath) return relativePath
   const separator = basePath.includes("\\") ? "\\" : "/"
   const cleanBase = basePath.replace(/[\\/]$/, "")
-  return `${cleanBase}${separator}${relativePath}`
+  const cleanRelative = relativePath.replace(/^[\\/]+/, "")
+  return `${cleanBase}${separator}${cleanRelative}`
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b85ad6b and 7163573.

📒 Files selected for processing (4)
  • web/src/components/torrents/TorrentDetailsPanel.tsx
  • web/src/components/torrents/TorrentFileTree.tsx
  • web/src/components/torrents/details/TorrentFileTable.tsx
  • web/src/lib/utils.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: finevan
Repo: autobrr/qui PR: 677
File: web/src/components/torrents/AddTorrentDialog.tsx:496-504
Timestamp: 2025-12-03T18:11:08.682Z
Learning: In the AddTorrentDialog component (web/src/components/torrents/AddTorrentDialog.tsx), temporary path settings (useDownloadPath/downloadPath) should be applied per-torrent rather than updating global instance preferences. The UI/UX is designed to suggest that these options apply to the individual torrent being added.
📚 Learning: 2025-12-03T18:11:08.682Z
Learnt from: finevan
Repo: autobrr/qui PR: 677
File: web/src/components/torrents/AddTorrentDialog.tsx:496-504
Timestamp: 2025-12-03T18:11:08.682Z
Learning: In the AddTorrentDialog component (web/src/components/torrents/AddTorrentDialog.tsx), temporary path settings (useDownloadPath/downloadPath) should be applied per-torrent rather than updating global instance preferences. The UI/UX is designed to suggest that these options apply to the individual torrent being added.

Applied to files:

  • web/src/components/torrents/details/TorrentFileTable.tsx
  • web/src/components/torrents/TorrentFileTree.tsx
  • web/src/components/torrents/TorrentDetailsPanel.tsx
🧬 Code graph analysis (1)
web/src/components/torrents/details/TorrentFileTable.tsx (1)
web/src/lib/utils.ts (2)
  • joinPath (312-317)
  • copyTextToClipboard (193-212)
🔇 Additional comments (2)
web/src/components/torrents/TorrentDetailsPanel.tsx (1)

1502-1502: LGTM! Clean prop propagation.

The savePath propagation to TorrentFileTable and TorrentFileTree correctly enables the new "Copy Path" feature by passing the torrent's save_path to child components.

Also applies to: 1557-1557

web/src/components/torrents/TorrentFileTree.tsx (1)

250-250: Good UX improvement with explicit labels.

Changing "Rename" to "Rename File" and "Rename Folder" improves clarity, especially in mobile view where context might be less obvious. This aligns well with the PR's goal of improving the mobile experience.

Also applies to: 376-376

Comment thread web/src/components/torrents/details/TorrentFileTable.tsx
Comment thread web/src/components/torrents/TorrentFileTree.tsx
@s0up4200 s0up4200 self-requested a review January 1, 2026 21:04
@s0up4200 s0up4200 changed the base branch from main to develop January 2, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants