@ -3,68 +3,6 @@
var is _seed = true ;
var is _seed = true ;
var current _hash = "" ;
var current _hash = "" ;
var setCBState = function ( state ) {
$ ( "tristate_cb" ) . state = state ;
if ( state === "partial" ) {
$ ( "tristate_cb" ) . indeterminate = true ;
}
else if ( state === "checked" ) {
$ ( "tristate_cb" ) . indeterminate = false ;
$ ( "tristate_cb" ) . checked = true ;
}
else if ( state === "unchecked" ) {
$ ( "tristate_cb" ) . indeterminate = false ;
$ ( "tristate_cb" ) . checked = false ;
}
} ;
var switchCBState = function ( ) {
// Uncheck
if ( ( $ ( "tristate_cb" ) . state === "partial" ) || ( $ ( "tristate_cb" ) . state === "checked" ) ) {
$ ( "tristate_cb" ) . state = "unchecked" ;
$ ( "tristate_cb" ) . checked = false ;
// Uncheck all checkboxes
var indexes = [ ] ;
$$ ( 'input.DownloadedCB' ) . each ( function ( item , index ) {
item . erase ( "checked" ) ;
indexes . push ( index ) ;
} ) ;
setFilePriority ( indexes , 0 ) ;
}
else if ( $ ( "tristate_cb" ) . state === "unchecked" ) {
// Check
$ ( "tristate_cb" ) . state = "checked" ;
$ ( "tristate_cb" ) . checked = true ;
// Check all checkboxes
var indexes = [ ] ;
$$ ( 'input.DownloadedCB' ) . each ( function ( item , index ) {
item . set ( "checked" , "checked" ) ;
indexes . push ( index ) ;
} ) ;
setFilePriority ( indexes , FilePriority . Normal ) ;
}
} ;
var allCBChecked = function ( ) {
var CBs = $$ ( 'input.DownloadedCB' ) ;
for ( var i = 0 ; i < CBs . length ; i += 1 ) {
var item = CBs [ i ] ;
if ( ! $defined ( item . get ( 'checked' ) ) || ! item . get ( 'checked' ) )
return false ;
}
return true ;
} ;
var allCBUnchecked = function ( ) {
var CBs = $$ ( 'input.DownloadedCB' ) ;
for ( var i = 0 ; i < CBs . length ; i += 1 ) {
var item = CBs [ i ] ;
if ( $defined ( item . get ( 'checked' ) ) && item . get ( 'checked' ) )
return false ;
}
return true ;
} ;
var FilePriority = {
var FilePriority = {
"Ignored" : 0 ,
"Ignored" : 0 ,
"Normal" : 1 ,
"Normal" : 1 ,
@ -86,194 +24,191 @@ var normalizePriority = function(priority) {
}
}
} ;
} ;
var setFilePriority = function ( id , priority ) {
var fileCheckboxChanged = function ( e ) {
if ( current _hash === "" ) return ;
var checkbox = e . target ;
var ids = Array . isArray ( id ) ? id : [ id ] ;
var priority = checkbox . checked ? FilePriority . Normal : FilePriority . Ignored ;
var id = checkbox . get ( 'data-id' ) ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
setFilePriority ( id , priority ) ;
new Request ( {
setGlobalCheckboxState ( ) ;
url : 'api/v2/torrents/filePrio' ,
return true ;
method : 'post' ,
data : {
'hash' : current _hash ,
'id' : ids . join ( '|' ) ,
'priority' : priority
} ,
onComplete : function ( ) {
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 1000 ) ;
}
} ) . send ( ) ;
// Display or add combobox
if ( priority > 0 ) {
ids . forEach ( function ( _id ) {
if ( $ ( 'comboPrio' + _id ) . hasClass ( "invisible" ) ) {
$ ( 'comboPrio' + _id ) . set ( "value" , priority ) ;
$ ( 'comboPrio' + _id ) . removeClass ( "invisible" ) ;
}
} ) ;
}
else {
ids . forEach ( function ( _id ) {
if ( ! $ ( 'comboPrio' + _id ) . hasClass ( "invisible" ) )
$ ( 'comboPrio' + _id ) . addClass ( "invisible" ) ;
} ) ;
}
} ;
} ;
var createDownloadedCB = function ( id , downloaded ) {
var fileComboboxChanged = function ( e ) {
var CB = new Element ( 'input' ) ;
var combobox = e . target ;
CB . set ( 'type' , 'checkbox' ) ;
var newPriority = combobox . value ;
if ( downloaded )
var id = combobox . get ( 'data-id' ) ;
CB . set ( 'checked' , 'checked' ) ;
CB . set ( 'id' , 'cbPrio' + id ) ;
setFilePriority ( id , newPriority ) ;
CB . set ( 'class' , 'DownloadedCB' ) ;
CB . addEvent ( 'change' , function ( e ) {
var checked = 0 ;
if ( $defined ( $ ( 'cbPrio' + id ) . get ( 'checked' ) ) && $ ( 'cbPrio' + id ) . get ( 'checked' ) )
checked = 1 ;
setFilePriority ( id , checked ) ;
if ( allCBChecked ( ) ) {
setCBState ( "checked" ) ;
}
else if ( allCBUnchecked ( ) ) {
setCBState ( "unchecked" ) ;
}
else {
setCBState ( "partial" ) ;
}
} ) ;
return CB ;
} ;
} ;
var createPriorityCombo = function ( id , selected _prio ) {
var isDownloadCheckboxExists = function ( id ) {
var select = new Element ( 'select' ) ;
return ( $ ( 'cbPrio' + id ) !== null ) ;
select . set ( 'id' , 'comboPrio' + id ) ;
} ;
select . addEvent ( 'change' , function ( e ) {
var new _prio = $ ( 'comboPrio' + id ) . get ( 'value' ) ;
var createDownloadCheckbox = function ( id , download ) {
setFilePriority ( id , new _prio ) ;
var checkbox = new Element ( 'input' ) ;
} ) ;
checkbox . set ( 'type' , 'checkbox' ) ;
if ( download )
checkbox . set ( 'checked' , 'checked' ) ;
checkbox . set ( 'id' , 'cbPrio' + id ) ;
checkbox . set ( 'data-id' , id ) ;
checkbox . set ( 'class' , 'DownloadedCB' ) ;
checkbox . addEvent ( 'change' , fileCheckboxChanged ) ;
return checkbox ;
} ;
var updateDownloadCheckbox = function ( id , download ) {
var checkbox = $ ( 'cbPrio' + id ) ;
checkbox . checked = download ;
} ;
var isPriorityComboExists = function ( id ) {
return ( $ ( 'comboPrio' + id ) !== null ) ;
} ;
function createOptionElement ( priority , html ) {
var createPriorityOptionElement = function ( priority , selected , html ) {
var elem = new Element ( "option" ) ;
var elem = new Element ( 'option' ) ;
elem . set ( 'value' , priority . toString ( ) ) ;
elem . set ( 'value' , priority . toString ( ) ) ;
elem . set ( 'html' , html ) ;
elem . set ( 'html' , html ) ;
if ( priority == selected _prio )
if ( selected )
elem . setAttribute ( 'selected' , '' ) ;
elem . setAttribute ( 'selected' , '' ) ;
return elem ;
return elem ;
}
} ;
createOptionElement ( FilePriority . Normal , "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
var createPriorityCombo = function ( id , selectedPriority ) {
createOptionElement ( FilePriority . High , "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
var select = new Element ( 'select' ) ;
createOptionElement ( FilePriority . Maximum , "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
select . set ( 'id' , 'comboPrio' + id ) ;
select . set ( 'data-id' , id ) ;
select . set ( 'disabled' , is _seed ) ;
select . addClass ( 'combo_priority' ) ;
select . addEvent ( 'change' , fileComboboxChanged ) ;
createPriorityOptionElement ( FilePriority . Ignored , ( FilePriority . Ignored === selectedPriority ) , 'QBT_TR(Do not download)QBT_TR[CONTEXT=PropListDelegate]' ) . injectInside ( select ) ;
createPriorityOptionElement ( FilePriority . Normal , ( FilePriority . Normal === selectedPriority ) , 'QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]' ) . injectInside ( select ) ;
createPriorityOptionElement ( FilePriority . High , ( FilePriority . High === selectedPriority ) , 'QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]' ) . injectInside ( select ) ;
createPriorityOptionElement ( FilePriority . Maximum , ( FilePriority . Maximum === selectedPriority ) , 'QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]' ) . injectInside ( select ) ;
if ( is _seed || ( selected _prio === FilePriority . Ignored ) || ( selected _prio === FilePriority . Mixed ) ) {
select . addClass ( "invisible" ) ;
}
else {
select . removeClass ( "invisible" ) ;
}
select . addClass ( "combo_priority" ) ;
return select ;
return select ;
} ;
} ;
var filesDynTable = new Class ( {
var updatePriorityCombo = function ( id , selectedPriority ) {
var combobox = $ ( 'comboPrio' + id ) ;
initialize : function ( ) { } ,
if ( parseInt ( combobox . value ) !== selectedPriority )
selectComboboxPriority ( combobox , selectedPriority ) ;
setup : function ( table ) {
if ( combobox . disabled !== is _seed )
this . table = $ ( table ) ;
combobox . disabled = is _seed ;
this . rows = new Hash ( ) ;
} ;
} ,
removeRow : function ( id ) {
var selectComboboxPriority = function ( combobox , priority ) {
if ( this . rows . has ( id ) ) {
var options = combobox . options ;
var tr = this . rows . get ( id ) ;
for ( var i = 0 ; i < options . length ; ++ i ) {
tr . dispose ( ) ;
var option = options [ i ] ;
this . rows . erase ( id ) ;
if ( parseInt ( option . value ) === priority )
return true ;
option . setAttribute ( 'selected' , '' ) ;
else
option . removeAttribute ( 'selected' ) ;
}
}
return false ;
} ,
removeAllRows : function ( ) {
combobox . value = priority ;
this . rows . each ( function ( tr , id ) {
} ;
this . removeRow ( id ) ;
} . bind ( this ) ) ;
} ,
updateRow : function ( tr , row , id ) {
var switchCheckboxState = function ( ) {
var tds = tr . getElements ( 'td' ) ;
var rows = [ ] ;
for ( var i = 0 ; i < row . length ; ++ i ) {
var priority = FilePriority . Ignored ;
switch ( i ) {
case 0 : // checkbox
if ( $ ( 'tristate_cb' ) . state === "checked" ) {
if ( row [ i ] > 0 )
setGlobalCheckboxUnchecked ( ) ;
tds [ i ] . getChildren ( 'input' ) [ 0 ] . set ( 'checked' , 'checked' ) ;
// set file priority for all checked to Ignored
else
torrentFilesTable . getFilteredAndSortedRows ( ) . forEach ( function ( row ) {
tds [ i ] . getChildren ( 'input' ) [ 0 ] . removeProperty ( 'checked' ) ;
if ( row . full _data . checked )
break ;
rows . push ( row . full _data . rowId ) ;
case 3 : // progress bar
} ) ;
$ ( 'pbf_' + id ) . setValue ( row [ i ] . toFloat ( ) ) ;
break ;
case 4 : // download priority
var priority = normalizePriority ( row [ i ] ) ;
if ( ! is _seed && ( priority > 0 ) ) {
tds [ i ] . getChildren ( 'select' ) . set ( 'value' , priority ) ;
if ( $ ( 'comboPrio' + id ) . hasClass ( "invisible" ) )
$ ( 'comboPrio' + id ) . removeClass ( "invisible" ) ;
}
}
else {
else {
if ( ! $ ( 'comboPrio' + id ) . hasClass ( "invisible" ) )
setGlobalCheckboxChecked ( ) ;
$ ( 'comboPrio' + id ) . addClass ( "invisible" ) ;
priority = FilePriority . Normal ;
}
// set file priority for all unchecked to Normal
break ;
torrentFilesTable . getFilteredAndSortedRows ( ) . forEach ( function ( row ) {
default :
if ( ! row . full _data . checked )
tds [ i ] . set ( 'html' , row [ i ] ) ;
rows . push ( row . full _data . rowId ) ;
} ) ;
}
}
if ( rows . length > 0 )
setFilePriority ( rows , priority ) ;
} ;
var setGlobalCheckboxState = function ( ) {
if ( isAllCheckboxesChecked ( ) )
setGlobalCheckboxChecked ( ) ;
else if ( isAllCheckboxesUnchecked ( ) )
setGlobalCheckboxUnchecked ( ) ;
else
setGlobalCheckboxPartial ( ) ;
} ;
var setGlobalCheckboxChecked = function ( ) {
$ ( 'tristate_cb' ) . state = "checked" ;
$ ( 'tristate_cb' ) . indeterminate = false ;
$ ( 'tristate_cb' ) . checked = true ;
} ;
var setGlobalCheckboxUnchecked = function ( ) {
$ ( 'tristate_cb' ) . state = "unchecked" ;
$ ( 'tristate_cb' ) . indeterminate = false ;
$ ( 'tristate_cb' ) . checked = false ;
} ;
var setGlobalCheckboxPartial = function ( ) {
$ ( 'tristate_cb' ) . state = "partial" ;
$ ( 'tristate_cb' ) . indeterminate = true ;
} ;
var isAllCheckboxesChecked = function ( ) {
var checkboxes = $$ ( 'input.DownloadedCB' ) ;
for ( var i = 0 ; i < checkboxes . length ; ++ i ) {
if ( ! checkboxes [ i ] . checked )
return false ;
}
}
return true ;
return true ;
} ,
} ;
insertRow : function ( id , row ) {
var isAllCheckboxesUnchecked = function ( ) {
if ( this . rows . has ( id ) ) {
var checkboxes = $$ ( 'input.DownloadedCB' ) ;
var tableRow = this . rows . get ( id ) ;
for ( var i = 0 ; i < checkboxes . length ; ++ i ) {
this . updateRow ( tableRow , row , id ) ;
if ( checkboxes [ i ] . checked )
return ;
return false ;
}
//this.removeRow(id);
var tr = new Element ( 'tr' ) ;
this . rows . set ( id , tr ) ;
for ( var i = 0 ; i < row . length ; ++ i ) {
var td = new Element ( 'td' ) ;
switch ( i ) {
case 0 :
var tree _img = new Element ( 'img' , {
src : 'images/L.gif' ,
style : 'margin-bottom: -2px'
} ) ;
td . adopt ( tree _img , createDownloadedCB ( id , row [ i ] ) ) ;
break ;
case 1 :
td . set ( 'html' , row [ i ] ) ;
td . set ( 'title' , row [ i ] ) ;
break ;
case 3 :
td . adopt ( new ProgressBar ( row [ i ] . toFloat ( ) , {
'id' : 'pbf_' + id ,
'width' : 80
} ) ) ;
break ;
case 4 :
td . adopt ( createPriorityCombo ( id , normalizePriority ( row [ i ] ) ) ) ;
break ;
default :
td . set ( 'html' , row [ i ] ) ;
break ;
}
td . injectInside ( tr ) ;
}
}
tr . injectInside ( this . table ) ;
return true ;
} ;
var setFilePriority = function ( id , priority ) {
if ( current _hash === "" ) return ;
var ids = Array . isArray ( id ) ? id : [ id ] ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
new Request ( {
url : 'api/v2/torrents/filePrio' ,
method : 'post' ,
data : {
'hash' : current _hash ,
'id' : ids . join ( '|' ) ,
'priority' : priority
} ,
} ,
onComplete : function ( ) {
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 1000 ) ;
}
} ) . send ( ) ;
ids . forEach ( function ( _id ) {
var combobox = $ ( 'comboPrio' + _id ) ;
if ( combobox !== null )
selectComboboxPriority ( combobox , priority ) ;
} ) ;
} ) ;
} ;
var loadTorrentFilesDataTimer ;
var loadTorrentFilesDataTimer ;
var loadTorrentFilesData = function ( ) {
var loadTorrentFilesData = function ( ) {
@ -284,13 +219,13 @@ var loadTorrentFilesData = function() {
}
}
var new _hash = torrentsTable . getCurrentTorrentHash ( ) ;
var new _hash = torrentsTable . getCurrentTorrentHash ( ) ;
if ( new _hash === "" ) {
if ( new _hash === "" ) {
fTable . removeAllRows ( ) ;
torrentFilesTable . clear ( ) ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 5000 ) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 5000 ) ;
return ;
return ;
}
}
if ( new _hash != current _hash ) {
if ( new _hash != current _hash ) {
fTable . removeAllRows ( ) ;
torrentFilesTable . clear ( ) ;
current _hash = new _hash ;
current _hash = new _hash ;
}
}
var url = new URI ( 'api/v2/torrents/files?hash=' + current _hash ) ;
var url = new URI ( 'api/v2/torrents/files?hash=' + current _hash ) ;
@ -298,51 +233,48 @@ var loadTorrentFilesData = function() {
url : url ,
url : url ,
noCache : true ,
noCache : true ,
method : 'get' ,
method : 'get' ,
onFailure : function ( ) {
onComplete : function ( ) {
$ ( 'error_div' ) . set ( 'html' , 'QBT_TR(qBittorrent client is not reachable)QBT_TR[CONTEXT=HttpServer]' ) ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 10 000) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 5 000) ;
} ,
} ,
onSuccess : function ( files ) {
onSuccess : function ( files ) {
$ ( 'error_div' ) . set ( 'html' , '' ) ;
var selectedFiles = torrentFilesTable . selectedRowsIds ( ) ;
if ( files ) {
// Update Trackers data
if ( ! files ) {
torrentFilesTable . clear ( ) ;
return ;
}
var i = 0 ;
var i = 0 ;
files . each ( function ( file ) {
files . each ( function ( file ) {
if ( i === 0 ) {
if ( i === 0 )
is _seed = file . is _seed ;
is _seed = file . is _seed ;
}
var row = [ ] ;
var row = {
row . length = 4 ;
rowId : i ,
row [ 0 ] = file . priority ;
checked : ( file . priority !== FilePriority . Ignored ) ,
row [ 1 ] = escapeHtml ( file . name ) ;
name : escapeHtml ( file . name ) ,
row [ 2 ] = friendlyUnit ( file . size , false ) ;
size : file . size ,
row [ 3 ] = ( file . progress * 100 ) . round ( 1 ) ;
progress : ( file . progress * 100 ) . round ( 1 ) ,
if ( row [ 3 ] == 100.0 && file . progress < 1.0 )
priority : normalizePriority ( file . priority ) ,
row [ 3 ] = 99.9 ;
remaining : ( file . size * ( 1.0 - file . progress ) ) ,
row [ 4 ] = file . priority ;
availability : file . availability
row [ 5 ] = friendlyUnit ( file . size * ( 1.0 - file . progress ) ) ;
} ;
row [ 6 ] = friendlyPercentage ( file . availability ) ;
if ( ( row . progress === 100 ) && ( file . progress < 1 ) )
fTable . insertRow ( i , row ) ;
row . progress = 99.9 ;
++ i ;
++ i ;
torrentFilesTable . updateRowData ( row ) ;
} . bind ( this ) ) ;
} . bind ( this ) ) ;
// Set global CB state
if ( allCBChecked ( ) ) {
torrentFilesTable . updateTable ( false ) ;
setCBState ( "checked" ) ;
torrentFilesTable . altRow ( ) ;
}
else if ( allCBUnchecked ( ) ) {
if ( selectedFiles . length > 0 )
setCBState ( "unchecked" ) ;
torrentFilesTable . reselectRows ( selectedFiles ) ;
}
else {
setGlobalCheckboxState ( ) ;
setCBState ( "partial" ) ;
}
}
else {
fTable . removeAllRows ( ) ;
}
clearTimeout ( loadTorrentFilesDataTimer ) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 5000 ) ;
}
}
} ) . send ( ) ;
} ) . send ( ) ;
} ;
} ;
@ -352,5 +284,62 @@ var updateTorrentFilesData = function() {
loadTorrentFilesData ( ) ;
loadTorrentFilesData ( ) ;
} ;
} ;
var fTable = new filesDynTable ( ) ;
var torrentFilesContextMenu = new ContextMenu ( {
fTable . setup ( $ ( 'filesTable' ) ) ;
targets : '#torrentFilesTableDiv tr' ,
menu : 'torrentFilesMenu' ,
actions : {
FilePrioIgnore : function ( element , ref ) {
var selectedRows = torrentFilesTable . selectedRowsIds ( ) ;
if ( selectedRows . length === 0 ) return ;
setFilePriority ( selectedRows , FilePriority . Ignored ) ;
} ,
FilePrioNormal : function ( element , ref ) {
var selectedRows = torrentFilesTable . selectedRowsIds ( ) ;
if ( selectedRows . length === 0 ) return ;
setFilePriority ( selectedRows , FilePriority . Normal ) ;
} ,
FilePrioHigh : function ( element , ref ) {
var selectedRows = torrentFilesTable . selectedRowsIds ( ) ;
if ( selectedRows . length === 0 ) return ;
setFilePriority ( selectedRows , FilePriority . High ) ;
} ,
FilePrioMaximum : function ( element , ref ) {
var selectedRows = torrentFilesTable . selectedRowsIds ( ) ;
if ( selectedRows . length === 0 ) return ;
setFilePriority ( selectedRows , FilePriority . Maximum ) ;
}
} ,
offsets : {
x : - 15 ,
y : 2
} ,
onShow : function ( ) {
var selectedRows = torrentFilesTable . selectedRowsIds ( ) ;
if ( is _seed )
this . hideItem ( 'FilePrio' ) ;
else
this . showItem ( 'FilePrio' ) ;
}
} ) ;
torrentFilesTable . setup ( 'torrentFilesTableDiv' , 'torrentFilesTableFixedHeaderDiv' , torrentFilesContextMenu ) ;
// inject checkbox into table header
var tableHeaders = $$ ( '#torrentFilesTableFixedHeaderDiv .dynamicTableHeader th' ) ;
if ( tableHeaders . length > 0 ) {
var checkbox = new Element ( 'input' ) ;
checkbox . set ( 'type' , 'checkbox' ) ;
checkbox . set ( 'id' , 'tristate_cb' ) ;
checkbox . addEvent ( 'click' , switchCheckboxState ) ;
var checkboxTH = tableHeaders [ 0 ] ;
checkbox . injectInside ( checkboxTH ) ;
}
// default sort by name column
if ( torrentFilesTable . getSortedColunn ( ) === null )
torrentFilesTable . setSortedColumn ( 'name' ) ;