@ -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 ;
var isDownloadCheckboxExists = function ( id ) {
if ( $defined ( $ ( 'cbPrio' + id ) . get ( 'checked' ) ) && $ ( 'cbPrio' + id ) . get ( 'checked' ) )
return ( $ ( 'cbPrio' + id ) !== null ) ;
checked = 1 ;
} ;
setFilePriority ( id , checked ) ;
if ( allCBChecked ( ) ) {
var createDownloadCheckbox = function ( id , download ) {
setCBState ( "checked" ) ;
var checkbox = new Element ( 'input' ) ;
}
checkbox . set ( 'type' , 'checkbox' ) ;
else if ( allCBUnchecked ( ) ) {
if ( download )
setCBState ( "unchecked" ) ;
checkbox . set ( 'checked' , 'checked' ) ;
}
checkbox . set ( 'id' , 'cbPrio' + id ) ;
else {
checkbox . set ( 'data-id' , id ) ;
setCBState ( "partial" ) ;
checkbox . set ( 'class' , 'DownloadedCB' ) ;
}
checkbox . addEvent ( 'change' , fileCheckboxChanged ) ;
} ) ;
return checkbox ;
return CB ;
} ;
var updateDownloadCheckbox = function ( id , download ) {
var checkbox = $ ( 'cbPrio' + id ) ;
checkbox . checked = download ;
} ;
} ;
var createPriorityCombo = function ( id , selected _prio ) {
var isPriorityComboExists = function ( id ) {
return ( $ ( 'comboPrio' + id ) !== null ) ;
} ;
var createPriorityOptionElement = function ( priority , selected , html ) {
var elem = new Element ( 'option' ) ;
elem . set ( 'value' , priority . toString ( ) ) ;
elem . set ( 'html' , html ) ;
if ( selected )
elem . setAttribute ( 'selected' , '' ) ;
return elem ;
} ;
var createPriorityCombo = function ( id , selectedPriority ) {
var select = new Element ( 'select' ) ;
var select = new Element ( 'select' ) ;
select . set ( 'id' , 'comboPrio' + id ) ;
select . set ( 'id' , 'comboPrio' + id ) ;
select . addEvent ( 'change' , function ( e ) {
select . set ( 'data-id' , id ) ;
var new _prio = $ ( 'comboPrio' + id ) . get ( 'value' ) ;
select . set ( 'disabled' , is _seed ) ;
setFilePriority ( id , new _prio ) ;
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 ) ;
return select ;
} ;
function createOptionElement ( priority , html ) {
var updatePriorityCombo = function ( id , selectedPriority ) {
var elem = new Element ( "option" ) ;
var combobox = $ ( 'comboPrio' + id ) ;
elem . set ( 'value' , priority . toString ( ) ) ;
elem . set ( 'html' , html ) ;
if ( parseInt ( combobox . value ) !== selectedPriority )
if ( priority == selected _prio )
selectComboboxPriority ( combobox , selectedPriority ) ;
elem . setAttribute ( 'selected' , '' ) ;
return elem ;
if ( combobox . disabled !== is _seed )
combobox . disabled = is _seed ;
} ;
var selectComboboxPriority = function ( combobox , priority ) {
var options = combobox . options ;
for ( var i = 0 ; i < options . length ; ++ i ) {
var option = options [ i ] ;
if ( parseInt ( option . value ) === priority )
option . setAttribute ( 'selected' , '' ) ;
else
option . removeAttribute ( 'selected' ) ;
}
}
createOptionElement ( FilePriority . Normal , "QBT_TR(Normal)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
combobox . value = priority ;
createOptionElement ( FilePriority . High , "QBT_TR(High)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
} ;
createOptionElement ( FilePriority . Maximum , "QBT_TR(Maximum)QBT_TR[CONTEXT=PropListDelegate]" ) . injectInside ( select ) ;
if ( is _seed || ( selected _prio === FilePriority . Ignored ) || ( selected _prio === FilePriority . Mixed ) ) {
var switchCheckboxState = function ( ) {
select . addClass ( "invisible" ) ;
var rows = [ ] ;
var priority = FilePriority . Ignored ;
if ( $ ( 'tristate_cb' ) . state === "checked" ) {
setGlobalCheckboxUnchecked ( ) ;
// set file priority for all checked to Ignored
torrentFilesTable . getFilteredAndSortedRows ( ) . forEach ( function ( row ) {
if ( row . full _data . checked )
rows . push ( row . full _data . rowId ) ;
} ) ;
}
}
else {
else {
select . removeClass ( "invisible" ) ;
setGlobalCheckboxChecked ( ) ;
priority = FilePriority . Normal ;
// set file priority for all unchecked to Normal
torrentFilesTable . getFilteredAndSortedRows ( ) . forEach ( function ( row ) {
if ( ! row . full _data . checked )
rows . push ( row . full _data . rowId ) ;
} ) ;
}
}
select . addClass ( "combo_priority" ) ;
return select ;
if ( rows . length > 0 )
setFilePriority ( rows , priority ) ;
} ;
} ;
var filesDynTable = new Class ( {
var setGlobalCheckboxState = function ( ) {
if ( isAllCheckboxesChecked ( ) )
setGlobalCheckboxChecked ( ) ;
else if ( isAllCheckboxesUnchecked ( ) )
setGlobalCheckboxUnchecked ( ) ;
else
setGlobalCheckboxPartial ( ) ;
} ;
initialize : function ( ) { } ,
var setGlobalCheckboxChecked = function ( ) {
$ ( 'tristate_cb' ) . state = "checked" ;
$ ( 'tristate_cb' ) . indeterminate = false ;
$ ( 'tristate_cb' ) . checked = true ;
} ;
setup : function ( table ) {
var setGlobalCheckboxUnchecked = function ( ) {
this . table = $ ( table ) ;
$ ( 'tristate_cb' ) . state = "unchecked" ;
this . rows = new Hash ( ) ;
$ ( 'tristate_cb' ) . indeterminate = false ;
} ,
$ ( 'tristate_cb' ) . checked = false ;
} ;
removeRow : function ( id ) {
var setGlobalCheckboxPartial = function ( ) {
if ( this . rows . has ( id ) ) {
$ ( 'tristate_cb' ) . state = "partial" ;
var tr = this . rows . get ( id ) ;
$ ( 'tristate_cb' ) . indeterminate = true ;
tr . dispose ( ) ;
} ;
this . rows . erase ( id ) ;
return true ;
}
return false ;
} ,
removeAllRows : function ( ) {
var isAllCheckboxesChecked = function ( ) {
this . rows . each ( function ( tr , id ) {
var checkboxes = $$ ( 'input.DownloadedCB' ) ;
this . removeRow ( id ) ;
for ( var i = 0 ; i < checkboxes . length ; ++ i ) {
} . bind ( this ) ) ;
if ( ! checkboxes [ i ] . checked )
} ,
return false ;
}
return true ;
} ;
updateRow : function ( tr , row , id ) {
var isAllCheckboxesUnchecked = function ( ) {
var tds = tr . getElements ( 'td' ) ;
var checkboxes = $$ ( 'input.DownloadedCB' ) ;
for ( var i = 0 ; i < row . length ; ++ i ) {
for ( var i = 0 ; i < checkboxes . length ; ++ i ) {
switch ( i ) {
if ( checkboxes [ i ] . checked )
case 0 : // checkbox
return false ;
if ( row [ i ] > 0 )
}
tds [ i ] . getChildren ( 'input' ) [ 0 ] . set ( 'checked' , 'checked' ) ;
return true ;
else
} ;
tds [ i ] . getChildren ( 'input' ) [ 0 ] . removeProperty ( 'checked' ) ;
break ;
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 {
if ( ! $ ( 'comboPrio' + id ) . hasClass ( "invisible" ) )
$ ( 'comboPrio' + id ) . addClass ( "invisible" ) ;
}
break ;
default :
tds [ i ] . set ( 'html' , row [ i ] ) ;
}
}
return true ;
} ,
insertRow : function ( id , row ) {
var setFilePriority = function ( id , priority ) {
if ( this . rows . has ( id ) ) {
if ( current _hash === "" ) return ;
var tableRow = this . rows . get ( id ) ;
var ids = Array . isArray ( id ) ? id : [ id ] ;
this . updateRow ( tableRow , row , id ) ;
return ;
clearTimeout ( loadTorrentFilesDataTimer ) ;
}
new Request ( {
//this.removeRow(id);
url : 'api/v2/torrents/filePrio' ,
var tr = new Element ( 'tr' ) ;
method : 'post' ,
this . rows . set ( id , tr ) ;
data : {
for ( var i = 0 ; i < row . length ; ++ i ) {
'hash' : current _hash ,
var td = new Element ( 'td' ) ;
'id' : ids . join ( '|' ) ,
switch ( i ) {
'priority' : priority
case 0 :
} ,
var tree _img = new Element ( 'img' , {
onComplete : function ( ) {
src : 'images/L.gif' ,
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 1000 ) ;
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 ) ;
} ) . 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 ) {
var i = 0 ;
torrentFilesTable . clear ( ) ;
files . each ( function ( file ) {
return ;
if ( i === 0 ) {
is _seed = file . is _seed ;
}
var row = [ ] ;
row . length = 4 ;
row [ 0 ] = file . priority ;
row [ 1 ] = escapeHtml ( file . name ) ;
row [ 2 ] = friendlyUnit ( file . size , false ) ;
row [ 3 ] = ( file . progress * 100 ) . round ( 1 ) ;
if ( row [ 3 ] == 100.0 && file . progress < 1.0 )
row [ 3 ] = 99.9 ;
row [ 4 ] = file . priority ;
row [ 5 ] = friendlyUnit ( file . size * ( 1.0 - file . progress ) ) ;
row [ 6 ] = friendlyPercentage ( file . availability ) ;
fTable . insertRow ( i , row ) ;
++ i ;
} . bind ( this ) ) ;
// Set global CB state
if ( allCBChecked ( ) ) {
setCBState ( "checked" ) ;
}
else if ( allCBUnchecked ( ) ) {
setCBState ( "unchecked" ) ;
}
else {
setCBState ( "partial" ) ;
}
}
else {
fTable . removeAllRows ( ) ;
}
}
clearTimeout ( loadTorrentFilesDataTimer ) ;
loadTorrentFilesDataTimer = loadTorrentFilesData . delay ( 5000 ) ;
var i = 0 ;
files . each ( function ( file ) {
if ( i === 0 )
is _seed = file . is _seed ;
var row = {
rowId : i ,
checked : ( file . priority !== FilePriority . Ignored ) ,
name : escapeHtml ( file . name ) ,
size : file . size ,
progress : ( file . progress * 100 ) . round ( 1 ) ,
priority : normalizePriority ( file . priority ) ,
remaining : ( file . size * ( 1.0 - file . progress ) ) ,
availability : file . availability
} ;
if ( ( row . progress === 100 ) && ( file . progress < 1 ) )
row . progress = 99.9 ;
++ i ;
torrentFilesTable . updateRowData ( row ) ;
} . bind ( this ) ) ;
torrentFilesTable . updateTable ( false ) ;
torrentFilesTable . altRow ( ) ;
if ( selectedFiles . length > 0 )
torrentFilesTable . reselectRows ( selectedFiles ) ;
setGlobalCheckboxState ( ) ;
}
}
} ) . 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' ) ;