This commit is contained in:
Carve 2024-01-07 17:04:03 -05:00
parent 4a190baf04
commit 7c5db5975d
22 changed files with 1976 additions and 897 deletions

View File

@ -29,6 +29,7 @@ Required by:
left: 0;
position: absolute; /* This is also set in theme.js in order to make theme transitions smoother */
top: 0;
height: auto !important; /* fixes issues with modal height */
}
/*

49
private/css/palette.css Normal file
View File

@ -0,0 +1,49 @@
/* Adaptive color palette */
/* Default rules */
* {
--color-accent-blue: hsl(210deg 65% 55%);
--color-text-blue: hsl(210deg 100% 55%);
--color-text-orange: hsl(26deg 100% 45%);
--color-text-red: hsl(0deg 100% 65%);
--color-text-green: hsl(110deg 94% 27%);
--color-text-white: hsl(0deg 0% 100%);
--color-text-disabled: hsl(0deg 0% 60%);
--color-text-default: hsl(0deg 0% 33%);
--color-background-blue: hsl(210deg 65% 55%);
--color-background-popup: hsl(0deg 0% 100%);
--color-background-default: hsl(0deg 0% 94%);
--color-background-hover: hsl(26deg 80% 60%);
--color-border-blue: hsl(210deg 42% 48%);
--color-border-default: hsl(0deg 0% 85%);
}
:root {
color-scheme: light dark;
}
/* Light corrections */
@media (prefers-color-scheme: light) {
:root {
color-scheme: light;
}
}
/* Dark corrections */
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
* {
--color-accent-blue: hsl(210deg 42% 48%);
--color-text-blue: hsl(210deg 88.1% 73.5%);
--color-text-orange: hsl(26deg 65% 70%);
--color-text-default: hsl(0deg 0% 90%);
--color-background-blue: hsl(210deg 42% 48%);
--color-background-popup: hsl(0deg 0% 20%);
--color-background-default: hsl(0deg 0% 25%);
--color-background-hover: hsl(26deg 50% 55%);
--color-border-default: hsl(0deg 0% 33%);
}
}

View File

@ -0,0 +1,231 @@
@import url("palette.css");
.hidden-search {
display: none !important;
}
li[data-parent].closed {
display: none !important;
}
li[data-parent].open:not(.hidden-search) {
display: block !important;
}
.vsb-menu {
background-clip: padding-box;
background-color: var(--color-background-default);
border: 1px solid var(--color-border-default);
cursor: pointer;
display: block;
font-size: 11px;
position: absolute;
visibility: hidden;
z-index: 1000; /*Don't change*/
}
.vsb-js-search-zone {
min-height: 1.8em;
padding: 2px;
position: absolute;
width: 80%;
z-index: 1001; /*Don't change*/
}
.vsb-js-search-zone input {
border-radius: 4px;
height: 25px !important;
margin-left: 2px;
width: 96%;
}
.vsb-main {
display: inline-block;
position: relative;
text-align: left;
vertical-align: top; /*Don't change*/
}
.vsb-menu ul {
cursor: pointer;
list-style: none;
margin: 0;
overflow-y: auto;
padding: 0;
user-select: none;
white-space: nowrap;
}
li.disabled {
background-color: #999;
cursor: not-allowed;
opacity: 0.3;
}
li.overflow {
background-color: #999;
cursor: not-allowed;
opacity: 0.3;
}
li.short {
overflow: hidden;
text-overflow: ellipsis;
}
.vsb-main button {
border: 1px solid var(--color-border-default);
border-radius: 4px;
min-width: 120px;
padding: 6px 12px;
text-align: left;
width: 100%;
z-index: 1;
}
.vsb-main button.disabled {
cursor: not-allowed;
opacity: 0.65;
}
.vsb-main .title {
margin-right: 6px;
user-select: none;
}
.vsb-main ul {
white-space: nowrap;
}
.vsb-menu li {
font-size: 12px;
padding: 4px 26px;
}
.vsb-menu li:hover {
background-color: var(--color-background-hover);
color: var(--color-text-white);
}
.vsb-menu li.grouped-option b {
display: inline-block;
margin-left: 10px;
transform: translate(-18px);
}
.vsb-menu li.grouped-option.open span {
border-radius: 2px;
display: inline-block;
font-size: inherit;
height: 8px;
margin-top: -2px;
transform: translate(-38px) rotate(45deg);
width: 8px;
}
.vsb-menu li.grouped-option.closed span {
border-radius: 2px;
display: inline-block;
font-size: inherit;
height: 8px;
transform: translate(-38px) rotate(-45deg);
width: 8px;
}
.vsb-menu li.grouped-option i {
border: 1px solid;
border-radius: 3px;
display: inline-block;
float: left;
font-size: inherit;
font-weight: bold;
height: 11px;
margin-left: 22px;
margin-right: 2px;
margin-top: 0px;
padding: 1px 3px 2px;
width: 8px;
}
.vsb-menu li.grouped-option.checked i::after {
content: "";
display: inline-block;
float: left;
font-size: inherit;
height: 8px;
margin-left: 0px;
transform: rotate(45deg);
width: 5px;
}
.vsb-menu :not(.multi) li.active {
margin-left: 7px;
}
.vsb-menu :not(.multi) li.active::before {
border-bottom: 3px solid var(--color-border-blue);
border-radius: 2px;
border-right: 3px solid var(--color-border-blue);
content: "";
display: inline-block;
font-size: inherit;
height: 10px;
margin-left: -18px;
transform: rotate(45deg);
width: 5px;
}
.vsb-menu .multi li.grouped-option {
padding-left: 5px;
}
.vsb-menu .multi li.grouped-option:hover {
color: rgb(52 31 112);
font-weight: bold;
text-decoration: underline;
}
.vsb-menu .multi li:not(.grouped-option)::before {
background: var(--color-background-popup);
border: 1px solid;
border-radius: 3px;
content: "";
display: inline-block;
float: left;
font-size: inherit;
font-weight: bold;
margin-left: -22px;
margin-right: 2px;
margin-top: 0px;
padding: 7px;
}
.vsb-menu .multi li:not(.grouped-option).active::after {
border-bottom: 3px solid var(--color-border-blue);
border-right: 3px solid var(--color-border-blue);
content: "";
display: inline-block;
float: left;
font-size: inherit;
height: 8px;
margin-left: -18px;
margin-top: 1px;
transform: rotate(45deg);
width: 5px;
}
.caret {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px dashed;
border-top: 4px solid;
display: inline-block;
height: 0;
margin-left: 2px;
vertical-align: middle;
width: 0;
}
li[data-parent] {
padding-left: 50px !important;
}

View File

@ -80,6 +80,14 @@
<input type="checkbox" id="startTorrent" />
</td>
</tr>
<tr>
<td>
<label for="addToTopOfQueue">Add to top of queue</label>
</td>
<td>
<input type="checkbox" id="addToTopOfQueue" name="addToTopOfQueue" value="true" />
</td>
</tr>
<tr>
<td>
<label for="stopCondition">Stop condition:</label>

View File

@ -30,6 +30,7 @@
<script src="scripts/piecesbar.js?v=${CACHEID}"></script>
<script src="scripts/file-tree.js?v=${CACHEID}"></script>
<script src="scripts/dynamicTable.js?locale=${LANG}&v=${CACHEID}"></script>
<script src="scripts/rename-files.js?v=${CACHEID}"></script>
<script src="scripts/client.js?locale=${LANG}&v=${CACHEID}"></script>
<script src="scripts/contextmenu.js?locale=${LANG}&v=${CACHEID}"></script>
</head>
@ -136,8 +137,13 @@
<li class="separator"><a href="#delete"><img src="images/list-remove.svg" alt="Remove" /> Remove</a></li>
<li class="separator">
<a href="#setLocation"><img src="images/set-location.svg" alt="Set location..." /> Set location...</a>
</li>
<li>
<a href="#rename"><img src="images/edit-rename.svg" alt="Rename..." /> Rename...</a>
</li>
<li>
<a href="#renameFiles"><img src="images/edit-rename.svg" alt="Rename Files..." /> Rename Files...</a>
</li>
<li>
<a href="#Category" class="arrow-right"><img src="images/view-categories.svg" alt="Category" /> Category</a>
<ul id="contextCategoryList" class="scrollableMenu"></ul>
@ -174,6 +180,7 @@
<li><a href="#" id="copyInfohash2" class="copyToClipboard"><img src="images/hash.svg" alt="Info hash v2" /> Info hash v2</a></li>
<li><a href="#" id="copyMagnetLink" class="copyToClipboard"><img src="images/torrent-magnet.svg" alt="Magnet link" /> Magnet link</a></li>
<li><a href="#" id="copyID" class="copyToClipboard"><img src="images/help-about.svg" alt="Torrent ID" /> Torrent ID</a></li>
<li><a href="#" id="copyComment" class="copyToClipboard"><img src="images/edit-copy.svg" alt="Comment" /> Comment</a></li>
</ul>
</li>
<li>
@ -182,6 +189,7 @@
</ul>
<ul id="categoriesFilterMenu" class="contextMenu">
<li><a href="#createCategory"><img src="images/list-add.svg" alt="Add category..." /> Add category...</a></li>
<li><a href="#createSubcategory"><img src="images/list-add.svg" alt="Add subcategory..." /> Add subcategory...</a></li>
<li><a href="#editCategory"><img src="images/edit-rename.svg" alt="Edit category..." /> Edit category...</a></li>
<li><a href="#deleteCategory"><img src="images/list-remove.svg" alt="Remove category" /> Remove category</a></li>
<li><a href="#deleteUnusedCategories"><img src="images/list-remove.svg" alt="Remove unused categories" /> Remove unused categories</a></li>
@ -225,6 +233,9 @@
</ul>
</li>
</ul>
<ul id="multiRenameFilesMenu" class="contextMenu">
<li><a href="#ToggleSelection"><img src="images/edit-rename.svg" alt="Toggle Selection" /> Toggle Selection</a></li>
</ul>
<div id="desktopFooterWrapper">
<div id="desktopFooter">
<span id="error_div"></span>

View File

@ -45,6 +45,10 @@
$('savePath').set('value', window.qBittorrent.Misc.escapeHtml(uriSavePath));
$('savePath').focus();
}
else if (uriAction === "createSubcategory") {
$('categoryName').set('value', window.qBittorrent.Misc.escapeHtml(uriCategoryName));
$('categoryName').focus();
}
else {
$('categoryName').focus();
}
@ -96,6 +100,7 @@
}).send();
break;
case "create":
case "createSubcategory":
if (!verifyCategoryName(categoryName))
return;

491
private/rename_files.html Normal file
View File

@ -0,0 +1,491 @@
<!DOCTYPE html>
<html lang="${LANG}">
<head>
<meta charset="UTF-8" />
<title>Renaming</title>
<script src="scripts/lib/MooTools-Core-1.6.0-compat-compressed.js"></script>
<script src="scripts/lib/MooTools-More-1.6.0-compat-compressed.js"></script>
<script src="scripts/filesystem.js?v=${CACHEID}"></script>
<script src="scripts/misc.js?locale=${LANG}&v=${CACHEID}"></script>
<script src="scripts/file-tree.js?v=${CACHEID}"></script>
<script src="scripts/dynamicTable.js?locale=${LANG}&v=${CACHEID}"></script>
<script src="scripts/rename-files.js?v=${CACHEID}"></script>
<script>
'use strict';
if (window.parent.qBittorrent !== undefined) {
window.qBittorrent = window.parent.qBittorrent;
}
window.qBittorrent = window.parent.qBittorrent;
var TriState = window.qBittorrent.FileTree.TriState;
var data = window.MUI.Windows.instances['multiRenamePage'].options.data;
var bulkRenameFilesContextMenu;
if (!bulkRenameFilesContextMenu) {
bulkRenameFilesContextMenu = new window.qBittorrent.ContextMenu.ContextMenu({
targets: '#bulkRenameFilesTableDiv tr',
menu: 'multiRenameFilesMenu',
actions: {
ToggleSelection: function(element, ref) {
const rowId = parseInt(element.get('data-row-id'));
const row = bulkRenameFilesTable.getNode(rowId);
const checkState = row.checked == 1 ? 0 : 1;
bulkRenameFilesTable.toggleNodeTreeCheckbox(rowId, checkState);
bulkRenameFilesTable.updateGlobalCheckbox();
bulkRenameFilesTable.onRowSelectionChange(bulkRenameFilesTable.getSelectedRows());
}
},
offsets: {
x: -15,
y: 2
}
});
}
// Setup the dynamic table for bulk renaming
var bulkRenameFilesTable = new window.qBittorrent.DynamicTable.BulkRenameTorrentFilesTable();
bulkRenameFilesTable.setup('bulkRenameFilesTableDiv', 'bulkRenameFilesTableFixedHeaderDiv', bulkRenameFilesContextMenu);
// Inject checkbox into the first column of the table header
var tableHeaders = $$('#bulkRenameFilesTableFixedHeaderDiv .dynamicTableHeader th');
var checkboxHeader;
if (tableHeaders.length > 0) {
if (checkboxHeader) {
checkboxHeader.remove();
}
checkboxHeader = new Element('input');
checkboxHeader.set('type', 'checkbox');
checkboxHeader.set('id', 'rootMultiRename_cb');
checkboxHeader.addEvent('click', function(e) {
bulkRenameFilesTable.toggleGlobalCheckbox();
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
fileRenamer.update();
});
const checkboxTH = tableHeaders[0];
checkboxHeader.injectInside(checkboxTH);
}
// Register keyboard events to modal window
// https://github.com/qbittorrent/qBittorrent/pull/18687#discussion_r1135045726
var keyboard;
if (!keyboard) {
keyboard = new Keyboard({
defaultEventType: 'keydown',
events: {
'Escape': function(event) {
window.parent.closeWindows();
event.preventDefault();
},
'Esc': function(event) {
window.parent.closeWindows();
event.preventDefault();
}
}
});
keyboard.activate();
}
var fileRenamer = new window.qBittorrent.MultiRename.RenameFiles();
fileRenamer.hash = data.hash;
// Load Multi Rename Preferences
var multiRenamePrefChecked = LocalPreferences.get('multirename_rememberPreferences', "true") === "true";
$('multirename_rememberprefs_checkbox').setProperty('checked', multiRenamePrefChecked);
if (multiRenamePrefChecked) {
var multirename_search = LocalPreferences.get('multirename_search', '');
fileRenamer.setSearch(multirename_search);
$('multiRenameSearch').set('value', multirename_search);
var multirename_useRegex = LocalPreferences.get('multirename_useRegex', false);
fileRenamer.useRegex = multirename_useRegex === 'true';
$('use_regex_search').checked = fileRenamer.useRegex;
var multirename_matchAllOccurrences = LocalPreferences.get('multirename_matchAllOccurrences', false);
fileRenamer.matchAllOccurrences = multirename_matchAllOccurrences === 'true';
$('match_all_occurrences').checked = fileRenamer.matchAllOccurrences;
var multirename_caseSensitive = LocalPreferences.get('multirename_caseSensitive', false);
fileRenamer.caseSensitive = multirename_caseSensitive === 'true';
$('case_sensitive').checked = fileRenamer.caseSensitive;
var multirename_replace = LocalPreferences.get('multirename_replace', '');
fileRenamer.setReplacement(multirename_replace);
$('multiRenameReplace').set('value', multirename_replace);
var multirename_appliesTo = LocalPreferences.get('multirename_appliesTo', window.qBittorrent.MultiRename.AppliesTo.FilenameExtension);
fileRenamer.appliesTo = window.qBittorrent.MultiRename.AppliesTo[multirename_appliesTo];
$('applies_to_option').set('value', fileRenamer.appliesTo);
var multirename_includeFiles = LocalPreferences.get('multirename_includeFiles', true);
fileRenamer.includeFiles = multirename_includeFiles === 'true';
$('include_files').checked = fileRenamer.includeFiles;
var multirename_includeFolders = LocalPreferences.get('multirename_includeFolders', false);
fileRenamer.includeFolders = multirename_includeFolders === 'true';
$('include_folders').checked = fileRenamer.includeFolders;
var multirename_fileEnumerationStart = LocalPreferences.get('multirename_fileEnumerationStart', 0);
fileRenamer.fileEnumerationStart = parseInt(multirename_fileEnumerationStart);
$('file_counter').set('value', fileRenamer.fileEnumerationStart);
var multirename_replaceAll = LocalPreferences.get('multirename_replaceAll', false);
fileRenamer.replaceAll = multirename_replaceAll === 'true';
var renameButtonValue = fileRenamer.replaceAll ? 'Replace All' : 'Replace';
$('renameOptions').set('value', renameButtonValue);
$('renameButton').set('value', renameButtonValue);
}
// Fires every time a row's selection changes
bulkRenameFilesTable.onRowSelectionChange = function(row) {
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
fileRenamer.update();
};
// Setup Search Events that control renaming
$('multiRenameSearch').addEvent('input', function(e) {
let sanitized = e.target.value.replace(/\n/g, '');
$('multiRenameSearch').set('value', sanitized);
// Search input has changed
$('multiRenameSearch').style['border-color'] = '';
LocalPreferences.set('multirename_search', sanitized);
fileRenamer.setSearch(sanitized);
});
$('use_regex_search').addEvent('change', function(e) {
fileRenamer.useRegex = e.target.checked;
LocalPreferences.set('multirename_useRegex', e.target.checked);
fileRenamer.update();
});
$('match_all_occurrences').addEvent('change', function(e) {
fileRenamer.matchAllOccurrences = e.target.checked;
LocalPreferences.set('multirename_matchAllOccurrences', e.target.checked);
fileRenamer.update();
});
$('case_sensitive').addEvent('change', function(e) {
fileRenamer.caseSensitive = e.target.checked;
LocalPreferences.set('multirename_caseSensitive', e.target.checked);
fileRenamer.update();
});
/**
* Fires every time the filerenamer gets changed, it will update all the rows in the table
*/
fileRenamer.onChanged = function(matchedRows) {
// Clear renamed column
document
.querySelectorAll("span[id^='filesTablefileRenamed']")
.forEach(function(span) {
span.set('text', "");
});
// Update renamed column for matched rows
for (let i = 0; i < matchedRows.length; ++i) {
const row = matchedRows[i];
$('filesTablefileRenamed' + row.rowId).set('text', row.renamed);
}
};
fileRenamer.onInvalidRegex = function(err) {
$('multiRenameSearch').style['border-color'] = '#CC0033';
};
// Setup Replace Events that control renaming
$('multiRenameReplace').addEvent('input', function(e) {
let sanitized = e.target.value.replace(/\n/g, '');
$('multiRenameReplace').set('value', sanitized);
// Replace input has changed
$('multiRenameReplace').style['border-color'] = '';
LocalPreferences.set('multirename_replace', sanitized);
fileRenamer.setReplacement(sanitized);
});
$('applies_to_option').addEvent('change', function(e) {
fileRenamer.appliesTo = e.target.value;
LocalPreferences.set('multirename_appliesTo', e.target.value);
fileRenamer.update();
});
$('include_files').addEvent('change', function(e) {
fileRenamer.includeFiles = e.target.checked;
LocalPreferences.set('multirename_includeFiles', e.target.checked);
fileRenamer.update();
});
$('include_folders').addEvent('change', function(e) {
fileRenamer.includeFolders = e.target.checked;
LocalPreferences.set('multirename_includeFolders', e.target.checked);
fileRenamer.update();
});
$('file_counter').addEvent('input', function(e) {
let value = e.target.valueAsNumber;
if (!value) { value = 0; }
if (value < 0) { value = 0; }
if (value > 99999999) { value = 99999999; }
fileRenamer.fileEnumerationStart = value;
$('file_counter').set('value', value);
LocalPreferences.set('multirename_fileEnumerationStart', value);
fileRenamer.update();
});
// Setup Rename Operation Events
$('renameButton').addEvent('click', function(e) {
// Disable Search Options
$('multiRenameSearch').disabled = true;
$('use_regex_search').disabled = true;
$('match_all_occurrences').disabled = true;
$('case_sensitive').disabled = true;
// Disable Replace Options
$('multiRenameReplace').disabled = true;
$('applies_to_option').disabled = true;
$('include_files').disabled = true;
$('include_folders').disabled = true;
$('file_counter').disabled = true;
// Disable Rename Buttons
$('renameButton').disabled = true;
$('renameOptions').disabled = true;
// Clear error text
$('rename_error').set('text', '');
fileRenamer.rename();
});
fileRenamer.onRenamed = function(rows) {
// Disable Search Options
$('multiRenameSearch').disabled = false;
$('use_regex_search').disabled = false;
$('match_all_occurrences').disabled = false;
$('case_sensitive').disabled = false;
// Disable Replace Options
$('multiRenameReplace').disabled = false;
$('applies_to_option').disabled = false;
$('include_files').disabled = false;
$('include_folders').disabled = false;
$('file_counter').disabled = false;
// Disable Rename Buttons
$('renameButton').disabled = false;
$('renameOptions').disabled = false;
// Recreate table
let selectedRows = bulkRenameFilesTable.getSelectedRows().map(row => row.rowId.toString());
for (let renamedRow of rows) {
selectedRows = selectedRows.filter(selectedRow => selectedRow !== renamedRow.rowId.toString());
}
bulkRenameFilesTable.clear();
// Adjust file enumeration count by 1 when replacing single files to prevent naming conflicts
if (!fileRenamer.replaceAll) {
fileRenamer.fileEnumerationStart++;
$('file_counter').set('value', fileRenamer.fileEnumerationStart);
}
setupTable(selectedRows);
};
fileRenamer.onRenameError = function(err, row) {
if (err.xhr.status === 409) {
$('rename_error').set('text', `Rename failed: file or folder already exists \`${row.renamed}\``);
}
};
$('renameOptions').addEvent('change', function(e) {
const combobox = e.target;
const replaceOperation = combobox.value;
if (replaceOperation == "Replace") {
fileRenamer.replaceAll = false;
}
else if (replaceOperation == "Replace All") {
fileRenamer.replaceAll = true;
}
else {
fileRenamer.replaceAll = false;
}
LocalPreferences.set('multirename_replaceAll', fileRenamer.replaceAll);
$('renameButton').set('value', replaceOperation);
});
$('closeButton').addEvent('click', function() {
window.parent.closeWindows();
event.preventDefault();
});
// synchronize header scrolling to table body
$('bulkRenameFilesTableDiv').onscroll = function() {
const length = $(this).scrollLeft;
$('bulkRenameFilesTableFixedHeaderDiv').scrollLeft = length;
};
var handleTorrentFiles = function(files, selectedRows) {
const rows = files.map(function(file, index) {
const row = {
fileId: index,
checked: 1, // unchecked
path: file.name,
original: window.qBittorrent.Filesystem.fileName(file.name),
renamed: "",
size: file.size
};
return row;
});
addRowsToTable(rows, selectedRows);
};
var addRowsToTable = function(rows, selectedRows) {
let rowId = 0;
const rootNode = new window.qBittorrent.FileTree.FolderNode();
rootNode.autoCheckFolders = false;
rows.forEach(function(row) {
const pathItems = row.path.split(window.qBittorrent.Filesystem.PathSeparator);
pathItems.pop(); // remove last item (i.e. file name)
let parent = rootNode;
pathItems.forEach(function(folderName) {
if (folderName === '.unwanted') {
return;
}
let folderNode = null;
if (parent.children !== null) {
for (let i = 0; i < parent.children.length; ++i) {
const childFolder = parent.children[i];
if (childFolder.original === folderName) {
folderNode = childFolder;
break;
}
}
}
if (folderNode === null) {
folderNode = new window.qBittorrent.FileTree.FolderNode();
folderNode.autoCheckFolders = false;
folderNode.rowId = rowId;
folderNode.path = (parent.path === "")
? folderName
: [parent.path, folderName].join(window.qBittorrent.Filesystem.PathSeparator);
folderNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
folderNode.original = folderName;
folderNode.renamed = "";
folderNode.root = parent;
parent.addChild(folderNode);
++rowId;
}
parent = folderNode;
});
const childNode = new window.qBittorrent.FileTree.FileNode();
childNode.rowId = rowId;
childNode.path = row.path;
childNode.checked = selectedRows.includes(rowId.toString()) ? 0 : 1;
childNode.original = row.original;
childNode.renamed = "";
childNode.root = parent;
childNode.data = row;
parent.addChild(childNode);
++rowId;
});
bulkRenameFilesTable.populateTable(rootNode);
bulkRenameFilesTable.updateTable(false);
bulkRenameFilesTable.altRow();
if (selectedRows !== undefined) {
bulkRenameFilesTable.reselectRows(selectedRows);
}
fileRenamer.selectedFiles = bulkRenameFilesTable.getSelectedRows();
fileRenamer.update();
};
var setupTable = function(selectedRows) {
new Request.JSON({
url: new URI('api/v2/torrents/files?hash=' + data.hash),
noCache: true,
method: 'get',
onSuccess: function(files) {
if (files.length === 0) {
bulkRenameFilesTable.clear();
}
else {
handleTorrentFiles(files, selectedRows);
}
}
}).send();
};
setupTable(data.selectedRows);
</script>
</head>
<body style="min-width: 400px; min-height: 300px;">
<div style="padding: 0px 10px 0px 0px;">
<div style="float: left; height: 100%; width: 228px;">
<div class="formRow">
<input type="checkbox" id="multirename_rememberprefs_checkbox" onchange="LocalPreferences.set('multirename_rememberPreferences', this.checked);" />
<label for="multirename_rememberprefs_checkbox">Remember Multi-Rename settings</label>
</div>
<hr>
<textarea id="multiRenameSearch" placeholder="Search Files" style="width: calc(100% - 8px); resize: vertical; min-height: 30px;"></textarea>
<div class="formRow">
<input type="checkbox" id="use_regex_search" />
<label for="use_regex_search">Use regular expressions</label>
</div>
<div class="formRow">
<input type="checkbox" id="match_all_occurrences" />
<label for="match_all_occurrences">Match all occurrences</label>
</div>
<div class="formRow">
<input type="checkbox" id="case_sensitive" />
<label for="case_sensitive">Case sensitive</label>
</div>
<hr>
<textarea id="multiRenameReplace" placeholder="Replacement Input" style="width: calc(100% - 8px); resize: vertical; min-height: 30px;"></textarea>
<select id="applies_to_option" name="applies_to_option" style="width: 100%; margin-bottom: 5px;">
<option selected value="FilenameExtension">Filename + Extension</option>
<option value="Filename">Filename</option>
<option value="Extension">Extension</option>
</select>
<div class="formRow">
<input type="checkbox" id="include_files" checked />
<label for="include_files">Include files</label>
</div>
<div class="formRow">
<input type="checkbox" id="include_folders" />
<label for="include_folders">Include folders</label>
</div>
<div class="formRow">
<input type="number" min="0" max="99999999" value="0" id="file_counter" style="width: 80px;" />
<label for="file_counter">Enumerate Files</label>
</div>
</div>
<div id="operation_btns" style="position: absolute; left: 0; bottom: 0; margin: 0px 12px 36px 12px; width: 228px;background: #ffffff;padding: 0px 5px 10px 0px;">
<div style="overflow: auto;">
<span id="rename_error" style="float: unset; font-size: unset;"></span>
</div>
<hr>
<div style="width: 60%; float: left;">
<input id="renameButton" type="button" value="Replace" style="float: left; width: 86px;">
<select id="renameOptions" name="renameOptions" style="width: 22px;">
<option selected value="Replace">Replace</option>
<option value="Replace All">Replace All</option>
</select>
</div>
<input id="closeButton" type="button" value="Close" style="float: right; width: 30%;">
</div>
<div id="torrentFiles" class="panel" style="position: absolute; top: 0; right: 0; bottom: 0; left: 228px; margin: 35px 10px 45px 20px; border-bottom: 0">
<div id="bulkRenameFilesTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
<table class="dynamicTable">
<thead>
<tr class="dynamicTableHeader"></tr>
</thead>
</table>
</div>
<div id="bulkRenameFilesTableDiv" class="dynamicTableDiv">
<table class="dynamicTable">
<thead>
<tr class="dynamicTableHeader"></tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@ -273,6 +273,7 @@ window.addEvent('load', function() {
$("stalled_uploading_filter").removeClass("selectedFilter");
$("stalled_downloading_filter").removeClass("selectedFilter");
$("checking_filter").removeClass("selectedFilter");
$("moving_filter").removeClass("selectedFilter");
$("errored_filter").removeClass("selectedFilter");
$(f + "_filter").addClass("selectedFilter");
selected_filter = f;
@ -446,6 +447,7 @@ window.addEvent('load', function() {
updateFilter('stalled_uploading', 'Stalled Uploading (%1)');
updateFilter('stalled_downloading', 'Stalled Downloading (%1)');
updateFilter('checking', 'Checking (%1)');
updateFilter('moving', 'Moving (%1)');
updateFilter('errored', 'Errored (%1)');
};
@ -453,7 +455,7 @@ window.addEvent('load', function() {
const categoryList = $('categoryFilterList');
if (!categoryList)
return;
categoryList.empty();
categoryList.getChildren().each(c => c.destroy());
const create_link = function(hash, text, count) {
let display_name = text;
@ -488,7 +490,19 @@ window.addEvent('load', function() {
Object.each(category_list, function(category) {
sortedCategories.push(category.name);
});
sortedCategories.sort();
sortedCategories.sort((leftCategory, rightCategory) => {
const leftSegments = leftCategory.split('/');
const rightSegments = rightCategory.split('/');
for (let i = 0, iMax = Math.min(leftSegments.length, rightSegments.length); i < iMax; ++i) {
const compareResult = window.qBittorrent.Misc.naturalSortCollator.compare(
leftSegments[i], rightSegments[i]);
if (compareResult !== 0)
return compareResult;
}
return leftSegments.length - rightSegments.length;
});
for (let i = 0; i < sortedCategories.length; ++i) {
const categoryName = sortedCategories[i];
@ -526,8 +540,7 @@ window.addEvent('load', function() {
if (tagFilterList === null)
return;
while (tagFilterList.firstChild !== null)
tagFilterList.removeChild(tagFilterList.firstChild);
tagFilterList.getChildren().each(c => c.destroy());
const createLink = function(hash, text, count) {
const html = '<a href="#" onclick="setTagFilter(' + hash + ');return false;">'
@ -580,8 +593,7 @@ window.addEvent('load', function() {
if (trackerFilterList === null)
return;
while (trackerFilterList.firstChild !== null)
trackerFilterList.removeChild(trackerFilterList.firstChild);
trackerFilterList.getChildren().each(c => c.destroy());
const createLink = function(hash, text, count) {
const html = '<a href="#" onclick="setTrackerFilter(' + hash + ');return false;">'
@ -1200,7 +1212,7 @@ window.addEvent('load', function() {
loadMethod: 'xhr',
contentURL: 'views/log.html',
require: {
css: ['css/lib/vanillaSelectBox.css'],
css: ['css/vanillaSelectBox.css'],
js: ['scripts/lib/vanillaSelectBox.js'],
},
tabsURL: 'views/logTabs.html',
@ -1512,6 +1524,8 @@ function setupCopyEventHandler() {
return copyMagnetLinkFN();
case "copyID":
return copyIdFN();
case "copyComment":
return copyCommentFN();
default:
return "";
}

File diff suppressed because it is too large Load Diff

View File

@ -816,8 +816,7 @@ window.qBittorrent.DynamicTable = (function() {
let rowPos = rows.length;
while ((rowPos < trs.length) && (trs.length > 0)) {
trs[trs.length - 1].dispose();
trs.pop();
trs.pop().destroy();
}
},
@ -839,7 +838,7 @@ window.qBittorrent.DynamicTable = (function() {
this.selectedRows.erase(rowId);
const tr = this.getTrByRowId(rowId);
if (tr !== null) {
tr.dispose();
tr.destroy();
this.rows.erase(rowId);
return true;
}
@ -851,8 +850,7 @@ window.qBittorrent.DynamicTable = (function() {
this.rows.empty();
const trs = this.tableBody.getElements('tr');
while (trs.length > 0) {
trs[trs.length - 1].dispose();
trs.pop();
trs.pop().destroy();
}
},
@ -945,6 +943,7 @@ window.qBittorrent.DynamicTable = (function() {
this.newColumn('seen_complete', '', 'Last Seen Complete', 100, false);
this.newColumn('last_activity', '', 'Last Activity', 100, false);
this.newColumn('availability', '', 'Availability', 100, false);
this.newColumn('reannounce', '', 'Reannounce In', 100, false);
this.columns['state_icon'].onclick = '';
this.columns['state_icon'].dataProperties[0] = 'state';
@ -1001,10 +1000,14 @@ window.qBittorrent.DynamicTable = (function() {
case "checkingUP":
case "queuedForChecking":
case "checkingResumeData":
case "moving":
state = "force-recheck";
img_path = "images/force-recheck.svg";
break;
case "moving":
state = "moving";
img_path = "images/set-location.svg";
break;
case "error":
case "unknown":
case "missingFiles":
state = "error";
@ -1331,6 +1334,13 @@ window.qBittorrent.DynamicTable = (function() {
td.set('text', value);
td.set('title', value);
};
// reannounce
this.columns['reannounce'].updateTd = function(td, row) {
const time = window.qBittorrent.Misc.friendlyDuration(this.getRowValue(row));
td.set('text', time);
td.set('title', time);
};
},
applyFilter: function(row, filterName, categoryHash, tagHash, trackerHash, filterTerms) {
@ -1387,6 +1397,10 @@ window.qBittorrent.DynamicTable = (function() {
if (state !== 'checkingUP' && state !== 'checkingDL' && state !== 'checkingResumeData')
return false;
break;
case 'moving':
if (state !== 'moving')
return false;
break;
case 'errored':
if (state != 'error' && state != "unknown" && state != "missingFiles")
return false;
@ -1567,7 +1581,7 @@ window.qBittorrent.DynamicTable = (function() {
if (!country_code) {
if (td.getChildren('img').length > 0)
td.getChildren('img')[0].dispose();
td.getChildren('img')[0].destroy();
return;
}

View File

@ -2262,7 +2262,8 @@ MUI.Window = new Class({
'styles': {
'position': 'absolute', // This is set here to make theme transitions smoother
'top': 0,
'left': 0
'left': 0,
'height': 'auto'
}
}).inject(this.windowEl);

View File

@ -89,6 +89,7 @@ let copyNameFN = function() {};
let copyInfohashFN = function(policy) {};
let copyMagnetLinkFN = function() {};
let copyIdFN = function() {};
let copyCommentFN = function() {};
let setQueuePositionFN = function() {};
let exportTorrentFN = function() {};
@ -348,7 +349,7 @@ const initializeWindows = function() {
const id = 'statisticspage';
new MochaUI.Window({
id: id,
title: 'Statistics',
title: 'Statistics]',
loadMethod: 'xhr',
contentURL: new URI("views/statistics.html").toString(),
maximizable: false,
@ -1005,6 +1006,21 @@ const initializeWindows = function() {
return torrentsTable.selectedRowsIds().join("\n");
};
copyCommentFN = function() {
const selectedRows = torrentsTable.selectedRowsIds();
const comments = [];
if (selectedRows.length > 0) {
const rows = torrentsTable.getFilteredAndSortedRows();
for (let i = 0; i < selectedRows.length; ++i) {
const hash = selectedRows[i];
const comment = rows[hash].full_data.comment;
if (comment && (comment !== ""))
comments.push(comment);
}
}
return comments.join("\n---------\n");
};
exportTorrentFN = async function() {
const hashes = torrentsTable.selectedRowsIds();
for (const hash of hashes) {

View File

@ -173,7 +173,7 @@ window.qBittorrent.PropFiles = (function() {
elem.set('value', priority.toString());
elem.set('html', html);
if (selected)
elem.setAttribute('selected', '');
elem.selected = true;
return elem;
};

View File

@ -50,8 +50,7 @@ window.qBittorrent.PropWebseeds = (function() {
removeRow: function(url) {
if (this.rows.has(url)) {
const tr = this.rows.get(url);
tr.dispose();
this.rows.get(url).destroy();
this.rows.erase(url);
return true;
}

View File

@ -40,16 +40,19 @@
const values = {
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
seedingTimeLimit: parseInt(origValues[1]),
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[2], 2),
maxSeedingTime: parseInt(origValues[3])
inactiveSeedingTimeLimit: parseInt(origValues[2]),
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[3], 2),
maxSeedingTime: parseInt(origValues[4]),
maxInactiveSeedingTime: parseInt(origValues[5])
};
// select default when orig values not passed. using double equals to compare string and int
if ((origValues[0] === "") || ((values.ratioLimit == UseGlobalLimit) && (values.seedingTimeLimit == UseGlobalLimit))) {
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)) {
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
}
@ -60,8 +63,12 @@
$('ratio').set('value', values.ratioLimit);
}
if (values.seedingTimeLimit >= 0) {
$('setMinutes').set('checked', true);
$('minutes').set('value', values.seedingTimeLimit);
$('setTotalMinutes').set('checked', true);
$('totalMinutes').set('value', values.seedingTimeLimit);
}
if (values.inactiveSeedingTimeLimit >= 0) {
$('setInactiveMinutes').set('checked', true);
$('inactiveMinutes').set('value', values.inactiveSeedingTimeLimit);
}
}
@ -78,16 +85,18 @@
const shareLimit = getSelectedRadioValue('shareLimit');
let ratioLimitValue = 0.00;
let seedingTimeLimitValue = 0;
let inactiveSeedingTimeLimitValue = 0;
if (shareLimit === 'default') {
ratioLimitValue = seedingTimeLimitValue = UseGlobalLimit;
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = UseGlobalLimit;
}
else if (shareLimit === 'none') {
ratioLimitValue = seedingTimeLimitValue = NoLimit;
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = NoLimit;
}
else if (shareLimit === 'custom') {
ratioLimitValue = $('setRatio').get('checked') ? $('ratio').get('value') : -1;
seedingTimeLimitValue = $('setMinutes').get('checked') ? $('minutes').get('value') : -1;
seedingTimeLimitValue = $('setTotalMinutes').get('checked') ? $('totalMinutes').get('value') : -1;
inactiveSeedingTimeLimitValue = $('setInactiveMinutes').get('checked') ? $('inactiveMinutes').get('value') : -1;
}
else {
return false;
@ -99,7 +108,8 @@
data: {
hashes: hashesList.join('|'),
ratioLimit: ratioLimitValue,
seedingTimeLimit: seedingTimeLimitValue
seedingTimeLimit: seedingTimeLimitValue,
inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue
},
onComplete: function() {
window.parent.closeWindows();
@ -132,7 +142,8 @@
function shareLimitChanged() {
const customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
$('setRatio').set('disabled', !customShareLimit);
$('setMinutes').set('disabled', !customShareLimit);
$('setTotalMinutes').set('disabled', !customShareLimit);
$('setInactiveMinutes').set('disabled', !customShareLimit);
enableInputBoxes();
@ -141,22 +152,24 @@
function enableInputBoxes() {
$('ratio').set('disabled', ($('setRatio').get('disabled') || !$('setRatio').get('checked')));
$('minutes').set('disabled', ($('setMinutes').get('disabled') || !$('setMinutes').get('checked')));
$('totalMinutes').set('disabled', ($('setTotalMinutes').get('disabled') || !$('setTotalMinutes').get('checked')));
$('inactiveMinutes').set('disabled', ($('setInactiveMinutes').get('disabled') || !$('setInactiveMinutes').get('checked')));
$('save').set('disabled', !isFormValid());
}
function isFormValid() {
return !((getSelectedRadioValue('shareLimit') === 'custom') && !$('setRatio').get('checked') && !$('setMinutes').get('checked'));
return !((getSelectedRadioValue('shareLimit') === 'custom') && !$('setRatio').get('checked')
&& !$('setTotalMinutes').get('checked') && !$('setInactiveMinutes').get('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;" />Use global share limit</br>
<input type="radio" name="shareLimit" value="none" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />Set no share limit</br>
<input type="radio" name="shareLimit" value="custom" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />Set share limit to</br>
<input type="radio" name="shareLimit" id="default" value="default" onchange="shareLimitChanged()" checked style="margin-bottom: 5px;" />Use global share limit<br />
<input type="radio" name="shareLimit" value="none" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />Set no share limit<br />
<input type="radio" name="shareLimit" value="custom" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />Set share limit to<br />
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setRatio" class="shareLimitInput" onclick="enableInputBoxes()" />
@ -164,12 +177,17 @@
<input type="number" id="ratio" value="0.00" step=".01" min="0" max="9999" class="shareLimitInput" />
</div>
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
<label for="setMinutes">minutes</label>
<input type="number" id="minutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
<input type="checkbox" id="setTotalMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
<label for="setTotalMinutes">total minutes</label>
<input type="number" id="totalMinutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
</div>
<div style="margin-left: 40px; margin-bottom: 5px;">
<input type="checkbox" id="setInactiveMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
<label for="setInactiveMinutes">inactive minutes</label>
<input type="number" id="inactiveMinutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
</div>
<div style="text-align: center; padding-top: 10px;">
<input class="button" type="button" value="Save" id="save" />
<input type="button" value="Save" id="save" />
</div>
</div>
</body>

View File

@ -12,24 +12,21 @@
</head>
<body>
<iframe id="upload_frame" name="upload_frame" class="invisible" src="about:blank"></iframe>
<iframe id="upload_frame" name="upload_frame" class="invisible" title="" src="about:blank"></iframe>
<form action="api/v2/torrents/add" enctype="multipart/form-data" method="post" id="uploadForm" style="text-align: center;" target="upload_frame" autocorrect="off" autocapitalize="none">
<div style="margin-top: 25px; display: inline-block; border: 1px solid lightgrey; border-radius: 4px;">
<label class="custom-file-upload">
<input type="file" class="fileselect" id="fileselect" accept="application/x-bittorrent, .torrent" name="fileselect[]" multiple />
Upload Files
</label>
<input type="file" id="fileselect" accept=".torrent, application/x-bittorrent" name="fileselect[]" multiple />
</div>
<fieldset class="settings" style="border: 0; text-align: left; margin-top: 12px;">
<table style="margin: auto;">
<tr>
<td>
<label for="autoTMM">Torrent Management Mode:</label>
<label for="autoTMM">(Torrent Management Mode:</label>
</td>
<td>
<select id="autoTMM" name="autoTMM" onchange="qBittorrent.Download.changeTMM(this)">
<option selected value="false">Manual</option>
<option value="true">Automatic</option>
<option selected value="false">(Manual</option>
<option value="true">(Automatic</option>
</select>
</td>
</tr>
@ -73,7 +70,15 @@
</tr>
<tr>
<td>
<label for="stopCondition">Stop condition:</label>
<label for="addToTopOfQueue">(Add to top of queue</label>
</td>
<td>
<input type="checkbox" id="addToTopOfQueue" name="addToTopOfQueue" value="true" />
</td>
</tr>
<tr>
<td>
<label for="stopCondition">(Stop condition:</label>
</td>
<td>
<select id="stopCondition" name="stopCondition">
@ -162,6 +167,10 @@
if (submitted)
window.parent.closeWindows();
});
if ((Browser.platform === 'ios') || ((Browser.platform === 'mac') && (navigator.maxTouchPoints > 1))) {
$('fileselect').accept = ".torrent";
}
</script>
<div id="upload_spinner" class="mochaSpinner"></div>
</body>

View File

@ -15,6 +15,7 @@
<li id="stalled_uploading_filter"><a href="#" onclick="setFilter('stalled_uploading');return false;"><img src="images/stalledUP.svg" alt="Stalled Uploading" />Stalled Uploading (0)</a></li>
<li id="stalled_downloading_filter"><a href="#" onclick="setFilter('stalled_downloading');return false;"><img src="images/stalledDL.svg" alt="Stalled Downloading" />Stalled Downloading (0)</a></li>
<li id="checking_filter"><a href="#" onclick="setFilter('checking'); return false;"><img src="images/force-recheck.svg" alt="Checking" />Checking (0)</a></li>
<li id="moving_filter"><a href="#" onclick="setFilter('moving'); return false;"><img src="images/set-location.svg" alt="Moving" />Moving (0)</a></li>
<li id="errored_filter"><a href="#" onclick="setFilter('errored');return false;"><img src="images/error.svg" alt="Errored" />Errored (0)</a></li>
</ul>
</div>
@ -63,6 +64,9 @@
createCategory: function(element, ref) {
createCategoryFN();
},
createSubcategory: function(element, ref) {
createSubcategoryFN(element.id);
},
editCategory: function(element, ref) {
editCategoryFN(element.id);
},

View File

@ -191,10 +191,10 @@
const init = () => {
$('logLevelSelect').getElements('option').each((x) => {
if (selectedLogLevels.indexOf(x.value.toString()) !== -1) {
x.setAttribute('selected', '');
x.selected = true;
}
else {
x.removeAttribute('selected');
x.selected = false;
}
});
@ -424,4 +424,6 @@
return exports();
})();
Object.freeze(window.qBittorrent.Log);
</script>

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
<!-- preferences -->
<div class="toolbarTabs">
<ul id="preferencesTabs" class="tab-menu">
<li id="PrefDownloadsLink" class="selected"><a>Downloads</a></li>
<li id="PrefBehaviorLink" class="selected"><a>Behavior</a></li>
<li id="PrefDownloadsLink"><a>Downloads</a></li>
<li id="PrefConnectionLink"><a>Connection</a></li>
<li id="PrefSpeedLink"><a>Speed</a></li>
<li id="PrefBittorrentLink"><a>BitTorrent</a></li>
@ -19,6 +20,10 @@
// Tabs
MochaUI.initializeTabs('preferencesTabs');
$('PrefBehaviorLink').addEvent('click', function(e) {
$$('.PrefTab').addClass('invisible');
$('BehaviorTab').removeClass('invisible');
});
$('PrefDownloadsLink').addEvent('click', function(e) {
$$('.PrefTab').addClass('invisible');
$('DownloadsTab').removeClass('invisible');

View File

@ -211,7 +211,16 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
</select>
</td>
</tr>
<tr>
<td>
<label class="noWrap">Add Tags:</label>
</td>
<td class="fullWidth">
<input type="text" id="ruleAddTags" class="fullWidth" autocapitalize="none" autocorrect="off" />
</td>
</tr>
</table>
<div class="formRow">
<input disabled type="checkbox" id="savetoDifferentDir" />
<label for="savetoDifferentDir">Save to a Different Directory</label>
@ -580,6 +589,16 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
rulesList[rule].assignedCategory = $('assignCategoryCombobox').value;
rulesList[rule].savePath = $('savetoDifferentDir').checked ? $('saveToText').value : '';
rulesList[rule].ignoreDays = parseInt($('ignoreDaysValue').value);
rulesList[rule].affectedFeeds = rssDownloaderFeedSelectionTable.rows.filter((row) => row.full_data.checked)
.map((row) => row.full_data.url)
.getValues();
rulesList[rule].torrentParams.category = $('assignCategoryCombobox').value;
rulesList[rule].torrentParams.tags = $('ruleAddTags').value.split(',');
if ($('savetoDifferentDir').checked) {
rulesList[rule].torrentParams.save_path = $('saveToText').value;
rulesList[rule].torrentParams.use_auto_tmm = false;
}
switch ($('addPausedCombobox').value) {
case 'default':
@ -666,6 +685,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
$('episodeFilterText').disabled = true;
$('useSmartFilter').disabled = true;
$('assignCategoryCombobox').disabled = true;
$('ruleAddTags').disabled = true;
$('savetoDifferentDir').disabled = true;
$('saveToText').disabled = true;
$('ignoreDaysValue').disabled = true;
@ -679,6 +699,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
$('episodeFilterText').value = '';
$('useSmartFilter').checked = false;
$('assignCategoryCombobox').value = 'default';
$('ruleAddTags').value = '';
$('savetoDifferentDir').checked = false;
$('saveToText').value = '';
$('ignoreDaysValue').value = 0;
@ -701,6 +722,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
$('episodeFilterText').disabled = false;
$('useSmartFilter').disabled = false;
$('assignCategoryCombobox').disabled = false;
$('ruleAddTags').disabled = false;
$('savetoDifferentDir').disabled = false;
$('savetoDifferentDir').checked = rulesList[ruleName].savePath ? false : true;
$('saveToText').disabled = rulesList[ruleName].savePath ? false : true;

View File

@ -48,13 +48,13 @@ function submitLoginForm() {
if ((xhr.status === 200) && (xhr.responseText === "Ok."))
location.reload(true);
else
errorMsgElement.textContent = 'QBT_TR(Invalid Username or Password.)QBT_TR[CONTEXT=HttpServer]';
errorMsgElement.textContent = 'Invalid Username or Password.';
}
});
xhr.addEventListener('error', function() {
errorMsgElement.textContent = (xhr.responseText !== "")
? xhr.responseText
: 'QBT_TR(Unable to log in, qBittorrent is probably unreachable.)QBT_TR[CONTEXT=HttpServer]';
: 'Unable to log in, qBittorrent is probably unreachable.';
});
const usernameElement = document.getElementById('username');