mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-25 22:14:32 +00:00
Implement tag management for WebUI
This commit is contained in:
parent
cf2e7d77d6
commit
b530e19a44
@ -445,6 +445,12 @@ void SyncController::maindataAction()
|
|||||||
|
|
||||||
data["categories"] = categories;
|
data["categories"] = categories;
|
||||||
|
|
||||||
|
QVariantList tags;
|
||||||
|
for (const QString &tag : asConst(session->tags()))
|
||||||
|
tags << tag;
|
||||||
|
|
||||||
|
data["tags"] = tags;
|
||||||
|
|
||||||
QVariantMap serverState = getTranserInfo();
|
QVariantMap serverState = getTranserInfo();
|
||||||
serverState[KEY_TRANSFER_FREESPACEONDISK] = getFreeDiskSpace();
|
serverState[KEY_TRANSFER_FREESPACEONDISK] = getFreeDiskSpace();
|
||||||
serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
|
serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
|
||||||
|
@ -1041,3 +1041,67 @@ void TorrentsController::categoriesAction()
|
|||||||
|
|
||||||
setResult(categories);
|
setResult(categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentsController::addTagsAction()
|
||||||
|
{
|
||||||
|
checkParams({"hashes", "tags"});
|
||||||
|
|
||||||
|
const QStringList hashes {params()["hashes"].split('|')};
|
||||||
|
const QStringList tags {params()["tags"].split(',', QString::SkipEmptyParts)};
|
||||||
|
|
||||||
|
for (const QString &tag : tags) {
|
||||||
|
const QString tagTrimmed {tag.trimmed()};
|
||||||
|
applyToTorrents(hashes, [&tagTrimmed](BitTorrent::TorrentHandle *const torrent)
|
||||||
|
{
|
||||||
|
torrent->addTag(tagTrimmed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TorrentsController::removeTagsAction()
|
||||||
|
{
|
||||||
|
checkParams({"hashes"});
|
||||||
|
|
||||||
|
const QStringList hashes {params()["hashes"].split('|')};
|
||||||
|
const QStringList tags {params()["tags"].split(',', QString::SkipEmptyParts)};
|
||||||
|
|
||||||
|
for (const QString &tag : tags) {
|
||||||
|
const QString tagTrimmed {tag.trimmed()};
|
||||||
|
applyToTorrents(hashes, [&tagTrimmed](BitTorrent::TorrentHandle *const torrent)
|
||||||
|
{
|
||||||
|
torrent->removeTag(tagTrimmed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags.isEmpty()) {
|
||||||
|
applyToTorrents(hashes, [](BitTorrent::TorrentHandle *const torrent)
|
||||||
|
{
|
||||||
|
torrent->removeAllTags();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TorrentsController::createTagsAction()
|
||||||
|
{
|
||||||
|
checkParams({"tags"});
|
||||||
|
|
||||||
|
const QStringList tags {params()["tags"].split(',', QString::SkipEmptyParts)};
|
||||||
|
|
||||||
|
for (const QString &tag : tags)
|
||||||
|
BitTorrent::Session::instance()->addTag(tag.trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TorrentsController::deleteTagsAction()
|
||||||
|
{
|
||||||
|
checkParams({"tags"});
|
||||||
|
|
||||||
|
const QStringList tags {params()["tags"].split(',', QString::SkipEmptyParts)};
|
||||||
|
for (const QString &tag : tags)
|
||||||
|
BitTorrent::Session::instance()->removeTag(tag.trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TorrentsController::tagsAction()
|
||||||
|
{
|
||||||
|
const QStringList tags = BitTorrent::Session::instance()->tags().toList();
|
||||||
|
setResult(QJsonArray::fromStringList(tags));
|
||||||
|
}
|
||||||
|
@ -56,6 +56,11 @@ private slots:
|
|||||||
void editCategoryAction();
|
void editCategoryAction();
|
||||||
void removeCategoriesAction();
|
void removeCategoriesAction();
|
||||||
void categoriesAction();
|
void categoriesAction();
|
||||||
|
void addTagsAction();
|
||||||
|
void removeTagsAction();
|
||||||
|
void createTagsAction();
|
||||||
|
void deleteTagsAction();
|
||||||
|
void tagsAction();
|
||||||
void addAction();
|
void addAction();
|
||||||
void deleteAction();
|
void deleteAction();
|
||||||
void addTrackersAction();
|
void addTrackersAction();
|
||||||
|
@ -258,6 +258,11 @@ a.propButton img {
|
|||||||
-ms-interpolation-mode: bicubic;
|
-ms-interpolation-mode: bicubic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contextMenu li input[type=checkbox] {
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sliders */
|
/* Sliders */
|
||||||
|
|
||||||
.slider {
|
.slider {
|
||||||
|
@ -21,6 +21,13 @@
|
|||||||
<ul class="filterList" id="categoryFilterList">
|
<ul class="filterList" id="categoryFilterList">
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="filterWrapper">
|
||||||
|
<span class="filterTitle" onclick="toggleFilterDisplay('tag');">
|
||||||
|
<img src="images/qbt-theme/go-down.svg">QBT_TR(Tags)QBT_TR[CONTEXT=TransferListFiltersWidget]
|
||||||
|
</span>
|
||||||
|
<ul class="filterList" id="tagFilterList">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
@ -60,9 +67,44 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tagsFilterContextMenu = new TagsFilterContextMenu({
|
||||||
|
targets: '.tagsFilterContextMenuTarget',
|
||||||
|
menu: 'tagsFilterMenu',
|
||||||
|
actions: {
|
||||||
|
createTag: function(element, ref) {
|
||||||
|
createTagFN();
|
||||||
|
},
|
||||||
|
deleteTag: function(element, ref) {
|
||||||
|
removeTagFN(element.id);
|
||||||
|
},
|
||||||
|
deleteUnusedTags: function(element, ref) {
|
||||||
|
deleteUnusedTagsFN();
|
||||||
|
},
|
||||||
|
startTorrentsByTag: function(element, ref) {
|
||||||
|
startTorrentsByTagFN(element.id);
|
||||||
|
},
|
||||||
|
pauseTorrentsByTag: function(element, ref) {
|
||||||
|
pauseTorrentsByTagFN(element.id);
|
||||||
|
},
|
||||||
|
deleteTorrentsByTag: function(element, ref) {
|
||||||
|
deleteTorrentsByTagFN(element.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
offsets: {
|
||||||
|
x: -15,
|
||||||
|
y: 2
|
||||||
|
},
|
||||||
|
onShow: function() {
|
||||||
|
this.options.element.firstChild.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (localStorage.getItem('filter_status_collapsed') === "true")
|
if (localStorage.getItem('filter_status_collapsed') === "true")
|
||||||
toggleFilterDisplay('status');
|
toggleFilterDisplay('status');
|
||||||
|
|
||||||
if (localStorage.getItem('filter_category_collapsed') === "true")
|
if (localStorage.getItem('filter_category_collapsed') === "true")
|
||||||
toggleFilterDisplay('category');
|
toggleFilterDisplay('category');
|
||||||
|
|
||||||
|
if (localStorage.getItem('filter_tag_collapsed') === "true")
|
||||||
|
toggleFilterDisplay('tag');
|
||||||
</script>
|
</script>
|
||||||
|
@ -132,6 +132,10 @@
|
|||||||
<a href="#Category" class="arrow-right"><img src="images/qbt-theme/view-categories.svg" alt="QBT_TR(Category)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Category)QBT_TR[CONTEXT=TransferListWidget]</a>
|
<a href="#Category" class="arrow-right"><img src="images/qbt-theme/view-categories.svg" alt="QBT_TR(Category)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Category)QBT_TR[CONTEXT=TransferListWidget]</a>
|
||||||
<ul id="contextCategoryList" class="scrollableMenu"></ul>
|
<ul id="contextCategoryList" class="scrollableMenu"></ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#Tags" class="arrow-right"><img src="images/qbt-theme/view-categories.svg" alt="QBT_TR(Tags)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Tags)QBT_TR[CONTEXT=TransferListWidget]</a>
|
||||||
|
<ul id="contextTagList" class="scrollableMenu"></ul>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#autoTorrentManagement"><img src="images/qbt-theme/checked.svg" alt="QBT_TR(Automatic Torrent Management)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Automatic Torrent Management)QBT_TR[CONTEXT=TransferListWidget]</a>
|
<a href="#autoTorrentManagement"><img src="images/qbt-theme/checked.svg" alt="QBT_TR(Automatic Torrent Management)QBT_TR[CONTEXT=TransferListWidget]"/> QBT_TR(Automatic Torrent Management)QBT_TR[CONTEXT=TransferListWidget]</a>
|
||||||
</li>
|
</li>
|
||||||
@ -170,6 +174,14 @@
|
|||||||
<li><a href="#pauseTorrentsByCategory"><img src="images/qbt-theme/media-playback-pause.svg" alt="QBT_TR(Pause torrents)QBT_TR[CONTEXT=CategoryFilterWidget]"/> QBT_TR(Pause torrents)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li>
|
<li><a href="#pauseTorrentsByCategory"><img src="images/qbt-theme/media-playback-pause.svg" alt="QBT_TR(Pause torrents)QBT_TR[CONTEXT=CategoryFilterWidget]"/> QBT_TR(Pause torrents)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li>
|
||||||
<li><a href="#deleteTorrentsByCategory"><img src="images/qbt-theme/edit-delete.svg" alt="QBT_TR(Delete torrents)QBT_TR[CONTEXT=CategoryFilterWidget]"/> QBT_TR(Delete torrents)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li>
|
<li><a href="#deleteTorrentsByCategory"><img src="images/qbt-theme/edit-delete.svg" alt="QBT_TR(Delete torrents)QBT_TR[CONTEXT=CategoryFilterWidget]"/> QBT_TR(Delete torrents)QBT_TR[CONTEXT=CategoryFilterWidget]</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<ul id="tagsFilterMenu" class="contextMenu">
|
||||||
|
<li><a href="#createTag"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add tag...)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Add tag...)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
<li><a href="#deleteTag"><img src="images/qbt-theme/list-remove.svg" alt="QBT_TR(Remove tag)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Remove tag)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
<li><a href="#deleteUnusedTags"><img src="images/qbt-theme/list-remove.svg" alt="QBT_TR(Remove unused tags)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Remove unused tags)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
<li class="separator"><a href="#startTorrentsByTag"><img src="images/qbt-theme/media-playback-start.svg" alt="QBT_TR(Resume torrents)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Resume torrents)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
<li><a href="#pauseTorrentsByTag"><img src="images/qbt-theme/media-playback-pause.svg" alt="QBT_TR(Pause torrents)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Pause torrents)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
<li><a href="#deleteTorrentsByTag"><img src="images/qbt-theme/edit-delete.svg" alt="QBT_TR(Delete torrents)QBT_TR[CONTEXT=TagFilterWidget]"/> QBT_TR(Delete torrents)QBT_TR[CONTEXT=TagFilterWidget]</a></li>
|
||||||
|
</ul>
|
||||||
<ul id="torrentTrackersMenu" class="contextMenu">
|
<ul id="torrentTrackersMenu" class="contextMenu">
|
||||||
<li><a href="#AddTracker"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add a new tracker...)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Add a new tracker...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
<li><a href="#AddTracker"><img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add a new tracker...)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Add a new tracker...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
<li class="separator"><a href="#EditTracker"><img src="images/qbt-theme/document-edit.svg" alt="QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
<li class="separator"><a href="#EditTracker"><img src="images/qbt-theme/document-edit.svg" alt="QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]"/> QBT_TR(Edit tracker URL...)QBT_TR[CONTEXT=TrackerListWidget]</a></li>
|
||||||
|
105
src/webui/www/private/newtag.html
Normal file
105
src/webui/www/private/newtag.html
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="${LANG}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>QBT_TR(Add Tags)QBT_TR[CONTEXT=TransferListWidget]</title>
|
||||||
|
<link rel="stylesheet" href="css/style.css?v=${CACHEID}" type="text/css" />
|
||||||
|
<script src="scripts/lib/mootools-1.2-core-yc.js"></script>
|
||||||
|
<script src="scripts/lib/mootools-1.2-more.js"></script>
|
||||||
|
<script src="scripts/misc.js?locale=${LANG}&v=${CACHEID}"></script>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
new Keyboard({
|
||||||
|
defaultEventType: 'keydown',
|
||||||
|
events: {
|
||||||
|
'Enter': function(event) {
|
||||||
|
$('tagNameButton').click();
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
'Escape': function(event) {
|
||||||
|
window.parent.closeWindows();
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
'Esc': function(event) {
|
||||||
|
window.parent.closeWindows();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).activate();
|
||||||
|
|
||||||
|
window.addEvent('domready', function() {
|
||||||
|
const uriAction = safeTrim(new URI().getData('action'));
|
||||||
|
const uriHashes = safeTrim(new URI().getData('hashes'));
|
||||||
|
|
||||||
|
if (uriAction === 'create')
|
||||||
|
$('legendText').innerText = 'QBT_TR(Tag:)QBT_TR[CONTEXT=TagFilterWidget]';
|
||||||
|
|
||||||
|
$('tagName').focus();
|
||||||
|
|
||||||
|
$('tagNameButton').addEvent('click', function(e) {
|
||||||
|
new Event(e).stop();
|
||||||
|
|
||||||
|
const tagName = $('tagName').value.trim();
|
||||||
|
|
||||||
|
const verifyTagName = function(name) {
|
||||||
|
if ((name === null) || (name === ""))
|
||||||
|
return false;
|
||||||
|
if (name.indexOf(",") >= 0) {
|
||||||
|
alert("QBT_TR(Invalid tag name)QBT_TR[CONTEXT=TagFilterWidget]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (uriAction) {
|
||||||
|
case "set":
|
||||||
|
if (uriHashes === "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/addTags',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: uriHashes,
|
||||||
|
tags: tagName,
|
||||||
|
},
|
||||||
|
onComplete: function() {
|
||||||
|
window.parent.closeWindows();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "create":
|
||||||
|
if (!verifyTagName(tagName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/createTags',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
tags: tagName,
|
||||||
|
},
|
||||||
|
onComplete: function() {
|
||||||
|
window.parent.closeWindows();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div style="padding: 10px 10px 0px 10px;">
|
||||||
|
<p id="legendText" style="font-weight: bold;">QBT_TR(Comma-separated tags:)QBT_TR[CONTEXT=TransferListWidget]</p>
|
||||||
|
<input type="text" id="tagName" value="" maxlength="100" style="width: 220px;" />
|
||||||
|
<div style="text-align: center; padding-top: 10px;">
|
||||||
|
<input type="button" value="QBT_TR(Add)QBT_TR[CONTEXT=HttpServer]" id="tagNameButton" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -55,6 +55,14 @@ var category_list = {};
|
|||||||
var selected_category = CATEGORIES_ALL;
|
var selected_category = CATEGORIES_ALL;
|
||||||
var setCategoryFilter = function() {};
|
var setCategoryFilter = function() {};
|
||||||
|
|
||||||
|
const TAGS_ALL = 1;
|
||||||
|
const TAGS_UNTAGGED = 2;
|
||||||
|
|
||||||
|
let tagList = {};
|
||||||
|
|
||||||
|
let selectedTag = TAGS_ALL;
|
||||||
|
let setTagFilter = function() {};
|
||||||
|
|
||||||
var selected_filter = getLocalStorageItem('selected_filter', 'all');
|
var selected_filter = getLocalStorageItem('selected_filter', 'all');
|
||||||
var setFilter = function() {};
|
var setFilter = function() {};
|
||||||
var toggleFilterDisplay = function() {};
|
var toggleFilterDisplay = function() {};
|
||||||
@ -64,6 +72,11 @@ var loadSelectedCategory = function() {
|
|||||||
};
|
};
|
||||||
loadSelectedCategory();
|
loadSelectedCategory();
|
||||||
|
|
||||||
|
const loadSelectedTag = function() {
|
||||||
|
selectedTag = getLocalStorageItem('selected_tag', TAGS_ALL);
|
||||||
|
};
|
||||||
|
loadSelectedTag();
|
||||||
|
|
||||||
function genHash(string) {
|
function genHash(string) {
|
||||||
var hash = 0;
|
var hash = 0;
|
||||||
for (var i = 0; i < string.length; ++i) {
|
for (var i = 0; i < string.length; ++i) {
|
||||||
@ -161,6 +174,14 @@ window.addEvent('load', function() {
|
|||||||
updateMainData();
|
updateMainData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setTagFilter = function(hash) {
|
||||||
|
selectedTag = hash.toString();
|
||||||
|
localStorage.setItem('selected_tag', selectedTag);
|
||||||
|
highlightSelectedTag();
|
||||||
|
if (torrentsTable.tableBody !== undefined)
|
||||||
|
updateMainData();
|
||||||
|
};
|
||||||
|
|
||||||
setFilter = function(f) {
|
setFilter = function(f) {
|
||||||
// Visually Select the right filter
|
// Visually Select the right filter
|
||||||
$("all_filter").removeClass("selectedFilter");
|
$("all_filter").removeClass("selectedFilter");
|
||||||
@ -282,8 +303,44 @@ window.addEvent('load', function() {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeTorrentFromTagList = function(hash) {
|
||||||
|
if ((hash === null) || (hash === ""))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let removed = false;
|
||||||
|
for (const key in tagList) {
|
||||||
|
const tag = tagList[key];
|
||||||
|
if (Object.contains(tag.torrents, hash)) {
|
||||||
|
removed = true;
|
||||||
|
tag.torrents.splice(tag.torrents.indexOf(hash), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
};
|
||||||
|
|
||||||
|
const addTorrentToTagList = function(torrent) {
|
||||||
|
if (torrent['tags'] === undefined) // Tags haven't changed
|
||||||
|
return false;
|
||||||
|
|
||||||
|
removeTorrentFromTagList(torrent['hash']);
|
||||||
|
|
||||||
|
if (torrent['tags'].length === 0) // No tags
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const tags = torrent['tags'].split(',');
|
||||||
|
let added = false;
|
||||||
|
for (let i = 0; i < tags.length; ++i) {
|
||||||
|
const tagHash = genHash(tags[i].trim());
|
||||||
|
if (!Object.contains(tagList[tagHash].torrents, torrent['hash'])) {
|
||||||
|
added = true;
|
||||||
|
tagList[tagHash].torrents.push(torrent['hash']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return added;
|
||||||
|
};
|
||||||
|
|
||||||
var updateFilter = function(filter, filterTitle) {
|
var updateFilter = function(filter, filterTitle) {
|
||||||
$(filter + '_filter').firstChild.childNodes[1].nodeValue = filterTitle.replace('%1', torrentsTable.getFilteredTorrentsNumber(filter, CATEGORIES_ALL));
|
$(filter + '_filter').firstChild.childNodes[1].nodeValue = filterTitle.replace('%1', torrentsTable.getFilteredTorrentsNumber(filter, CATEGORIES_ALL, TAGS_ALL));
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateFiltersList = function() {
|
var updateFiltersList = function() {
|
||||||
@ -353,6 +410,60 @@ window.addEvent('load', function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateTagList = function() {
|
||||||
|
const tagFilterList = $('tagFilterList');
|
||||||
|
if (tagFilterList === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (tagFilterList.firstChild !== null)
|
||||||
|
tagFilterList.removeChild(tagFilterList.firstChild);
|
||||||
|
|
||||||
|
const createLink = function(hash, text, count) {
|
||||||
|
const html = '<a href="#" onclick="setTagFilter(' + hash + ');return false;">'
|
||||||
|
+ '<img src="images/qbt-theme/inode-directory.svg"/>'
|
||||||
|
+ escapeHtml(text) + ' (' + count + ')' + '</a>';
|
||||||
|
const el = new Element('li', {
|
||||||
|
id: hash,
|
||||||
|
html: html
|
||||||
|
});
|
||||||
|
tagsFilterContextMenu.addTarget(el);
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
|
const torrentsCount = torrentsTable.getRowIds().length;
|
||||||
|
let untagged = 0;
|
||||||
|
for (const key in torrentsTable.rows) {
|
||||||
|
if (torrentsTable.rows.hasOwnProperty(key) && torrentsTable.rows[key]['full_data'].tags.length === 0)
|
||||||
|
untagged += 1;
|
||||||
|
}
|
||||||
|
tagFilterList.appendChild(createLink(TAGS_ALL, 'QBT_TR(All)QBT_TR[CONTEXT=TagFilterModel]', torrentsCount));
|
||||||
|
tagFilterList.appendChild(createLink(TAGS_UNTAGGED, 'QBT_TR(Untagged)QBT_TR[CONTEXT=TagFilterModel]', untagged));
|
||||||
|
|
||||||
|
const sortedTags = [];
|
||||||
|
for (const key in tagList)
|
||||||
|
sortedTags.push(tagList[key].name);
|
||||||
|
sortedTags.sort();
|
||||||
|
|
||||||
|
for (let i = 0; i < sortedTags.length; ++i) {
|
||||||
|
const tagName = sortedTags[i];
|
||||||
|
const tagHash = genHash(tagName);
|
||||||
|
const tagCount = tagList[tagHash].torrents.length;
|
||||||
|
tagFilterList.appendChild(createLink(tagHash, tagName, tagCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightSelectedTag();
|
||||||
|
};
|
||||||
|
|
||||||
|
const highlightSelectedTag = function() {
|
||||||
|
const tagFilterList = $('tagFilterList');
|
||||||
|
if (!tagFilterList)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const children = tagFilterList.childNodes;
|
||||||
|
for (let i = 0; i < children.length; ++i)
|
||||||
|
children[i].className = (children[i].id === selectedTag) ? "selectedFilter" : "";
|
||||||
|
};
|
||||||
|
|
||||||
var syncMainDataTimer;
|
var syncMainDataTimer;
|
||||||
var syncMainData = function() {
|
var syncMainData = function() {
|
||||||
var url = new URI('api/v2/sync/maindata');
|
var url = new URI('api/v2/sync/maindata');
|
||||||
@ -374,11 +485,13 @@ window.addEvent('load', function() {
|
|||||||
clearTimeout(torrentsFilterInputTimer);
|
clearTimeout(torrentsFilterInputTimer);
|
||||||
var torrentsTableSelectedRows;
|
var torrentsTableSelectedRows;
|
||||||
var update_categories = false;
|
var update_categories = false;
|
||||||
|
let updateTags = false;
|
||||||
var full_update = (response['full_update'] === true);
|
var full_update = (response['full_update'] === true);
|
||||||
if (full_update) {
|
if (full_update) {
|
||||||
torrentsTableSelectedRows = torrentsTable.selectedRowsIds();
|
torrentsTableSelectedRows = torrentsTable.selectedRowsIds();
|
||||||
torrentsTable.clear();
|
torrentsTable.clear();
|
||||||
category_list = {};
|
category_list = {};
|
||||||
|
tagList = {};
|
||||||
}
|
}
|
||||||
if (response['rid']) {
|
if (response['rid']) {
|
||||||
syncMainDataLastResponseId = response['rid'];
|
syncMainDataLastResponseId = response['rid'];
|
||||||
@ -408,6 +521,25 @@ window.addEvent('load', function() {
|
|||||||
});
|
});
|
||||||
update_categories = true;
|
update_categories = true;
|
||||||
}
|
}
|
||||||
|
if (response['tags']) {
|
||||||
|
for (const tag of response['tags']) {
|
||||||
|
const tagHash = genHash(tag);
|
||||||
|
if (!tagList[tagHash]) {
|
||||||
|
tagList[tagHash] = {
|
||||||
|
name: tag,
|
||||||
|
torrents: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateTags = true;
|
||||||
|
}
|
||||||
|
if (response['tags_removed']) {
|
||||||
|
for (let i = 0; i < response['tags_removed'].length; ++i) {
|
||||||
|
const tagHash = genHash(response['tags_removed'][i]);
|
||||||
|
delete tagList[tagHash];
|
||||||
|
}
|
||||||
|
updateTags = true;
|
||||||
|
}
|
||||||
if (response['torrents']) {
|
if (response['torrents']) {
|
||||||
var updateTorrentList = false;
|
var updateTorrentList = false;
|
||||||
for (var key in response['torrents']) {
|
for (var key in response['torrents']) {
|
||||||
@ -418,6 +550,8 @@ window.addEvent('load', function() {
|
|||||||
torrentsTable.updateRowData(response['torrents'][key]);
|
torrentsTable.updateRowData(response['torrents'][key]);
|
||||||
if (addTorrentToCategoryList(response['torrents'][key]))
|
if (addTorrentToCategoryList(response['torrents'][key]))
|
||||||
update_categories = true;
|
update_categories = true;
|
||||||
|
if (addTorrentToTagList(response['torrents'][key]))
|
||||||
|
updateTags = true;
|
||||||
if (response['torrents'][key]['name'])
|
if (response['torrents'][key]['name'])
|
||||||
updateTorrentList = true;
|
updateTorrentList = true;
|
||||||
}
|
}
|
||||||
@ -430,6 +564,8 @@ window.addEvent('load', function() {
|
|||||||
torrentsTable.removeRow(hash);
|
torrentsTable.removeRow(hash);
|
||||||
removeTorrentFromCategoryList(hash);
|
removeTorrentFromCategoryList(hash);
|
||||||
update_categories = true; // Always to update All category
|
update_categories = true; // Always to update All category
|
||||||
|
removeTorrentFromTagList(hash);
|
||||||
|
updateTags = true; // Always to update All tag
|
||||||
});
|
});
|
||||||
torrentsTable.updateTable(full_update);
|
torrentsTable.updateTable(full_update);
|
||||||
torrentsTable.altRow();
|
torrentsTable.altRow();
|
||||||
@ -444,6 +580,10 @@ window.addEvent('load', function() {
|
|||||||
updateCategoryList();
|
updateCategoryList();
|
||||||
torrentsTableContextMenu.updateCategoriesSubMenu(category_list);
|
torrentsTableContextMenu.updateCategoriesSubMenu(category_list);
|
||||||
}
|
}
|
||||||
|
if (updateTags) {
|
||||||
|
updateTagList();
|
||||||
|
torrentsTableContextMenu.updateTagsSubMenu(tagList);
|
||||||
|
}
|
||||||
|
|
||||||
if (full_update)
|
if (full_update)
|
||||||
// re-select previously selected rows
|
// re-select previously selected rows
|
||||||
|
@ -293,6 +293,7 @@ var TorrentsTableContextMenu = new Class({
|
|||||||
var all_are_super_seeding = true;
|
var all_are_super_seeding = true;
|
||||||
var all_are_auto_tmm = true;
|
var all_are_auto_tmm = true;
|
||||||
var there_are_auto_tmm = false;
|
var there_are_auto_tmm = false;
|
||||||
|
const tagsSelectionState = Object.clone(tagList);
|
||||||
|
|
||||||
var h = torrentsTable.selectedRowsIds();
|
var h = torrentsTable.selectedRowsIds();
|
||||||
h.each(function(item, index) {
|
h.each(function(item, index) {
|
||||||
@ -327,6 +328,18 @@ var TorrentsTableContextMenu = new Class({
|
|||||||
there_are_auto_tmm = true;
|
there_are_auto_tmm = true;
|
||||||
else
|
else
|
||||||
all_are_auto_tmm = false;
|
all_are_auto_tmm = false;
|
||||||
|
|
||||||
|
const torrentTags = data['tags'].split(', ');
|
||||||
|
for (const key in tagsSelectionState) {
|
||||||
|
const tag = tagsSelectionState[key];
|
||||||
|
const tagExists = torrentTags.contains(tag.name);
|
||||||
|
if ((tag.checked !== undefined) && (tag.checked != tagExists))
|
||||||
|
tag.indeterminate = true;
|
||||||
|
if (tag.checked === undefined)
|
||||||
|
tag.checked = tagExists;
|
||||||
|
else
|
||||||
|
tag.checked = tag.checked && tagExists;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var show_seq_dl = true;
|
var show_seq_dl = true;
|
||||||
@ -389,6 +402,13 @@ var TorrentsTableContextMenu = new Class({
|
|||||||
this.setItemChecked('autoTorrentManagement', all_are_auto_tmm);
|
this.setItemChecked('autoTorrentManagement', all_are_auto_tmm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextTagList = $('contextTagList');
|
||||||
|
for (const tagHash in tagList) {
|
||||||
|
const checkbox = contextTagList.getElement('a[href=#Tag/' + tagHash + '] input[type=checkbox]');
|
||||||
|
const checkboxState = tagsSelectionState[tagHash];
|
||||||
|
checkbox.indeterminate = checkboxState.indeterminate;
|
||||||
|
checkbox.checked = checkboxState.checked;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateCategoriesSubMenu: function(category_list) {
|
updateCategoriesSubMenu: function(category_list) {
|
||||||
@ -419,6 +439,43 @@ var TorrentsTableContextMenu = new Class({
|
|||||||
}
|
}
|
||||||
categoryList.appendChild(el);
|
categoryList.appendChild(el);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateTagsSubMenu: function(tagList) {
|
||||||
|
const contextTagList = $('contextTagList');
|
||||||
|
while (contextTagList.firstChild !== null)
|
||||||
|
contextTagList.removeChild(contextTagList.firstChild);
|
||||||
|
|
||||||
|
contextTagList.appendChild(new Element('li', {
|
||||||
|
html: '<a href="javascript:torrentAddTagsFN();">'
|
||||||
|
+ '<img src="images/qbt-theme/list-add.svg" alt="QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||||
|
+ ' QBT_TR(Add...)QBT_TR[CONTEXT=TransferListWidget]'
|
||||||
|
+ '</a>'
|
||||||
|
}));
|
||||||
|
contextTagList.appendChild(new Element('li', {
|
||||||
|
html: '<a href="javascript:torrentRemoveAllTagsFN();">'
|
||||||
|
+ '<img src="images/qbt-theme/edit-clear.svg" alt="QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]"/>'
|
||||||
|
+ ' QBT_TR(Remove All)QBT_TR[CONTEXT=TransferListWidget]'
|
||||||
|
+ '</a>'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const sortedTags = [];
|
||||||
|
for (const key in tagList)
|
||||||
|
sortedTags.push(tagList[key].name);
|
||||||
|
sortedTags.sort();
|
||||||
|
|
||||||
|
for (let i = 0; i < sortedTags.length; ++i) {
|
||||||
|
const tagName = sortedTags[i];
|
||||||
|
const tagHash = genHash(tagName);
|
||||||
|
const el = new Element('li', {
|
||||||
|
html: '<a href="#Tag/' + tagHash + '" onclick="event.preventDefault(); torrentSetTagsFN(\'' + tagHash + '\', !event.currentTarget.getElement(\'input[type=checkbox]\').checked);">'
|
||||||
|
+ '<input type="checkbox" onclick="this.checked = !this.checked;"> ' + escapeHtml(tagName)
|
||||||
|
+ '</a>'
|
||||||
|
});
|
||||||
|
if (i === 0)
|
||||||
|
el.addClass('separator');
|
||||||
|
contextTagList.appendChild(el);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -437,6 +494,17 @@ var CategoriesFilterContextMenu = new Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TagsFilterContextMenu = new Class({
|
||||||
|
Extends: ContextMenu,
|
||||||
|
updateMenuItems: function() {
|
||||||
|
const id = this.options.element.id;
|
||||||
|
if ((id !== TAGS_ALL.toString()) && (id !== TAGS_UNTAGGED.toString()))
|
||||||
|
this.showItem('deleteTag');
|
||||||
|
else
|
||||||
|
this.hideItem('deleteTag');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var SearchPluginsTableContextMenu = new Class({
|
var SearchPluginsTableContextMenu = new Class({
|
||||||
Extends: ContextMenu,
|
Extends: ContextMenu,
|
||||||
|
|
||||||
|
@ -1183,7 +1183,7 @@ var TorrentsTable = new Class({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
applyFilter: function(row, filterName, categoryHash, filterTerms) {
|
applyFilter: function(row, filterName, categoryHash, tagHash, filterTerms) {
|
||||||
var state = row['full_data'].state;
|
var state = row['full_data'].state;
|
||||||
var name = row['full_data'].name.toLowerCase();
|
var name = row['full_data'].name.toLowerCase();
|
||||||
var inactive = false;
|
var inactive = false;
|
||||||
@ -1242,6 +1242,28 @@ var TorrentsTable = new Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tagHashInt = parseInt(tagHash);
|
||||||
|
const isNumber = !isNaN(tagHashInt);
|
||||||
|
if (isNumber) {
|
||||||
|
switch (tagHashInt) {
|
||||||
|
case TAGS_ALL:
|
||||||
|
break; // do nothing
|
||||||
|
|
||||||
|
case TAGS_UNTAGGED:
|
||||||
|
if (row['full_data'].tags.length !== 0)
|
||||||
|
return false;
|
||||||
|
break; // do nothing
|
||||||
|
|
||||||
|
default:
|
||||||
|
let rowTags = row['full_data'].tags.split(', ');
|
||||||
|
rowTags = rowTags.map(function(tag) {
|
||||||
|
return genHash(tag);
|
||||||
|
});
|
||||||
|
if (!rowTags.contains(tagHashInt))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (filterTerms) {
|
if (filterTerms) {
|
||||||
for (var i = 0; i < filterTerms.length; ++i) {
|
for (var i = 0; i < filterTerms.length; ++i) {
|
||||||
if (name.indexOf(filterTerms[i]) === -1)
|
if (name.indexOf(filterTerms[i]) === -1)
|
||||||
@ -1252,21 +1274,21 @@ var TorrentsTable = new Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
getFilteredTorrentsNumber: function(filterName, categoryHash) {
|
getFilteredTorrentsNumber: function(filterName, categoryHash, tagHash) {
|
||||||
var cnt = 0;
|
var cnt = 0;
|
||||||
var rows = this.rows.getValues();
|
var rows = this.rows.getValues();
|
||||||
|
|
||||||
for (var i = 0; i < rows.length; ++i)
|
for (var i = 0; i < rows.length; ++i)
|
||||||
if (this.applyFilter(rows[i], filterName, categoryHash, null)) ++cnt;
|
if (this.applyFilter(rows[i], filterName, categoryHash, tagHash, null)) ++cnt;
|
||||||
return cnt;
|
return cnt;
|
||||||
},
|
},
|
||||||
|
|
||||||
getFilteredTorrentsHashes: function(filterName, categoryHash) {
|
getFilteredTorrentsHashes: function(filterName, categoryHash, tagHash) {
|
||||||
var rowsHashes = [];
|
var rowsHashes = [];
|
||||||
var rows = this.rows.getValues();
|
var rows = this.rows.getValues();
|
||||||
|
|
||||||
for (var i = 0; i < rows.length; ++i)
|
for (var i = 0; i < rows.length; ++i)
|
||||||
if (this.applyFilter(rows[i], filterName, categoryHash, null))
|
if (this.applyFilter(rows[i], filterName, categoryHash, tagHash, null))
|
||||||
rowsHashes.push(rows[i]['rowId']);
|
rowsHashes.push(rows[i]['rowId']);
|
||||||
|
|
||||||
return rowsHashes;
|
return rowsHashes;
|
||||||
@ -1280,7 +1302,7 @@ var TorrentsTable = new Class({
|
|||||||
var filterTerms = (filterText.length > 0) ? filterText.split(" ") : null;
|
var filterTerms = (filterText.length > 0) ? filterText.split(" ") : null;
|
||||||
|
|
||||||
for (var i = 0; i < rows.length; ++i) {
|
for (var i = 0; i < rows.length; ++i) {
|
||||||
if (this.applyFilter(rows[i], selected_filter, selected_category, filterTerms)) {
|
if (this.applyFilter(rows[i], selected_filter, selected_category, selectedTag, filterTerms)) {
|
||||||
filteredRows.push(rows[i]);
|
filteredRows.push(rows[i]);
|
||||||
filteredRows[rows[i].rowId] = rows[i];
|
filteredRows[rows[i].rowId] = rows[i];
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,15 @@ var deleteUnusedCategoriesFN = function() {};
|
|||||||
var startTorrentsByCategoryFN = function() {};
|
var startTorrentsByCategoryFN = function() {};
|
||||||
var pauseTorrentsByCategoryFN = function() {};
|
var pauseTorrentsByCategoryFN = function() {};
|
||||||
var deleteTorrentsByCategoryFN = function() {};
|
var deleteTorrentsByCategoryFN = function() {};
|
||||||
|
let torrentAddTagsFN = function() {};
|
||||||
|
let torrentSetTagsFN = function() {};
|
||||||
|
let torrentRemoveAllTagsFN = function() {};
|
||||||
|
let createTagFN = function() {};
|
||||||
|
let removeTagFN = function() {};
|
||||||
|
let deleteUnusedTagsFN = function() {};
|
||||||
|
let startTorrentsByTagFN = function() {};
|
||||||
|
let pauseTorrentsByTagFN = function() {};
|
||||||
|
let deleteTorrentsByTagFN = function() {};
|
||||||
var copyNameFN = function() {};
|
var copyNameFN = function() {};
|
||||||
var copyMagnetLinkFN = function() {};
|
var copyMagnetLinkFN = function() {};
|
||||||
var copyHashFN = function() {};
|
var copyHashFN = function() {};
|
||||||
@ -616,7 +625,7 @@ var initializeWindows = function() {
|
|||||||
deleteUnusedCategoriesFN = function() {
|
deleteUnusedCategoriesFN = function() {
|
||||||
var categories = [];
|
var categories = [];
|
||||||
for (var hash in category_list) {
|
for (var hash in category_list) {
|
||||||
if (torrentsTable.getFilteredTorrentsNumber('all', hash) === 0)
|
if (torrentsTable.getFilteredTorrentsNumber('all', hash, TAGS_ALL) === 0)
|
||||||
categories.push(category_list[hash].name);
|
categories.push(category_list[hash].name);
|
||||||
}
|
}
|
||||||
new Request({
|
new Request({
|
||||||
@ -630,7 +639,7 @@ var initializeWindows = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
startTorrentsByCategoryFN = function(categoryHash) {
|
startTorrentsByCategoryFN = function(categoryHash) {
|
||||||
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash, TAGS_ALL);
|
||||||
if (hashes.length) {
|
if (hashes.length) {
|
||||||
new Request({
|
new Request({
|
||||||
url: 'api/v2/torrents/resume',
|
url: 'api/v2/torrents/resume',
|
||||||
@ -644,7 +653,7 @@ var initializeWindows = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pauseTorrentsByCategoryFN = function(categoryHash) {
|
pauseTorrentsByCategoryFN = function(categoryHash) {
|
||||||
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash, TAGS_ALL);
|
||||||
if (hashes.length) {
|
if (hashes.length) {
|
||||||
new Request({
|
new Request({
|
||||||
url: 'api/v2/torrents/pause',
|
url: 'api/v2/torrents/pause',
|
||||||
@ -658,7 +667,148 @@ var initializeWindows = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
deleteTorrentsByCategoryFN = function(categoryHash) {
|
deleteTorrentsByCategoryFN = function(categoryHash) {
|
||||||
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash);
|
var hashes = torrentsTable.getFilteredTorrentsHashes('all', categoryHash, TAGS_ALL);
|
||||||
|
if (hashes.length) {
|
||||||
|
new MochaUI.Window({
|
||||||
|
id: 'confirmDeletionPage',
|
||||||
|
title: "QBT_TR(Deletion confirmation)QBT_TR[CONTEXT=confirmDeletionDlg]",
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL: 'confirmdeletion.html?hashes=' + hashes.join("|"),
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
padding: 10,
|
||||||
|
width: 424,
|
||||||
|
height: 140
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
torrentAddTagsFN = function() {
|
||||||
|
const action = "set";
|
||||||
|
const hashes = torrentsTable.selectedRowsIds();
|
||||||
|
if (hashes.length) {
|
||||||
|
new MochaUI.Window({
|
||||||
|
id: 'newTagPage',
|
||||||
|
title: "QBT_TR(Add Tags)QBT_TR[CONTEXT=TransferListWidget]",
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL: 'newtag.html?action=' + action + '&hashes=' + hashes.join('|'),
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
paddingVertical: 0,
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
width: 250,
|
||||||
|
height: 100
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
torrentSetTagsFN = function(tagHash, isSet) {
|
||||||
|
const tagName = ((tagHash === '0') ? '' : tagList[tagHash].name);
|
||||||
|
const hashes = torrentsTable.selectedRowsIds();
|
||||||
|
if (hashes.length) {
|
||||||
|
new Request({
|
||||||
|
url: (isSet ? 'api/v2/torrents/addTags' : 'api/v2/torrents/removeTags'),
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: hashes.join("|"),
|
||||||
|
tags: tagName,
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
torrentRemoveAllTagsFN = function() {
|
||||||
|
const hashes = torrentsTable.selectedRowsIds();
|
||||||
|
if (hashes.length) {
|
||||||
|
new Request({
|
||||||
|
url: ('api/v2/torrents/removeTags'),
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: hashes.join("|"),
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
createTagFN = function() {
|
||||||
|
const action = "create";
|
||||||
|
new MochaUI.Window({
|
||||||
|
id: 'newTagPage',
|
||||||
|
title: "QBT_TR(New Tag)QBT_TR[CONTEXT=TagFilterWidget]",
|
||||||
|
loadMethod: 'iframe',
|
||||||
|
contentURL: 'newtag.html?action=' + action,
|
||||||
|
scrollbars: false,
|
||||||
|
resizable: false,
|
||||||
|
maximizable: false,
|
||||||
|
paddingVertical: 0,
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
width: 250,
|
||||||
|
height: 100
|
||||||
|
});
|
||||||
|
updateMainData();
|
||||||
|
};
|
||||||
|
|
||||||
|
removeTagFN = function(tagHash) {
|
||||||
|
const tagName = tagList[tagHash].name;
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/deleteTags',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
tags: tagName
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
setTagFilter(TAGS_ALL);
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteUnusedTagsFN = function() {
|
||||||
|
const tags = [];
|
||||||
|
for (const hash in tagList) {
|
||||||
|
if (torrentsTable.getFilteredTorrentsNumber('all', CATEGORIES_ALL, hash) === 0)
|
||||||
|
tags.push(tagList[hash].name);
|
||||||
|
}
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/deleteTags',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
tags: tags.join(',')
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
setTagFilter(TAGS_ALL);
|
||||||
|
};
|
||||||
|
|
||||||
|
startTorrentsByTagFN = function(tagHash) {
|
||||||
|
const hashes = torrentsTable.getFilteredTorrentsHashes('all', CATEGORIES_ALL, tagHash);
|
||||||
|
if (hashes.length) {
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/resume',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: hashes.join("|")
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pauseTorrentsByTagFN = function(tagHash) {
|
||||||
|
const hashes = torrentsTable.getFilteredTorrentsHashes('all', CATEGORIES_ALL, tagHash);
|
||||||
|
if (hashes.length) {
|
||||||
|
new Request({
|
||||||
|
url: 'api/v2/torrents/pause',
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
hashes: hashes.join("|")
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
updateMainData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteTorrentsByTagFN = function(tagHash) {
|
||||||
|
const hashes = torrentsTable.getFilteredTorrentsHashes('all', CATEGORIES_ALL, tagHash);
|
||||||
if (hashes.length) {
|
if (hashes.length) {
|
||||||
new MochaUI.Window({
|
new MochaUI.Window({
|
||||||
id: 'confirmDeletionPage',
|
id: 'confirmDeletionPage',
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
<file>private/index.html</file>
|
<file>private/index.html</file>
|
||||||
<file>private/installsearchplugin.html</file>
|
<file>private/installsearchplugin.html</file>
|
||||||
<file>private/newcategory.html</file>
|
<file>private/newcategory.html</file>
|
||||||
|
<file>private/newtag.html</file>
|
||||||
<file>private/preferences.html</file>
|
<file>private/preferences.html</file>
|
||||||
<file>private/preferences_content.html</file>
|
<file>private/preferences_content.html</file>
|
||||||
<file>private/properties.html</file>
|
<file>private/properties.html</file>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user