Skip to content

feat: multi-file torrent upload with per-file editing#696

Open
staners2 wants to merge 1 commit intoYouROK:masterfrom
staners2:feat/multi-add-torrents
Open

feat: multi-file torrent upload with per-file editing#696
staners2 wants to merge 1 commit intoYouROK:masterfrom
staners2:feat/multi-add-torrents

Conversation

@staners2
Copy link
Copy Markdown

@staners2 staners2 commented Apr 10, 2026

Summary

Adds support for selecting and uploading multiple .torrent files at once, with a dedicated dialog for editing each file's metadata before saving.

New functionality

  • Multi-file upload: Dropzone now accepts multiple .torrent files (drag & drop or file picker)
  • MultiAddDialog: When files are selected, a new dialog displays all files as a scrollable list. Each file has:
    • Poster thumbnail (auto-fetched from TMDB)
    • Editable title field
    • Editable poster URL field
    • Category selector
    • Delete button to remove from batch
  • Duplicate detection: Each file's infohash is parsed client-side and compared against existing torrents in DB. Duplicates are highlighted with a warning ("already in database") and fields are pre-filled from existing data
  • Unified flow: Both single and multiple file uploads use the same list-based UI for consistency

Bug fixes

  • Card jumping fix: Torrent list now uses useMemo with stable sort (timestamp + hash tiebreaker) to prevent cards from reordering on each 1-second refetch. The backend returns torrents in non-deterministic order when timestamp and title are equal
  • Sort comparator fix: Replaced broken (a, b) => a.title > b.title (returns boolean, causes unstable sort) with localeCompare
  • Grid stability: Replaced minmax(max-content, 570px) with minmax(450px, 570px) to prevent layout shifts from dynamic content
  • TorrentCard memo optimization: Custom comparator checks only visible fields (hash, title, name, poster, category, stat, size, speed, data) instead of shallow object comparison, preventing unnecessary re-renders every second
  • Crash fix: Added null guards for torrents before .map()/.filter() calls (undefined on initial render before query resolves)

Code cleanup

  • Removed dead code: LeftSideBottomSectionFileSelected, TorrentIconWrapper, CancelIconWrapper styled-components; unused hashRegex export; commented-out catArray
  • Simplified AddDialog: file upload logic moved entirely to MultiAddDialog, AddDialog now only handles link/magnet/hash and edit mode
  • Simplified LeftSideComponent: removed "file selected" state, dropzone always visible
  • Backend: removed dead multiFile title/poster blanking logic in upload.go (frontend now sends one request per file)

Localization

  • Updated ClickOrDrag text in all 7 locales to indicate multiple file support (e.g., "CLICK / DRAG & DROP FILES (.torrent)")

Test plan

  • Drop single .torrent file — MultiAddDialog opens with one item, fields editable
  • Drop multiple .torrent files — all shown in scrollable list with individual fields
  • Drop already-added .torrent — warning shown, fields pre-filled from DB
  • Add via magnet/hash/link — original AddDialog flow unchanged
  • Edit existing torrent — edit dialog unchanged
  • Verify torrent cards don't jump/reorder after adding
  • Test on narrow screen (<700px) — dialog goes fullscreen

New feature: multiple .torrent files can be selected/dropped at once.
Instead of adding them blindly, a dedicated MultiAddDialog shows all
files as a scrollable list where each file has its own editable fields:
title, poster URL, and category. Duplicate detection compares infohash
against existing torrents and pre-fills fields from DB with a warning.

Frontend changes:
- New MultiAddDialog component for batch .torrent file uploads
  with per-file title, poster, category editing and duplicate detection
- AddDialog simplified: file uploads always delegate to MultiAddDialog,
  AddDialog now only handles link/magnet/hash input and edit mode
- LeftSideComponent simplified: dropzone always visible (no "file selected"
  state), supports multiple file selection
- TorrentList: stable sort via useMemo (timestamp + hash tiebreaker),
  fixes card jumping caused by unstable backend sort order
- TorrentCard: custom memo comparator prevents unnecessary re-renders
  on every 1s refetch interval
- Grid layout: replaced unstable max-content minimum with fixed 450px
- Locales: updated ClickOrDrag text to indicate multiple files support
- Removed dead code: LeftSideBottomSectionFileSelected,
  TorrentIconWrapper, CancelIconWrapper, unused hashRegex export,
  commented-out catArray

Backend changes:
- upload.go: removed dead multiFile title/poster blanking logic
  (frontend now sends one request per file with individual metadata)
- upload.go: API still supports multiple files per request for
  backward compatibility
@staners2 staners2 force-pushed the feat/multi-add-torrents branch from bbe6318 to 9de64e7 Compare April 10, 2026 13:46
Copy link
Copy Markdown
Contributor

@pavelpikta pavelpikta left a comment

Choose a reason for hiding this comment

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

Hi @staners2
Don't need to push chages for static files, static files will udpated before release

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.

2 participants