Torrents: surface the stall settings as UI controls (noldevin)
Follow-up to 5187fe5f, which shipped stall handling as config-only keys.
Boulder wanted them user-accessible, so the two knobs now render in the
Torrent Client settings section:
- "Stalled torrent timeout (minutes)" — number input. Shown in MINUTES for
friendliness, stored in SECONDS (download_source.torrent_stall_timeout_
seconds). 0 disables. Blank/NaN falls back to the 10-min default on save.
- "When a torrent stalls" — Abandon (default) / Pause select, maps to
download_source.torrent_stall_action.
Both live under download_source (already in the settings POST allowlist), so
no backend change — load converts seconds→minutes, save converts back.
Inputs/selects only (no onclick), so the script-split onclick-coverage test
stays green. settings.js syntax-checked via Windows node.
This commit is contained in:
parent
5187fe5f66
commit
46f03827a2
2 changed files with 34 additions and 0 deletions
|
|
@ -5349,6 +5349,23 @@
|
||||||
Override where the torrent client writes downloads. This path is on the <strong>torrent client's</strong> machine, not SoulSync's.
|
Override where the torrent client writes downloads. This path is on the <strong>torrent client's</strong> machine, not SoulSync's.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Stalled torrent timeout (minutes):</label>
|
||||||
|
<input type="number" id="torrent-stall-timeout" min="0" step="1" placeholder="10">
|
||||||
|
<div class="setting-help-text">
|
||||||
|
Give up on a torrent that makes <strong>zero download progress</strong> for this long — a dead magnet stuck on "downloading metadata", or a swarm with no seeders. Without this, a dud torrent ties up a download slot for the full 6-hour limit. <strong>0 disables</strong> (wait the full limit).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>When a torrent stalls:</label>
|
||||||
|
<select id="torrent-stall-action" class="form-select">
|
||||||
|
<option value="abandon">Abandon — remove it & its partial data, fail the download</option>
|
||||||
|
<option value="pause">Pause — pause it in the client, leave it for me</option>
|
||||||
|
</select>
|
||||||
|
<div class="setting-help-text">
|
||||||
|
Abandon frees the slot so the next source can try. Pause keeps the torrent in your client so you can inspect or resume it manually.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Status:</label>
|
<label>Status:</label>
|
||||||
<div class="form-actions" style="margin-top: 4px;">
|
<div class="form-actions" style="margin-top: 4px;">
|
||||||
|
|
|
||||||
|
|
@ -1128,6 +1128,15 @@ async function loadSettingsData() {
|
||||||
if (_tcPass) _tcPass.value = settings.torrent_client?.password || '';
|
if (_tcPass) _tcPass.value = settings.torrent_client?.password || '';
|
||||||
if (_tcCat) _tcCat.value = settings.torrent_client?.category || 'soulsync';
|
if (_tcCat) _tcCat.value = settings.torrent_client?.category || 'soulsync';
|
||||||
if (_tcPath) _tcPath.value = settings.torrent_client?.save_path || '';
|
if (_tcPath) _tcPath.value = settings.torrent_client?.save_path || '';
|
||||||
|
// Stalled-torrent knobs live under download_source but render in the
|
||||||
|
// torrent client section. Timeout is stored in SECONDS, shown in MINUTES.
|
||||||
|
const _tcStall = document.getElementById('torrent-stall-timeout');
|
||||||
|
const _tcStallAct = document.getElementById('torrent-stall-action');
|
||||||
|
if (_tcStall) {
|
||||||
|
const secs = settings.download_source?.torrent_stall_timeout_seconds;
|
||||||
|
_tcStall.value = (secs === undefined || secs === null) ? 10 : Math.round(Number(secs) / 60);
|
||||||
|
}
|
||||||
|
if (_tcStallAct) _tcStallAct.value = settings.download_source?.torrent_stall_action || 'abandon';
|
||||||
const _ucType = document.getElementById('usenet-client-type');
|
const _ucType = document.getElementById('usenet-client-type');
|
||||||
const _ucUrl = document.getElementById('usenet-client-url');
|
const _ucUrl = document.getElementById('usenet-client-url');
|
||||||
const _ucKey = document.getElementById('usenet-client-api-key');
|
const _ucKey = document.getElementById('usenet-client-api-key');
|
||||||
|
|
@ -2886,6 +2895,14 @@ async function saveSettings(quiet = false) {
|
||||||
hybrid_order: getHybridOrder(),
|
hybrid_order: getHybridOrder(),
|
||||||
stream_source: document.getElementById('stream-source').value,
|
stream_source: document.getElementById('stream-source').value,
|
||||||
max_concurrent: parseInt(document.getElementById('max-concurrent-downloads').value) || 3,
|
max_concurrent: parseInt(document.getElementById('max-concurrent-downloads').value) || 3,
|
||||||
|
// Stalled-torrent knobs (rendered in the torrent client section).
|
||||||
|
// UI is in MINUTES; stored in SECONDS. Blank/NaN → 10 min default;
|
||||||
|
// 0 stays 0 (disabled).
|
||||||
|
torrent_stall_timeout_seconds: (() => {
|
||||||
|
const m = parseInt(document.getElementById('torrent-stall-timeout')?.value, 10);
|
||||||
|
return (Number.isFinite(m) && m >= 0 ? m : 10) * 60;
|
||||||
|
})(),
|
||||||
|
torrent_stall_action: document.getElementById('torrent-stall-action')?.value || 'abandon',
|
||||||
},
|
},
|
||||||
tidal_download: {
|
tidal_download: {
|
||||||
quality: document.getElementById('tidal-download-quality').value || 'lossless',
|
quality: document.getElementById('tidal-download-quality').value || 'lossless',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue