WebUI: Use Map instead of Mootools Hash in Torrents table
[qBittorrent.git] / src / webui / www / private / views / searchplugins.html
blob1aee0bf7e1e3d5dd73413033a223ef65f1dfe1cf
1 <style>
2 #searchPluginsContainer {
3 height: calc(100% - 20px);
4 margin: 10px;
5 overflow: auto;
8 #searchPluginsContainer button {
9 padding: 2px;
12 #searchPluginsContainer span {
13 display: block;
14 margin-top: 10px;
17 #searchPluginsTable {
18 width: 100%;
19 height: calc(100% - 150px);
22 #searchPluginsTable .dynamicTable {
23 width: 100%;
26 #searchPluginsTableDiv {
27 height: calc(100% - 26px);
30 #dynamicTableFixedHeaderDiv {
31 height: 26px;
34 #searchPlugins_content {
35 height: 100%;
38 </style>
40 <div id="searchPluginsContainer">
41 <h2>QBT_TR(Installed search plugins:)QBT_TR[CONTEXT=PluginSelectDlg]</h2>
43 <div id="searchPluginsTable">
44 <div id="searchPluginsTableFixedHeaderDiv" class="dynamicTableFixedHeaderDiv">
45 <table class="dynamicTable unselectable" style="position:relative;">
46 <thead>
47 <tr class="dynamicTableHeader" id="searchPluginsTableFixedHeaderRow"></tr>
48 </thead>
49 </table>
50 </div>
51 <div id="searchPluginsTableDiv" class="dynamicTableDiv">
52 <table class="dynamicTable unselectable">
53 <thead>
54 <tr class="dynamicTableHeader"></tr>
55 </thead>
56 <tbody></tbody>
57 </table>
58 </div>
59 </div>
61 <span>QBT_TR(Warning: Be sure to comply with your country's copyright laws when downloading torrents from any of these search engines.)QBT_TR[CONTEXT=PluginSelectDlg]</span>
62 <span style="font-style: italic;">QBT_TR(You can get new search engine plugins here:)QBT_TR[CONTEXT=PluginSelectDlg] <a href="https://plugins.qbittorrent.org" target="_blank">https://plugins.qbittorrent.org</a></span>
63 <div style="width: 100%; margin-top: 10px;">
64 <button type="button" style="width: 33%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.installPlugin();">QBT_TR(Install new plugin)QBT_TR[CONTEXT=PluginSelectDlg]</button>
65 <button type="button" style="width: 33%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.checkForUpdates();">QBT_TR(Check for updates)QBT_TR[CONTEXT=PluginSelectDlg]</button>
66 <button type="button" style="width: 32%; line-height: 1.4em;" onclick="qBittorrent.SearchPlugins.closeSearchWindow('searchPlugins');">QBT_TR(Close)QBT_TR[CONTEXT=PluginSelectDlg]</button>
67 </div>
68 </div>
70 <ul id="searchPluginsTableMenu" class="contextMenu">
71 <li><a href="#Enabled"><img src="images/checked-completed.svg" alt="QBT_TR(Enabled)QBT_TR[CONTEXT=PluginSelectDlg]"> QBT_TR(Enabled)QBT_TR[CONTEXT=PluginSelectDlg]</a></li>
72 <li class="separator"><a href="#Uninstall"><img src="images/list-remove.svg" alt="QBT_TR(Uninstall)QBT_TR[CONTEXT=PluginSelectDlg]"> QBT_TR(Uninstall)QBT_TR[CONTEXT=PluginSelectDlg]</a></li>
73 </ul>
75 <script>
76 "use strict";
78 window.qBittorrent ??= {};
79 window.qBittorrent.SearchPlugins ??= (() => {
80 const exports = () => {
81 return {
82 closeSearchWindow: closeSearchWindow,
83 setup: setup,
84 installPlugin: installPlugin,
85 checkForUpdates: checkForUpdates,
86 updateTable: updateTable
90 let searchPluginsTable;
91 let searchPluginsTableContextMenu;
92 let prevOffsetLeft;
93 let prevOffsetTop;
95 const setup = function() {
96 searchPluginsTable = new window.qBittorrent.DynamicTable.SearchPluginsTable();
97 searchPluginsTableContextMenu = new window.qBittorrent.ContextMenu.SearchPluginsTableContextMenu({
98 targets: ".searchPluginsTableRow",
99 menu: "searchPluginsTableMenu",
100 actions: {
101 Enabled: enablePlugin,
102 Uninstall: uninstallPlugin
104 offsets: calculateContextMenuOffsets()
106 searchPluginsTable.setup("searchPluginsTableDiv", "searchPluginsTableFixedHeaderDiv", searchPluginsTableContextMenu);
107 updateTable();
110 const closeSearchWindow = function(id) {
111 window.parent.MochaUI.closeWindow(window.parent.$(id));
114 const installPlugin = function(path) {
115 new MochaUI.Window({
116 id: "installSearchPlugin",
117 icon: "images/qbittorrent-tray.svg",
118 title: "QBT_TR(Install plugin)QBT_TR[CONTEXT=PluginSourceDlg]",
119 loadMethod: "xhr",
120 contentURL: "views/installsearchplugin.html",
121 scrollbars: false,
122 resizable: false,
123 maximizable: false,
124 paddingVertical: 0,
125 paddingHorizontal: 0,
126 width: 500,
127 height: 120
131 const uninstallPlugin = function() {
132 const plugins = searchPluginsTable.selectedRowsIds().join("|");
133 const url = new URI("api/v2/search/uninstallPlugin");
134 new Request({
135 url: url,
136 method: "post",
137 data: {
138 names: plugins,
140 }).send();
143 const enablePlugin = function() {
144 const plugins = searchPluginsTable.selectedRowsIds();
145 let enable = true;
146 if (plugins && plugins.length)
147 enable = !window.qBittorrent.Search.getPlugin(plugins[0]).enabled;
149 const url = new URI("api/v2/search/enablePlugin");
150 new Request({
151 url: url,
152 method: "post",
153 data: {
154 names: plugins.join("|"),
155 enable: enable
157 }).send();
160 const checkForUpdates = function() {
161 const url = new URI("api/v2/search/updatePlugins");
162 new Request({
163 url: url,
164 method: "post"
165 }).send();
168 const calculateContextMenuOffsets = function() {
169 prevOffsetLeft = document.getElementById("searchPlugins").getBoundingClientRect().left;
170 prevOffsetTop = document.getElementById("searchPlugins").getBoundingClientRect().top;
172 return {
173 x: -(prevOffsetLeft + 20),
174 y: -(prevOffsetTop + 2)
178 const updateSearchPluginsTableContextMenuOffset = function() {
179 // only re-calculate if window has moved
180 if ((prevOffsetLeft !== document.getElementById("searchPlugins").getBoundingClientRect().left) || (prevOffsetTop !== document.getElementById("searchPlugins").getBoundingClientRect().top))
181 searchPluginsTableContextMenu.options.offsets = calculateContextMenuOffsets();
184 const setupSearchPluginTableEvents = function(enable) {
185 const clickHandler = (e) => { enablePlugin(); };
186 const menuHandler = (e) => { updateSearchPluginsTableContextMenuOffset(); };
187 if (enable) {
188 $$(".searchPluginsTableRow").each((target) => {
189 target.addEventListener("dblclick", clickHandler);
190 target.addEventListener("contextmenu", menuHandler, true);
193 else {
194 $$(".searchPluginsTableRow").each((target) => {
195 target.removeEventListener("dblclick", clickHandler);
196 target.removeEventListener("contextmenu", menuHandler, true);
201 const updateTable = function() {
202 // clear event listeners
203 setupSearchPluginTableEvents(false);
205 const oldPlugins = Object.keys(searchPluginsTable.rows);
206 // remove old rows from the table
207 for (let i = 0; i < oldPlugins.length; ++i) {
208 let found = false;
209 for (let j = 0; j < window.qBittorrent.Search.searchPlugins.length; ++j) {
210 if (window.qBittorrent.Search.searchPlugins[j].name === oldPlugins[i]) {
211 found = true;
212 break;
215 if (!found)
216 searchPluginsTable.removeRow(oldPlugins[i]);
219 for (let i = 0; i < window.qBittorrent.Search.searchPlugins.length; ++i) {
220 window.qBittorrent.Search.searchPlugins[i].rowId = window.qBittorrent.Search.searchPlugins[i].name;
221 searchPluginsTable.updateRowData(window.qBittorrent.Search.searchPlugins[i]);
224 searchPluginsTable.updateTable();
226 // add event listeners
227 setupSearchPluginTableEvents(true);
230 return exports();
231 })();
232 Object.freeze(window.qBittorrent.SearchPlugins);
234 window.qBittorrent.SearchPlugins.setup();
235 </script>