-
Notifications
You must be signed in to change notification settings - Fork 0
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"]
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.
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.
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.
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.
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.
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.
Unspool is an independent project and is not affiliated with Telegram. Repository · Privacy · Security · MIT License
- Getting Started
- Detailed Telegram Setup
- Feature Overview
- Chats and History
- Attachments and Filenames
- Search and Selection
- Download Workflow
- Conflicts and Recovery
- Download History
- Settings
- Accessibility
- Troubleshooting
- Detailed Troubleshooting and FAQ
- Privacy and Security
- Detailed Security Model
- TDLib Integration
- Persistence
- Concurrency and Errors
- Glossary