diff --git a/index.html b/index.html index 4291dd0..5f47e79 100755 --- a/index.html +++ b/index.html @@ -264,7 +264,7 @@
- +
Found: {{totalDownloads}} / {{totalAria2Downloads()}}
@@ -277,7 +277,7 @@ - {{getName(download)}} + {{download.name}} @@ -368,11 +368,11 @@
  • -   {{download.totalLength | blength}} +   {{download.fmtTotalLength}}
  • -   {{download.completedLength | blength}} +   {{download.fmtCompletedLength}}
  • @@ -389,11 +389,11 @@
  • -   {{download.totalLength | blength}} +   {{download.fmtTotalLength}}
  • -   {{download.completedLength | blength}} +   {{download.fmtCompletedLength}}
  • @@ -436,7 +436,7 @@
  • -   {{download.totalLength | blength}} +   {{download.fmtTotalLength}}
  • @@ -455,7 +455,7 @@
  • -   {{download.totalLength | blength}} +   {{download.fmtTotalLength}}
  • @@ -471,7 +471,7 @@
  • -   {{download.totalLength | blength}} +   {{download.fmtTotalLength}}
  • @@ -495,21 +495,21 @@
    diff --git a/js/ctrls/download.js b/js/ctrls/download.js index 6d4432c..249136b 100644 --- a/js/ctrls/download.js +++ b/js/ctrls/download.js @@ -106,10 +106,26 @@ function( // download search filter scope.downloadFilter = ""; + scope.downloadFilterCommitted = ""; + + scope.onDownloadFilter = function() { + if (scope.downloadFilterTimer) { + clearTimeout(scope.downloadFilterTimer); + } + scope.downloadFilterTimer = setTimeout(function() { + delete scope.downloadFilterTimer; + if (scope.downloadFilterCommitted !== scope.downloadFilter) { + scope.downloadFilterCommitted = scope.downloadFilter; + scope.$digest(); + } + }, 500); + }; scope.filterDownloads = function(downloads) { - var filter = scope.downloadFilter; - if (!filter.length) return downloads; + if (!scope.downloadFilterCommitted) { + return downloads; + } + var filter = scope.downloadFilterCommitted; return _.filter(downloads, function(d) { if (!d.files.length) return true; @@ -187,27 +203,79 @@ function( // convert the donwload form aria2 to once used by the view, // minor additions of some fields and checks scope.getCtx = function(d, ctx) { - ctx = ctx || {}; + if (!ctx) { + ctx = { + dir: d.dir, + status: d.status, + gid: d.gid, + numPieces: d.numPieces, + connections: d.connections, + bitfield: d.bitfield, + totalLength: d.totalLength, + fmtTotalLength: utils.fmtsize(d.totalLength), + completedLength: d.completedLength, + fmtCompletedLength: utils.fmtsize(d.completedLength), + uploadLength: d.uploadLength, + fmtUploadLength: utils.fmtsize(d.uploadLength), + pieceLength: d.pieceLength, + fmtPieceLength: utils.fmtsize(d.pieceLength), + downloadSpeed: d.downloadSpeed, + fmtDownloadSpeed: utils.fmtspeed(d.downloadSpeed), + uploadSpeed: d.uploadSpeed, + fmtUploadSpeed: utils.fmtspeed(d.uploadSpeed), + files: [] + }; + } + else { + ctx.dir = d.dir; + ctx.status = d.status; + ctx.gid = d.gid; + ctx.numPieces = d.numPieces; + ctx.connections = d.connections; + ctx.bitfield = d.bitfield; + if (ctx.totalLength !== d.totalLength) { + ctx.totalLength = d.totalLength; + ctx.fmtTotalLength = utils.fmtsize(d.totalLength); + } + if (ctx.completedLength !== d.completedLength) { + ctx.completedLength = d.completedLength; + ctx.fmtCompletedLength = utils.fmtsize(d.completedLength); + } + if (ctx.uploadLength !== d.uploadength) { + ctx.uploadLength = d.uploadlength; + ctx.fmtUploadLength = utils.fmtsize(d.uploadLength); + } + if (ctx.pieceLength !== d.pieceLength) { + ctx.pieceLength = d.pieceLength; + ctx.fmtPieceLength = utils.fmtsize(d.pieceLength); + } + if (ctx.downloadSpeed !== d.downloadSpeed) { + ctx.downloadSpeed = d.downloadSpeed; + ctx.fmtDownloadSpeed = utils.fmtspeed(d.downloadSpeed); + } + if (ctx.uploadSpeed !== d.uploadSpeed) { + ctx.uploadSpeed = d.uploadSpeed; + ctx.fmtUploadSpeed = utils.fmtspeed(d.uploadSpeed); + } + } - _.each([ - 'totalLength', 'completedLength', 'uploadLength', 'dir', - 'pieceLength', 'downloadSpeed', 'uploadSpeed', 'status', - 'gid', 'numPieces', 'connections', 'bitfield' - ], function(e) { - ctx[e] = d[e]; - }); - - var files = d["files"]; + var dlName; + var files = d.files; if (files) { - var cfiles = ctx["files"] || (ctx["files"] = []); + dlName = files[0].path || d.files[0].uris[0].uri; + var cfiles = ctx.files; for (var i = 0; i < files.length; ++i) { var cfile = cfiles[i] || (cfiles[i] = {}); var file = files[i]; if (file.path !== cfile.path) { cfile.path = file.path; cfile.length = file.length; + cfile.fmtLength = utils.fmtsize(file.length); cfile.relpath = file.path.replace(re_slashes, slash); - if (!cfile.relpath.startsWith("[")) { // METADATA + if (!cfile.relpath) { + cfile.relpath = (file.uris && file.uris[0] && file.uris[0].uri) || "Unknown"; + } + else if (!cfile.relpath.startsWith("[")) { // METADATA cfile.relpath = cfile.relpath.substr(ctx.dir.length + 1); } } @@ -215,20 +283,24 @@ function( cfiles.length = files.length; } else { - delete ctx["files"]; + delete ctx.files; } + var btName; if (d.bittorrent) { - ctx.bittorrentName = d.bittorrent.info && d.bittorrent.info.name; + btName = d.bittorrent.info && d.bittorrent.info.name; ctx.bittorrent = true; } else { - delete ctx.bittorrentName; + delete ctx.bittorrent; } + ctx.name = btName || utils.getFileName(dlName) || dlName || "Unknown"; + // collapse the download details initially - if (ctx.collapsed === undefined) + if (ctx.collapsed === undefined) { ctx.collapsed = true; + } return ctx; }; @@ -284,17 +356,6 @@ function( return percentage; }; - // gets a pretty name for the download - scope.getName = function(d) { - if (d.bittorrentName) { - return d.bittorrentName; - } - - return utils.getFileName( - d.files[0].path || d.files[0].uris[0].uri - ); - } - // gets the type for the download as classified by the aria2 rpc calls scope.getType = function(d) { var type = d.status; @@ -320,7 +381,7 @@ function( settings[i].val = vals[i] || settings[i].val; } - modals.invoke('settings', settings, scope.getName(d) + ' settings', function(settings) { + modals.invoke('settings', settings, scope.name + ' settings', function(settings) { var sets = {}; for (var i in settings) { sets[i] = settings[i].val }; diff --git a/js/filters/bytes.js b/js/filters/bytes.js index 6765ab1..2ce8cac 100644 --- a/js/filters/bytes.js +++ b/js/filters/bytes.js @@ -1,47 +1,25 @@ -(function() { - function fmtlen(len) { - len = +len; // coerce to number - if (len <= 1024) { - return len.toFixed(0) + " B"; - } - len /= 1024; - if (len <= 1024) { - return len.toFixed(1) + " KB" - } - len /= 1024; - if (len <= 1024) { - return len.toFixed(2) + " MB"; - } - len /= 1024; - return len.toFixed(3) + " GB"; +angular.module('webui.filters.bytes', ["webui.services.utils"]) +.filter('blength', ['$filter', "$utils", function(filter, utils) { + return utils.fmtsize; +}]) +.filter('bspeed', ['$filter', "$utils", function(filter, utils) { + return utils.fmtspeed; +}]) +.filter('time', function() { + function pad(f) { + return ("0" + f).substr(-2); } - angular .module('webui.filters.bytes', []) - .filter('blength', ['$filter', function(filter) { - return fmtlen; - }]) - .filter('bspeed', ['$filter', function(filter) { - return function(speed) { - return fmtlen(speed) + "/s"; - }; - }]) - .filter('time', function() { - function pad(f) { - return ("0" + f).substr(-2); - } - - return function(time) { - time = parseInt(time, 10); - if (!time || !isFinite(time)) return "∞"; - var secs = time % 60; - if (time < 60) return secs + "s"; - var mins = Math.floor((time % 3600) / 60) - if (time < 3600) return pad(mins) + ":" + pad(secs); - var hrs = Math.floor((time % 86400) / 3600); - if (time < 86400) return pad(hrs) + ":" + pad(mins) + ":" + pad(secs); - var days = Math.floor(time / 86400); - return days + "::" + pad(hrs) + ":" + pad(mins) + ":" + pad(secs); - }; - }); -})(); - + return function(time) { + time = parseInt(time, 10); + if (!time || !isFinite(time)) return "∞"; + var secs = time % 60; + if (time < 60) return secs + "s"; + var mins = Math.floor((time % 3600) / 60) + if (time < 3600) return pad(mins) + ":" + pad(secs); + var hrs = Math.floor((time % 86400) / 3600); + if (time < 86400) return pad(hrs) + ":" + pad(mins) + ":" + pad(secs); + var days = Math.floor(time / 86400); + return days + "::" + pad(hrs) + ":" + pad(mins) + ":" + pad(secs); + }; +}); diff --git a/js/services/utils.js b/js/services/utils.js index f45b2c9..9e98629 100644 --- a/js/services/utils.js +++ b/js/services/utils.js @@ -26,7 +26,28 @@ angular.module('webui.services.utils', []) }; })(); - return { + var utils = { + + fmtsize: function(len) { + len = +len; // coerce to number + if (len <= 1024) { + return len.toFixed(0) + " B"; + } + len /= 1024; + if (len <= 1024) { + return len.toFixed(1) + " KB" + } + len /= 1024; + if (len <= 1024) { + return len.toFixed(2) + " MB"; + } + len /= 1024; + return len.toFixed(3) + " GB"; + }, + + fmtspeed: function(speed) { + return utils.fmtsize(speed) + "/s"; + }, // saves the key value pair in cookies setCookie: function(key, value) { var exdate = new Date(); @@ -70,31 +91,29 @@ angular.module('webui.services.utils', []) }; })(), randStr: function() { - return this.uuid(); + return utils.uuid(); }, // maps the array in place to the destination // arr, dest (optional): array // func: a merge mapping func, see ctrls/download.js mergeMap: function(arr, dest, func) { - if (!dest) dest = []; - - for (var i = 0; i < dest.length; i++) { - if (i >= arr.length) { - // remove the deleted downloads - dest.splice(i, dest.length - arr.length); - break; - } - if (!dest[i]) dest[i] = {}; + if (!dest) { + dest = []; + } + for (var i = 0, e = Math.min(arr.length, dest.length); i < e; ++i) { func(arr[i], dest[i]); } - // insert newly created downloads + // Insert newly created downloads while (i < arr.length) { dest.push(func(arr[i++])); } + // Truncate if necessary. + dest.length = arr.length; + return dest; }, // get info title from global statistics @@ -144,4 +163,5 @@ angular.module('webui.services.utils', []) return chunks; } }; + return utils; }]);