Merge branch 'select-sender-identity' into next
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 18 Jan 2011 07:05:37 +0000 (08:05 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 18 Jan 2011 07:05:37 +0000 (08:05 +0100)
15 files changed:
src/main/java/net/pterodactylus/sone/web/CreatePostPage.java
src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java
src/main/java/net/pterodactylus/sone/web/DeletePostPage.java
src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java
src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java
src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DeletePostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DeleteReplyAjaxPage.java
src/main/resources/i18n/sone.en.properties
src/main/resources/static/css/sone.css
src/main/resources/static/javascript/sone.js
src/main/resources/templates/include/updateStatus.html
src/main/resources/templates/include/viewPost.html
src/main/resources/templates/include/viewReply.html

index aba4700..ef88fd6 100644 (file)
@@ -56,10 +56,15 @@ public class CreatePostPage extends SoneTemplatePage {
                if (request.getMethod() == Method.POST) {
                        String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim();
                        if (text.length() != 0) {
+                               String senderId = request.getHttpRequest().getPartAsStringFailsafe("sender", 43);
                                String recipientId = request.getHttpRequest().getPartAsStringFailsafe("recipient", 43);
-                               Sone recipient = webInterface.getCore().getSone(recipientId, false);
                                Sone currentSone = getCurrentSone(request.getToadletContext());
-                               webInterface.getCore().createPost(currentSone, recipient, System.currentTimeMillis(), text);
+                               Sone sender = webInterface.getCore().getLocalSone(senderId, false);
+                               if (sender == null) {
+                                       sender = currentSone;
+                               }
+                               Sone recipient = webInterface.getCore().getSone(recipientId, false);
+                               webInterface.getCore().createPost(sender, recipient, System.currentTimeMillis(), text);
                                throw new RedirectException(returnPage);
                        }
                        dataProvider.set("errorTextEmpty", true);
index d4a9775..d3b7c35 100644 (file)
@@ -58,8 +58,12 @@ public class CreateReplyPage extends SoneTemplatePage {
                if (request.getMethod() == Method.POST) {
                        Post post = webInterface.getCore().getPost(postId);
                        if (text.length() > 0) {
-                               Sone currentSone = getCurrentSone(request.getToadletContext());
-                               webInterface.getCore().createReply(currentSone, post, text);
+                               String senderId = request.getHttpRequest().getPartAsStringFailsafe("sender", 43);
+                               Sone sender = webInterface.getCore().getLocalSone(senderId, false);
+                               if (sender == null) {
+                                       sender = getCurrentSone(request.getToadletContext());
+                               }
+                               webInterface.getCore().createReply(sender, post, text);
                                throw new RedirectException(returnPage);
                        }
                        dataProvider.set("errorTextEmpty", true);
index 5722ee3..78c9f22 100644 (file)
@@ -18,7 +18,6 @@
 package net.pterodactylus.sone.web;
 
 import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.Page.Request.Method;
 import net.pterodactylus.util.template.DataProvider;
 import net.pterodactylus.util.template.Template;
@@ -63,12 +62,11 @@ public class DeletePostPage extends SoneTemplatePage {
                        String postId = request.getHttpRequest().getPartAsStringFailsafe("post", 36);
                        String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
                        Post post = webInterface.getCore().getPost(postId);
-                       Sone currentSone = getCurrentSone(request.getToadletContext());
-                       if (!post.getSone().equals(currentSone)) {
+                       if (!webInterface.getCore().isLocalSone(post.getSone())) {
                                throw new RedirectException("noPermission.html");
                        }
                        if (request.getHttpRequest().isPartSet("confirmDelete")) {
-                               currentSone.removePost(post);
+                               webInterface.getCore().deletePost(post);
                                throw new RedirectException(returnPage);
                        } else if (request.getHttpRequest().isPartSet("abortDelete")) {
                                throw new RedirectException(returnPage);
index 8d90474..e10036b 100644 (file)
@@ -18,7 +18,6 @@
 package net.pterodactylus.sone.web;
 
 import net.pterodactylus.sone.data.Reply;
-import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.page.Page.Request.Method;
 import net.pterodactylus.util.template.DataProvider;
 import net.pterodactylus.util.template.Template;
@@ -56,8 +55,7 @@ public class DeleteReplyPage extends SoneTemplatePage {
                Reply reply = webInterface.getCore().getReply(replyId);
                String returnPage = request.getHttpRequest().getPartAsStringFailsafe("returnPage", 256);
                if (request.getMethod() == Method.POST) {
-                       Sone currentSone = getCurrentSone(request.getToadletContext());
-                       if (!reply.getSone().equals(currentSone)) {
+                       if (!webInterface.getCore().isLocalSone(reply.getSone())) {
                                throw new RedirectException("noPermission.html");
                        }
                        if (request.getHttpRequest().isPartSet("confirmDelete")) {
index dc41865..9619531 100644 (file)
@@ -189,6 +189,7 @@ public class SoneTemplatePage extends TemplatePage {
        protected void processTemplate(Request request, DataProvider dataProvider) throws RedirectException {
                super.processTemplate(request, dataProvider);
                dataProvider.set("currentSone", getCurrentSone(request.getToadletContext(), false));
+               dataProvider.set("localSones", webInterface.getCore().getLocalSones());
                dataProvider.set("request", request);
                dataProvider.set("currentVersion", SonePlugin.VERSION);
                dataProvider.set("hasLatestVersion", webInterface.getCore().getUpdateChecker().hasLatestVersion());
index 1e45a60..eff7c41 100644 (file)
@@ -50,12 +50,17 @@ public class CreatePostAjaxPage extends JsonPage {
                }
                String recipientId = request.getHttpRequest().getParam("recipient");
                Sone recipient = webInterface.getCore().getSone(recipientId, false);
+               String senderId = request.getHttpRequest().getParam("sender");
+               Sone sender = webInterface.getCore().getLocalSone(senderId, false);
+               if (sender == null) {
+                       sender = sone;
+               }
                String text = request.getHttpRequest().getParam("text");
                if ((text == null) || (text.trim().length() == 0)) {
                        return createErrorJsonObject("text-required");
                }
-               Post newPost = webInterface.getCore().createPost(sone, recipient, text);
-               return createSuccessJsonObject().put("postId", newPost.getId());
+               Post newPost = webInterface.getCore().createPost(sender, recipient, text);
+               return createSuccessJsonObject().put("postId", newPost.getId()).put("sone", sender.getId()).put("recipient", (newPost.getRecipient() != null) ? newPost.getRecipient().getId() : null);
        }
 
 }
index 0181ff2..9ed960f 100644 (file)
@@ -51,16 +51,17 @@ public class CreateReplyAjaxPage extends JsonPage {
        protected JsonObject createJsonObject(Request request) {
                String postId = request.getHttpRequest().getParam("post");
                String text = request.getHttpRequest().getParam("text").trim();
-               Sone currentSone = getCurrentSone(request.getToadletContext());
-               if (currentSone == null) {
-                       return createErrorJsonObject("auth-required");
+               String senderId = request.getHttpRequest().getParam("sender");
+               Sone sender = webInterface.getCore().getLocalSone(senderId, false);
+               if (sender == null) {
+                       sender = getCurrentSone(request.getToadletContext());
                }
                Post post = webInterface.getCore().getPost(postId);
                if ((post == null) || (post.getSone() == null)) {
                        return createErrorJsonObject("invalid-post-id");
                }
-               Reply reply = webInterface.getCore().createReply(currentSone, post, text);
-               return createSuccessJsonObject().put("reply", reply.getId());
+               Reply reply = webInterface.getCore().createReply(sender, post, text);
+               return createSuccessJsonObject().put("reply", reply.getId()).put("sone", sender.getId());
        }
 
 }
index 479e71e..8d3b414 100644 (file)
@@ -18,7 +18,6 @@
 package net.pterodactylus.sone.web.ajax;
 
 import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
 import net.pterodactylus.util.json.JsonObject;
 
@@ -50,14 +49,10 @@ public class DeletePostAjaxPage extends JsonPage {
        protected JsonObject createJsonObject(Request request) {
                String postId = request.getHttpRequest().getParam("post");
                Post post = webInterface.getCore().getPost(postId, false);
-               Sone currentSone = getCurrentSone(request.getToadletContext());
                if ((post == null) || (post.getSone() == null)) {
                        return createErrorJsonObject("invalid-post-id");
                }
-               if (currentSone == null) {
-                       return createErrorJsonObject("auth-required");
-               }
-               if (!post.getSone().equals(currentSone)) {
+               if (!webInterface.getCore().isLocalSone(post.getSone())) {
                        return createErrorJsonObject("not-authorized");
                }
                webInterface.getCore().deletePost(post);
index 7614de8..f34d202 100644 (file)
@@ -18,7 +18,6 @@
 package net.pterodactylus.sone.web.ajax;
 
 import net.pterodactylus.sone.data.Reply;
-import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.web.WebInterface;
 import net.pterodactylus.util.json.JsonObject;
 
@@ -50,14 +49,10 @@ public class DeleteReplyAjaxPage extends JsonPage {
        protected JsonObject createJsonObject(Request request) {
                String replyId = request.getHttpRequest().getParam("reply");
                Reply reply = webInterface.getCore().getReply(replyId);
-               Sone currentSone = getCurrentSone(request.getToadletContext());
                if (reply == null) {
                        return createErrorJsonObject("invalid-reply-id");
                }
-               if (currentSone == null) {
-                       return createErrorJsonObject("auth-required");
-               }
-               if (!reply.getSone().equals(currentSone)) {
+               if (!webInterface.getCore().isLocalSone(reply.getSone())) {
                        return createErrorJsonObject("not-authorized");
                }
                webInterface.getCore().deleteReply(reply);
index 7b8450f..b5c7e24 100644 (file)
@@ -55,6 +55,7 @@ Page.DeleteSone.Button.No=No, do not delete.
 
 Page.Index.Title=Your Sone - Sone
 Page.Index.Label.Text=Post text:
+Page.Index.Label.Sender=Sender:
 Page.Index.Button.Post=Post!
 Page.Index.PostList.Title=Post Feed
 Page.Index.PostList.Text.NoPostYet=Nobody has written any posts yet. You should probably start it right now!
@@ -200,6 +201,8 @@ View.Post.Reply.DeleteLink=Delete
 View.Post.LikeLink=Like
 View.Post.UnlikeLink=Unlike
 
+View.UpdateStatus.Text.ChooseSenderIdentity=Choose the sender identity
+
 View.Trust.Tooltip.Trust=Trust this person
 View.Trust.Tooltip.Distrust=Assign negative trust to this person
 View.Trust.Tooltip.Untrust=Remove your trust assignment for this person
index 255ab57..bc7445a 100644 (file)
@@ -35,6 +35,11 @@ textarea {
        margin: 0px;
 }
 
+#sone select {
+       color: #444;
+       padding: 0.5ex 1.5ex;
+}
+
 /* now for the real stuff. */
 
 #sone {
@@ -167,6 +172,15 @@ textarea {
        float: right;
 }
 
+#sone #update-status .select-sender, #sone .create-reply .select-sender {
+       display: none;
+}
+
+#sone #update-status .select-sender button {
+       display: inline;
+       float: none;
+}
+
 #sone .nice-name {
        font-weight: bold;
 }
@@ -357,12 +371,12 @@ textarea {
 
 #sone .post .create-reply input[type=text] {
        margin-left: 0.5ex;
-       width: 44em;
+       width: 42em;
 }
 
 #sone .post .create-reply textarea {
        margin-left: 0.5ex;
-       width: 44em;
+       width: 42em;
        height: 4em;
 }
 
@@ -370,6 +384,11 @@ textarea {
        float: right;
 }
 
+#sone .create-reply .select-sender button {
+       display: inline;
+       float: left;
+}
+
 #sone .sone {
        clear: both;
        background-color: #f0f0ff;
index 9d00c5a..35b53e3 100644 (file)
@@ -491,6 +491,8 @@ function updateReplyLikes(replyId) {
 /**
  * Posts a reply and calls the given callback when the request finishes.
  *
+ * @param sender
+ *            The ID of the sender
  * @param postId
  *            The ID of the post the reply refers to
  * @param text
@@ -499,14 +501,14 @@ function updateReplyLikes(replyId) {
  *            The callback function to call when the request finishes (takes 3
  *            parameters: success, error, replyId)
  */
-function postReply(postId, text, callbackFunction) {
-       $.getJSON("createReply.ajax", { "formPassword" : getFormPassword(), "post" : postId, "text": text }, function(data, textStatus) {
+function postReply(sender, postId, text, callbackFunction) {
+       $.getJSON("createReply.ajax", { "formPassword" : getFormPassword(), "sender": sender, "post" : postId, "text": text }, function(data, textStatus) {
                if (data == null) {
                        /* TODO - show error */
                        return;
                }
                if (data.success) {
-                       callbackFunction(true, null, data.reply);
+                       callbackFunction(true, null, data.reply, data.sone);
                } else {
                        callbackFunction(false, data.error);
                }
@@ -545,21 +547,25 @@ function ajaxifyPost(postElement) {
                return false;
        });
        $(postElement).find(".create-reply button:submit").click(function() {
-               inputField = $(this.form).find(":input:enabled").get(0);
+               sender = $(this.form).find(":input[name=sender]").val();
+               inputField = $(this.form).find(":input[name=text]:enabled").get(0);
                postId = getPostId(this);
                text = $(inputField).val();
-               (function(postId, text, inputField) {
-                       postReply(postId, text, function(success, error, replyId) {
+               (function(sender, postId, text, inputField) {
+                       postReply(sender, postId, text, function(success, error, replyId, soneId) {
                                if (success) {
                                        $(inputField).val("");
-                                       loadNewReply(replyId, getCurrentSoneId(), postId);
+                                       loadNewReply(replyId, soneId, postId);
                                        markPostAsKnown(getPostElement(inputField));
                                        $("#sone .post#" + postId + " .create-reply").addClass("hidden");
+                                       $("#sone .post#" + postId + " .create-reply .sender").hide();
+                                       $("#sone .post#" + postId + " .create-reply .select-sender").show();
+                                       $("#sone .post#" + postId + " .create-reply :input[name=sender]").val(getCurrentSoneId());
                                } else {
                                        alert(error);
                                }
                        });
-               })(postId, text, inputField);
+               })(sender, postId, text, inputField);
                return false;
        });
 
@@ -612,6 +618,15 @@ function ajaxifyPost(postElement) {
                });
        });
 
+       /* process sender selection. */
+       $(".select-sender", postElement).css("display", "inline");
+       $(".sender", postElement).hide();
+       $(".select-sender button", postElement).click(function() {
+               $(".sender", postElement).show();
+               $(".select-sender", postElement).hide();
+               return false;
+       });
+
        /* mark everything as known on click. */
        $(postElement).click(function(event) {
                if ($(event.target).hasClass("click-to-show")) {
@@ -1078,17 +1093,28 @@ $(document).ready(function() {
        /* this initializes the status update input field. */
        getTranslation("WebInterface.DefaultText.StatusUpdate", function(defaultText) {
                registerInputTextareaSwap("#sone #update-status .status-input", defaultText, "text", false, false);
+               $("#sone #update-status .select-sender").css("display", "inline");
+               $("#sone #update-status .sender").hide();
+               $("#sone #update-status .select-sender button").click(function() {
+                       $("#sone #update-status .sender").show();
+                       $("#sone #update-status .select-sender").hide();
+                       return false;
+               });
                $("#sone #update-status").submit(function() {
                        if ($(this).find(":input.default:enabled").length > 0) {
                                return false;
                        }
-                       text = $(this).find(":input:enabled").val();
-                       $.getJSON("createPost.ajax", { "formPassword": getFormPassword(), "text": text }, function(data, textStatus) {
+                       sender = $(this).find(":input[name=sender]").val();
+                       text = $(this).find(":input[name=text]:enabled").val();
+                       $.getJSON("createPost.ajax", { "formPassword": getFormPassword(), "sender": sender, "text": text }, function(data, textStatus) {
                                if ((data != null) && data.success) {
-                                       loadNewPost(data.postId, getCurrentSoneId());
+                                       loadNewPost(data.postId, data.sone, data.recipient);
                                }
                        });
-                       $(this).find(":input:enabled").val("").blur();
+                       $(this).find(":input[name=sender]").val(getCurrentSoneId());
+                       $(this).find(":input[name=text]:enabled").val("").blur();
+                       $(this).find(".sender").hide();
+                       $(this).find(".select-sender").show();
                        return false;
                });
        });
index fba951d..43d4d70 100644 (file)
@@ -1,7 +1,15 @@
 <form id="update-status" action="createPost.html" method="post">
        <input type="hidden" name="formPassword" value="<% formPassword|html>" />
        <input type="hidden" name="returnPage" value="<% request.uri|html>" />
-       <label for="text"><%= Page.Index.Label.Text|l10n|html></label>
+       <label for="sender"><%= Page.Index.Label.Sender|l10n|html></label>
+       <div class="sender">
+               <select name="sender" title="<%= View.UpdateStatus.Text.ChooseSenderIdentity|l10n|html>">
+                       <%foreach localSones localSone>
+                               <option value="<% localSone.id|html>"<%if localSone.current> selected="selected"<%/if>><% localSone.niceName|html></option>
+                       <%/foreach>
+               </select>
+       </div>
+       <div class="select-sender"><button type="button" title="<%= View.UpdateStatus.Text.ChooseSenderIdentity|l10n|html>">+</button></div><label for="text"><%= Page.Index.Label.Text|l10n|html></label>
        <input type="text" class="status-input" name="text" value="" />
        <button type="submit"><%= Page.Index.Button.Post|l10n|html></button>
 </form>
index 5161dfe..74e3450 100644 (file)
@@ -62,7 +62,7 @@
                                        </form>
                                <%/if>
                        <%/if>
-                       <%if post.sone.current>
+                       <%if post.sone.local>
                                <span class='separator'>·</span>
                                <form class="delete delete-post" action="deletePost.html" method="post">
                                        <input type="hidden" name="formPassword" value="<% formPassword|html>" />
                                                <input type="hidden" name="formPassword" value="<% formPassword|html>" />
                                                <input type="hidden" name="returnPage" value="<% request.uri|html>" />
                                                <input type="hidden" name="post" value="<% post.id|html>" />
+                                               <div class="sender">
+                                                       <select name="sender" title="<%= View.UpdateStatus.Text.ChooseSenderIdentity|l10n|html>">
+                                                               <%foreach localSones localSone>
+                                                                       <option value="<% localSone.id|html>"<%if localSone.current> selected="selected"<%/if>><% localSone.niceName|html></option>
+                                                               <%/foreach>
+                                                       </select>
+                                               </div>
+                                               <div class="select-sender"><button type="button" title="<%= View.UpdateStatus.Text.ChooseSenderIdentity|l10n|html>">+</button></div>
                                                <input type="text" class="reply-input" name="text" value="" />
                                                <button type="submit"><%= View.Post.SendReply|l10n|html></button>
                                        </form>
index 805626a..6b13776 100644 (file)
@@ -54,7 +54,7 @@
                                        </form>
                                <%/if>
                        <%/if>
-                       <%if reply.sone.current>
+                       <%if reply.sone.local>
                                <span class='separator'>·</span>
                                <form class="delete delete-reply" action="deleteReply.html" method="post">
                                        <input type="hidden" name="formPassword" value="<% formPassword|html>" />