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 "" + + "
" + + } + + 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