mirror of
https://github.com/Carve/qbittorrent-webui-cjratliff.com.git
synced 2025-02-28 15:40:28 +01:00
parent
4a190baf04
commit
7c5db5975d
@ -29,6 +29,7 @@ Required by:
|
|||||||
left: 0;
|
left: 0;
|
||||||
position: absolute; /* This is also set in theme.js in order to make theme transitions smoother */
|
position: absolute; /* This is also set in theme.js in order to make theme transitions smoother */
|
||||||
top: 0;
|
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" />
|
<input type="checkbox" id="startTorrent" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="stopCondition">Stop condition:</label>
|
<label for="stopCondition">Stop condition:</label>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<script src="scripts/piecesbar.js?v=${CACHEID}"></script>
|
<script src="scripts/piecesbar.js?v=${CACHEID}"></script>
|
||||||
<script src="scripts/file-tree.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/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/client.js?locale=${LANG}&v=${CACHEID}"></script>
|
||||||
<script src="scripts/contextmenu.js?locale=${LANG}&v=${CACHEID}"></script>
|
<script src="scripts/contextmenu.js?locale=${LANG}&v=${CACHEID}"></script>
|
||||||
</head>
|
</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="#delete"><img src="images/list-remove.svg" alt="Remove" /> Remove</a></li>
|
||||||
<li class="separator">
|
<li class="separator">
|
||||||
<a href="#setLocation"><img src="images/set-location.svg" alt="Set location..." /> Set location...</a>
|
<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>
|
<a href="#rename"><img src="images/edit-rename.svg" alt="Rename..." /> Rename...</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#renameFiles"><img src="images/edit-rename.svg" alt="Rename Files..." /> Rename Files...</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#Category" class="arrow-right"><img src="images/view-categories.svg" alt="Category" /> Category</a>
|
<a href="#Category" class="arrow-right"><img src="images/view-categories.svg" alt="Category" /> Category</a>
|
||||||
<ul id="contextCategoryList" class="scrollableMenu"></ul>
|
<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="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="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="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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -182,6 +189,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<ul id="categoriesFilterMenu" class="contextMenu">
|
<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="#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="#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="#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>
|
<li><a href="#deleteUnusedCategories"><img src="images/list-remove.svg" alt="Remove unused categories" /> Remove unused categories</a></li>
|
||||||
@ -225,6 +233,9 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</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="desktopFooterWrapper">
|
||||||
<div id="desktopFooter">
|
<div id="desktopFooter">
|
||||||
<span id="error_div"></span>
|
<span id="error_div"></span>
|
||||||
|
@ -45,6 +45,10 @@
|
|||||||
$('savePath').set('value', window.qBittorrent.Misc.escapeHtml(uriSavePath));
|
$('savePath').set('value', window.qBittorrent.Misc.escapeHtml(uriSavePath));
|
||||||
$('savePath').focus();
|
$('savePath').focus();
|
||||||
}
|
}
|
||||||
|
else if (uriAction === "createSubcategory") {
|
||||||
|
$('categoryName').set('value', window.qBittorrent.Misc.escapeHtml(uriCategoryName));
|
||||||
|
$('categoryName').focus();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$('categoryName').focus();
|
$('categoryName').focus();
|
||||||
}
|
}
|
||||||
@ -96,6 +100,7 @@
|
|||||||
}).send();
|
}).send();
|
||||||
break;
|
break;
|
||||||
case "create":
|
case "create":
|
||||||
|
case "createSubcategory":
|
||||||
if (!verifyCategoryName(categoryName))
|
if (!verifyCategoryName(categoryName))
|
||||||
return;
|
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_uploading_filter").removeClass("selectedFilter");
|
||||||
$("stalled_downloading_filter").removeClass("selectedFilter");
|
$("stalled_downloading_filter").removeClass("selectedFilter");
|
||||||
$("checking_filter").removeClass("selectedFilter");
|
$("checking_filter").removeClass("selectedFilter");
|
||||||
|
$("moving_filter").removeClass("selectedFilter");
|
||||||
$("errored_filter").removeClass("selectedFilter");
|
$("errored_filter").removeClass("selectedFilter");
|
||||||
$(f + "_filter").addClass("selectedFilter");
|
$(f + "_filter").addClass("selectedFilter");
|
||||||
selected_filter = f;
|
selected_filter = f;
|
||||||
@ -446,6 +447,7 @@ window.addEvent('load', function() {
|
|||||||
updateFilter('stalled_uploading', 'Stalled Uploading (%1)');
|
updateFilter('stalled_uploading', 'Stalled Uploading (%1)');
|
||||||
updateFilter('stalled_downloading', 'Stalled Downloading (%1)');
|
updateFilter('stalled_downloading', 'Stalled Downloading (%1)');
|
||||||
updateFilter('checking', 'Checking (%1)');
|
updateFilter('checking', 'Checking (%1)');
|
||||||
|
updateFilter('moving', 'Moving (%1)');
|
||||||
updateFilter('errored', 'Errored (%1)');
|
updateFilter('errored', 'Errored (%1)');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -453,7 +455,7 @@ window.addEvent('load', function() {
|
|||||||
const categoryList = $('categoryFilterList');
|
const categoryList = $('categoryFilterList');
|
||||||
if (!categoryList)
|
if (!categoryList)
|
||||||
return;
|
return;
|
||||||
categoryList.empty();
|
categoryList.getChildren().each(c => c.destroy());
|
||||||
|
|
||||||
const create_link = function(hash, text, count) {
|
const create_link = function(hash, text, count) {
|
||||||
let display_name = text;
|
let display_name = text;
|
||||||
@ -488,7 +490,19 @@ window.addEvent('load', function() {
|
|||||||
Object.each(category_list, function(category) {
|
Object.each(category_list, function(category) {
|
||||||
sortedCategories.push(category.name);
|
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) {
|
for (let i = 0; i < sortedCategories.length; ++i) {
|
||||||
const categoryName = sortedCategories[i];
|
const categoryName = sortedCategories[i];
|
||||||
@ -526,8 +540,7 @@ window.addEvent('load', function() {
|
|||||||
if (tagFilterList === null)
|
if (tagFilterList === null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (tagFilterList.firstChild !== null)
|
tagFilterList.getChildren().each(c => c.destroy());
|
||||||
tagFilterList.removeChild(tagFilterList.firstChild);
|
|
||||||
|
|
||||||
const createLink = function(hash, text, count) {
|
const createLink = function(hash, text, count) {
|
||||||
const html = '<a href="#" onclick="setTagFilter(' + hash + ');return false;">'
|
const html = '<a href="#" onclick="setTagFilter(' + hash + ');return false;">'
|
||||||
@ -580,8 +593,7 @@ window.addEvent('load', function() {
|
|||||||
if (trackerFilterList === null)
|
if (trackerFilterList === null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (trackerFilterList.firstChild !== null)
|
trackerFilterList.getChildren().each(c => c.destroy());
|
||||||
trackerFilterList.removeChild(trackerFilterList.firstChild);
|
|
||||||
|
|
||||||
const createLink = function(hash, text, count) {
|
const createLink = function(hash, text, count) {
|
||||||
const html = '<a href="#" onclick="setTrackerFilter(' + hash + ');return false;">'
|
const html = '<a href="#" onclick="setTrackerFilter(' + hash + ');return false;">'
|
||||||
@ -1200,7 +1212,7 @@ window.addEvent('load', function() {
|
|||||||
loadMethod: 'xhr',
|
loadMethod: 'xhr',
|
||||||
contentURL: 'views/log.html',
|
contentURL: 'views/log.html',
|
||||||
require: {
|
require: {
|
||||||
css: ['css/lib/vanillaSelectBox.css'],
|
css: ['css/vanillaSelectBox.css'],
|
||||||
js: ['scripts/lib/vanillaSelectBox.js'],
|
js: ['scripts/lib/vanillaSelectBox.js'],
|
||||||
},
|
},
|
||||||
tabsURL: 'views/logTabs.html',
|
tabsURL: 'views/logTabs.html',
|
||||||
@ -1512,6 +1524,8 @@ function setupCopyEventHandler() {
|
|||||||
return copyMagnetLinkFN();
|
return copyMagnetLinkFN();
|
||||||
case "copyID":
|
case "copyID":
|
||||||
return copyIdFN();
|
return copyIdFN();
|
||||||
|
case "copyComment":
|
||||||
|
return copyCommentFN();
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -816,8 +816,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
let rowPos = rows.length;
|
let rowPos = rows.length;
|
||||||
|
|
||||||
while ((rowPos < trs.length) && (trs.length > 0)) {
|
while ((rowPos < trs.length) && (trs.length > 0)) {
|
||||||
trs[trs.length - 1].dispose();
|
trs.pop().destroy();
|
||||||
trs.pop();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -839,7 +838,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
this.selectedRows.erase(rowId);
|
this.selectedRows.erase(rowId);
|
||||||
const tr = this.getTrByRowId(rowId);
|
const tr = this.getTrByRowId(rowId);
|
||||||
if (tr !== null) {
|
if (tr !== null) {
|
||||||
tr.dispose();
|
tr.destroy();
|
||||||
this.rows.erase(rowId);
|
this.rows.erase(rowId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -851,8 +850,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
this.rows.empty();
|
this.rows.empty();
|
||||||
const trs = this.tableBody.getElements('tr');
|
const trs = this.tableBody.getElements('tr');
|
||||||
while (trs.length > 0) {
|
while (trs.length > 0) {
|
||||||
trs[trs.length - 1].dispose();
|
trs.pop().destroy();
|
||||||
trs.pop();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -945,6 +943,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
this.newColumn('seen_complete', '', 'Last Seen Complete', 100, false);
|
this.newColumn('seen_complete', '', 'Last Seen Complete', 100, false);
|
||||||
this.newColumn('last_activity', '', 'Last Activity', 100, false);
|
this.newColumn('last_activity', '', 'Last Activity', 100, false);
|
||||||
this.newColumn('availability', '', 'Availability', 100, false);
|
this.newColumn('availability', '', 'Availability', 100, false);
|
||||||
|
this.newColumn('reannounce', '', 'Reannounce In', 100, false);
|
||||||
|
|
||||||
this.columns['state_icon'].onclick = '';
|
this.columns['state_icon'].onclick = '';
|
||||||
this.columns['state_icon'].dataProperties[0] = 'state';
|
this.columns['state_icon'].dataProperties[0] = 'state';
|
||||||
@ -1001,10 +1000,14 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
case "checkingUP":
|
case "checkingUP":
|
||||||
case "queuedForChecking":
|
case "queuedForChecking":
|
||||||
case "checkingResumeData":
|
case "checkingResumeData":
|
||||||
case "moving":
|
|
||||||
state = "force-recheck";
|
state = "force-recheck";
|
||||||
img_path = "images/force-recheck.svg";
|
img_path = "images/force-recheck.svg";
|
||||||
break;
|
break;
|
||||||
|
case "moving":
|
||||||
|
state = "moving";
|
||||||
|
img_path = "images/set-location.svg";
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
case "unknown":
|
case "unknown":
|
||||||
case "missingFiles":
|
case "missingFiles":
|
||||||
state = "error";
|
state = "error";
|
||||||
@ -1331,6 +1334,13 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
td.set('text', value);
|
td.set('text', value);
|
||||||
td.set('title', 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) {
|
applyFilter: function(row, filterName, categoryHash, tagHash, trackerHash, filterTerms) {
|
||||||
@ -1387,6 +1397,10 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
if (state !== 'checkingUP' && state !== 'checkingDL' && state !== 'checkingResumeData')
|
if (state !== 'checkingUP' && state !== 'checkingDL' && state !== 'checkingResumeData')
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case 'moving':
|
||||||
|
if (state !== 'moving')
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
case 'errored':
|
case 'errored':
|
||||||
if (state != 'error' && state != "unknown" && state != "missingFiles")
|
if (state != 'error' && state != "unknown" && state != "missingFiles")
|
||||||
return false;
|
return false;
|
||||||
@ -1567,7 +1581,7 @@ window.qBittorrent.DynamicTable = (function() {
|
|||||||
|
|
||||||
if (!country_code) {
|
if (!country_code) {
|
||||||
if (td.getChildren('img').length > 0)
|
if (td.getChildren('img').length > 0)
|
||||||
td.getChildren('img')[0].dispose();
|
td.getChildren('img')[0].destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2262,7 +2262,8 @@ MUI.Window = new Class({
|
|||||||
'styles': {
|
'styles': {
|
||||||
'position': 'absolute', // This is set here to make theme transitions smoother
|
'position': 'absolute', // This is set here to make theme transitions smoother
|
||||||
'top': 0,
|
'top': 0,
|
||||||
'left': 0
|
'left': 0,
|
||||||
|
'height': 'auto'
|
||||||
}
|
}
|
||||||
}).inject(this.windowEl);
|
}).inject(this.windowEl);
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ let copyNameFN = function() {};
|
|||||||
let copyInfohashFN = function(policy) {};
|
let copyInfohashFN = function(policy) {};
|
||||||
let copyMagnetLinkFN = function() {};
|
let copyMagnetLinkFN = function() {};
|
||||||
let copyIdFN = function() {};
|
let copyIdFN = function() {};
|
||||||
|
let copyCommentFN = function() {};
|
||||||
let setQueuePositionFN = function() {};
|
let setQueuePositionFN = function() {};
|
||||||
let exportTorrentFN = function() {};
|
let exportTorrentFN = function() {};
|
||||||
|
|
||||||
@ -348,7 +349,7 @@ const initializeWindows = function() {
|
|||||||
const id = 'statisticspage';
|
const id = 'statisticspage';
|
||||||
new MochaUI.Window({
|
new MochaUI.Window({
|
||||||
id: id,
|
id: id,
|
||||||
title: 'Statistics',
|
title: 'Statistics]',
|
||||||
loadMethod: 'xhr',
|
loadMethod: 'xhr',
|
||||||
contentURL: new URI("views/statistics.html").toString(),
|
contentURL: new URI("views/statistics.html").toString(),
|
||||||
maximizable: false,
|
maximizable: false,
|
||||||
@ -1005,6 +1006,21 @@ const initializeWindows = function() {
|
|||||||
return torrentsTable.selectedRowsIds().join("\n");
|
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() {
|
exportTorrentFN = async function() {
|
||||||
const hashes = torrentsTable.selectedRowsIds();
|
const hashes = torrentsTable.selectedRowsIds();
|
||||||
for (const hash of hashes) {
|
for (const hash of hashes) {
|
||||||
|
@ -173,7 +173,7 @@ window.qBittorrent.PropFiles = (function() {
|
|||||||
elem.set('value', priority.toString());
|
elem.set('value', priority.toString());
|
||||||
elem.set('html', html);
|
elem.set('html', html);
|
||||||
if (selected)
|
if (selected)
|
||||||
elem.setAttribute('selected', '');
|
elem.selected = true;
|
||||||
return elem;
|
return elem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,8 +50,7 @@ window.qBittorrent.PropWebseeds = (function() {
|
|||||||
|
|
||||||
removeRow: function(url) {
|
removeRow: function(url) {
|
||||||
if (this.rows.has(url)) {
|
if (this.rows.has(url)) {
|
||||||
const tr = this.rows.get(url);
|
this.rows.get(url).destroy();
|
||||||
tr.dispose();
|
|
||||||
this.rows.erase(url);
|
this.rows.erase(url);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -40,16 +40,19 @@
|
|||||||
const values = {
|
const values = {
|
||||||
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
|
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
|
||||||
seedingTimeLimit: parseInt(origValues[1]),
|
seedingTimeLimit: parseInt(origValues[1]),
|
||||||
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[2], 2),
|
inactiveSeedingTimeLimit: parseInt(origValues[2]),
|
||||||
maxSeedingTime: parseInt(origValues[3])
|
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
|
// 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
|
// use default option
|
||||||
setSelectedRadioValue('shareLimit', 'default');
|
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');
|
setSelectedRadioValue('shareLimit', 'none');
|
||||||
// TODO set input boxes to *global* max ratio and seeding time
|
// TODO set input boxes to *global* max ratio and seeding time
|
||||||
}
|
}
|
||||||
@ -60,8 +63,12 @@
|
|||||||
$('ratio').set('value', values.ratioLimit);
|
$('ratio').set('value', values.ratioLimit);
|
||||||
}
|
}
|
||||||
if (values.seedingTimeLimit >= 0) {
|
if (values.seedingTimeLimit >= 0) {
|
||||||
$('setMinutes').set('checked', true);
|
$('setTotalMinutes').set('checked', true);
|
||||||
$('minutes').set('value', values.seedingTimeLimit);
|
$('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');
|
const shareLimit = getSelectedRadioValue('shareLimit');
|
||||||
let ratioLimitValue = 0.00;
|
let ratioLimitValue = 0.00;
|
||||||
let seedingTimeLimitValue = 0;
|
let seedingTimeLimitValue = 0;
|
||||||
|
let inactiveSeedingTimeLimitValue = 0;
|
||||||
|
|
||||||
if (shareLimit === 'default') {
|
if (shareLimit === 'default') {
|
||||||
ratioLimitValue = seedingTimeLimitValue = UseGlobalLimit;
|
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = UseGlobalLimit;
|
||||||
}
|
}
|
||||||
else if (shareLimit === 'none') {
|
else if (shareLimit === 'none') {
|
||||||
ratioLimitValue = seedingTimeLimitValue = NoLimit;
|
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = NoLimit;
|
||||||
}
|
}
|
||||||
else if (shareLimit === 'custom') {
|
else if (shareLimit === 'custom') {
|
||||||
ratioLimitValue = $('setRatio').get('checked') ? $('ratio').get('value') : -1;
|
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 {
|
else {
|
||||||
return false;
|
return false;
|
||||||
@ -99,7 +108,8 @@
|
|||||||
data: {
|
data: {
|
||||||
hashes: hashesList.join('|'),
|
hashes: hashesList.join('|'),
|
||||||
ratioLimit: ratioLimitValue,
|
ratioLimit: ratioLimitValue,
|
||||||
seedingTimeLimit: seedingTimeLimitValue
|
seedingTimeLimit: seedingTimeLimitValue,
|
||||||
|
inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onComplete: function() {
|
||||||
window.parent.closeWindows();
|
window.parent.closeWindows();
|
||||||
@ -132,7 +142,8 @@
|
|||||||
function shareLimitChanged() {
|
function shareLimitChanged() {
|
||||||
const customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
|
const customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
|
||||||
$('setRatio').set('disabled', !customShareLimit);
|
$('setRatio').set('disabled', !customShareLimit);
|
||||||
$('setMinutes').set('disabled', !customShareLimit);
|
$('setTotalMinutes').set('disabled', !customShareLimit);
|
||||||
|
$('setInactiveMinutes').set('disabled', !customShareLimit);
|
||||||
|
|
||||||
enableInputBoxes();
|
enableInputBoxes();
|
||||||
|
|
||||||
@ -141,22 +152,24 @@
|
|||||||
|
|
||||||
function enableInputBoxes() {
|
function enableInputBoxes() {
|
||||||
$('ratio').set('disabled', ($('setRatio').get('disabled') || !$('setRatio').get('checked')));
|
$('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());
|
$('save').set('disabled', !isFormValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
function 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>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div style="padding: 10px 10px 0px 10px;">
|
<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" 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="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" value="custom" onchange="shareLimitChanged()" style="margin-bottom: 5px;" />Set share limit to<br />
|
||||||
|
|
||||||
<div style="margin-left: 40px; margin-bottom: 5px;">
|
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||||
<input type="checkbox" id="setRatio" class="shareLimitInput" onclick="enableInputBoxes()" />
|
<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" />
|
<input type="number" id="ratio" value="0.00" step=".01" min="0" max="9999" class="shareLimitInput" />
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left: 40px; margin-bottom: 5px;">
|
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||||
<input type="checkbox" id="setMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
<input type="checkbox" id="setTotalMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
||||||
<label for="setMinutes">minutes</label>
|
<label for="setTotalMinutes">total minutes</label>
|
||||||
<input type="number" id="minutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
|
<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>
|
||||||
<div style="text-align: center; padding-top: 10px;">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -12,24 +12,21 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<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">
|
<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;">
|
<div style="margin-top: 25px; display: inline-block; border: 1px solid lightgrey; border-radius: 4px;">
|
||||||
<label class="custom-file-upload">
|
<input type="file" id="fileselect" accept=".torrent, application/x-bittorrent" name="fileselect[]" multiple />
|
||||||
<input type="file" class="fileselect" id="fileselect" accept="application/x-bittorrent, .torrent" name="fileselect[]" multiple />
|
|
||||||
Upload Files
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<fieldset class="settings" style="border: 0; text-align: left; margin-top: 12px;">
|
<fieldset class="settings" style="border: 0; text-align: left; margin-top: 12px;">
|
||||||
<table style="margin: auto;">
|
<table style="margin: auto;">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="autoTMM">Torrent Management Mode:</label>
|
<label for="autoTMM">(Torrent Management Mode:</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="autoTMM" name="autoTMM" onchange="qBittorrent.Download.changeTMM(this)">
|
<select id="autoTMM" name="autoTMM" onchange="qBittorrent.Download.changeTMM(this)">
|
||||||
<option selected value="false">Manual</option>
|
<option selected value="false">(Manual</option>
|
||||||
<option value="true">Automatic</option>
|
<option value="true">(Automatic</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -73,7 +70,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<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>
|
||||||
<td>
|
<td>
|
||||||
<select id="stopCondition" name="stopCondition">
|
<select id="stopCondition" name="stopCondition">
|
||||||
@ -162,6 +167,10 @@
|
|||||||
if (submitted)
|
if (submitted)
|
||||||
window.parent.closeWindows();
|
window.parent.closeWindows();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ((Browser.platform === 'ios') || ((Browser.platform === 'mac') && (navigator.maxTouchPoints > 1))) {
|
||||||
|
$('fileselect').accept = ".torrent";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<div id="upload_spinner" class="mochaSpinner"></div>
|
<div id="upload_spinner" class="mochaSpinner"></div>
|
||||||
</body>
|
</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_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="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="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>
|
<li id="errored_filter"><a href="#" onclick="setFilter('errored');return false;"><img src="images/error.svg" alt="Errored" />Errored (0)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -63,6 +64,9 @@
|
|||||||
createCategory: function(element, ref) {
|
createCategory: function(element, ref) {
|
||||||
createCategoryFN();
|
createCategoryFN();
|
||||||
},
|
},
|
||||||
|
createSubcategory: function(element, ref) {
|
||||||
|
createSubcategoryFN(element.id);
|
||||||
|
},
|
||||||
editCategory: function(element, ref) {
|
editCategory: function(element, ref) {
|
||||||
editCategoryFN(element.id);
|
editCategoryFN(element.id);
|
||||||
},
|
},
|
||||||
|
@ -191,10 +191,10 @@
|
|||||||
const init = () => {
|
const init = () => {
|
||||||
$('logLevelSelect').getElements('option').each((x) => {
|
$('logLevelSelect').getElements('option').each((x) => {
|
||||||
if (selectedLogLevels.indexOf(x.value.toString()) !== -1) {
|
if (selectedLogLevels.indexOf(x.value.toString()) !== -1) {
|
||||||
x.setAttribute('selected', '');
|
x.selected = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x.removeAttribute('selected');
|
x.selected = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -424,4 +424,6 @@
|
|||||||
|
|
||||||
return exports();
|
return exports();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Object.freeze(window.qBittorrent.Log);
|
||||||
</script>
|
</script>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,8 @@
|
|||||||
<!-- preferences -->
|
<!-- preferences -->
|
||||||
<div class="toolbarTabs">
|
<div class="toolbarTabs">
|
||||||
<ul id="preferencesTabs" class="tab-menu">
|
<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="PrefConnectionLink"><a>Connection</a></li>
|
||||||
<li id="PrefSpeedLink"><a>Speed</a></li>
|
<li id="PrefSpeedLink"><a>Speed</a></li>
|
||||||
<li id="PrefBittorrentLink"><a>BitTorrent</a></li>
|
<li id="PrefBittorrentLink"><a>BitTorrent</a></li>
|
||||||
@ -19,6 +20,10 @@
|
|||||||
// Tabs
|
// Tabs
|
||||||
MochaUI.initializeTabs('preferencesTabs');
|
MochaUI.initializeTabs('preferencesTabs');
|
||||||
|
|
||||||
|
$('PrefBehaviorLink').addEvent('click', function(e) {
|
||||||
|
$$('.PrefTab').addClass('invisible');
|
||||||
|
$('BehaviorTab').removeClass('invisible');
|
||||||
|
});
|
||||||
$('PrefDownloadsLink').addEvent('click', function(e) {
|
$('PrefDownloadsLink').addEvent('click', function(e) {
|
||||||
$$('.PrefTab').addClass('invisible');
|
$$('.PrefTab').addClass('invisible');
|
||||||
$('DownloadsTab').removeClass('invisible');
|
$('DownloadsTab').removeClass('invisible');
|
||||||
|
@ -211,7 +211,16 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
</table>
|
||||||
|
|
||||||
<div class="formRow">
|
<div class="formRow">
|
||||||
<input disabled type="checkbox" id="savetoDifferentDir" />
|
<input disabled type="checkbox" id="savetoDifferentDir" />
|
||||||
<label for="savetoDifferentDir">Save to a Different Directory</label>
|
<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].assignedCategory = $('assignCategoryCombobox').value;
|
||||||
rulesList[rule].savePath = $('savetoDifferentDir').checked ? $('saveToText').value : '';
|
rulesList[rule].savePath = $('savetoDifferentDir').checked ? $('saveToText').value : '';
|
||||||
rulesList[rule].ignoreDays = parseInt($('ignoreDaysValue').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) {
|
switch ($('addPausedCombobox').value) {
|
||||||
case 'default':
|
case 'default':
|
||||||
@ -666,6 +685,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
|
|||||||
$('episodeFilterText').disabled = true;
|
$('episodeFilterText').disabled = true;
|
||||||
$('useSmartFilter').disabled = true;
|
$('useSmartFilter').disabled = true;
|
||||||
$('assignCategoryCombobox').disabled = true;
|
$('assignCategoryCombobox').disabled = true;
|
||||||
|
$('ruleAddTags').disabled = true;
|
||||||
$('savetoDifferentDir').disabled = true;
|
$('savetoDifferentDir').disabled = true;
|
||||||
$('saveToText').disabled = true;
|
$('saveToText').disabled = true;
|
||||||
$('ignoreDaysValue').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 = '';
|
$('episodeFilterText').value = '';
|
||||||
$('useSmartFilter').checked = false;
|
$('useSmartFilter').checked = false;
|
||||||
$('assignCategoryCombobox').value = 'default';
|
$('assignCategoryCombobox').value = 'default';
|
||||||
|
$('ruleAddTags').value = '';
|
||||||
$('savetoDifferentDir').checked = false;
|
$('savetoDifferentDir').checked = false;
|
||||||
$('saveToText').value = '';
|
$('saveToText').value = '';
|
||||||
$('ignoreDaysValue').value = 0;
|
$('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;
|
$('episodeFilterText').disabled = false;
|
||||||
$('useSmartFilter').disabled = false;
|
$('useSmartFilter').disabled = false;
|
||||||
$('assignCategoryCombobox').disabled = false;
|
$('assignCategoryCombobox').disabled = false;
|
||||||
|
$('ruleAddTags').disabled = false;
|
||||||
$('savetoDifferentDir').disabled = false;
|
$('savetoDifferentDir').disabled = false;
|
||||||
$('savetoDifferentDir').checked = rulesList[ruleName].savePath ? false : true;
|
$('savetoDifferentDir').checked = rulesList[ruleName].savePath ? false : true;
|
||||||
$('saveToText').disabled = 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."))
|
if ((xhr.status === 200) && (xhr.responseText === "Ok."))
|
||||||
location.reload(true);
|
location.reload(true);
|
||||||
else
|
else
|
||||||
errorMsgElement.textContent = 'QBT_TR(Invalid Username or Password.)QBT_TR[CONTEXT=HttpServer]';
|
errorMsgElement.textContent = 'Invalid Username or Password.';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
xhr.addEventListener('error', function() {
|
xhr.addEventListener('error', function() {
|
||||||
errorMsgElement.textContent = (xhr.responseText !== "")
|
errorMsgElement.textContent = (xhr.responseText !== "")
|
||||||
? 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');
|
const usernameElement = document.getElementById('username');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user