mirror of
https://github.com/Carve/qbittorrent-webui-cjratliff.com.git
synced 2025-02-28 07:30:36 +01:00
parent
4a190baf04
commit
7c5db5975d
@ -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
49
private/css/palette.css
Normal 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%);
|
||||
}
|
||||
}
|
231
private/css/vanillaSelectBox.css
Normal file
231
private/css/vanillaSelectBox.css
Normal 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;
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
491
private/rename_files.html
Normal 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>
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
},
|
||||
|
@ -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
@ -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');
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
Loading…
x
Reference in New Issue
Block a user