Merge branch 'new-web-of-trust' into next
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 29 Mar 2011 17:37:27 +0000 (19:37 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 29 Mar 2011 17:37:27 +0000 (19:37 +0200)
17 files changed:
pom.xml
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/SoneDownloader.java
src/main/java/net/pterodactylus/sone/main/SonePlugin.java
src/main/java/net/pterodactylus/sone/template/PostAccessor.java
src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java
src/main/java/net/pterodactylus/sone/web/BookmarksPage.java
src/main/java/net/pterodactylus/sone/web/LoginPage.java
src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java
src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java
src/main/java/net/pterodactylus/sone/web/ViewPostPage.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/bookmarks.html
src/main/resources/templates/include/viewPost.html
src/main/resources/templates/include/viewReply.html

diff --git a/pom.xml b/pom.xml
index c69a01b..229f2ef 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -2,12 +2,12 @@
        <modelVersion>4.0.0</modelVersion>
        <groupId>net.pterodactylus</groupId>
        <artifactId>sone</artifactId>
-       <version>0.4.3</version>
+       <version>0.5.1</version>
        <dependencies>
                <dependency>
                        <groupId>net.pterodactylus</groupId>
                        <artifactId>utils</artifactId>
-                       <version>0.9-SNAPSHOT</version>
+                       <version>0.9.1</version>
                </dependency>
                <dependency>
                        <groupId>junit</groupId>
index 7dc398e..e0373e9 100644 (file)
@@ -817,7 +817,6 @@ public class Core implements IdentityListener, UpdateListener {
                                @SuppressWarnings("synthetic-access")
                                public void run() {
                                        if (!preferences.isSoneRescueMode()) {
-                                               soneDownloader.fetchSone(sone);
                                                return;
                                        }
                                        logger.log(Level.INFO, "Trying to restore Sone from Freenet…");
index 933191f..7022f5e 100644 (file)
@@ -93,10 +93,10 @@ public class SoneDownloader extends AbstractService {
         *            The Sone to add
         */
        public void addSone(Sone sone) {
-               if (sones.add(sone)) {
+               if (!sones.add(sone)) {
                        freenetInterface.unregisterUsk(sone);
-                       freenetInterface.registerUsk(sone, this);
                }
+               freenetInterface.registerUsk(sone, this);
        }
 
        /**
@@ -133,9 +133,6 @@ public class SoneDownloader extends AbstractService {
         *            The URI to fetch the Sone from
         */
        public void fetchSone(Sone sone, FreenetURI soneUri) {
-               if (core.getSoneStatus(sone) == SoneStatus.downloading) {
-                       return;
-               }
                logger.log(Level.FINE, "Starting fetch for Sone “%s” from %s…", new Object[] { sone, soneUri });
                FreenetURI requestUri = soneUri.setMetaString(new String[] { "sone.xml" });
                core.setSoneStatus(sone, SoneStatus.downloading);
index e51f9a1..0f7f0e8 100644 (file)
@@ -78,7 +78,7 @@ public class SonePlugin implements FredPlugin, FredPluginL10n, FredPluginBaseL10
        }
 
        /** The version. */
-       public static final Version VERSION = new Version(0, 4, 3);
+       public static final Version VERSION = new Version(0, 5, 1);
 
        /** The logger. */
        private static final Logger logger = Logging.getLogger(SonePlugin.class);
index 584cb72..ca0c84a 100644 (file)
@@ -64,6 +64,8 @@ public class PostAccessor extends ReflectionAccessor {
                        return core.isNewPost(post.getId());
                } else if (member.equals("bookmarked")) {
                        return core.isBookmarked(post);
+               } else if (member.equals("loaded")) {
+                       return post.getSone() != null;
                }
                return super.get(templateContext, object, member);
        }
index f439abe..1e54d53 100644 (file)
@@ -58,6 +58,8 @@ public class ReplyAccessor extends ReflectionAccessor {
                        return (currentSone != null) && (currentSone.isLikedReplyId(reply.getId()));
                } else if (member.equals("new")) {
                        return core.isNewReply(reply.getId());
+               } else if (member.equals("loaded")) {
+                       return reply.getSone() != null;
                }
                return super.get(templateContext, object, member);
        }
index d8a18c8..d6f63aa 100644 (file)
@@ -24,6 +24,8 @@ import java.util.Set;
 
 import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.util.collection.Pagination;
+import net.pterodactylus.util.filter.Filter;
+import net.pterodactylus.util.filter.Filters;
 import net.pterodactylus.util.number.Numbers;
 import net.pterodactylus.util.template.Template;
 import net.pterodactylus.util.template.TemplateContext;
@@ -57,12 +59,20 @@ public class BookmarksPage extends SoneTemplatePage {
        @Override
        protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException {
                super.processTemplate(request, templateContext);
-               Set<Post> posts = webInterface.getCore().getBookmarkedPosts();
-               List<Post> sortedPosts = new ArrayList<Post>(posts);
+               Set<Post> allPosts = webInterface.getCore().getBookmarkedPosts();
+               Set<Post> loadedPosts = Filters.filteredSet(allPosts, new Filter<Post>() {
+
+                       @Override
+                       public boolean filterObject(Post post) {
+                               return post.getSone() != null;
+                       }
+               });
+               List<Post> sortedPosts = new ArrayList<Post>(loadedPosts);
                Collections.sort(sortedPosts, Post.TIME_COMPARATOR);
                Pagination<Post> pagination = new Pagination<Post>(sortedPosts, 25).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0));
                templateContext.set("pagination", pagination);
                templateContext.set("posts", pagination.getItems());
+               templateContext.set("postsNotLoaded", allPosts.size() != loadedPosts.size());
        }
 
 }
index 1126f7b..eaa8351 100644 (file)
@@ -72,7 +72,11 @@ public class LoginPage extends SoneTemplatePage {
                        Sone selectedSone = webInterface.getCore().getLocalSone(soneId, false);
                        if (selectedSone != null) {
                                setCurrentSone(request.getToadletContext(), selectedSone);
-                               throw new RedirectException("index.html");
+                               String target = request.getHttpRequest().getParam("target");
+                               if ((target == null) || (target.length() == 0)) {
+                                       target = "index.html";
+                               }
+                               throw new RedirectException(target);
                        }
                }
                List<OwnIdentity> ownIdentitiesWithoutSone = CreateSonePage.getOwnIdentitiesWithoutSone(webInterface.getCore());
index a7df9c2..a04873d 100644 (file)
@@ -17,6 +17,8 @@
 
 package net.pterodactylus.sone.web;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.Collection;
 
@@ -28,6 +30,7 @@ import net.pterodactylus.util.template.Template;
 import net.pterodactylus.util.template.TemplateContext;
 import freenet.clients.http.SessionManager.Session;
 import freenet.clients.http.ToadletContext;
+import freenet.support.api.HTTPRequest;
 
 /**
  * Base page for the Freetalk web interface.
@@ -204,7 +207,26 @@ public class SoneTemplatePage extends TemplatePage {
        @Override
        protected String getRedirectTarget(Page.Request request) {
                if (requiresLogin() && (getCurrentSone(request.getToadletContext(), false) == null)) {
-                       return "login.html";
+                       HTTPRequest httpRequest = request.getHttpRequest();
+                       String originalUrl = httpRequest.getPath();
+                       if (httpRequest.hasParameters()) {
+                               StringBuilder requestParameters = new StringBuilder();
+                               for (String parameterName : httpRequest.getParameterNames()) {
+                                       if (requestParameters.length() > 0) {
+                                               requestParameters.append("%26");
+                                       }
+                                       String[] parameterValues = httpRequest.getMultipleParam(parameterName);
+                                       for (String parameterValue : parameterValues) {
+                                               try {
+                                                       requestParameters.append(URLEncoder.encode(parameterName, "UTF-8")).append("%3d").append(URLEncoder.encode(parameterValue, "UTF-8"));
+                                               } catch (UnsupportedEncodingException uee1) {
+                                                       /* A JVM without UTF-8? I don’t think so. */
+                                               }
+                                       }
+                               }
+                               originalUrl += "?" + requestParameters.toString();
+                       }
+                       return "login.html?target=" + originalUrl;
                }
                return null;
        }
index 85a0359..85f46f0 100644 (file)
@@ -17,6 +17,9 @@
 
 package net.pterodactylus.sone.web;
 
+import java.util.Set;
+
+import net.pterodactylus.sone.data.Post;
 import net.pterodactylus.sone.web.page.Page.Request.Method;
 import net.pterodactylus.util.template.Template;
 import net.pterodactylus.util.template.TemplateContext;
@@ -54,6 +57,16 @@ public class UnbookmarkPage extends SoneTemplatePage {
                        webInterface.getCore().unbookmarkPost(id);
                        throw new RedirectException(returnPage);
                }
+               String id = request.getHttpRequest().getParam("post");
+               if (id.equals("allNotLoaded")) {
+                       Set<Post> posts = webInterface.getCore().getBookmarkedPosts();
+                       for (Post post : posts) {
+                               if (post.getSone() == null) {
+                                       webInterface.getCore().unbookmark(post);
+                               }
+                       }
+                       throw new RedirectException("bookmarks.html");
+               }
        }
 
 }
index 864dc84..967b9c5 100644 (file)
@@ -52,8 +52,10 @@ public class ViewPostPage extends SoneTemplatePage {
        protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException {
                super.processTemplate(request, templateContext);
                String postId = request.getHttpRequest().getParam("post");
+               boolean raw = request.getHttpRequest().getParam("raw").equals("true");
                Post post = webInterface.getCore().getPost(postId);
                templateContext.set("post", post);
+               templateContext.set("raw", raw);
        }
 
        /**
index 2165bb5..9b48cad 100644 (file)
@@ -167,6 +167,7 @@ Page.Unbookmark.Title=Remove Bookmark - Sone
 Page.Bookmarks.Title=Bookmarks - Sone
 Page.Bookmarks.Page.Title=Bookmarks
 Page.Bookmarks.Text.NoBookmarks=You don’t have any bookmarks defined right now. You can bookmark posts by clicking the star below the post.
+Page.Bookmarks.Text.PostsNotLoaded=Some of your bookmarked posts have not been shown because they could not be loaded. This can happen if you restarted Sone recently or if the originating Sone has deleted the post. If you are reasonable sure that these posts do not exist anymore, you can {link}unbookmark them{/link}.
 
 Page.NoPermission.Title=Unauthorized Access - Sone
 Page.NoPermission.Page.Title=Unauthorized Access
@@ -212,6 +213,7 @@ View.Post.SendReply=Post Reply!
 View.Post.Reply.DeleteLink=Delete
 View.Post.LikeLink=Like
 View.Post.UnlikeLink=Unlike
+View.Post.ShowSource=Toggle Parser
 
 View.UpdateStatus.Text.ChooseSenderIdentity=Choose the sender identity
 
index 371a86d..8eb8449 100644 (file)
@@ -239,11 +239,15 @@ textarea {
        font-weight: bold;
 }
 
-#sone .post .text {
+#sone .post .text, #sone .post .raw-text {
        display: inline;
        white-space: pre-wrap;
 }
 
+#sone .post .text.hidden, #sone .post .raw-text.hidden {
+       display: none;
+}
+
 #sone .post .status-line {
        margin-top: 0.5ex;
        font-size: 85%;
@@ -254,6 +258,10 @@ textarea {
        color: rgb(28, 131, 191);
 }
 
+#sone .show-source, #sone .show-reply-source {
+       display: inline;
+}
+
 #sone .post .bookmarks {
        display: inline;
        color: rgb(28, 131, 191);
index e99d654..9ef6812 100644 (file)
@@ -702,6 +702,15 @@ function ajaxifyPost(postElement) {
                return false;
        });
 
+       /* convert “show source” link into javascript function. */
+       $(postElement).find(".show-source").each(function() {
+               $("a", this).click(function() {
+                       $(".post-text.text", getPostElement(this)).toggleClass("hidden");
+                       $(".post-text.raw-text", getPostElement(this)).toggleClass("hidden");
+                       return false;
+               });
+       });
+
        /* add “comment” link. */
        addCommentLink(getPostId(postElement), postElement, $(postElement).find(".post-status-line .time"));
 
@@ -762,6 +771,15 @@ function ajaxifyReply(replyElement) {
        })(replyElement);
        addCommentLink(getPostId(replyElement), replyElement, $(replyElement).find(".reply-status-line .time"));
 
+       /* convert “show source” link into javascript function. */
+       $(replyElement).find(".show-reply-source").each(function() {
+               $("a", this).click(function() {
+                       $(".reply-text.text", getReplyElement(this)).toggleClass("hidden");
+                       $(".reply-text.raw-text", getReplyElement(this)).toggleClass("hidden");
+                       return false;
+               });
+       });
+
        /* convert trust control buttons to javascript functions. */
        $(replyElement).find(".reply-trust").submit(function() {
                trustSone(getReplyAuthor(this));
index ddf2bfc..8768b5a 100644 (file)
@@ -8,10 +8,13 @@
                <%include include/pagination.html>
                <%foreach posts post>
                        <%include include/viewPost.html>
-               <%foreachelse>
-                       <p><%= Page.Bookmarks.Text.NoBookmarks|l10n|html></p>
                <%/foreach>
                <%include include/pagination.html>
+               <%if postsNotLoaded>
+                       <p><%= Page.Bookmarks.Text.PostsNotLoaded|l10n|html|replace needle='{link}' replacement='<a href="unbookmark.html?post=allNotLoaded">'|replace needle='{/link}' replacement='</a>'></p>
+               <%elseif posts.empty>
+                       <p><%= Page.Bookmarks.Text.NoBookmarks|l10n|html></p>
+               <%/if>
        </div>
 
 <%include include/tail.html>
index 30ffe25..676fa6a 100644 (file)
@@ -16,7 +16,8 @@
                                        <div class="recipient profile-link"><a href="viewSone.html?sone=<% post.recipient.id|html>"><% post.recipient.niceName|html></a></div>
                                <%/if>
                        <%/if>
-                       <div class="text"><% post.text|parse sone=post.sone></div>
+                       <div class="post-text raw-text<%if !raw> hidden<%/if>"><% post.text|html></div>
+                       <div class="post-text text<%if raw> hidden<%/if>"><% post.text|parse sone=post.sone></div>
                </div>
                <div class="post-status-line status-line">
                        <div class="bookmarks">
@@ -35,6 +36,8 @@
                        </div>
                        <span class='separator'>·</span>
                        <div class="time"><a href="viewPost.html?post=<% post.id|html>"><% post.time|date format="MMM d, yyyy, HH:mm:ss"></a></div>
+                       <span class='separator'>·</span>
+                       <div class="show-source"><a href="viewPost.html?post=<% post.id|html>&amp;raw=<%if raw>false<%else>true<%/if>"><%= View.Post.ShowSource|l10n|html></a></div>
                        <div class="likes<%if post.likes.size|match value=0> hidden<%/if>">
                                <span class='separator'>·</span>
                                <span title="<% post.likes.soneNames|html>">↑<span class="like-count"><% post.likes.size></span></span>
index 2b507ff..e179e01 100644 (file)
@@ -8,10 +8,13 @@
        <div class="inner-part">
                <div>
                        <div class="author profile-link"><a href="viewSone.html?sone=<% reply.sone.id|html>"><% reply.sone.niceName|html></a></div>
-                       <div class="text"><% reply.text|parse sone=reply.sone></div>
+                       <div class="reply-text raw-text<%if !raw> hidden<%/if>"><% reply.text|html></div>
+                       <div class="reply-text text<%if raw> hidden<%/if>"><% reply.text|parse sone=reply.sone></div>
                </div>
                <div class="reply-status-line status-line">
                        <div class="time"><% reply.time|date format="MMM d, yyyy, HH:mm:ss"></div>
+                       <span class='separator'>·</span>
+                       <div class="show-reply-source"><a href="viewPost.html?post=<% post.id|html>&amp;raw=<%if raw>false<%else>true<%/if>"><%= View.Post.ShowSource|l10n|html></a></div>
                        <div class="likes<%if reply.likes.size|match value=0> hidden<%/if>">
                                <span class='separator'>·</span>
                                <span title="<% reply.likes.soneNames|html>">↑<span class="like-count"><% reply.likes.size></span></span>