Compare commits

...

3 Commits

Author SHA1 Message Date
zzz
901e8f4dd8 Highlight class js tweaks, implement in ubergine CSS 2023-01-02 09:22:56 -05:00
zzz
2778a9767e js updates, add ids to buttons
CSS highlight class TODO
2023-01-01 11:32:29 -05:00
zzz
1a5b9c2241 i2psnark: Add basic JS drag and drop support
for files and URLs.
Expand form and put URLs in the right place, can be dropped anywhere on the page
Popup to guide user where to drop files, can't get full path from js due to browser security.
Strip file:// from create torrent form to support file drag and drop of the path
2022-12-29 13:17:20 -05:00
3 changed files with 257 additions and 11 deletions

View File

@@ -340,7 +340,8 @@ public class I2PSnarkServlet extends BasicServlet {
"var deleteMessage1 = \"" + _t("Are you sure you want to delete the file \\''{0}\\'' (downloaded data will not be deleted) ?") + "\";\n" +
"var deleteMessage2 = \"" + _t("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?") + "\";\n" +
"</script>\n" +
"<script src=\".resources/js/delete.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
"<script src=\".resources/js/delete.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n" +
"<script src=\".resources/js/dnd.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
}
out.write(HEADER_A + _themePath + HEADER_B);
@@ -384,7 +385,7 @@ public class I2PSnarkServlet extends BasicServlet {
String newURL = req.getParameter("newURL");
if (newURL != null && newURL.trim().length() > 0 && req.getMethod().equals("GET"))
_manager.addMessage(_t("Click \"Add torrent\" button to fetch torrent"));
out.write("<div class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
out.write("<div id=\"page\" class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
writeMessages(out, isConfigure, peerString);
@@ -1337,6 +1338,9 @@ public class I2PSnarkServlet extends BasicServlet {
} else if ("Create".equals(action)) {
String baseData = req.getParameter("nofilter_baseFile");
if (baseData != null && baseData.trim().length() > 0) {
// drag and drop, no js
if (baseData.startsWith("file://"))
baseData = baseData.substring(7);
File baseFile = new File(baseData.trim());
if (!baseFile.isAbsolute())
baseFile = new File(_manager.getDataDir(), baseData);
@@ -2312,19 +2316,19 @@ public class I2PSnarkServlet extends BasicServlet {
out.write("<hr>\n<table border=\"0\"><tr><td>");
out.write(_t("From URL"));
out.write(":<td><input type=\"text\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"" +
out.write(":<td><input type=\"text\" id=\"nofilter_newURL\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"" +
" title=\"");
out.write(_t("Enter the torrent file download URL (I2P only), magnet link, or info hash"));
out.write("\">\n");
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
out.write("<input type=\"submit\" class=\"add\" value=\"");
out.write("<input type=\"submit\" id=\"addButton\" class=\"add\" value=\"");
out.write(_t("Add torrent"));
out.write("\" name=\"foo\" ><br>\n" +
"<tr><td>");
out.write(_t("Data dir"));
out.write(":<td><input type=\"text\" name=\"nofilter_newDir\" size=\"85\" value=\"\" spellcheck=\"false\"" +
out.write(":<td><input type=\"text\" id=\"nofilter_newDir\" name=\"nofilter_newDir\" size=\"85\" value=\"\" spellcheck=\"false\"" +
" title=\"");
out.write(_t("Enter the directory to save the data in (default {0})", _manager.getDataDir().getAbsolutePath()));
out.write("\"></td></tr>\n");
@@ -2350,11 +2354,11 @@ public class I2PSnarkServlet extends BasicServlet {
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
out.write(_t("Data to seed"));
out.write(":<td>"
+ "<input type=\"text\" name=\"nofilter_baseFile\" size=\"85\" value=\""
+ "<input type=\"text\" id=\"nofilter_baseFile\" name=\"nofilter_baseFile\" size=\"85\" value=\""
+ "\" spellcheck=\"false\" title=\"");
out.write(_t("File or directory to seed (full path or within the directory {0} )",
_manager.getDataDir().getAbsolutePath() + File.separatorChar));
out.write("\" > <input type=\"submit\" class=\"create\" value=\"");
out.write("\" > <input type=\"submit\" id=\"createButton\" class=\"create\" value=\"");
out.write(_t("Create torrent"));
out.write("\" name=\"foo\" >" +
"<tr><td>\n");

View File

@@ -0,0 +1,242 @@
/* @license http://www.gnu.org/licenses/gpl-2.0.html GPL-2.0 */
/* see also licenses/LICENSE-GPLv2.txt */
/**
* Drop a link anywhere on the page and we will open the add and create torrent sections
* and put it in the add torrent form.
*
* Drop a file anywhere on the page and we will open the add and create torrent sections
* and throw up an alert telling you to pick one.
*
* ref: https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop
*
* @since 0.9.57
*/
function initDND()
{
var add = document.getElementById("toggle_addtorrent");
if (add != null) {
// we are on page one
var create = document.getElementById("toggle_createtorrent");
var div = document.getElementById("page");
var form1 = document.getElementById("nofilter_newURL");
var form2 = document.getElementById("nofilter_newDir");
var form3 = document.getElementById("nofilter_baseFile");
var addbutton = document.getElementById("addButton");
var createbutton = document.getElementById("createButton");
div.addEventListener("drop", function(event) {
var name = "";
var isURL = false;
var isDir = false;
if (event.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
var item = event.dataTransfer.items[0];
// Chrome bug
// https://bugs.chromium.org/p/chromium/issues/detail?id=1363757
// sometimes undefined for directories, throws uncaught TypeError
if (((typeof item.kind) !== "undefined") && (item.kind === "file")) {
var file = item.getAsFile();
if (file.size == 0)
isDir = true;
name = file.name;
} else {
// If dropped items aren't files, maybe they are URLs
// we're going here in chrome for files usually
name = event.dataTransfer.getData("URL");
if (name.length > 0) {
isURL = true;
}
// else chrome bug
// https://bugs.chromium.org/p/chromium/issues/detail?id=1363757
}
} else {
// Use DataTransfer interface to access the file(s)
var file = event.dataTransfer.files[0];
if (file.size == 0)
isDir = true;
name = file.name;
}
// set name in form
if (name.length > 0) {
if (isURL) {
event.preventDefault();
// prevent inadvertent drag-from-self
var url = new URL(name);
var us = new URL(document.location.href);
if (url.origin === us.origin) {
form1.value = "";
event.dataTransfer.dropEffect = "none";
} else {
form1.value = name;
addbutton.classList.add("highlight");
}
} else {
form1.value = "";
form2.value = "";
/*
if (event.target.id != "nofilter_newDir" && event.target.id != "nofilter_baseFile") {
// we don't get here any more, because dragover sets dropEffect="none"
// boo, we can't get the full path
// user must hit the target, either datadir or basefile
event.preventDefault();
// TODO translate
if (isDir) {
alert("Drop the directory \"" + name + "\" in \"Data dir\" to add a torrent or \"Data to seed\" to create a torrent");
} else {
// not a directory, can't be add torrent
alert("Drop the file \"" + name + "\" in \"Data to seed\" to create a torrent");
}
}
*/
}
} else {
// Chrome bug
// https://bugs.chromium.org/p/chromium/issues/detail?id=1363757
console.info("Chrome bug? File drag and drop not supported on this browser");
}
});
div.addEventListener("dragover", function(event) {
event.preventDefault();
// Setting to "none" causes the snap-back effect when dropped.
// The drop event will not be fired, and we won't popup the alert.
var fileRequired = (event.target.id === "nofilter_newDir" || event.target.id === "nofilter_baseFile");
if (event.dataTransfer.items) {
var item = event.dataTransfer.items[0];
// needed for Chrome
if (((typeof item.kind) !== "undefined") && (item.kind === "file")) {
if (fileRequired) {
event.dataTransfer.dropEffect = "copy";
} else {
event.dataTransfer.dropEffect = "none";
}
} else {
if (fileRequired) {
event.dataTransfer.dropEffect = "none";
} else {
event.dataTransfer.dropEffect = "link";
}
}
} else {
if (fileRequired) {
event.dataTransfer.dropEffect = "copy";
} else {
event.dataTransfer.dropEffect = "none";
}
}
});
div.addEventListener("dragenter", function(event) {
event.preventDefault();
// expand one or both sections and scroll to view
if (event.dataTransfer.items) {
var item = event.dataTransfer.items[0];
if (((typeof item.kind) !== "undefined") && (item.kind === "file")) {
create.checked = true;
form1.classList.remove("highlight");
form2.classList.add("highlight");
form3.classList.add("highlight");
} else {
create.checked = false;
form1.classList.add("highlight");
form2.classList.remove("highlight");
form3.classList.remove("highlight");
}
} else {
create.checked = true;
form1.classList.remove("highlight");
form2.classList.add("highlight");
form3.classList.add("highlight");
}
add.checked = true;
add.scrollIntoView(true);
});
form1.addEventListener("change", function(event) {
if (form1.value.length > 0) {
form1.classList.remove("highlight");
form2.classList.remove("highlight");
addbutton.classList.add("highlight");
} else {
addbutton.classList.remove("highlight");
}
});
form2.addEventListener("change", function(event) {
if (form2.value.length > 7 && form2.value.startsWith("file://")) {
form2.value = form2.value.substring(7);
}
if (form1.value.length > 0) {
form1.classList.remove("highlight");
form2.classList.remove("highlight");
addbutton.classList.add("highlight");
} else {
addbutton.classList.remove("highlight");
}
});
form3.addEventListener("change", function(event) {
if (form3.value.length > 7 && form3.value.startsWith("file://")) {
form3.value = form3.value.substring(7);
}
if (form3.value.length > 0) {
form3.classList.remove("highlight");
createbutton.classList.add("highlight");
} else {
createbutton.classList.remove("highlight");
}
});
form1.addEventListener("blur", function(event) {
if (form1.value.length > 0) {
form1.classList.remove("highlight");
form3.classList.remove("highlight");
form3.value="";
addbutton.classList.add("highlight");
createbutton.classList.remove("highlight");
} else {
addbutton.classList.remove("highlight");
}
form2.classList.remove("highlight");
});
form2.addEventListener("blur", function(event) {
if (form1.value.length > 0) {
form1.classList.remove("highlight");
form2.classList.remove("highlight");
form3.classList.remove("highlight");
form3.value="";
addbutton.classList.add("highlight");
createbutton.classList.remove("highlight");
} else {
form1.classList.add("highlight");
addbutton.classList.remove("highlight");
}
});
form3.addEventListener("blur", function(event) {
if (form3.value.length > 0) {
form1.classList.remove("highlight");
form2.classList.remove("highlight");
form3.classList.remove("highlight");
form1.value="";
form2.value="";
createbutton.classList.add("highlight");
addbutton.classList.remove("highlight");
} else {
createbutton.classList.remove("highlight");
}
});
} else {
// we are not on page one
// TODO
}
}
document.addEventListener("DOMContentLoaded", function() {
initDND();
}, true);
/* @license-end */

View File

@@ -1477,7 +1477,7 @@ input[name="nofilter_commentsName"]:focus::placeholder {
opacity: 0;
}
input[type=text]:active, input[type=text]:focus, input.r:focus, input[name="nofilter_dataDir"]:focus, textarea:focus {
input[type=text]:active, input[type=text]:focus, input.r:focus, input[name="nofilter_dataDir"]:focus, textarea:focus, input[type=text].highlight {
background: #d60;
background: linear-gradient(to bottom, #d60, #c50);
color: #fff;
@@ -1587,17 +1587,17 @@ input[type="submit"], input[type="reset"] {
box-shadow: 0 0 1px 1px rgba(48,16,48,0.7);
}
input[type="submit"]:hover, input[type="submit"]:focus {
input[type="submit"]:hover, input[type="submit"]:focus, input[type="submit"].highlight {
background-blend-mode: luminosity;
}
input[type="submit"]:hover, input[type="submit"]:focus, a.control:hover, a.control:focus {
input[type="submit"]:hover, input[type="submit"]:focus, a.control:hover, a.control:focus, input[type="submit"].highlight {
border: 1px outset #bbb;
color: #fff;
filter: drop-shadow(0 0 1px #515) !important;
}
input[type="submit"]:focus, input[type="reset"]:focus, a.control:focus {
input[type="submit"]:focus, input[type="reset"]:focus, a.control:focus, input[type="submit"].highlight {
filter: drop-shadow(0 0 1px #f60) !important;
}