diff --git a/src/index-template.html b/src/index-template.html
index b5731fae..350e0393 100644
--- a/src/index-template.html
+++ b/src/index-template.html
@@ -187,7 +187,7 @@
{{ 'Manage' | translate }}
-
-->
+
diff --git a/src/js/ctrls/nav.js b/src/js/ctrls/nav.js
index 9c6d09b8..1912810b 100644
--- a/src/js/ctrls/nav.js
+++ b/src/js/ctrls/nav.js
@@ -146,5 +146,31 @@ export default angular
scope.shutDownServer = function() {
rpc.once("shutdown", []);
};
+
+ scope.restartError = function(offset, limit) {
+ // offset, limit, like sql
+ // count
+ var fetch = function(off, lim, count) {
+ console.log("fetching: " + off + " limit: " + lim);
+ rpc.once("tellStopped", [off, count], function(data) {
+ var errors = _.filter(data[0], function(d) {
+ return d["status"] == "error";
+ });
+ errors = errors.slice(0, lim);
+ console.log("restart: " + errors.length);
+ _.forEach(errors, function(d) {
+ rhelpers.restart(d);
+ // console.log(d.status);
+ });
+
+ if (errors.length < lim && data[0].length == count) {
+ fetch(off + count, lim - errors.length, count);
+ } else {
+ console.log("end");
+ }
+ });
+ };
+ fetch(offset, limit, 100);
+ };
}
]).name;
diff --git a/src/js/services/rpc/helpers.js b/src/js/services/rpc/helpers.js
index 1dec4964..0e04c23c 100644
--- a/src/js/services/rpc/helpers.js
+++ b/src/js/services/rpc/helpers.js
@@ -15,6 +15,7 @@ export default angular
rpc.once("getVersion", [], function(data) {
miscellaneous = data[0];
});
+
return {
isFeatureEnabled: function(feature) {
return miscellaneous.enabledFeatures.indexOf(feature) != -1;
@@ -61,6 +62,84 @@ export default angular
// now dispatch all addUri syscalls
rpc.forceUpdate();
+ },
+ // copied from main.js
+ restart: function(d) {
+ // assumes downloads which are started by URIs, not torrents.
+ // the preferences are also not transferred, just simple restart
+ var thisService = this;
+ rpc.once("getOption", [d.gid], function(data) {
+ var prefs = data[0];
+ rpc.once("getFiles", [d.gid], function(data) {
+ var files = data[0];
+ var uris = _.chain(files)
+ .map(function(f) {
+ return f.uris;
+ })
+ .filter(function(uris) {
+ return uris && uris.length;
+ })
+ .map(function(uris) {
+ var u = _.chain(uris)
+ .map(function(u) {
+ return u.uri;
+ })
+ .uniq()
+ .value();
+ return u;
+ })
+ .value();
+
+ if (uris.length > 0) {
+ console.log("adding uris:", uris, prefs);
+ thisService.remove(
+ d,
+ function() {
+ thisService.addUris(uris, prefs);
+ },
+ true
+ );
+ }
+ });
+ });
+ },
+ canRestart: function(d) {
+ return ["active", "paused"].indexOf(d.status) == -1 && !d.bittorrent;
+ },
+ // remove the download,
+ // put it in stopped list if active,
+ // otherwise permanantly remove it
+ // d: the download ctx
+ remove: function(d, cb, noConfirm) {
+ // HACK to make sure an angular digest is not running, as only one can happen at a time, and confirm is a blocking
+ var thisService = this;
+ // call so an rpc response can also trigger a digest call
+ setTimeout(function() {
+ if (
+ !noConfirm &&
+ !confirm(
+ filter("translate")("Remove {{name}} and associated meta-data?", { name: d.name })
+ )
+ ) {
+ return;
+ }
+
+ var method = "remove";
+
+ if (thisService.getType(d) == "stopped") method = "removeDownloadResult";
+
+ if (d.followedFrom) {
+ thisService.remove(d.followedFrom, function() {}, true);
+ d.followedFrom = null;
+ }
+ rpc.once(method, [d.gid], cb);
+ }, 0);
+ },
+ getType: function(d) {
+ var type = d.status;
+ if (type == "paused") type = "waiting";
+ if (["error", "removed", "complete"].indexOf(type) != -1) type = "stopped";
+ return type;
}
};
}
diff --git a/src/scss/app.scss b/src/scss/app.scss
index 404d8c55..69e8b60c 100644
--- a/src/scss/app.scss
+++ b/src/scss/app.scss
@@ -9,3 +9,29 @@
@import "style";
@import "download";
@import "modals";
+
+.dropdown-submenu {
+ position: relative;
+}
+
+.dropdown-submenu:hover > .dropdown-menu {
+ display: block;
+}
+
+.dropdown-submenu > a:after {
+ display: block;
+ content: " ";
+ float: right;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #ccc;
+ margin-top: 5px;
+ margin-right: -10px;
+}
+
+.dropdown-submenu:hover > a:after {
+ border-left-color: #fff;
+}