Skip to content

Download Workflow

QenTerra edited this page Jul 29, 2026 · 2 revisions

Download Workflow

Downloads are split into preparation, explicit conflict review, TDLib transfer, and safe destination placement.

flowchart TD
    S["Selected eligible attachments"] --> P["Preflight"]
    P --> D{"Destination and capacity valid?"}
    D -->|No| E["Recoverable error"]
    D -->|Yes| C{"Filename conflicts?"}
    C -->|Yes| R["Choose Skip, Replace, or Save a Copy"]
    C -->|No| Q["Create pending batch"]
    R --> Q
    Q --> T["TDLib file downloads<br/>1-6 concurrent"]
    T --> V["Validate completed local file and size"]
    V --> A["Atomic destination placement"]
    A --> H["Persist outcomes and clear pending batch"]
Loading

1. Selection validation

The download intent requires:

  • no batch already running;
  • an active selected chat;
  • at least one selected attachment;
  • every selected identity to belong to the active chat.

If the selected chat changed underneath the intent, Unspool clears selection and reports the mismatch instead of downloading into the wrong chat folder.

2. Preflight

DownloadPreflightBuilder deduplicates selected attachments by Telegram file ID. For each unique file it computes the destination path and detects:

  • a file that already exists at that path;
  • two selected attachments that would resolve to the same destination path.

It also sums all known file sizes and asks the destination volume for capacity available for important usage. If capacity is known and insufficient, the batch does not start.

The review sheet displays file count, known size, destination, and conflicts. Every conflict defaults to Skip.

3. Pending-batch persistence

Immediately before transfer, Unspool stores:

  • batch ID;
  • attachments;
  • chat title;
  • per-chat-folder option;
  • explicit conflict choices;
  • creation date.

That record makes relaunch recovery possible. Only one active pending batch is retained.

4. Transfer scheduling

DownloadCoordinator clamps concurrency to 1–6. It starts new child tasks while:

  • the batch is not paused;
  • the batch is not cancelled;
  • running tasks remain below the selected limit;
  • pending work remains.

Each worker calls TDLib downloadFile with synchronous completion requested. The returned TDLib file must report is_downloading_completed and contain a nonempty local path.

5. Placement

Before writing, DestinationAccess:

  • resolves the security-scoped bookmark;
  • starts access to the selected folder;
  • validates the exact original filename;
  • creates the optional safe chat directory;
  • verifies the downloaded file size when Telegram supplied one.

Normal placement copies to a uniquely named hidden partial file and then moves it to the final path. Replacement uses a temporary replacement file and replaceItemAt.

6. Completion

Every item accepted into a running batch produces a DownloadRecord with one of the current transfer outcomes:

  • completed;
  • filename conflict;
  • failed with a user-facing message;
  • cancelled.

Records are added to history, active selection is cleared, the pending file is removed, and the inline queue expands. Finder reveal runs only when enabled and at least one file completed.

The persisted outcome model also understands alreadyDownloaded for history compatibility. In the current Browse flow, the local completed-file guard normally marks that attachment ineligible before it enters preflight.

Related: Conflicts, File Safety, and Recovery and Download History.

Clone this wiki locally