Make “follow”, “unfollow”, “block” and “unblock” buttons dynamic.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 22 Oct 2010 21:39:42 +0000 (23:39 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 22 Oct 2010 21:39:42 +0000 (23:39 +0200)
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/main/java/net/pterodactylus/sone/web/ajax/BlockSoneAjaxPage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/web/ajax/FollowSoneAjaxPage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/web/ajax/UnblockSoneAjaxPage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/web/ajax/UnfollowSoneAjaxPage.java [new file with mode: 0644]
src/main/resources/static/css/sone.css
src/main/resources/static/javascript/sone.js
src/main/resources/templates/include/head.html
src/main/resources/templates/include/viewSone.html

index 2bdeff5..4294e64 100644 (file)
@@ -38,10 +38,14 @@ import net.pterodactylus.sone.template.PostAccessor;
 import net.pterodactylus.sone.template.RequestChangeFilter;
 import net.pterodactylus.sone.template.SoneAccessor;
 import net.pterodactylus.sone.template.SubstringFilter;
+import net.pterodactylus.sone.web.ajax.BlockSoneAjaxPage;
 import net.pterodactylus.sone.web.ajax.DeletePostAjaxPage;
 import net.pterodactylus.sone.web.ajax.DeleteReplyAjaxPage;
+import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage;
 import net.pterodactylus.sone.web.ajax.GetSoneStatusPage;
 import net.pterodactylus.sone.web.ajax.GetTranslationPage;
+import net.pterodactylus.sone.web.ajax.UnblockSoneAjaxPage;
+import net.pterodactylus.sone.web.ajax.UnfollowSoneAjaxPage;
 import net.pterodactylus.sone.web.page.PageToadlet;
 import net.pterodactylus.sone.web.page.PageToadletFactory;
 import net.pterodactylus.sone.web.page.StaticPage;
@@ -230,6 +234,10 @@ public class WebInterface extends AbstractService {
                pageToadlets.add(pageToadletFactory.createPageToadlet(new GetSoneStatusPage(this)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new DeletePostAjaxPage(this)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new DeleteReplyAjaxPage(this)));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(new FollowSoneAjaxPage(this)));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(new UnfollowSoneAjaxPage(this)));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(new BlockSoneAjaxPage(this)));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(new UnblockSoneAjaxPage(this)));
 
                ToadletContainer toadletContainer = sonePlugin.pluginRespirator().getToadletContainer();
                toadletContainer.getPageMaker().addNavigationCategory("/Sone/index.html", "Navigation.Menu.Name", "Navigation.Menu.Tooltip", sonePlugin);
diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/BlockSoneAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/BlockSoneAjaxPage.java
new file mode 100644 (file)
index 0000000..e4ffe2b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Sone - BlockSoneAjaxPage.java - Copyright © 2010 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web.ajax;
+
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.web.WebInterface;
+import net.pterodactylus.util.json.JsonObject;
+
+/**
+ * AJAX page that lets the user block another Sone.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class BlockSoneAjaxPage extends JsonPage {
+
+       /**
+        * Creates a new “block Sone” AJAX page.
+        *
+        * @param webInterface
+        *            The Sone web interface
+        */
+       public BlockSoneAjaxPage(WebInterface webInterface) {
+               super("ajax/blockSone.ajax", webInterface);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected JsonObject createJsonObject(Request request) {
+               String soneId = request.getHttpRequest().getParam("sone");
+               if (soneId == null) {
+                       return new JsonObject().put("success", false).put("error", "invalid-sone-id");
+               }
+               Sone currentSone = getCurrentSone(request.getToadletContext());
+               if (currentSone == null) {
+                       return new JsonObject().put("success", false).put("error", "auth-required");
+               }
+               currentSone.addBlockedSoneId(soneId);
+               return new JsonObject().put("success", true);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/FollowSoneAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/FollowSoneAjaxPage.java
new file mode 100644 (file)
index 0000000..5b4fdc2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Sone - FollowSoneAjaxPage.java - Copyright © 2010 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web.ajax;
+
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.web.WebInterface;
+import net.pterodactylus.util.json.JsonObject;
+
+/**
+ * AJAX page that lets a Sone follow another Sone.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class FollowSoneAjaxPage extends JsonPage {
+
+       /**
+        * Creates a new “follow Sone” AJAX page.
+        *
+        * @param webInterface
+        *            The Sone web interface
+        */
+       public FollowSoneAjaxPage(WebInterface webInterface) {
+               super("ajax/followSone.ajax", webInterface);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected JsonObject createJsonObject(Request request) {
+               String soneId = request.getHttpRequest().getParam("sone");
+               Sone sone = webInterface.core().getSone(soneId);
+               if (sone == null) {
+                       return new JsonObject().put("success", false).put("error", "invalid-sone-id");
+               }
+               Sone currentSone = getCurrentSone(request.getToadletContext());
+               if (currentSone == null) {
+                       return new JsonObject().put("success", false).put("error", "auth-required");
+               }
+               currentSone.addFriend(sone);
+               return new JsonObject().put("success", true);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/UnblockSoneAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/UnblockSoneAjaxPage.java
new file mode 100644 (file)
index 0000000..9012aee
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Sone - UnblockSoneAjaxPage.java - Copyright © 2010 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web.ajax;
+
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.web.WebInterface;
+import net.pterodactylus.util.json.JsonObject;
+
+/**
+ * AJAX page that lets the user unblock another Sone.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class UnblockSoneAjaxPage extends JsonPage {
+
+       /**
+        * Creates a new “unblock Sone” AJAX page.
+        *
+        * @param webInterface
+        *            The Sone web interface
+        */
+       public UnblockSoneAjaxPage(WebInterface webInterface) {
+               super("ajax/unblockSone.ajax", webInterface);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected JsonObject createJsonObject(Request request) {
+               String soneId = request.getHttpRequest().getParam("sone");
+               if (soneId == null) {
+                       return new JsonObject().put("success", false).put("error", "invalid-sone-id");
+               }
+               Sone currentSone = getCurrentSone(request.getToadletContext());
+               if (currentSone == null) {
+                       return new JsonObject().put("success", false).put("error", "auth-required");
+               }
+               currentSone.removeBlockedSoneId(soneId);
+               return new JsonObject().put("success", true);
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/UnfollowSoneAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/UnfollowSoneAjaxPage.java
new file mode 100644 (file)
index 0000000..012b9cf
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Sone - UnfollowSoneAjaxPage.java - Copyright © 2010 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web.ajax;
+
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.web.WebInterface;
+import net.pterodactylus.util.json.JsonObject;
+
+/**
+ * AJAX page that lets a Sone unfollow another Sone.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class UnfollowSoneAjaxPage extends JsonPage {
+
+       /**
+        * Creates a new “unfollow Sone” AJAX page.
+        *
+        * @param webInterface
+        *            The Sone web interface
+        */
+       public UnfollowSoneAjaxPage(WebInterface webInterface) {
+               super("ajax/unfollowSone.ajax", webInterface);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       protected JsonObject createJsonObject(Request request) {
+               String soneId = request.getHttpRequest().getParam("sone");
+               Sone sone = webInterface.core().getSone(soneId);
+               if (sone == null) {
+                       return new JsonObject().put("success", false).put("error", "invalid-sone-id");
+               }
+               Sone currentSone = getCurrentSone(request.getToadletContext());
+               if (currentSone == null) {
+                       return new JsonObject().put("success", false).put("error", "auth-required");
+               }
+               currentSone.removeFriend(sone);
+               return new JsonObject().put("success", true);
+       }
+
+}
index 503555e..79c91b8 100644 (file)
@@ -294,6 +294,10 @@ textarea {
        bottom: -0.5ex
 }
 
+#sone .sone form.hidden {
+       display: none;
+}
+
 #sone .sone form.block button, #sone .sone form.unblock button, #sone .sone form.follow button, #sone .sone form.unfollow button {
        display: inline;
        color: rgb(28, 131, 191);
index 45a678f..63b8361 100644 (file)
@@ -232,3 +232,22 @@ function enhanceDeleteReplyButton(buttonId, replyId) {
                });
        });
 }
+
+function getFormPassword() {
+       return $("#sone #formPassword").text();
+}
+
+function getSoneElement(element) {
+       return $(element).parent(".sone");
+}
+
+/**
+ * Returns the ID of the Sone that this element belongs to.
+ *
+ * @param element
+ *            The element to locate the matching Sone ID for
+ * @returns The ID of the Sone, or undefined
+ */
+function getSoneId(element) {
+       return getSoneElement(element).find(".id").text();
+}
index 9528ecd..ee4278c 100644 (file)
                });
        </script>
 
+       <script language="javascript">
+               /* convert all “follow”, “unfollow”, “block”, and “unblock” links to something nicer. */
+               $(document).ready(function() {
+                       $("#sone .follow").submit(function() {
+                               var followElement = this;
+                               $.getJSON("ajax/followSone.ajax", { "sone": getSoneId(this), "formPassword": getFormPassword() }, function() {
+                                       $(followElement).addClass("hidden");
+                                       $(followElement).parent().find(".unfollow").removeClass("hidden");
+                               });
+                               return false;
+                       });
+                       $("#sone .unfollow").submit(function() {
+                               var unfollowElement = this;
+                               $.getJSON("ajax/unfollowSone.ajax", { "sone": getSoneId(this), "formPassword": getFormPassword() }, function() {
+                                       $(unfollowElement).addClass("hidden");
+                                       $(unfollowElement).parent().find(".follow").removeClass("hidden");
+                               });
+                               return false;
+                       });
+                       $("#sone .block").submit(function() {
+                               var blockElement = this;
+                               $.getJSON("ajax/blockSone.ajax", { "sone": getSoneId(this), "formPassword": getFormPassword() }, function() {
+                                       $(blockElement).addClass("hidden");
+                                       $(blockElement).parent().find(".unblock").removeClass("hidden");
+                               });
+                               return false;
+                       });
+                       $("#sone .unblock").submit(function() {
+                               var unblockElement = this;
+                               $.getJSON("ajax/unblockSone.ajax", { "sone": getSoneId(this), "formPassword": getFormPassword() }, function() {
+                                       $(unblockElement).addClass("hidden");
+                                       $(unblockElement).parent().find(".block").removeClass("hidden");
+                               });
+                               return false;
+                       });
+               });
+       </script>
+
        <div id="main">
 
                <div id="profile" class="<%ifnull currentSone>offline<%else>online<%/if>">
index b12de4a..f2c51f7 100644 (file)
        <div class="short-request-uri"><% sone.requestUri|substring start=4 length=43|html></div>
        <%ifnull ! currentSone>
                <%if ! sone.current>
-                       <%if sone.friend>
-                               <form class="unfollow" action="unfollowSone.html" method="post">
-                                       <input type="hidden" name="formPassword" value="<% formPassword|html>" />
-                                       <input type="hidden" name="sone" value="<% sone.id|html>" />
-                                       <input type="hidden" name="returnPage" value="<% request.uri|html>" />
-                                       <button type="submit"><%= View.Sone.Button.UnfollowSone|l10n|html></button>
-                               </form>
-                       <%else>
-                               <form class="follow" action="followSone.html" method="post">
-                                       <input type="hidden" name="formPassword" value="<% formPassword|html>" />
-                                       <input type="hidden" name="sone" value="<% sone.id|html>" />
-                                       <input type="hidden" name="returnPage" value="<% request.uri|html>" />
-                                       <button type="submit"><%= View.Sone.Button.FollowSone|l10n|html></button>
-                               </form>
-                       <%/if>
-                       <%if sone.blocked>
-                               <form class="unblock" action="unblockSone.html" method="post">
-                                       <input type="hidden" name="formPassword" value="<% formPassword|html>" />
-                                       <input type="hidden" name="sone" value="<% sone.id|html>" />
-                                       <input type="hidden" name="returnPage" value="<% request.uri|html>" />
-                                       <button type="submit"><%= View.Sone.Button.UnblockSone|l10n|html></button>
-                               </form>
-                       <%else>
-                               <form class="block" action="blockSone.html" method="post">
-                                       <input type="hidden" name="formPassword" value="<% formPassword|html>" />
-                                       <input type="hidden" name="sone" value="<% sone.id|html>" />
-                                       <input type="hidden" name="returnPage" value="<% request.uri|html>" />
-                                       <button type="submit"><%= View.Sone.Button.BlockSone|l10n|html></button>
-                               </form>
-                       <%/if>
+                       <form class="unfollow<%if ! sone.friend> hidden<%/if>" action="unfollowSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<% formPassword|html>" />
+                               <input type="hidden" name="sone" value="<% sone.id|html>" />
+                               <input type="hidden" name="returnPage" value="<% request.uri|html>" />
+                               <button type="submit"><%= View.Sone.Button.UnfollowSone|l10n|html></button>
+                       </form>
+                       <form class="follow<%if sone.friend> hidden<%/if>" action="followSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<% formPassword|html>" />
+                               <input type="hidden" name="sone" value="<% sone.id|html>" />
+                               <input type="hidden" name="returnPage" value="<% request.uri|html>" />
+                               <button type="submit"><%= View.Sone.Button.FollowSone|l10n|html></button>
+                       </form>
+                       <form class="unblock<%if ! sone.blocked> hidden<%/if>" action="unblockSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<% formPassword|html>" />
+                               <input type="hidden" name="sone" value="<% sone.id|html>" />
+                               <input type="hidden" name="returnPage" value="<% request.uri|html>" />
+                               <button type="submit"><%= View.Sone.Button.UnblockSone|l10n|html></button>
+                       </form>
+                       <form class="block<%if sone.blocked> hidden<%/if>" action="blockSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<% formPassword|html>" />
+                               <input type="hidden" name="sone" value="<% sone.id|html>" />
+                               <input type="hidden" name="returnPage" value="<% request.uri|html>" />
+                               <button type="submit"><%= View.Sone.Button.BlockSone|l10n|html></button>
+                       </form>
                <%/if>
        <%/if>
        <div class="spacer">&nbsp;</div>