Browse Source

- started to remodel the UI to match the new qBT UI

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
13e22aef51
  1. 1
      Changelog
  2. 46
      src/eventmanager.cpp
  3. 19
      src/webui/css/style.css
  4. 38
      src/webui/index.html
  5. 70
      src/webui/scripts/client.js
  6. 49
      src/webui/scripts/dynamicTable.js
  7. 20
      src/webui/scripts/mocha-init.js

1
Changelog

@ -33,6 +33,7 @@
- FEATURE: Include DHT traffic in the rate limiter (libtorrent >= v0.15 only) - FEATURE: Include DHT traffic in the rate limiter (libtorrent >= v0.15 only)
- FEATURE: Support for bitcomet padding files (libtorrent >= v0.15 only) - FEATURE: Support for bitcomet padding files (libtorrent >= v0.15 only)
- FEATURE: Option to skip file checking and start seeding immediately in torrent addition dialog (Stephanos Antaris) (libtorrent >= v0.15 only) - FEATURE: Option to skip file checking and start seeding immediately in torrent addition dialog (Stephanos Antaris) (libtorrent >= v0.15 only)
- WEB UI: Removed Web UI to match new qBittorrent UI
- COSMETIC: Merged download / upload lists - COSMETIC: Merged download / upload lists
- COSMETIC: Torrents can be filtered based on their status - COSMETIC: Torrents can be filtered based on their status
- COSMETIC: Torrent properties are now displayed in main window - COSMETIC: Torrent properties are now displayed in main window

46
src/eventmanager.cpp

@ -58,29 +58,41 @@ void EventManager::modifiedTorrent(QTorrentHandle h)
QVariantMap event; QVariantMap event;
if(h.is_paused()) { if(h.is_paused()) {
event["state"] = QVariant("paused"); if(h.is_seed())
event["state"] = QVariant("pausedUP");
else
event["state"] = QVariant("pausedDL");
} else { } else {
if(BTSession->isQueueingEnabled() && h.is_queued()) { if(BTSession->isQueueingEnabled() && h.is_queued()) {
event["state"] = QVariant("queued"); if(h.is_seed())
event["state"] = QVariant("queuedUP");
else
event["state"] = QVariant("queuedDL");
} else { } else {
switch(h.state()) switch(h.state())
{ {
case torrent_status::finished: case torrent_status::finished:
case torrent_status::seeding: case torrent_status::seeding:
event["state"] = QVariant("seeding"); if(h.upload_payload_rate() > 0)
event["state"] = QVariant("seeding");
else
event["state"] = QVariant("stalledUP");
break; break;
case torrent_status::allocating: case torrent_status::allocating:
case torrent_status::checking_files: case torrent_status::checking_files:
case torrent_status::queued_for_checking: case torrent_status::queued_for_checking:
case torrent_status::checking_resume_data: case torrent_status::checking_resume_data:
event["state"] = QVariant("checking"); if(h.is_seed())
event["state"] = QVariant("checkingUP");
else
event["state"] = QVariant("checkingDL");
break; break;
case torrent_status::downloading: case torrent_status::downloading:
case torrent_status::downloading_metadata: case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0) if(h.download_payload_rate() > 0)
event["state"] = QVariant("downloading"); event["state"] = QVariant("downloading");
else else
event["state"] = QVariant("stalled"); event["state"] = QVariant("stalledDL");
break; break;
default: default:
qDebug("No status, should not happen!!! status is %d", h.state()); qDebug("No status, should not happen!!! status is %d", h.state());
@ -90,14 +102,12 @@ void EventManager::modifiedTorrent(QTorrentHandle h)
} }
event["name"] = QVariant(h.name()); event["name"] = QVariant(h.name());
event["size"] = QVariant((qlonglong)h.actual_size()); event["size"] = QVariant((qlonglong)h.actual_size());
if(!h.is_seed()) { event["progress"] = QVariant(h.progress());
event["progress"] = QVariant(h.progress()); event["dlspeed"] = QVariant(h.download_payload_rate());
event["dlspeed"] = QVariant(h.download_payload_rate()); if(BTSession->isQueueingEnabled()) {
if(BTSession->isQueueingEnabled()) { event["priority"] = QVariant(h.queue_position());
event["priority"] = QVariant(h.queue_position()); } else {
} else { event["priority"] = -1;
event["priority"] = -1;
}
} }
event["upspeed"] = QVariant(h.upload_payload_rate()); event["upspeed"] = QVariant(h.upload_payload_rate());
event["seed"] = QVariant(h.is_seed()); event["seed"] = QVariant(h.is_seed());

19
src/webui/css/style.css

@ -120,3 +120,22 @@ hr {
height:100%; height:100%;
} }
#Filters {
width: 120px;
border-right: 1px solid #ccc;
color: #000;
}
#Filters ul {
list-style-type: none;
}
#Filters ul img {
padding-right: 2px;
margin-top: 2px;
}
#Transfers {
vertical-align: top;
}

38
src/webui/index.html

@ -6,13 +6,11 @@
<link rel="stylesheet" href="css/dynamicTable.css" type="text/css" /> <link rel="stylesheet" href="css/dynamicTable.css" type="text/css" />
<link rel="stylesheet" href="css/style.css" type="text/css" /> <link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/mocha.css" type="text/css" /> <link rel="stylesheet" href="css/mocha.css" type="text/css" />
<link rel="stylesheet" href="css/mootabs1.2.css" type="text/css" />
<script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-core-yc.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script> <script type="text/javascript" src="scripts/mootools-1.2-more.js" charset="utf-8"></script>
<!--[if IE]> <!--[if IE]>
<script type="text/javascript" src="scripts/excanvas-compressed.js"></script> <script type="text/javascript" src="scripts/excanvas-compressed.js"></script>
<![endif]--> <![endif]-->
<script type="text/javascript" src="scripts/mootabs1.2.js" charset="utf-8"></script>
<script type="text/javascript" src="scripts/mocha.js"></script> <script type="text/javascript" src="scripts/mocha.js"></script>
<script type="text/javascript" src="scripts/mocha-init.js"></script> <script type="text/javascript" src="scripts/mocha-init.js"></script>
<script type="text/javascript" src="scripts/progressbar.js"></script> <script type="text/javascript" src="scripts/progressbar.js"></script>
@ -23,7 +21,7 @@
<div id="desktop"> <div id="desktop">
<div id="desktopHeader"> <div id="desktopHeader">
<div id="desktopTitlebar"> <div id="desktopTitlebar">
<h1 class="applicationTitle">qBittorrent Web User Interface <span class="version">version 1.3.2</span></h1> <h1 class="applicationTitle">qBittorrent Web User Interface <span class="version">version 2.0.0</span></h1>
</div> </div>
<div id="desktopNavbar"> <div id="desktopNavbar">
<ul> <ul>
@ -73,13 +71,18 @@
</span> </span>
</div> </div>
</div> </div>
<div id="pageWrapper"> <span id="error_div"></span> <div id="pageWrapper"> <span id="error_div"></span>
<div id="myTabs" class="toolbarTabs"> <table>
<ul class="mootabs_title"> <tr><td id="Filters">
<li title="Tab1"><a>Downloads</a></li> <ul>
<li title="Tab2"><a>Uploads</a></li> <li><a href="#" onclick="setFilter('all');"><img src="images/oxygen/folder.png"/>All</li>
</ul> <li><a href="#" onclick="setFilter('downloading');"><img src="images/skin/downloading.png"/>Downloading</li>
<div id="Tab1" class="mootabs_panel"> <li><a href="#" onclick="setFilter('completed');"><img src="images/skin/seeding.png"/>Completed</li>
<li><a href="#" onclick="setFilter('active');"><img src="images/oxygen/draw-triangle2.png"/>Active</li>
<li><a href="#" onclick="setFilter('inactive');"><img src="images/oxygen/draw-rectangle.png"/>Inactive</li>
</ul>
</td>
<td id="Transfers">
<table class="torrentTable" cellpadding="0" cellspacing="0"> <table class="torrentTable" cellpadding="0" cellspacing="0">
<thead> <thead>
<tr> <tr>
@ -94,21 +97,8 @@
</thead> </thead>
<tbody id="myTable"></tbody> <tbody id="myTable"></tbody>
</table> </table>
</td><tr>
</div><!-- tab1 --> </div><!-- tab1 -->
<div id="Tab2" class="mootabs_panel">
<table class="torrentTable" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Size</th>
<th>UP Speed</th>
</tr>
</thead>
<tbody id="myTableUP"></tbody>
</table>
</div>
</div><!-- tabs -->
</div> </div>
</div> </div>
</body> </body>

70
src/webui/scripts/client.js

@ -23,7 +23,7 @@
*/ */
myTable = new dynamicTable(); myTable = new dynamicTable();
myTableUP = new dynamicTable(); ajaxfn = function(){};
window.addEvent('domready', function(){ window.addEvent('domready', function(){
MochaUI.Desktop = new MochaUI.Desktop(); MochaUI.Desktop = new MochaUI.Desktop();
@ -32,29 +32,27 @@ window.addEvent('domready', function(){
'visibility': 'visible' 'visibility': 'visible'
}); });
initializeWindows(); initializeWindows();
// Tabs
myTabs1 = new mootabs('myTabs', {
width: '100%',
height: '100%'
});
myTable.setup('myTable', 3); myTable.setup('myTable', 3);
myTableUP.setup('myTableUP', -1);
var r=0; var r=0;
var waiting=false; var waiting=false;
var stateToImg = function(state){ var stateToImg = function(state){
switch (state) switch (state)
{ {
case 'paused': case 'pausedUP':
case 'pausedDL':
return '<img src="images/skin/paused.png"/>'; return '<img src="images/skin/paused.png"/>';
case 'seeding': case 'seeding':
case 'stalledUP':
return '<img src="images/skin/seeding.png"/>'; return '<img src="images/skin/seeding.png"/>';
case 'checking': case 'checkingUP':
case 'checkingDL':
return '<img src="images/oxygen/run-build.png"/>'; return '<img src="images/oxygen/run-build.png"/>';
case 'downloading': case 'downloading':
return '<img src="images/skin/downloading.png"/>'; return '<img src="images/skin/downloading.png"/>';
case 'stalled': case 'stalledDL':
return '<img src="images/skin/stalled.png"/>'; return '<img src="images/skin/stalled.png"/>';
case 'queued': case 'queuedUP':
case 'queuedDL':
return '<img src="images/oxygen/mail-queue.png"/>'; return '<img src="images/oxygen/mail-queue.png"/>';
default: default:
return '<img src="images/skin/stalled.png"/>'; return '<img src="images/skin/stalled.png"/>';
@ -90,33 +88,10 @@ window.addEvent('domready', function(){
$('error_div').set('html', ''); $('error_div').set('html', '');
if(events){ if(events){
// Add new torrents or update them // Add new torrents or update them
unfinished_hashes = myTable.getRowIds(); torrent_hashes = myTable.getRowIds();
finished_hashes = myTableUP.getRowIds();
events_hashes = new Array(); events_hashes = new Array();
events.each(function(event){ events.each(function(event){
events_hashes[events_hashes.length] = event.hash; events_hashes[events_hashes.length] = event.hash;
if(event.seed) {
var row = new Array();
row.length = 4;
row[0] = stateToImg(event.state);
row[1] = event.name;
row[2] = fsize(event.size);
row[3] = fspeed(event.upspeed);
if(!finished_hashes.contains(event.hash)) {
// New finished torrent
finished_hashes[finished_hashes.length] = event.hash;
myTableUP.insertRow(event.hash, row);
if(unfinished_hashes.contains(event.hash)) {
// Torrent used to be in unfinished list
// Remove it
myTable.removeRow(event.hash);
unfinished_hashes.erase(event.hash);
}
} else {
// Update torrent data
myTableUP.updateRow(event.hash, row);
}
} else {
var row = new Array(); var row = new Array();
row.length = 6; row.length = 6;
row[0] = stateToImg(event.state); row[0] = stateToImg(event.state);
@ -128,33 +103,21 @@ window.addEvent('domready', function(){
row[6] = event.priority row[6] = event.priority
if(row[6] != -1) if(row[6] != -1)
queueing_enabled = true; queueing_enabled = true;
if(!unfinished_hashes.contains(event.hash)) { if(!torrent_hashes.contains(event.hash)) {
// New unfinished torrent // New unfinished torrent
unfinished_hashes[unfinished_hashes.length] = event.hash; torrent_hashes[torrent_hashes.length] = event.hash;
myTable.insertRow(event.hash, row); myTable.insertRow(event.hash, row);
if(finished_hashes.contains(event.hash)) {
// Torrent used to be in unfinished list
// Remove it
myTableUP.removeRow(event.hash);
finished_hashes.erase(event.hash);
}
} else { } else {
// Update torrent data // Update torrent data
myTable.updateRow(event.hash, row); myTable.updateRow(event.hash, row, event.state);
} }
}
}); });
// Remove deleted torrents // Remove deleted torrents
unfinished_hashes.each(function(hash){ torrent_hashes.each(function(hash){
if(!events_hashes.contains(hash)) { if(!events_hashes.contains(hash)) {
myTable.removeRow(hash); myTable.removeRow(hash);
} }
}); });
finished_hashes.each(function(hash){
if(!events_hashes.contains(hash)) {
myTableUP.removeRow(hash);
}
});
if(queueing_enabled) { if(queueing_enabled) {
$('queueingButtons').removeClass('invisible'); $('queueingButtons').removeClass('invisible');
myTable.showPriority(); myTable.showPriority();
@ -171,6 +134,11 @@ window.addEvent('domready', function(){
}; };
ajaxfn(); ajaxfn();
// ajaxfn.periodical(5000); // ajaxfn.periodical(5000);
setFilter = function(f) {
myTable.setFilter(f);
ajaxfn();
}
}); });
// This runs when a person leaves your page. // This runs when a person leaves your page.

49
src/webui/scripts/dynamicTable.js

@ -42,6 +42,7 @@ var dynamicTable = new Class ({
this.cur = new Array(); this.cur = new Array();
this.priority_hidden = false; this.priority_hidden = false;
this.progressIndex = progressIndex; this.progressIndex = progressIndex;
this.filter = 'all';
}, },
altRow: function() altRow: function()
@ -66,6 +67,10 @@ var dynamicTable = new Class ({
}.bind(this)); }.bind(this));
this.priority_hidden = true; this.priority_hidden = true;
}, },
setFilter: function(f) {
this.filter = f;
},
showPriority: function(){ showPriority: function(){
if(!this.priority_hidden) return; if(!this.priority_hidden) return;
@ -77,14 +82,52 @@ var dynamicTable = new Class ({
}.bind(this)); }.bind(this));
this.priority_hidden = false; this.priority_hidden = false;
}, },
applyFilterOnRow: function(tr, status) {
switch(this.filter) {
case 'all':
tr.removeClass("invisible");
return;
case 'downloading':
if(status == "downloading" || status == "stalledDL" || status == "checkingDL" || status == "pausedDL" || status == "queuedDL") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
return;
case 'completed':
if(status == "seeding" || status == "stalledUP" || status == "checkingUP" || status == "pausedUP" || status == "queuedUP") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
return;
case 'active':
if(status == "downloading" || status == "seeding") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
return;
case 'inactive':
if(status != "downloading" && status != "seeding") {
tr.removeClass("invisible");
} else {
tr.addClass("invisible");
}
return;
}
},
insertRow: function(id, row){ insertRow: function(id, row, status){
var tr = this.rows[id]; var tr = this.rows[id];
if($defined(tr)) if($defined(tr))
return; return;
//this.removeRow(id); //this.removeRow(id);
var tr = new Element('tr'); var tr = new Element('tr');
this.rows[id] = tr; this.rows[id] = tr;
// Apply filter
this.applyFilterOnRow(tr, status);
for(var i=0; i<row.length; i++) for(var i=0; i<row.length; i++)
{ {
var td = new Element('td'); var td = new Element('td');
@ -181,10 +224,12 @@ var dynamicTable = new Class ({
} }
}, },
updateRow: function(id, row){ updateRow: function(id, row, status){
var tr = this.rows[id]; var tr = this.rows[id];
if($defined(tr)) if($defined(tr))
{ {
// Apply filter
this.applyFilterOnRow(tr, status);
var tds = tr.getElements('td'); var tds = tr.getElements('td');
for(var i=0; i<row.length; i++) { for(var i=0; i<row.length; i++) {
if(i==this.progressIndex) { if(i==this.progressIndex) {

20
src/webui/scripts/mocha-init.js

@ -63,11 +63,7 @@ initializeWindows = function(){
addClickEvent('delete', function(e){ addClickEvent('delete', function(e){
new Event(e).stop(); new Event(e).stop();
if($("Tab1").hasClass('active')) { var h = myTable.selectedIds();
var h = myTable.selectedIds();
} else {
var h = myTableUP.selectedIds();
}
if(h.length && confirm('Are you sure you want to delete the selected item in download list?')) { if(h.length && confirm('Are you sure you want to delete the selected item in download list?')) {
h.each(function(item, index){ h.each(function(item, index){
new Request({url: '/command/delete', method: 'post', data: {hash: item}}).send(); new Request({url: '/command/delete', method: 'post', data: {hash: item}}).send();
@ -79,11 +75,7 @@ initializeWindows = function(){
addClickEvent('deletePerm', function(e){ addClickEvent('deletePerm', function(e){
new Event(e).stop(); new Event(e).stop();
if($("Tab1").hasClass('active')) { var h = myTable.selectedIds();
var h = myTable.selectedIds();
} else {
var h = myTableUP.selectedIds();
}
if(h.length && confirm('Are you sure you want to delete from hard drive the selected item in download list?')) { if(h.length && confirm('Are you sure you want to delete from hard drive the selected item in download list?')) {
h.each(function(item, index){ h.each(function(item, index){
new Request({url: '/command/deletePerm', method: 'post', data: {hash: item}}).send(); new Request({url: '/command/deletePerm', method: 'post', data: {hash: item}}).send();
@ -94,13 +86,7 @@ initializeWindows = function(){
['pause','resume','decreasePrio','increasePrio','recheck'].each(function(item) { ['pause','resume','decreasePrio','increasePrio','recheck'].each(function(item) {
addClickEvent(item, function(e){ addClickEvent(item, function(e){
new Event(e).stop(); new Event(e).stop();
if($("Tab1").hasClass('active')) { var h = myTable.selectedIds();
var h = myTable.selectedIds();
} else {
if(item=='decreasePrio' || item=='increasePrio')
return;
var h = myTableUP.selectedIds();
}
if(h.length){ if(h.length){
h.each(function(hash, index){ h.each(function(hash, index){
new Request({url: '/command/'+item, method: 'post', data: {hash: hash}}).send(); new Request({url: '/command/'+item, method: 'post', data: {hash: hash}}).send();

Loading…
Cancel
Save