From: David ‘Bombe’ Roden Date: Fri, 26 Nov 2010 22:02:14 +0000 (+0100) Subject: Merge commit '0.3.1-RC3' into message-recipient X-Git-Tag: 0.3.2-RC1~15^2~2 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=a57e3b33c5837a40aa08c11fb92f600d928be1ab;hp=3793feb13134119c1954c11e92e7f8dd5206fcc1 Merge commit '0.3.1-RC3' into message-recipient --- diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 54908d8..bdea989 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -1016,13 +1016,18 @@ public class Core implements IdentityListener { if (postId == null) { break; } + String postRecipientId = configuration.getStringValue(postPrefix + "/Recipient").getValue(null); long postTime = configuration.getLongValue(postPrefix + "/Time").getValue((long) 0); String postText = configuration.getStringValue(postPrefix + "/Text").getValue(null); if ((postTime == 0) || (postText == null)) { logger.log(Level.WARNING, "Invalid post found, aborting load!"); return; } - posts.add(getPost(postId).setSone(sone).setTime(postTime).setText(postText)); + Post post = getPost(postId).setSone(sone).setTime(postTime).setText(postText); + if ((postRecipientId != null) && (postRecipientId.length() == 43)) { + post.setRecipient(getSone(postRecipientId)); + } + posts.add(post); } /* load replies. */ @@ -1140,6 +1145,9 @@ public class Core implements IdentityListener { for (Post post : sone.getPosts()) { String postPrefix = sonePrefix + "/Posts/" + postCounter++; configuration.getStringValue(postPrefix + "/ID").setValue(post.getId()); + if (post.getRecipient() != null) { + configuration.getStringValue(postPrefix + "/Recipient").setValue(post.getRecipient().getId()); + } configuration.getLongValue(postPrefix + "/Time").setValue(post.getTime()); configuration.getStringValue(postPrefix + "/Text").setValue(post.getText()); } @@ -1208,11 +1216,48 @@ public class Core implements IdentityListener { * @return The created post */ public Post createPost(Sone sone, long time, String text) { + return createPost(sone, null, time, text); + } + + /** + * Creates a new post. + * + * @param sone + * The Sone that creates the post + * @param recipient + * The recipient Sone, or {@code null} if this post does not have + * a recipient + * @param text + * The text of the post + * @return The created post + */ + public Post createPost(Sone sone, Sone recipient, String text) { + return createPost(sone, recipient, System.currentTimeMillis(), text); + } + + /** + * Creates a new post. + * + * @param sone + * The Sone that creates the post + * @param recipient + * The recipient Sone, or {@code null} if this post does not have + * a recipient + * @param time + * The time of the post + * @param text + * The text of the post + * @return The created post + */ + public Post createPost(Sone sone, Sone recipient, long time, String text) { if (!isLocalSone(sone)) { logger.log(Level.FINE, "Tried to create post for non-local Sone: %s", sone); return null; } Post post = new Post(sone, time, text); + if (recipient != null) { + post.setRecipient(recipient); + } synchronized (posts) { posts.put(post.getId(), post); } diff --git a/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java b/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java index 0cedc15..fa0063e 100644 --- a/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java +++ b/src/main/java/net/pterodactylus/sone/core/SoneDownloader.java @@ -295,6 +295,7 @@ public class SoneDownloader extends AbstractService { } else { for (SimpleXML postXml : postsXml.getNodes("post")) { String postId = postXml.getValue("id", null); + String postRecipientId = postXml.getValue("recipient", null); String postTime = postXml.getValue("time", null); String postText = postXml.getValue("text", null); if ((postId == null) || (postTime == null) || (postText == null)) { @@ -303,7 +304,11 @@ public class SoneDownloader extends AbstractService { return null; } try { - posts.add(core.getPost(postId).setSone(sone).setTime(Long.parseLong(postTime)).setText(postText)); + Post post = core.getPost(postId).setSone(sone).setTime(Long.parseLong(postTime)).setText(postText); + if ((postRecipientId != null) && (postRecipientId.length() == 43)) { + post.setRecipient(core.getSone(postRecipientId)); + } + posts.add(post); } catch (NumberFormatException nfe1) { /* TODO - mark Sone as bad. */ logger.log(Level.WARNING, "Downloaded post for Sone %s with invalid time: %s", new Object[] { sone, postTime }); diff --git a/src/main/java/net/pterodactylus/sone/data/Post.java b/src/main/java/net/pterodactylus/sone/data/Post.java index 654b827..21ba42d 100644 --- a/src/main/java/net/pterodactylus/sone/data/Post.java +++ b/src/main/java/net/pterodactylus/sone/data/Post.java @@ -44,6 +44,9 @@ public class Post { /** The Sone this post belongs to. */ private volatile Sone sone; + /** The Sone of the recipient. */ + private volatile Sone recipient; + /** The time of the post (in milliseconds since Jan 1, 1970 UTC). */ private volatile long time; @@ -140,6 +143,27 @@ public class Post { } /** + * Returns the recipient of this post, if any. + * + * @return The recipient of this post, or {@code null} + */ + public Sone getRecipient() { + return recipient; + } + + /** + * Sets the recipient of this post. + * + * @param recipient + * The recipient of this post, or {@code null} + * @return This post (for method chaining) + */ + public Post setRecipient(Sone recipient) { + this.recipient = recipient; + return this; + } + + /** * Returns the time of the post. * * @return The time of the post (in milliseconds since Jan 1, 1970 UTC) diff --git a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java index 10a8c7a..a8e2128 100644 --- a/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java +++ b/src/main/java/net/pterodactylus/sone/web/CreatePostPage.java @@ -55,8 +55,10 @@ public class CreatePostPage extends SoneTemplatePage { if (request.getMethod() == Method.POST) { String text = request.getHttpRequest().getPartAsStringFailsafe("text", 65536).trim(); if (text.length() != 0) { + String recipientId = request.getHttpRequest().getPartAsStringFailsafe("recipient", 43); + Sone recipient = webInterface.getCore().getSone(recipientId, false); Sone currentSone = getCurrentSone(request.getToadletContext()); - webInterface.getCore().createPost(currentSone, System.currentTimeMillis(), text); + webInterface.getCore().createPost(currentSone, recipient, System.currentTimeMillis(), text); throw new RedirectException(returnPage); } template.set("errorTextEmpty", true); diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java index 0d553cc..ce2462c 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java @@ -48,11 +48,13 @@ public class CreatePostAjaxPage extends JsonPage { if (sone == null) { return createErrorJsonObject("auth-required"); } + String recipientId = request.getHttpRequest().getParam("recipient"); + Sone recipient = webInterface.getCore().getSone(recipientId, false); String text = request.getHttpRequest().getParam("text"); if ((text == null) || (text.trim().length() == 0)) { return createErrorJsonObject("text-required"); } - Post newPost = webInterface.getCore().createPost(sone, text); + Post newPost = webInterface.getCore().createPost(sone, recipient, text); return createSuccessJsonObject().put("postId", newPost.getId()); } diff --git a/src/main/resources/i18n/sone.en.properties b/src/main/resources/i18n/sone.en.properties index 0db2276..32ff6c6 100644 --- a/src/main/resources/i18n/sone.en.properties +++ b/src/main/resources/i18n/sone.en.properties @@ -89,6 +89,7 @@ Page.ViewSone.Title=View Sone - Sone Page.ViewSone.Page.TitleWithoutSone=View unknown Sone Page.ViewSone.NoSone.Description=There is currently no known Sone with the ID {sone}. If you were looking for a specific Sone, make sure that it is visible in your web of trust! Page.ViewSone.UnknownSone.Description=This Sone has not yet been retrieved. Please check back in a short time. +Page.ViewSone.WriteAMessage=You can write a message to this Sone here. Please note that everybody will be able to read this message! Page.ViewSone.PostList.Title=Posts by {sone} Page.ViewSone.PostList.Text.NoPostYet=This Sone has not yet posted anything. @@ -149,6 +150,7 @@ View.Sone.Status.Idle=This Sone is idle, i.e. not being inserted or downloaded. View.Sone.Status.Downloading=This Sone is currently being downloaded. View.Sone.Status.Inserting=This Sone is currently being inserted. +View.Post.UnknownAuthor=(unknown) View.Post.DeleteLink=Delete View.Post.SendReply=Post Reply! View.Post.Reply.DeleteLink=Delete @@ -156,6 +158,7 @@ View.Post.LikeLink=Like View.Post.UnlikeLink=Unlike WebInterface.DefaultText.StatusUpdate=What’s on your mind? +WebInterface.DefaultText.Message=Write a Message… WebInterface.DefaultText.Reply=Write a Reply… WebInterface.DefaultText.FirstName=First name WebInterface.DefaultText.MiddleName=Middle name(s) diff --git a/src/main/resources/static/css/sone.css b/src/main/resources/static/css/sone.css index 608a4e8..2861575 100644 --- a/src/main/resources/static/css/sone.css +++ b/src/main/resources/static/css/sone.css @@ -177,7 +177,7 @@ textarea { min-height: 48px; } -#sone .post .author { +#sone .post .author, #sone .post .recipient { display: inline; font-weight: bold; } diff --git a/src/main/resources/static/javascript/sone.js b/src/main/resources/static/javascript/sone.js index ba78d2c..75facb3 100644 --- a/src/main/resources/static/javascript/sone.js +++ b/src/main/resources/static/javascript/sone.js @@ -753,6 +753,21 @@ $(document).ready(function() { }); }); + /* ajaxify input field on “view Sone” page. */ + getTranslation("WebInterface.DefaultText.Message", function(defaultText) { + registerInputTextareaSwap("#sone #post-message input[name=text]", defaultText, "text", false, false); + $("#sone #post-message").submit(function() { + text = $(this).find(":input:enabled").val(); + $.getJSON("ajax/createPost.ajax", { "formPassword": getFormPassword(), "recipient": $("#sone #sone-id").text(), "text": text }, function(data, textStatus) { + if ((data != null) && data.success) { + loadNewPost(data.postId); + } + }); + $(this).find(":input:enabled").val("").blur(); + return false; + }); + }); + /* Ajaxifies all posts. */ /* calling getTranslation here will cache the necessary values. */ getTranslation("WebInterface.Confirmation.DeletePostButton", function(text) { diff --git a/src/main/resources/templates/include/viewPost.html b/src/main/resources/templates/include/viewPost.html index e351fd0..ffc7608 100644 --- a/src/main/resources/templates/include/viewPost.html +++ b/src/main/resources/templates/include/viewPost.html @@ -7,6 +7,14 @@
+ <%ifnull !post.recipient> + → + <%ifnull post.recipient.identity> + + <%else> + + <%/if> + <%/if>
<% post.text|html>
diff --git a/src/main/resources/templates/insert/sone.xml b/src/main/resources/templates/insert/sone.xml index d6dd643..4e8cbae 100644 --- a/src/main/resources/templates/insert/sone.xml +++ b/src/main/resources/templates/insert/sone.xml @@ -21,6 +21,7 @@ <%foreach currentSone.posts post> <% post.id|xml> + <%ifnull !post.recipient><% post.recipient.id|xml><%/if> <% post.text|xml> diff --git a/src/main/resources/templates/viewSone.html b/src/main/resources/templates/viewSone.html index 534c5ff..4d96fab 100644 --- a/src/main/resources/templates/viewSone.html +++ b/src/main/resources/templates/viewSone.html @@ -1,5 +1,7 @@ <%include include/head.html> + + <%ifnull sone>

<%= Page.ViewSone.Page.TitleWithoutSone|l10n|html>

@@ -18,6 +20,16 @@ <%include include/viewSone.html> <%/if> +

<%= Page.ViewSone.WriteAMessage|l10n|html>

+ +
+ + + + + +
+

<%= Page.ViewSone.PostList.Title|l10n|insert needle="{sone}" key=sone.niceName|html>