Settings
Every Apollo Download Manager setting, what it does, and its bounds. They are sections of one settings document in the database, each read and saved through Database::section and Database::save_section, and checked first (the Section trait). Each setting is checked in Rust before it applies, whatever the screen allows.
The Settings screen
The screen (#30, src/features/settings/SettingsView.tsx) edits every section below except the window's look, which keeps saving through set_appearance so it never overwrites a panel width (the window).
Saved whole:
set_settingschecks every section first and saves none when one is refused (INVALID_INPUT); then it writes them all in one go, and applies them at once (velocity_core::settings::Settings,Manager::set_settings). The screen says "Saving…", then "Saved", or why it wasn't, and shows what is saved.When each applies: at once, all of them. The engine's retries, timeouts, preallocation and write buffer apply to downloads that start or retry after the change; the connection budget, the queue, the limits and the torrent helper's settings apply to running ones too. None needs a restart.
Read with defaults: a section is read merged over its defaults, so settings an older Apollo Download Manager saved get the newer fields' defaults (V1's
migrate_settings_json). A field this build doesn't know is refused, never dropped.When the app starts: the saved settings are applied (
Manager::apply_saved_settings), and the torrent helper starts with its own. A failure is logged, and the defaults hold for what couldn't be read.Reset to defaults asks first, and keeps the download folder (V1's).
What the build can't do is disabled with the reason (below). Today's engine does everything the screen offers, Metalink included (#54).
Engine
EngineSettings in crates/velocity-core/src/transfer.rs (#30), the engine section: V1's retry, timeout, connection-budget and disk settings, as ADR-0005 mapped them. The engine gets them through set_engine_settings (transfer contract version 14); its supervisor gives them to a new engine after a restart.
| Setting | Default | Bounds | V1's |
|---|---|---|---|
failuresInARow | 5 | 1 to 100 | max_tries |
maxRetryWaitSecs | 60 | 1 to 600 | retry_wait_secs |
stalledAfterSecs | 15 | 5 to 600 | lowest_speed_limit_kib: time without data, or under the engine's 1 KiB/s floor (#292) |
resetAfterSecs | 30 | 5 to 3600, never below stalledAfterSecs | timeout_secs |
connectTimeoutSecs | 30 | 1 to 300 | connect_timeout_secs (HTTP, HTTPS and FTP; SFTP keeps its own) |
downloadRetries | 2 | 0 to 10 | app_retries |
connectionBudget | 48 | 1 to 256 | connection_budget |
preallocation | sparse | none, sparse or full | file_allocation |
writeBufferMib | 2 | 1 to 64, per connection | disk_cache_mib |
Preallocation:
sparsemarks the part file sparse on Windows (#42's measurement),nonedoesn't, andfullsets the file's length as soon as its size is known, so a disk too small fails at once.Write buffer: how many fetch events, of at most 1 MiB each, a connection may have waiting for the writer.
Advanced and new torrents
AdvancedSettings (the advanced section) and NewTorrentSettings (newTorrents) in crates/velocity-core/src/settings.rs (#30).
| Section | Setting | Default | Bounds |
|---|---|---|---|
advanced | Forget servers (a button, not a saved setting) | — | Forgets what downloads learned about servers (forget_learned_servers, #325) |
globalDownloadLimitKib | 0: none | 0, or at least 1 KiB/s (#49). Direct downloads only: torrents have their own downloadLimit (TORRENTS.md, #312) | |
enableBittorrent | on (V1's) | Off refuses torrents and magnet links with PROTOCOL_DISABLED | |
enableMetalink | off (V1's) | Offered when the engine reads Metalink, as it does since #54 | |
userAgent | null: ApolloDownloadManager/<version> | At most 256 bytes, no control characters; for downloads added after it | |
newTorrents | chooseFilesForMagnets | off | The Add dialog's "Choose files before downloading" |
seeding | never | As a torrent's seeding policy (TORRENTS.md) | |
uploadLimitKib | 0: none | The Add dialog's upload limit |
Browser
BrowserSettings (the browser section) in crates/velocity-core/src/browser/mod.rs (#65), V1's. The screen's Browser section also registers the native host with each browser (BROWSER_EXTENSION.md).
| Setting | Default | What it does |
|---|---|---|
acceptRequests | on | Off refuses links from the extension (DISABLED); the browser then downloads them |
confirmBeforeAdding | on | A link opens the Add dialog. Off adds it at once, unless it is a torrent, a magnet link, a taken name or a link added before |
The torrent helper's own settings are the torrent section, TorrentSettings (TORRENTS.md); the screen shows them with the helper's port and port mapping (get_torrent_network).
Proxy
ProxySettings (the proxy section) in crates/velocity-core/src/proxy.rs (#192, ADR-0008). The screen's Proxy section edits it. It holds no password.
| Setting | Default | Bounds |
|---|---|---|
kind | none | none, http, https or socks5 |
host | empty | With a proxy: a DNS name (an international one kept in its ASCII form, as links are), an IPv4 address, or an IPv6 address in brackets; no scheme, port or login. Without one, kept as typed |
port | 8080 | 1 to 65535 with a proxy |
userName | empty: no login | What a login may have: no : or control character |
rememberPassword | off | Keep the password in the system keychain (ADR-0015) |
The password is set on its own (
set_proxy_password) and never comes back to the window, which only learns whether one is set (get_proxy_password_set). It is held in memory, and saved in the keychain only whilerememberPasswordis on; turning it off deletes it there (PO decision on #192). A keychain that refuses is said (KEYCHAIN_UNAVAILABLE), and the password is still used until the app closes.What it covers: every direct download (HTTP, HTTPS, FTP, SFTP) that starts, resumes or retries after a change, and the torrent helper at once. SFTP and torrents can't use an HTTPS proxy: SFTP downloads fail with a message saying so, and no torrent starts (
PROXY_UNSUPPORTED). How each engine uses it is in ENGINE_INTERNALS.md and TORRENTS.md.When the app starts the torrent helper gets the proxy, with a remembered password, before anything else, and the transfer engine before the first download starts.
The window
Performance
Performance profiles are limits for the adaptive engine (ADR-0005, #57), not V1's aria2 option sets. Within a profile's limits, a download opens every connection it may use, a step at a time, and the engine drops those that don't make it faster (ENGINE_INTERNALS.md, #47, #221). A server that gains nothing from more connections gets fewer.
| Profile | Connections, per download and per server | Smallest piece | Notes |
|---|---|---|---|
| Conservative | 2 | 20 MiB | V1's values, for servers or networks that dislike many connections |
| Balanced, the default | 8 | 1 MiB | The engine's values before profiles existed, so nothing changed without a measurement |
| Maximum | 16 | 1 MiB | V1's connections. More than 8 only helps a server that gives each connection its own speed |
| Custom | The user's: 1 to 16 | The user's: 1 to 1024 MiB | V1's max_connection_per_server and min_split_size_mib. aria2's split count is gone, as Apollo DM splits by itself |
All profiles keep a connection at the same 10% loss for now: one whose loss would slow the download by 10% or more stays (#221; #57 set one threshold for every profile). Whether Conservative and Maximum should use other thresholds is for #77's measurements.
The smallest piece applies to downloads that start after the profile changes. The connection cap applies at once: a lower one holds running downloads back, which their details then say ("the performance profile allows no more to one server").
The shared budget for all downloads together stays 48 connections, V1's
connection_budget(#47).In code:
PerformanceSettingsincrates/velocity-core/src/performance.rsmaps a profile toEngineLimits.Manager::set_performanceapplies it, and new downloads ask for at most its connections (Manager::connections_for_new_downloads). The engine takes the limits throughset_engine_limits(ENGINE_CONTRACT.md).Removed, as ADR-0005 decided: "allow mid-download tuning" (Apollo Download Manager changes connections without restarting a download), and the aria2 optimizer.
Queue
QueueSettings in crates/velocity-core/src/queue.rs (#50):
| Setting | Default | Bounds |
|---|---|---|
maxConcurrentDownloads | 2 (3 before 0.2.0, #351) | 1 to 32 |
startImmediately | on | — |
restartOnNetwork | on | A download that failed because there was no network waits for it, and starts again from its bytes when the system's network changes (#318, ADR-0019) |
schedule.enabled | off | — |
schedule.startTime, schedule.stopTime | 02:00 to 07:00 | HH:MM, 24-hour, whatever the time format shown; chosen on the screen with hour and minute boxes (#350). No stop time, or 00:00, runs to midnight, and a stop before the start crosses midnight |
schedule.days | every day | 0 (Monday) to 6 (Sunday); at least one when the schedule is on |
How the queue applies them is in ENGINE_CONTRACT.md.
Updating from 0.1.x (#351, option B, PO decision): a saved maxConcurrentDownloads of 3, the old default, becomes 2 once, through migration 8 (DATA_AND_MIGRATIONS.md). Apollo Download Manager can't tell a chosen 3 from the old default, since the queue section is saved whole. Every other value is kept, and a 3 chosen after the update stays.
Folders
FolderSettings in crates/velocity-core/src/destination.rs (#31), V1's downloads settings, saved as the settings document's downloads section. #30 puts them on the Settings screen (PO decision on #31). What they do is in FILE_NAMING.md.
| Setting | Default | Bounds |
|---|---|---|
defaultDirectory | empty: the system's Downloads folder, or Downloads in the home folder when the system names none | An absolute folder, at most 4096 bytes, with no control character and no .. part |
autoCategorize | on | — |
categorySubfolders | on, V1's default since its #38 | — |
Before any are saved, the defaults apply.
Saved ones that can't be read, or that fail their checks, are a
DATABASEerror and are left as they were, never replaced by the defaults.
History
StorageSettings in crates/velocity-core/src/history.rs (#32), V1's storage settings, saved as the settings document's storage section. set_storage_settings saves them and applies them at once; the app also applies them when it starts. #30 puts them on the Settings screen.
| Setting | Default | Bounds |
|---|---|---|
historyRetentionDays | 90 | 0 to 3650; 0 keeps entries forever |
maxHistoryEntries | 10,000 | 100 to 1,000,000 |
What they forget: entries no longer in the download list that finished more than the retention ago, then the oldest beyond the most kept. An entry still in the list is never forgotten.
Never files: forgetting an entry deletes its record, with its checkpoint and torrent row, and never a file on disk.
A failure to apply them at start is the snapshot's
storageError, which the window shows; the app runs on.
The window
V1's general, notifications and appearance settings and its first-run flag, in crates/velocity-core/src/app_settings.rs (#29). Each is a section of the settings document, on the Settings screen (#30). What the window does with them is in UI_ARCHITECTURE.md.
| Section | Setting | Default | Bounds |
|---|---|---|---|
general | closeToTray | on | Closing hides the window in the tray, when there is one |
startMinimized | off | Starts hidden in the tray, when there is one, also when it starts at sign-in | |
startAtLogin | off; finishing the first-run setup turns it on in a released build | Starts the app when the user signs in (#321, PO decisions). On Windows, a value named after the app's identifier under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run; on Linux, <identifier>.desktop in the XDG autostart folder (velocity_core::autostart). Saving changes the entry first, and a refusal saves nothing. At each start the entry is put right when the app has moved. A development build never adds itself unless switched on, and V1's entry is never touched | |
confirmExitWithActive | on | Asks before quitting while downloads are active | |
notifications | onComplete | on | Also when a torrent starts seeding, or waits for its files to be chosen |
onFailure | on | — | |
onStart | off | When a download leaves the queue or a pause, not when it recovers from a retry or a stall | |
onEngineFailure | on | When the transfer engine or the torrent helper becomes unavailable | |
appearance | theme | system | system, light or dark |
density | compact | compact or comfortable, for the download list (#59) | |
timeFormat | twentyFourHour | twentyFourHour or twelveHour, for every time the app shows (#350; PO decision) | |
layout.sidebarWidth | null: about 17% of the window, 220 to 240 px | 184 to 360 px | |
layout.sidebarCollapsed, layout.sidebarVisible | off, on | — | |
layout.detailsWidth | null: a fifth of the window, 300 to 340 px | 280 to 600 px, for the details panel (#61) | |
layout.detailsVisible | off | — | |
visibleColumns | name, size, progress, speed, eta, status, category, added (V1's) | The download list's columns, in display order (#59). Always with name, each column once. The ids are V1's 13: those above and downloaded, avgSpeed, destination, started and completed (ColumnId, fixture columns.json) | |
columnWidths | none: each column's default width | The widths the user set by dragging, in CSS pixels by column id, 48 to 1200 px (#59) | |
onboarding | completed | off | Set by finishing the first-run setup, which also saves its folder as downloads.defaultDirectory |
upkeep | windowDataCleared | off | Not on any screen: set once the window's old browsing data, with the autofill entries earlier versions kept, was cleared (#345, PRIVACY.md) |
Saved and read like the folder settings: a panel or column width outside its bounds, and a column list without
nameor with a column twice, are refused withINVALID_INPUT. An unknown column id doesn't parse, soset_appearancerefuses it before it reaches the core, and a saved section that can't be read is aDATABASEerror for the window, left as it was.Read when the app starts:
generalandnotificationsare read when the app starts. A section that can't be read is left as it was, and its defaults apply until it is fixed, so closing and notifications keep working. The Settings screen (#30) changes them while the app runs, and closing and notifications follow at once.
What a build can do
Settings and details never offer what the build can't do. The engine reports its capabilities per protocol (ProtocolCapabilities, CONTRACTS.md): whether it downloads the protocol at all, and whether it segments, resumes, checks validators, uses HTTP/2 and can encrypt it. In the UI, availability (src/capabilities.ts) turns that into "available" or a reason, and CapabilityOption shows a control that is disabled, with the reason beside it, when the build lacks something; the Settings screen's Metalink switch is one, disabled only with an engine that can't read Metalink (#30).