diff --git a/webui/src/main/java/com/muwire/webui/FeedManager.java b/webui/src/main/java/com/muwire/webui/FeedManager.java
index 4807f78a..d861aa07 100644
--- a/webui/src/main/java/com/muwire/webui/FeedManager.java
+++ b/webui/src/main/java/com/muwire/webui/FeedManager.java
@@ -14,6 +14,7 @@ import com.muwire.core.filefeeds.FeedLoadedEvent;
import com.muwire.core.filefeeds.UIDownloadFeedItemEvent;
import com.muwire.core.filefeeds.UIFeedConfigurationEvent;
import com.muwire.core.filefeeds.UIFeedDeletedEvent;
+import com.muwire.core.filefeeds.UIFeedUpdateEvent;
public class FeedManager {
@@ -83,6 +84,12 @@ public class FeedManager {
core.getEventBus().publish(event);
}
+ void update(Persona publisher) {
+ UIFeedUpdateEvent event = new UIFeedUpdateEvent();
+ event.setHost(publisher);
+ core.getEventBus().publish(event);
+ }
+
static class RemoteFeed {
private final Feed feed;
private volatile long revision;
diff --git a/webui/src/main/java/com/muwire/webui/FeedServlet.java b/webui/src/main/java/com/muwire/webui/FeedServlet.java
index f78cdae0..59f16474 100644
--- a/webui/src/main/java/com/muwire/webui/FeedServlet.java
+++ b/webui/src/main/java/com/muwire/webui/FeedServlet.java
@@ -186,6 +186,22 @@ public class FeedServlet extends HttpServlet {
event.setTarget(target);
core.getEventBus().publish(event);
Util.pause();
+ } else if (action.equals("update")) {
+ String personaB64 = req.getParameter("host");
+ if (personaB64 == null) {
+ resp.sendError(403,"Bad param");
+ return;
+ }
+ Persona host;
+ try {
+ host = new Persona(new ByteArrayInputStream(Base64.decode(personaB64)));
+ } catch (Exception bad) {
+ resp.sendError(403,"Bad param");
+ return;
+ }
+
+ feedManager.update(host);
+ Util.pause();
}
}
@@ -239,7 +255,7 @@ public class FeedServlet extends HttpServlet {
static {
ITEM_COMPARATORS.add("Name", ITEM_BY_NAME);
ITEM_COMPARATORS.add("Size", ITEM_BY_SIZE);
- ITEM_COMPARATORS.add("Status", ITEM_BY_STATUS);
+ ITEM_COMPARATORS.add("Download", ITEM_BY_STATUS);
ITEM_COMPARATORS.add("Published", ITEM_BY_TIMESTAMP);
}
diff --git a/webui/src/main/java/com/muwire/webui/Util.java b/webui/src/main/java/com/muwire/webui/Util.java
index adf5a651..4bdd1d2e 100644
--- a/webui/src/main/java/com/muwire/webui/Util.java
+++ b/webui/src/main/java/com/muwire/webui/Util.java
@@ -104,6 +104,7 @@ public class Util {
_x("Trusted User"),
_x("Unshare"),
_x("Unsubscribe"),
+ _x("Update"),
_x("Upload"),
_x("Uploads"),
_x("User"),
diff --git a/webui/src/main/js/feeds.js b/webui/src/main/js/feeds.js
index b4c6dc23..f30119eb 100644
--- a/webui/src/main/js/feeds.js
+++ b/webui/src/main/js/feeds.js
@@ -10,7 +10,27 @@ class Feed {
}
getMapping() {
- // TODO: implement
+ var mapping = new Map()
+ var publisherLink = new Link(this.publisher, "displayFeed", [this.publisher])
+ var updateHTML = ""
+ if (this.active != "true") {
+ var updateLink = new Link(_t("Update"), "forceUpdate", [this.publisherB64])
+ updateHTML = updateLink.render()
+ }
+ var unsubscribeLink = new Link(_t("Unsubscribe"), "unsubscribe", [this.publisherB64])
+ var configureLink = new Link(_t("Configure", "configure", [this.publisherB64]))
+
+ var publisherHTML = publisherLink.render() + "" + updateHTML + " " +
+ unsubscribeLink.render() + " " +
+ configureLink.render() +
+ ""
+
+ mapping.set("Publisher", publisherHTML)
+ mapping.set("Files", this.files)
+ mapping.set("Last Updated", this.lastUpdated)
+ mapping.set("Status", this.status)
+
+ return mapping
}
}
@@ -26,12 +46,65 @@ class Item {
try {
this.comment = xmlNode.getElementsByTagName("Comment")[0].childNodes[0].nodeValue
} catch (ignore) {
- this.comment = ""
+ this.comment = null
}
}
+ getCommentBlock() {
+ if (this.comment == null)
+ return ""
+ if (expandedComments.get(this.infoHash)) {
+ var hideCommentLink = new Link(_t("Hide Comment"), "hideComment", [this.infoHash])
+ var html = "
"
+ return html
+ } else {
+ var showCommentLink = new Link(_t("Show Comment"), "showComment", [this.infoHash])
+ var html = ""
+ html += ""
+ return html
+ }
+ }
+
+ getCertificatesBlock() {
+ if (this.certificates == "0")
+ return ""
+
+ var linkText
+ if (this.certificates == "1")
+ linkText = _t("View 1 Certificate")
+ else
+ linkText = _t("View {0} Certificates", this.certificates)
+ var b64 = feeds.get(currentFeed).publisherB64
+ var link = new Link(linkText, "showCertificates", [b64, this.infoHash])
+ var id = b64 + "_" + this.infoHash
+
+ return "'" + link.render() + "
" +
+ ""
+
+ }
+
+ getDownloadBlock() {
+ if (this.resultStatus == "DOWNLOADING")
+ return "" + _t("Downloading") + ""
+ if (this.resultStatus == "SHARED")
+ return "" + _t("Downloaded") + ""
+ var downloadLink = new Link(_t("Download"), "download", [this.infoHash])
+ return "" + downloadLink.render() + ""
+ }
+
getMapping() {
- // TODO: implement
+ var mapping = new Map()
+
+ var nameHtml = this.name
+ nameHtml += this.getCommentBlock()
+ nameHtml += this.getCertificatesBlock()
+ mapping.set("Name", nameHtml)
+ mapping.set("Size", this.size)
+ mapping.set("Download", this.getDownloadBlock())
+ mapping.set("Published", this.timestamp)
}
}
@@ -90,18 +163,23 @@ function displayFeed(feed) {
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
+ itemsByInfohash.clear()
+
var items = []
var itemNodes = this.responseXML.getElementsByTagName("Item")
var i
- for (i = 0; i < itemNodes.length; i++)
- items.push(new Item(itemNodes[i]))
+ for (i = 0; i < itemNodes.length; i++) {
+ var item = new Item(itemNodes[i])
+ items.push(item)
+ itemsByInfoHash.set(item.infoHash, item)
+ }
var newOrder
if (itemsSortOrder == "descending")
newOrder = "ascending"
else if (itemsSortOrder == "ascending")
newOrder = "descending"
- var table = new Table(["Name", "Size", "Status", "Published"], "sortItems", itemsSortKey, newOrder, null)
+ var table = new Table(["Name", "Size", "Download", "Published"], "sortItems", itemsSortKey, newOrder, null)
for (i = 0; i < items.length; i++) {
table.addRow(items[i].getMapping())
}
@@ -130,10 +208,96 @@ function sortItems(key, order) {
displayFeed(currentFeed)
}
+function forceUpdate(b64) {
+ var xmlhttp = new XMLHttpRequest()
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ refreshFeeds()
+ }
+ }
+ xmlhttp.open("POST","/MuWire/Feed", true)
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xmlhttp.open("action=update&host=" + b64)
+}
+
+function unsubscribe(b64) {
+ var xmlhttp = new XMLHttpRequest()
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ refreshFeeds()
+ }
+ }
+ xmlhttp.open("POST","/MuWire/Feed", true)
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xmlhttp.open("action=unsubscribe&host=" + b64)
+}
+
+function configure(b64) {
+ // TODO: implement
+}
+
+function showCertificates(hostB64, infoHash) {
+ var fetch = new CertificateFetch(hostB64, infoHash)
+ certificateFetches.set(fetch.divId, fetch)
+
+ var xmlhttp = new XMLHttpRequest()
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ var hideLink = new Link(_t("Hide Certificates"), "hideCertificates", [hostB64, infoHash])
+ var hideLinkSpan = document.getElementById("certificates-link-" + fetch.divId)
+ hideLinkSpan.innerHTML = hideLink.render()
+
+ var certSpan = document.getElementById("certificates-" + fetch.divId)
+ certSpan.innerHTML = _t("Fetching Certificates")
+ }
+ }
+ xmlhttp.open("POST", "/MuWire/Certificate", true)
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xmlhttp.send("action=fetch&user=" + hostB64 + "&infoHash=" + infoHash)
+}
+
+function hideCertificates(hostB64, infoHash) {
+ var id = hostB64 + "_" + infoHash
+ certificateFetches.delete(id)
+
+ var certSpan = document.getElementById("certificates-" + id)
+ certSpan.innerHTML = ""
+
+ var item = itemsByInfoHash.get(infoHash)
+ var showLinkText
+ if (item.certificates == "1")
+ showLinkText = _t("View 1 Certificate")
+ else
+ showLinkText = _t("View {0} Certificates", item.certificates)
+
+ var showLink = new Link(showLinkText, "showCertificates", [hostB64, infoHash])
+ var linkSpan = document.getElementById("certificates-link-" + id)
+ linkSpan.innerHTML = showLink.render()
+}
+
+function download(infoHash) {
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ var resultSpan = document.getElementById("download-" + infoHash);
+ resultSpan.innerHTML = "" + _t("Downloading") + ""
+ }
+ }
+
+ var hostB64 = feeds.get(currentFeed).publisherB64
+ xmlhttp.open("POST", "/MuWire/Feed", true)
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ xmlhttp.send("action=download&host=" + hostB64 + "&infoHash=" + infoHash)
+}
+
var feeds = new Map()
var currentFeed = null
+var itemsByInfoHash = new Map()
+
var feedsSortKey = "Publisher"
var feedsSortOrder = "descending"
var itemsSortKey = "Name"
-var itemsSortOrder = "descending"
\ No newline at end of file
+var itemsSortOrder = "descending"
+
+var expandedComments = new Map()
\ No newline at end of file