Files
qBittorrent/src/webui/www/private/shareratio.html
2025-07-20 16:39:31 +08:00

212 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="${LANG}" class="dark">
<head>
<meta charset="UTF-8">
<title>QBT_TR(Torrent Upload/Download Ratio Limiting)QBT_TR[CONTEXT=UpDownRatioDialog]</title>
<link rel="stylesheet" href="css/style.css?v=${CACHEID}" type="text/css">
<script defer src="scripts/localpreferences.js?v=${CACHEID}"></script>
<script defer src="scripts/color-scheme.js?v=${CACHEID}"></script>
<script>
"use strict";
const UseGlobalLimit = -2;
const NoLimit = -1;
let limitReachedActionsEl;
window.addEventListener("DOMContentLoaded", (event) => {
limitReachedActionsEl = document.getElementById("limitReachedActions");
window.addEventListener("keydown", (event) => {
switch (event.key) {
case "Enter":
event.preventDefault();
document.getElementById("save").click();
break;
case "Escape":
event.preventDefault();
window.parent.qBittorrent.Client.closeFrameWindow(window);
break;
}
});
const searchParams = new URLSearchParams(window.location.search);
const origValues = searchParams.get("orig").split("|");
const values = {
ratioLimit: Number(origValues[0]),
seedingTimeLimit: Number(origValues[1]),
inactiveSeedingTimeLimit: Number(origValues[2]),
maxRatio: Number(origValues[3]),
maxSeedingTime: Number(origValues[4]),
maxInactiveSeedingTime: Number(origValues[5]),
shareLimitAction: String(origValues[6])
};
// select default when orig values not passed. using double equals to compare string and int
if ((origValues[0] === "")
|| ((values.ratioLimit === UseGlobalLimit)
&& (values.seedingTimeLimit === UseGlobalLimit)
&& (values.inactiveSeedingTimeLimit === UseGlobalLimit))) {
// use default option
setSelectedRadioValue("shareLimit", "default");
}
else if ((values.maxRatio === NoLimit) && (values.maxSeedingTime === NoLimit) && (values.maxInactiveSeedingTime === NoLimit)) {
setSelectedRadioValue("shareLimit", "none");
// TODO set input boxes to *global* max ratio and seeding time
}
else {
setSelectedRadioValue("shareLimit", "custom");
if (values.ratioLimit >= 0) {
document.getElementById("setRatio").checked = true;
document.getElementById("ratio").value = values.ratioLimit.toFixed(2);
}
if (values.seedingTimeLimit >= 0) {
document.getElementById("setTotalMinutes").checked = true;
document.getElementById("totalMinutes").value = values.seedingTimeLimit;
}
if (values.inactiveSeedingTimeLimit >= 0) {
document.getElementById("setInactiveMinutes").checked = true;
document.getElementById("inactiveMinutes").value = values.inactiveSeedingTimeLimit;
}
limitReachedActionsEl.value = values.shareLimitAction;
}
shareLimitChanged();
document.getElementById("default").focus();
document.getElementById("save").addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
if (!isFormValid())
return;
const shareLimit = getSelectedRadioValue("shareLimit");
let ratioLimitValue = 0.00;
let seedingTimeLimitValue = 0;
let inactiveSeedingTimeLimitValue = 0;
let shareLimitActionValue = "Default";
if (shareLimit === "default") {
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = UseGlobalLimit;
}
else if (shareLimit === "none") {
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = NoLimit;
}
else if (shareLimit === "custom") {
ratioLimitValue = document.getElementById("setRatio").checked ? document.getElementById("ratio").value : -1;
seedingTimeLimitValue = document.getElementById("setTotalMinutes").checked ? document.getElementById("totalMinutes").value : -1;
inactiveSeedingTimeLimitValue = document.getElementById("setInactiveMinutes").checked ? document.getElementById("inactiveMinutes").value : -1;
shareLimitActionValue = limitReachedActionsEl.value;
}
else {
return;
}
fetch("api/v2/torrents/setShareLimits", {
method: "POST",
body: new URLSearchParams({
hashes: searchParams.get("hashes"),
ratioLimit: ratioLimitValue,
seedingTimeLimit: seedingTimeLimitValue,
inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue,
shareLimitAction: shareLimitActionValue
})
})
.then((response) => {
if (!response.ok)
return;
window.parent.qBittorrent.Client.closeFrameWindow(window);
});
});
});
const getSelectedRadioValue = (name) => {
const radios = document.getElementsByName(name);
for (let i = 0; i < radios.length; ++i) {
const radio = radios[i];
if (radio.checked)
return radio.value;
}
};
const setSelectedRadioValue = (name, value) => {
const radios = document.getElementsByName(name);
for (let i = 0; i < radios.length; ++i) {
const radio = radios[i];
if (radio.value === value)
radio.checked = true;
}
};
const shareLimitChanged = () => {
const customShareLimit = getSelectedRadioValue("shareLimit") === "custom";
document.getElementById("setRatio").disabled = !customShareLimit;
document.getElementById("setTotalMinutes").disabled = !customShareLimit;
document.getElementById("setInactiveMinutes").disabled = !customShareLimit;
limitReachedActionsEl.disabled = !customShareLimit;
enableInputBoxes();
document.getElementById("save").disabled = !isFormValid();
};
const enableInputBoxes = () => {
document.getElementById("ratio").disabled = document.getElementById("setRatio").disabled || !document.getElementById("setRatio").checked;
document.getElementById("totalMinutes").disabled = document.getElementById("setTotalMinutes").disabled || !document.getElementById("setTotalMinutes").checked;
document.getElementById("inactiveMinutes").disabled = document.getElementById("setInactiveMinutes").disabled || !document.getElementById("setInactiveMinutes").checked;
document.getElementById("save").disabled = !isFormValid();
};
const isFormValid = () => {
return !((getSelectedRadioValue("shareLimit") === "custom") && !document.getElementById("setRatio").checked
&& !document.getElementById("setTotalMinutes").checked && !document.getElementById("setInactiveMinutes").checked);
};
</script>
</head>
<body>
<div style="padding: 10px 10px 0px 10px;">
<input type="radio" name="shareLimit" id="default" value="default" onchange="shareLimitChanged()" checked style="margin-bottom: 5px;"><label for="default">QBT_TR(Use global share limit)QBT_TR[CONTEXT=UpDownRatioDialog]</label><br>
<input type="radio" name="shareLimit" id="shareLimitNone" value="none" onchange="shareLimitChanged()" style="margin-bottom: 5px;"><label for="shareLimitNone">QBT_TR(Set no share limit)QBT_TR[CONTEXT=UpDownRatioDialog]</label><br>
<input type="radio" name="shareLimit" id="shareLimitCustom" value="custom" onchange="shareLimitChanged()" style="margin-bottom: 5px;"><label for="shareLimitCustom">QBT_TR(Set share limit to)QBT_TR[CONTEXT=UpDownRatioDialog]</label><br>
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setRatio" class="shareLimitInput" onclick="enableInputBoxes()">
<label id="ratioLabel" for="setRatio">QBT_TR(ratio)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
<input type="number" id="ratio" value="0.00" step=".01" min="0" class="shareLimitInput" aria-labelledby="ratioLabel">
</div>
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setTotalMinutes" class="shareLimitInput" onclick="enableInputBoxes()">
<label id="totalMinutesLabel" for="setTotalMinutes">QBT_TR(total minutes)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
<input type="number" id="totalMinutes" value="0" step="1" min="0" class="shareLimitInput" aria-labelledby="totalMinutesLabel">
</div>
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setInactiveMinutes" class="shareLimitInput" onclick="enableInputBoxes()">
<label id="inactiveMinutesLabel" for="setInactiveMinutes">QBT_TR(inactive minutes)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
<input type="number" id="inactiveMinutes" value="0" step="1" min="0" class="shareLimitInput" aria-labelledby="inactiveMinutesLabel">
</div>
<div style="margin-left: 40px; margin-bottom: 5px;">
<label id="actionListLabel" for="limitReachedActions">QBT_TR(Action when the limit is reached)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
<select id="limitReachedActions" aria-labelledby="actionListLabel">
<option value="Default">QBT_TR(Default)QBT_TR[CONTEXT=UpDownRatioDialog]</option>
<option value="Stop">QBT_TR(Stop torrent)QBT_TR[CONTEXT=UpDownRatioDialog]</option>
<option value="Remove">QBT_TR(Remove torrent)QBT_TR[CONTEXT=UpDownRatioDialog]</option>
<option value="RemoveWithContent">QBT_TR(Remove torrent and its content)QBT_TR[CONTEXT=UpDownRatioDialog]</option>
<option value="EnableSuperSeeding">QBT_TR(Enable super seeding for torrent)QBT_TR[CONTEXT=UpDownRatioDialog]</option>
</select>
</div>
<div style="text-align: center; padding-top: 10px;">
<input type="button" value="QBT_TR(Save)QBT_TR[CONTEXT=HttpServer]" id="save">
</div>
</div>
</body>
</html>