From: David ‘Bombe’ Roden Date: Fri, 7 Apr 2017 20:55:54 +0000 (+0200) Subject: Show and manage linked elements in web interface X-Git-Tag: 0.9.7^2~262 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=972ca0e1490124c9da45a12ee9a079d91d62d6dc Show and manage linked elements in web interface --- diff --git a/src/main/resources/static/css/sone.css b/src/main/resources/static/css/sone.css index 34dad50..7392483 100644 --- a/src/main/resources/static/css/sone.css +++ b/src/main/resources/static/css/sone.css @@ -444,7 +444,7 @@ textarea { margin-top: 1ex; } -#sone .post .linked-element { +#sone .post .linked-element.loaded .image { display: inline-block; border: solid 1px black; width: 160px; @@ -515,7 +515,7 @@ textarea { margin-top: 1ex; } -#sone .post .reply .linked-element { +#sone .post .reply .linked-element.loaded .image { display: inline-block; border: solid 1px black; width: 120px; diff --git a/src/main/resources/static/javascript/sone.js b/src/main/resources/static/javascript/sone.js index 7ef585d..a003780 100644 --- a/src/main/resources/static/javascript/sone.js +++ b/src/main/resources/static/javascript/sone.js @@ -1194,7 +1194,13 @@ function checkForRemovedReplies(oldNotification, newNotification) { } function getStatus() { - ajaxGet("getStatus.ajax", isViewSonePage() ? {"soneIds": getShownSoneId() } : isKnownSonesPage() ? {"soneIds": getShownSoneIds() } : {}, function(data, textStatus) { + var parameters = isViewSonePage() ? {"soneIds": getShownSoneId() } : isKnownSonesPage() ? {"soneIds": getShownSoneIds() } : {}; + $.extend(parameters, { + "elements": JSON.stringify($(".linked-element.not-loaded").map(function () { + return $(this).attr("title"); + }).toArray()) + }); + ajaxGet("getStatus.ajax", parameters, function(data, textStatus) { if ((data != null) && data.success) { /* process Sone information. */ $.each(data.sones, function(index, value) { @@ -1216,6 +1222,9 @@ function getStatus() { loadNewReply(value.id, value.sone, value.post, value.postSone); }); } + if (data.linkedElements) { + loadLinkedElements(data.linkedElements) + } /* do it again in 5 seconds. */ setTimeout(getStatus, 5000); } else { @@ -1520,6 +1529,37 @@ function loadNewReply(replyId, soneId, postId, postSoneId) { }); } +function loadLinkedElements(links) { + var failedElements = links.filter(function(element) { + return element.failed; + }); + if (failedElements.length > 0) { + failedElements.forEach(function(element) { + $(getLinkedElement(element.link)).remove() + }); + } + var loadedElements = links.filter(function(element) { + return !element.loading && !element.failed; + }); + if (loadedElements.length > 0) { + ajaxGet("getLinkedElement.ajax", { + "elements": JSON.stringify(loadedElements.map(function(element) { + return element.link; + })) + }, function (data, textStatus) { + if ((data != null) && (data.success)) { + data.linkedElements.forEach(function (linkedElement) { + $(getLinkedElement(linkedElement.link)).replaceWith(linkedElement.html); + }); + } + }); + } +} + +function getLinkedElement(link) { + return $(".linked-element[title='" + link + "']")[0] +} + /** * Marks the given Sone as known if it is still new. * diff --git a/src/main/resources/templates/linked/image.html b/src/main/resources/templates/linked/image.html index 17fa28a..d7fef5a 100644 --- a/src/main/resources/templates/linked/image.html +++ b/src/main/resources/templates/linked/image.html @@ -1 +1 @@ - + diff --git a/src/main/resources/templates/linked/notLoaded.html b/src/main/resources/templates/linked/notLoaded.html index 87ee516..4a2d977 100644 --- a/src/main/resources/templates/linked/notLoaded.html +++ b/src/main/resources/templates/linked/notLoaded.html @@ -1 +1 @@ - + diff --git a/src/test/kotlin/net/pterodactylus/sone/template/LinkedElementRenderFilterTest.kt b/src/test/kotlin/net/pterodactylus/sone/template/LinkedElementRenderFilterTest.kt index e8e7fc3..c3e26c0 100644 --- a/src/test/kotlin/net/pterodactylus/sone/template/LinkedElementRenderFilterTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/template/LinkedElementRenderFilterTest.kt @@ -34,26 +34,28 @@ class LinkedElementRenderFilterTest { } @Test - fun `filter renders loading animation for not loaded elements`() { + fun `filter renders empty span for not loaded elements`() { val html = filter.format(null, LinkedElement("KSK@gpl.png", loading = true), emptyMap()) as String val spanNode = Jsoup.parseBodyFragment(html).body().child(0) assertThat(spanNode.nodeName(), `is`("span")) - assertThat(spanNode.attr("class"), `is`("linked-element")) + assertThat(spanNode.attr("class"), `is`("linked-element not-loaded")) assertThat(spanNode.attr("title"), `is`("KSK@gpl.png")) - assertThat(spanNode.attr("style"), `is`("background-image: url('images/loading-animation.gif')")) + assertThat(spanNode.hasAttr("style"), `is`(false)) + assertThat(spanNode.children().isEmpty(), `is`(true)) } @Test fun `filter can render linked images`() { val html = filter.format(null, LinkedElement("KSK@gpl.png"), emptyMap()) as String - val linkNode = Jsoup.parseBodyFragment(html).body().child(0) + val outerSpanNode = Jsoup.parseBodyFragment(html).body().child(0) + assertThat(outerSpanNode.nodeName(), `is`("span")) + assertThat(outerSpanNode.attr("class"), `is`("linked-element loaded")) + assertThat(outerSpanNode.attr("title"), `is`("KSK@gpl.png")) + val linkNode = outerSpanNode.child(0) assertThat(linkNode.nodeName(), `is`("a")) assertThat(linkNode.attr("href"), `is`("/KSK@gpl.png")) - val spanNode = linkNode.child(0) - assertThat(spanNode.nodeName(), `is`("span")) - assertThat(spanNode.attr("class"), `is`("linked-element")) - assertThat(spanNode.attr("title"), `is`("KSK@gpl.png")) - assertThat(spanNode.attr("style"), `is`("background-image: url('/KSK@gpl.png')")) + val innerSpanNode = linkNode.child(0) + assertThat(innerSpanNode.attr("style"), `is`("background-image: url('/KSK@gpl.png')")) } @Test