Merge branch 'mark-as-read' into next
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 19 Jan 2011 18:12:40 +0000 (19:12 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 19 Jan 2011 18:12:40 +0000 (19:12 +0100)
Conflicts:
src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java

17 files changed:
src/main/java/net/pterodactylus/sone/template/SoneAccessor.java
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/editProfile.html
src/main/resources/templates/include/updateStatus.html
src/main/resources/templates/include/viewPost.html
src/main/resources/templates/include/viewReply.html

index 911f5cd..27b4c24 100644 (file)
@@ -74,7 +74,7 @@ public class SoneAccessor extends ReflectionAccessor {
                if (member.equals("niceName")) {
                        return getNiceName(sone);
                } else if (member.equals("local")) {
-                       return sone.getInsertUri() != null;
+                       return core.isLocalSone(sone);
                } else if (member.equals("friend")) {
                        Sone currentSone = (Sone) templateContext.get("currentSone");
                        return (currentSone != null) && currentSone.hasFriend(sone.getId());
index 8e60287..57eb18a 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);
                        }
                        templateContext.set("errorTextEmpty", true);
index 0b7e88f..aae5e83 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);
                        }
                        templateContext.set("errorTextEmpty", true);
index ecbb368..7a36d02 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.Template;
 import net.pterodactylus.util.template.TemplateContext;
@@ -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 67a6f3d..782589f 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.Template;
 import net.pterodactylus.util.template.TemplateContext;
@@ -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 c1afade..fa43945 100644 (file)
@@ -189,6 +189,7 @@ public class SoneTemplatePage extends TemplatePage {
        protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException {
                super.processTemplate(request, templateContext);
                templateContext.set("currentSone", getCurrentSone(request.getToadletContext(), false));
+               templateContext.set("localSones", webInterface.getCore().getLocalSones());
                templateContext.set("request", request);
                templateContext.set("currentVersion", SonePlugin.VERSION);
                templateContext.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 26c13df..50dab27 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!
@@ -202,6 +203,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 a83d3a1..c2cbdd1 100644 (file)
@@ -35,6 +35,11 @@ textarea {
        margin: 0px;
 }
 
+#sone select {
+       color: #444;
+       padding: 0.5ex 1.5ex;
+}
+
 /* now for the real stuff. */
 
 #sone {
@@ -171,6 +176,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: left;
+}
+
 #sone .nice-name {
        font-weight: bold;
 }
@@ -361,12 +375,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;
 }
 
@@ -374,6 +388,11 @@ textarea {
        float: right;
 }
 
+#sone .create-reply .select-sender button {
+       display: inline;
+       float: left;
+}
+
 #sone .sone {
        clear: both;
        background-color: #f0f0ff;
@@ -479,7 +498,7 @@ textarea {
        display: none;
 }
 
-#sone .profile-field button.confirm {
+#sone .profile-field button.confirm.edit {
        font-weight: bold;
        color: #080;
 }
@@ -500,6 +519,7 @@ textarea {
 #sone .profile-field .edit-field-name, #sone .profile-field .move-up-field, #sone .profile-field .move-down-field, #sone .profile-field .delete-field-name {
        float: right;
        margin-top: -1ex;
+       position: relative;
 }
 
 #sone #tail {
index 5922717..a0bbf8a 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")) {
@@ -1086,17 +1101,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 8a1b7d7..ecde2f7 100644 (file)
                <%foreach fields field fieldLoop>
                        <div class="profile-field" id="<% field.id|html>">
                                <div class="name"><% field.name|html></div>
-                               <input class="short hidden" type="text"><button class="confirm hidden" type="button">✔</button><button class="cancel hidden" type="button">✘</button>
+                               <input class="short hidden" type="text"><button class="edit confirm hidden" type="button">✔</button><button class="cancel hidden" type="button">✘</button>
                                <div class="edit-field-name"><button type="submit" name="edit-field-<% field.id|html>" value="true"><%= Page.EditProfile.Fields.Button.Edit|l10n|html></button></div>
                                <div class="delete-field-name"><button type="submit" name="delete-field-<% field.id|html>" value="true"><%= Page.EditProfile.Fields.Button.Delete|l10n|html></button></div>
                                <div class="<%if fieldLoop.last>hidden <%/if>move-down-field"><button type="submit" name="move-down-field-<% field.id|html>" value="true"><%= Page.EditProfile.Fields.Button.MoveDown|l10n|html></button></div>
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>" />