<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>
@SuppressWarnings("synthetic-access")
public void run() {
if (!preferences.isSoneRescueMode()) {
- soneDownloader.fetchSone(sone);
return;
}
logger.log(Level.INFO, "Trying to restore Sone from Freenet…");
* 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);
}
/**
* 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);
}
/** 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);
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);
}
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);
}
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;
@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());
}
}
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());
package net.pterodactylus.sone.web;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
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.
@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;
}
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;
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");
+ }
}
}
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);
}
/**
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
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
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%;
color: rgb(28, 131, 191);
}
+#sone .show-source, #sone .show-reply-source {
+ display: inline;
+}
+
#sone .post .bookmarks {
display: inline;
color: rgb(28, 131, 191);
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"));
})(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));
<%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>
<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">
</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>&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>
<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>&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>