diff --git a/src/webui/www/private/confirmfeeddeletion.html b/src/webui/www/private/confirmfeeddeletion.html
new file mode 100644
index 000000000..ad34122d4
--- /dev/null
+++ b/src/webui/www/private/confirmfeeddeletion.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ QBT_TR(Deletion confirmation)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/confirmruleclear.html b/src/webui/www/private/confirmruleclear.html
new file mode 100644
index 000000000..75314288a
--- /dev/null
+++ b/src/webui/www/private/confirmruleclear.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+ QBT_TR(Clear downloaded episodes)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/confirmruledeletion.html b/src/webui/www/private/confirmruledeletion.html
new file mode 100644
index 000000000..2b0ed7090
--- /dev/null
+++ b/src/webui/www/private/confirmruledeletion.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+ QBT_TR(Rule deletion confirmation)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/css/Tabs.css b/src/webui/www/private/css/Tabs.css
index c6c115d35..0de8965ee 100644
--- a/src/webui/www/private/css/Tabs.css
+++ b/src/webui/www/private/css/Tabs.css
@@ -34,7 +34,6 @@ Required by:
}
.tab-menu li {
- display: block;
float: left;
margin: 0 0 5px 0;
cursor: pointer;
diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html
index 80c76c841..7e97c4836 100644
--- a/src/webui/www/private/index.html
+++ b/src/webui/www/private/index.html
@@ -74,6 +74,7 @@
QBT_TR(Status Bar)QBT_TR[CONTEXT=MainWindow]
QBT_TR(Speed in Title Bar)QBT_TR[CONTEXT=MainWindow]
QBT_TR(Search Engine)QBT_TR[CONTEXT=MainWindow]
+
QBT_TR(Statistics)QBT_TR[CONTEXT=MainWindow]
@@ -112,6 +113,7 @@
diff --git a/src/webui/www/private/newfeed.html b/src/webui/www/private/newfeed.html
new file mode 100644
index 000000000..07ae77edf
--- /dev/null
+++ b/src/webui/www/private/newfeed.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+ QBT_TR(Please type a RSS feed URL)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
+
+
QBT_TR(Feed URL:)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/newfolder.html b/src/webui/www/private/newfolder.html
new file mode 100644
index 000000000..4f2cc121a
--- /dev/null
+++ b/src/webui/www/private/newfolder.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+ QBT_TR(Please choose a folder name)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
+
+
QBT_TR(Folder name:)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/newrule.html b/src/webui/www/private/newrule.html
new file mode 100644
index 000000000..cc46cb20c
--- /dev/null
+++ b/src/webui/www/private/newrule.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+ QBT_TR(New rule name)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
+
+
QBT_TR(Please type the name of the new download rule.)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/rename_feed.html b/src/webui/www/private/rename_feed.html
new file mode 100644
index 000000000..7153f9a0b
--- /dev/null
+++ b/src/webui/www/private/rename_feed.html
@@ -0,0 +1,88 @@
+
+
+
+
+
+ QBT_TR(Please choose a new name for this RSS feed)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
+
+
QBT_TR(New feed name:)QBT_TR[CONTEXT=RSSWidget]
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/rename_rule.html b/src/webui/www/private/rename_rule.html
new file mode 100644
index 000000000..b36ca965c
--- /dev/null
+++ b/src/webui/www/private/rename_rule.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+ QBT_TR(Rule renaming)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
+
+
QBT_TR(Please type the new rule name)QBT_TR[CONTEXT=AutomatedRssDownloader]
+
+
+
+
+
+
+
+
diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js
index 07f7f3491..d30967b45 100644
--- a/src/webui/www/private/scripts/client.js
+++ b/src/webui/www/private/scripts/client.js
@@ -34,6 +34,7 @@ let queueing_enabled = true;
let serverSyncMainDataInterval = 1500;
let customSyncMainDataInterval = null;
let searchTabInitialized = false;
+let rssTabInitialized = false;
let syncRequestInProgress = false;
@@ -171,8 +172,20 @@ window.addEvent('load', function() {
$("searchTabColumn").addClass("invisible");
};
+ const buildRssTab = function() {
+ new MochaUI.Column({
+ id: 'rssTabColumn',
+ placement: 'main',
+ width: null
+ });
+
+ // start off hidden
+ $("rssTabColumn").addClass("invisible");
+ };
+
buildTransfersTab();
buildSearchTab();
+ buildRssTab();
MochaUI.initializeTabs('mainWindowTabsList');
setCategoryFilter = function(hash) {
@@ -275,12 +288,7 @@ window.addEvent('load', function() {
// After showing/hiding the toolbar + status bar
let showSearchEngine = LocalPreferences.get('show_search_engine') !== "false";
- if (!showSearchEngine) {
- // uncheck menu option
- $('showSearchEngineLink').firstChild.style.opacity = '0';
- // hide tabs
- $('mainWindowTabs').addClass('invisible');
- }
+ let showRssReader = LocalPreferences.get('show_rss_reader') !== "false";
// After Show Top Toolbar
MochaUI.Desktop.setDesktopSize();
@@ -860,22 +868,48 @@ window.addEvent('load', function() {
$('showSearchEngineLink').addEvent('click', function(e) {
showSearchEngine = !showSearchEngine;
LocalPreferences.set('show_search_engine', showSearchEngine.toString());
+ updateTabDisplay();
+ });
+
+ $('showRssReaderLink').addEvent('click', function(e) {
+ showRssReader = !showRssReader;
+ LocalPreferences.set('show_rss_reader', showRssReader.toString());
+ updateTabDisplay();
+ });
+
+ const updateTabDisplay = function() {
+ if (showRssReader) {
+ $('showRssReaderLink').firstChild.style.opacity = '1';
+ $('mainWindowTabs').removeClass('invisible');
+ $('rssTabLink').removeClass('invisible');
+ if (!MochaUI.Panels.instances.RssPanel)
+ addRssPanel();
+ }
+ else {
+ $('showRssReaderLink').firstChild.style.opacity = '0';
+ $('rssTabLink').addClass('invisible');
+ if ($('rssTabLink').hasClass('selected'))
+ $("transfersTabLink").click();
+ }
+
if (showSearchEngine) {
$('showSearchEngineLink').firstChild.style.opacity = '1';
$('mainWindowTabs').removeClass('invisible');
-
- addMainWindowTabsEventListener();
+ $('searchTabLink').removeClass('invisible');
if (!MochaUI.Panels.instances.SearchPanel)
addSearchPanel();
}
else {
$('showSearchEngineLink').firstChild.style.opacity = '0';
- $('mainWindowTabs').addClass('invisible');
- $("transfersTabLink").click();
-
- removeMainWindowTabsEventListener();
+ $('searchTabLink').addClass('invisible');
+ if ($('searchTabLink').hasClass('selected'))
+ $("transfersTabLink").click();
}
- });
+
+ // display no tabs
+ if (!showRssReader && !showSearchEngine)
+ $('mainWindowTabs').addClass('invisible');
+ };
$('StatisticsLink').addEvent('click', StatisticsLinkFN);
@@ -890,6 +924,7 @@ window.addEvent('load', function() {
syncData(100);
hideSearchTab();
+ hideRssTab();
};
const hideTransfersTab = function() {
@@ -908,6 +943,7 @@ window.addEvent('load', function() {
$("searchTabColumn").removeClass("invisible");
customSyncMainDataInterval = 30000;
hideTransfersTab();
+ hideRssTab();
};
const hideSearchTab = function() {
@@ -915,14 +951,25 @@ window.addEvent('load', function() {
MochaUI.Desktop.resizePanels();
};
- const addMainWindowTabsEventListener = function() {
- $('transfersTabLink').addEvent('click', showTransfersTab);
- $('searchTabLink').addEvent('click', showSearchTab);
+ const showRssTab = function() {
+ if (!rssTabInitialized) {
+ window.qBittorrent.Rss.init();
+ rssTabInitialized = true;
+ }
+ else {
+ window.qBittorrent.Rss.load();
+ }
+
+ $("rssTabColumn").removeClass("invisible");
+ customSyncMainDataInterval = 30000;
+ hideTransfersTab();
+ hideSearchTab();
};
- const removeMainWindowTabsEventListener = function() {
- $('transfersTabLink').removeEvent('click', showTransfersTab);
- $('searchTabLink').removeEvent('click', showSearchTab);
+ const hideRssTab = function() {
+ $("rssTabColumn").addClass("invisible");
+ window.qBittorrent.Rss.unload();
+ MochaUI.Desktop.resizePanels();
};
const addSearchPanel = function() {
@@ -944,6 +991,25 @@ window.addEvent('load', function() {
});
};
+ const addRssPanel = function() {
+ new MochaUI.Panel({
+ id: 'RssPanel',
+ title: 'Rss',
+ header: false,
+ padding: {
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ },
+ loadMethod: 'xhr',
+ contentURL: 'views/rss.html',
+ content: '',
+ column: 'rssTabColumn',
+ height: null
+ });
+ };
+
new MochaUI.Panel({
id: 'transferList',
title: 'Panel',
@@ -1081,10 +1147,10 @@ window.addEvent('load', function() {
}
});
- if (showSearchEngine) {
- addMainWindowTabsEventListener();
- addSearchPanel();
- }
+ $('transfersTabLink').addEvent('click', showTransfersTab);
+ $('searchTabLink').addEvent('click', showSearchTab);
+ $('rssTabLink').addEvent('click', showRssTab);
+ updateTabDisplay();
});
function registerMagnetHandler() {
diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js
index 5179ef470..b4fdec732 100644
--- a/src/webui/www/private/scripts/contextmenu.js
+++ b/src/webui/www/private/scripts/contextmenu.js
@@ -39,7 +39,10 @@ window.qBittorrent.ContextMenu = (function() {
TorrentsTableContextMenu: TorrentsTableContextMenu,
CategoriesFilterContextMenu: CategoriesFilterContextMenu,
TagsFilterContextMenu: TagsFilterContextMenu,
- SearchPluginsTableContextMenu: SearchPluginsTableContextMenu
+ SearchPluginsTableContextMenu: SearchPluginsTableContextMenu,
+ RssFeedContextMenu: RssFeedContextMenu,
+ RssArticleContextMenu: RssArticleContextMenu,
+ RssDownloaderRuleContextMenu: RssDownloaderRuleContextMenu
};
};
@@ -538,5 +541,129 @@ window.qBittorrent.ContextMenu = (function() {
}
});
+ const RssFeedContextMenu = new Class({
+ Extends: ContextMenu,
+ updateMenuItems: function() {
+ let selectedRows = window.qBittorrent.Rss.rssFeedTable.selectedRowsIds();
+ this.menu.getElement('a[href$=newSubscription]').parentNode.addClass('separator');
+ switch (selectedRows.length) {
+ case 0:
+ // remove seperator on top of newSubscription entry to avoid double line
+ this.menu.getElement('a[href$=newSubscription]').parentNode.removeClass('separator');
+ // menu when nothing selected
+ this.hideItem('update');
+ this.hideItem('markRead');
+ this.hideItem('rename');
+ this.hideItem('delete');
+ this.showItem('newSubscription');
+ this.showItem('newFolder');
+ this.showItem('updateAll');
+ this.hideItem('copyFeedURL');
+ break;
+ case 1:
+ if (selectedRows[0] === 0) {
+ // menu when "unread" feed selected
+ this.showItem('update');
+ this.showItem('markRead');
+ this.hideItem('rename');
+ this.hideItem('delete');
+ this.showItem('newSubscription');
+ this.hideItem('newFolder');
+ this.hideItem('updateAll');
+ this.hideItem('copyFeedURL');
+ }
+ else if (window.qBittorrent.Rss.rssFeedTable.rows[selectedRows[0]].full_data.dataUid === '') {
+ // menu when single folder selected
+ this.showItem('update');
+ this.showItem('markRead');
+ this.showItem('rename');
+ this.showItem('delete');
+ this.showItem('newSubscription');
+ this.showItem('newFolder');
+ this.hideItem('updateAll');
+ this.hideItem('copyFeedURL');
+ }
+ else {
+ // menu when single feed selected
+ this.showItem('update');
+ this.showItem('markRead');
+ this.showItem('rename');
+ this.showItem('delete');
+ this.showItem('newSubscription');
+ this.hideItem('newFolder');
+ this.hideItem('updateAll');
+ this.showItem('copyFeedURL');
+ }
+ break;
+ default:
+ // menu when multiple items selected
+ this.showItem('update');
+ this.showItem('markRead');
+ this.hideItem('rename');
+ this.showItem('delete');
+ this.hideItem('newSubscription');
+ this.hideItem('newFolder');
+ this.hideItem('updateAll');
+ this.showItem('copyFeedURL');
+ }
+ }
+ });
+
+ const RssArticleContextMenu = new Class({
+ Extends: ContextMenu
+ });
+
+ const RssDownloaderRuleContextMenu = new Class({
+ Extends: ContextMenu,
+ adjustMenuPosition: function(e) {
+ this.updateMenuItems();
+
+ // draw the menu off-screen to know the menu dimensions
+ this.menu.setStyles({
+ left: '-999em',
+ top: '-999em'
+ });
+ // position the menu
+ let xPosMenu = e.page.x + this.options.offsets.x - $('rssdownloaderpage').offsetLeft;
+ let yPosMenu = e.page.y + this.options.offsets.y - $('rssdownloaderpage').offsetTop;
+ if ((xPosMenu + this.menu.offsetWidth) > document.documentElement.clientWidth)
+ xPosMenu -= this.menu.offsetWidth;
+ if ((yPosMenu + this.menu.offsetHeight) > document.documentElement.clientHeight)
+ yPosMenu = document.documentElement.clientHeight - this.menu.offsetHeight;
+ xPosMenu = Math.max(xPosMenu, 0);
+ yPosMenu = Math.max(yPosMenu, 0);
+
+ this.menu.setStyles({
+ left: xPosMenu,
+ top: yPosMenu,
+ position: 'absolute',
+ 'z-index': '2000'
+ });
+ },
+ updateMenuItems: function() {
+ let selectedRows = window.qBittorrent.RssDownloader.rssDownloaderRulesTable.selectedRowsIds();
+ this.showItem('addRule');
+ switch (selectedRows.length) {
+ case 0:
+ // menu when nothing selected
+ this.hideItem('deleteRule');
+ this.hideItem('renameRule');
+ this.hideItem('clearDownloadedEpisodes');
+ break;
+ case 1:
+ // menu when single item selected
+ this.showItem('deleteRule');
+ this.showItem('renameRule');
+ this.showItem('clearDownloadedEpisodes');
+ break;
+ default:
+ // menu when multiple items selected
+ this.showItem('deleteRule');
+ this.hideItem('renameRule');
+ this.showItem('clearDownloadedEpisodes');
+ }
+ }
+ });
+
return exports();
})();
diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js
index 7c1f25b53..6b60a8e58 100644
--- a/src/webui/www/private/scripts/dynamicTable.js
+++ b/src/webui/www/private/scripts/dynamicTable.js
@@ -45,7 +45,12 @@ window.qBittorrent.DynamicTable = (function() {
SearchResultsTable: SearchResultsTable,
SearchPluginsTable: SearchPluginsTable,
TorrentTrackersTable: TorrentTrackersTable,
- TorrentFilesTable: TorrentFilesTable
+ TorrentFilesTable: TorrentFilesTable,
+ RssFeedTable: RssFeedTable,
+ RssArticleTable: RssArticleTable,
+ RssDownloaderRulesTable: RssDownloaderRulesTable,
+ RssDownloaderFeedSelectionTable: RssDownloaderFeedSelectionTable,
+ RssDownloaderArticlesTable: RssDownloaderArticlesTable
};
};
@@ -1867,7 +1872,7 @@ window.qBittorrent.DynamicTable = (function() {
if (tr.hasClass("invisible"))
return;
- if (addClass){
+ if (addClass) {
tr.addClass("alt");
tr.removeClass("nonAlt");
}
@@ -2000,6 +2005,492 @@ window.qBittorrent.DynamicTable = (function() {
}
});
+ const RssFeedTable = new Class({
+ Extends: DynamicTable,
+ initColumns: function() {
+ this.newColumn('state_icon', '', '', 30, true);
+ this.newColumn('name', '', 'QBT_TR(RSS feeds)QBT_TR[CONTEXT=FeedListWidget]', -1, true);
+
+ this.columns['state_icon'].dataProperties[0] = '';
+
+ // map name row to "[name] ([unread])"
+ this.columns['name'].dataProperties.push('unread');
+ this.columns['name'].updateTd = function(td, row) {
+ const name = this.getRowValue(row, 0);
+ const unreadCount = this.getRowValue(row, 1);
+ let value = name + ' (' + unreadCount + ')';
+ td.set('text', value);
+ td.set('title', value);
+ };
+ },
+ setupHeaderMenu: function() {},
+ setupHeaderEvents: function() {},
+ getFilteredAndSortedRows: function() {
+ return this.rows.getValues();
+ },
+ selectRow: function(rowId) {
+ this.selectedRows.push(rowId);
+ this.setRowClass();
+ this.onSelectedRowChanged();
+
+ const rows = this.rows.getValues();
+ let path = '';
+ for (let i = 0; i < rows.length; ++i) {
+ if (rows[i].rowId === rowId) {
+ path = rows[i].full_data.dataPath;
+ break;
+ }
+ }
+ window.qBittorrent.Rss.showRssFeed(path);
+ },
+ setupTr: function(tr) {
+ tr.addEvent('dblclick', function(e) {
+ if (this.rowId !== 0) {
+ window.qBittorrent.Rss.moveItem(this._this.rows.get(this.rowId).full_data.dataPath);
+ return true;
+ }
+ });
+ },
+ updateRow: function(tr, fullUpdate) {
+ const row = this.rows.get(tr.rowId);
+ const data = row[fullUpdate ? 'full_data' : 'data'];
+
+ const tds = tr.getElements('td');
+ for (let i = 0; i < this.columns.length; ++i) {
+ if (data.hasOwnProperty(this.columns[i].dataProperties[0]))
+ this.columns[i].updateTd(tds[i], row);
+ }
+ row['data'] = {};
+ tds[0].style.overflow = 'visible';
+ let indentaion = row.full_data.indentaion;
+ tds[0].style.paddingLeft = (indentaion * 32 + 4) + 'px';
+ tds[1].style.paddingLeft = (indentaion * 32 + 4) + 'px';
+ },
+ updateIcons: function() {
+ // state_icon
+ this.rows.each(row => {
+ let img_path;
+ switch (row.full_data.status) {
+ case 'default':
+ img_path = 'icons/application-rss+xml.svg';
+ break;
+ case 'hasError':
+ img_path = 'icons/unavailable.svg';
+ break;
+ case 'isLoading':
+ img_path = 'images/spinner.gif';
+ break;
+ case 'unread':
+ img_path = 'icons/mail-folder-inbox.svg';
+ break;
+ case 'isFolder':
+ img_path = 'icons/folder-documents.svg';
+ break;
+ }
+ let td;
+ for (let i = 0; i < this.tableBody.rows.length; ++i) {
+ if (this.tableBody.rows[i].rowId === row.rowId) {
+ td = this.tableBody.rows[i].children[0];
+ break;
+ }
+ }
+ if (td.getChildren('img').length > 0) {
+ const img = td.getChildren('img')[0];
+ if (img.src.indexOf(img_path) < 0) {
+ img.set('src', img_path);
+ img.set('title', status);
+ }
+ }
+ else {
+ td.adopt(new Element('img', {
+ 'src': img_path,
+ 'class': 'stateIcon',
+ 'height': '22px',
+ 'width': '22px'
+ }));
+ }
+ });
+ },
+ newColumn: function(name, style, caption, defaultWidth, defaultVisible) {
+ const column = {};
+ column['name'] = name;
+ column['title'] = name;
+ column['visible'] = defaultVisible;
+ column['force_hide'] = false;
+ column['caption'] = caption;
+ column['style'] = style;
+ if (defaultWidth !== -1) {
+ column['width'] = defaultWidth;
+ }
+
+ column['dataProperties'] = [name];
+ column['getRowValue'] = function(row, pos) {
+ if (pos === undefined)
+ pos = 0;
+ return row['full_data'][this.dataProperties[pos]];
+ };
+ column['compareRows'] = function(row1, row2) {
+ if (this.getRowValue(row1) < this.getRowValue(row2))
+ return -1;
+ else if (this.getRowValue(row1) > this.getRowValue(row2))
+ return 1;
+ else return 0;
+ };
+ column['updateTd'] = function(td, row) {
+ const value = this.getRowValue(row)
+ td.set('text', value);
+ td.set('title', value);
+ };
+ column['onResize'] = null;
+ this.columns.push(column);
+ this.columns[name] = column;
+
+ this.hiddenTableHeader.appendChild(new Element('th'));
+ this.fixedTableHeader.appendChild(new Element('th'));
+ },
+ setupCommonEvents: function() {
+ const scrollFn = function() {
+ $(this.dynamicTableFixedHeaderDivId).getElements('table')[0].style.left = -$(this.dynamicTableDivId).scrollLeft + 'px';
+ }.bind(this);
+
+ $(this.dynamicTableDivId).addEvent('scroll', scrollFn);
+ }
+ });
+
+ const RssArticleTable = new Class({
+ Extends: DynamicTable,
+ initColumns: function() {
+ this.newColumn('name', '', 'QBT_TR(Torrents: (double-click to download))QBT_TR[CONTEXT=RSSWidget]', -1, true);
+ },
+ setupHeaderMenu: function() {},
+ setupHeaderEvents: function() {},
+ getFilteredAndSortedRows: function() {
+ return this.rows.getValues();
+ },
+ selectRow: function(rowId) {
+ this.selectedRows.push(rowId);
+ this.setRowClass();
+ this.onSelectedRowChanged();
+
+ const rows = this.rows.getValues();
+ let articleId = '';
+ let feedUid = '';
+ for (let i = 0; i < rows.length; ++i) {
+ if (rows[i].rowId === rowId) {
+ articleId = rows[i].full_data.dataId;
+ feedUid = rows[i].full_data.feedUid;
+ this.tableBody.rows[rows[i].rowId].removeClass('unreadArticle');
+ break;
+ }
+ }
+ window.qBittorrent.Rss.showDetails(feedUid, articleId);
+ },
+ setupTr: function(tr) {
+ tr.addEvent('dblclick', function(e) {
+ showDownloadPage([this._this.rows.get(this.rowId).full_data.torrentURL]);
+ return true;
+ });
+ tr.addClass('torrentsTableContextMenuTarget');
+ },
+ updateRow: function(tr, fullUpdate) {
+ const row = this.rows.get(tr.rowId);
+ const data = row[fullUpdate ? 'full_data' : 'data'];
+ if (!row.full_data.isRead)
+ tr.addClass('unreadArticle');
+ else
+ tr.removeClass('unreadArticle');
+
+ const tds = tr.getElements('td');
+ for (let i = 0; i < this.columns.length; ++i) {
+ if (data.hasOwnProperty(this.columns[i].dataProperties[0]))
+ this.columns[i].updateTd(tds[i], row);
+ }
+ row['data'] = {};
+ },
+ newColumn: function(name, style, caption, defaultWidth, defaultVisible) {
+ const column = {};
+ column['name'] = name;
+ column['title'] = name;
+ column['visible'] = defaultVisible;
+ column['force_hide'] = false;
+ column['caption'] = caption;
+ column['style'] = style;
+ if (defaultWidth !== -1) {
+ column['width'] = defaultWidth;
+ }
+
+ column['dataProperties'] = [name];
+ column['getRowValue'] = function(row, pos) {
+ if (pos === undefined)
+ pos = 0;
+ return row['full_data'][this.dataProperties[pos]];
+ };
+ column['compareRows'] = function(row1, row2) {
+ if (this.getRowValue(row1) < this.getRowValue(row2))
+ return -1;
+ else if (this.getRowValue(row1) > this.getRowValue(row2))
+ return 1;
+ else return 0;
+ };
+ column['updateTd'] = function(td, row) {
+ const value = this.getRowValue(row)
+ td.set('text', value);
+ td.set('title', value);
+ };
+ column['onResize'] = null;
+ this.columns.push(column);
+ this.columns[name] = column;
+
+ this.hiddenTableHeader.appendChild(new Element('th'));
+ this.fixedTableHeader.appendChild(new Element('th'));
+ },
+ setupCommonEvents: function() {
+ const scrollFn = function() {
+ $(this.dynamicTableFixedHeaderDivId).getElements('table')[0].style.left = -$(this.dynamicTableDivId).scrollLeft + 'px';
+ }.bind(this);
+
+ $(this.dynamicTableDivId).addEvent('scroll', scrollFn);
+ }
+ });
+
+ const RssDownloaderRulesTable = new Class({
+ Extends: DynamicTable,
+ initColumns: function() {
+ this.newColumn('checked', '', '', 30, true);
+ this.newColumn('name', '', '', -1, true);
+
+ this.columns['checked'].updateTd = function(td, row) {
+ if ($('cbRssDlRule' + row.rowId) === null) {
+ const checkbox = new Element('input');
+ checkbox.set('type', 'checkbox');
+ checkbox.set('id', 'cbRssDlRule' + row.rowId);
+ checkbox.checked = row.full_data.checked;
+
+ checkbox.addEvent('click', function(e) {
+ window.qBittorrent.RssDownloader.rssDownloaderRulesTable.updateRowData({
+ rowId: row.rowId,
+ checked: this.checked
+ });
+ window.qBittorrent.RssDownloader.modifyRuleState(row.full_data.name, 'enabled', this.checked);
+ e.stopPropagation();
+ });
+
+ td.append(checkbox);
+ }
+ else {
+ $('cbRssDlRule' + row.rowId).checked = row.full_data.checked;
+ }
+ };
+ },
+ setupHeaderMenu: function() {},
+ setupHeaderEvents: function() {},
+ getFilteredAndSortedRows: function() {
+ return this.rows.getValues();
+ },
+ setupTr: function(tr) {
+ tr.addEvent('dblclick', function(e) {
+ window.qBittorrent.RssDownloader.renameRule(this._this.rows.get(this.rowId).full_data.name);
+ return true;
+ });
+ },
+ newColumn: function(name, style, caption, defaultWidth, defaultVisible) {
+ const column = {};
+ column['name'] = name;
+ column['title'] = name;
+ column['visible'] = defaultVisible;
+ column['force_hide'] = false;
+ column['caption'] = caption;
+ column['style'] = style;
+ if (defaultWidth !== -1) {
+ column['width'] = defaultWidth;
+ }
+
+ column['dataProperties'] = [name];
+ column['getRowValue'] = function(row, pos) {
+ if (pos === undefined)
+ pos = 0;
+ return row['full_data'][this.dataProperties[pos]];
+ };
+ column['compareRows'] = function(row1, row2) {
+ if (this.getRowValue(row1) < this.getRowValue(row2))
+ return -1;
+ else if (this.getRowValue(row1) > this.getRowValue(row2))
+ return 1;
+ else return 0;
+ };
+ column['updateTd'] = function(td, row) {
+ const value = this.getRowValue(row)
+ td.set('text', value);
+ td.set('title', value);
+ };
+ column['onResize'] = null;
+ this.columns.push(column);
+ this.columns[name] = column;
+
+ this.hiddenTableHeader.appendChild(new Element('th'));
+ this.fixedTableHeader.appendChild(new Element('th'));
+ },
+ selectRow: function(rowId) {
+ this.selectedRows.push(rowId);
+ this.setRowClass();
+ this.onSelectedRowChanged();
+
+ const rows = this.rows.getValues();
+ let name = '';
+ for (let i = 0; i < rows.length; ++i) {
+ if (rows[i].rowId === rowId) {
+ name = rows[i].full_data.name;
+ break;
+ }
+ }
+ window.qBittorrent.RssDownloader.showRule(name);
+ }
+ });
+
+ const RssDownloaderFeedSelectionTable = new Class({
+ Extends: DynamicTable,
+ initColumns: function() {
+ this.newColumn('checked', '', '', 30, true);
+ this.newColumn('name', '', '', -1, true);
+
+ this.columns['checked'].updateTd = function(td, row) {
+ if ($('cbRssDlFeed' + row.rowId) === null) {
+ const checkbox = new Element('input');
+ checkbox.set('type', 'checkbox');
+ checkbox.set('id', 'cbRssDlFeed' + row.rowId);
+ checkbox.checked = row.full_data.checked;
+
+ checkbox.addEvent('click', function(e) {
+ window.qBittorrent.RssDownloader.rssDownloaderFeedSelectionTable.updateRowData({
+ rowId: row.rowId,
+ checked: this.checked
+ });
+ e.stopPropagation();
+ });
+
+ td.append(checkbox);
+ }
+ else {
+ $('cbRssDlFeed' + row.rowId).checked = row.full_data.checked;
+ }
+ };
+ },
+ setupHeaderMenu: function() {},
+ setupHeaderEvents: function() {},
+ getFilteredAndSortedRows: function() {
+ return this.rows.getValues();
+ },
+ newColumn: function(name, style, caption, defaultWidth, defaultVisible) {
+ const column = {};
+ column['name'] = name;
+ column['title'] = name;
+ column['visible'] = defaultVisible;
+ column['force_hide'] = false;
+ column['caption'] = caption;
+ column['style'] = style;
+ if (defaultWidth !== -1) {
+ column['width'] = defaultWidth;
+ }
+
+ column['dataProperties'] = [name];
+ column['getRowValue'] = function(row, pos) {
+ if (pos === undefined)
+ pos = 0;
+ return row['full_data'][this.dataProperties[pos]];
+ };
+ column['compareRows'] = function(row1, row2) {
+ if (this.getRowValue(row1) < this.getRowValue(row2))
+ return -1;
+ else if (this.getRowValue(row1) > this.getRowValue(row2))
+ return 1;
+ else return 0;
+ };
+ column['updateTd'] = function(td, row) {
+ const value = this.getRowValue(row)
+ td.set('text', value);
+ td.set('title', value);
+ };
+ column['onResize'] = null;
+ this.columns.push(column);
+ this.columns[name] = column;
+
+ this.hiddenTableHeader.appendChild(new Element('th'));
+ this.fixedTableHeader.appendChild(new Element('th'));
+ },
+ selectRow: function() {}
+ });
+
+ const RssDownloaderArticlesTable = new Class({
+ Extends: DynamicTable,
+ initColumns: function() {
+ this.newColumn('name', '', '', -1, true);
+ },
+ setupHeaderMenu: function() {},
+ setupHeaderEvents: function() {},
+ getFilteredAndSortedRows: function() {
+ return this.rows.getValues();
+ },
+ newColumn: function(name, style, caption, defaultWidth, defaultVisible) {
+ const column = {};
+ column['name'] = name;
+ column['title'] = name;
+ column['visible'] = defaultVisible;
+ column['force_hide'] = false;
+ column['caption'] = caption;
+ column['style'] = style;
+ if (defaultWidth !== -1) {
+ column['width'] = defaultWidth;
+ }
+
+ column['dataProperties'] = [name];
+ column['getRowValue'] = function(row, pos) {
+ if (pos === undefined)
+ pos = 0;
+ return row['full_data'][this.dataProperties[pos]];
+ };
+ column['compareRows'] = function(row1, row2) {
+ if (this.getRowValue(row1) < this.getRowValue(row2))
+ return -1;
+ else if (this.getRowValue(row1) > this.getRowValue(row2))
+ return 1;
+ else return 0;
+ };
+ column['updateTd'] = function(td, row) {
+ const value = this.getRowValue(row)
+ td.set('text', value);
+ td.set('title', value);
+ };
+ column['onResize'] = null;
+ this.columns.push(column);
+ this.columns[name] = column;
+
+ this.hiddenTableHeader.appendChild(new Element('th'));
+ this.fixedTableHeader.appendChild(new Element('th'));
+ },
+ selectRow: function() {},
+ updateRow: function(tr, fullUpdate) {
+ const row = this.rows.get(tr.rowId);
+ const data = row[fullUpdate ? 'full_data' : 'data'];
+
+ if (row.full_data.isFeed) {
+ tr.addClass('articleTableFeed');
+ tr.removeClass('articleTableArticle');
+ }
+ else {
+ tr.removeClass('articleTableFeed');
+ tr.addClass('articleTableArticle');
+ }
+
+ const tds = tr.getElements('td');
+ for (let i = 0; i < this.columns.length; ++i) {
+ if (data.hasOwnProperty(this.columns[i].dataProperties[0]))
+ this.columns[i].updateTd(tds[i], row);
+ }
+ row['data'] = {};
+ }
+ });
+
+
return exports();
})();
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html
index 12ee09257..409d0fe27 100644
--- a/src/webui/www/private/views/preferences.html
+++ b/src/webui/www/private/views/preferences.html
@@ -595,6 +595,54 @@
+
+