+ }, function(xmlHttpRequest, textStatus, error) {
+ /* ignore error. */
+ });
+}
+
+/**
+ * Ajaxifies the given post by enhancing all eligible elements with AJAX.
+ *
+ * @param postElement
+ * The post element to ajaxify
+ */
+function ajaxifyPost(postElement) {
+ $(postElement).find("form").submit(function() {
+ return false;
+ });
+ $(postElement).find(".create-reply button:submit").click(function() {
+ inputField = $(this.form).find(":input:enabled").get(0);
+ postId = getPostId(this);
+ text = $(inputField).val();
+ $(inputField).val("");
+ postReply(postId, text, function(success, error, replyId) {
+ if (success) {
+ loadNewReply(replyId);
+ $("#sone .post#" + postId + " .create-reply").addClass("hidden");
+ } else {
+ alert(error);
+ }
+ });
+ return false;
+ });
+
+ /* replace all “delete” buttons with javascript. */
+ (function(postElement) {
+ getTranslation("WebInterface.Confirmation.DeletePostButton", function(deletePostText) {
+ postId = getPostId(postElement);
+ enhanceDeletePostButton($(postElement).find(".delete-post button"), postId, deletePostText);
+ });
+ })(postElement);
+
+ /* convert all “like” buttons to javascript functions. */
+ $(postElement).find(".like-post").submit(function() {
+ likePost(getPostId(this));
+ return false;
+ });
+ $(postElement).find(".unlike-post").submit(function() {
+ unlikePost(getPostId(this));
+ return false;
+ });
+
+ /* process all replies. */
+ $(postElement).find(".reply").each(function() {
+ ajaxifyReply(this);
+ });
+
+ /* process reply input fields. */
+ getTranslation("WebInterface.DefaultText.Reply", function(text) {
+ $(postElement).find("input.reply-input").each(function() {
+ registerInputTextareaSwap(this, text, "text", false, false);
+ addCommentLink(getPostId(postElement), postElement);
+ });
+ });
+
+ /* add “comment” link. */
+ addCommentLink(getPostId(postElement), postElement);
+
+ /* hide reply input field. */
+ $(postElement).find(".create-reply").addClass("hidden");
+}
+
+/**
+ * Ajaxifies the given reply element.
+ *
+ * @param replyElement
+ * The reply element to ajaxify
+ */
+function ajaxifyReply(replyElement) {
+ $(replyElement).find(".like-reply").submit(function() {
+ likeReply(getReplyId(this));
+ return false;
+ });
+ $(replyElement).find(".unlike-reply").submit(function() {
+ unlikeReply(getReplyId(this));
+ return false;
+ });
+ (function(replyElement) {
+ getTranslation("WebInterface.Confirmation.DeleteReplyButton", function(deleteReplyText) {
+ $(replyElement).find(".delete-reply button").each(function() {
+ enhanceDeleteReplyButton(this, getReplyId(replyElement), deleteReplyText);
+ });
+ });
+ })(replyElement);
+ addCommentLink(getPostId(replyElement), replyElement);
+}
+
+/**
+ * Ajaxifies the given notification by replacing the form with AJAX.
+ *
+ * @param notification
+ * jQuery object representing the notification.
+ */
+function ajaxifyNotification(notification) {
+ notification.find("form.dismiss").submit(function() {
+ return false;
+ });
+ notification.find("form.dismiss button").click(function() {
+ $.getJSON("ajax/dismissNotification.ajax", { "formPassword" : getFormPassword(), "notification" : notification.attr("id") }, function(data, textStatus) {
+ /* dismiss in case of error, too. */
+ notification.slideUp();
+ }, function(xmlHttpRequest, textStatus, error) {
+ /* ignore error. */
+ });
+ });
+ return notification;
+}
+
+function getStatus() {
+ $.getJSON("ajax/getStatus.ajax", {}, function(data, textStatus) {
+ if ((data != null) && data.success) {
+ /* process Sone information. */
+ $.each(data.sones, function(index, value) {
+ updateSoneStatus(value.id, value.name, value.status, value.modified, value.locked, value.lastUpdated);
+ });
+ /* process notifications. */
+ $.each(data.notifications, function(index, value) {
+ oldNotification = $("#sone #notification-area .notification#" + value.id);
+ notification = ajaxifyNotification(createNotification(value.id, value.text, value.dismissable)).hide();
+ if (oldNotification.length != 0) {
+ oldNotification.replaceWith(notification.show());
+ } else {
+ $("#sone #notification-area").append(notification);
+ notification.slideDown();
+ }
+ });
+ $.each(data.removedNotifications, function(index, value) {
+ $("#sone #notification-area .notification#" + value.id).slideUp();
+ });
+ /* process new posts. */
+ $.each(data.newPosts, function(index, value) {
+ loadNewPost(value);
+ });
+ /* process new replies. */
+ $.each(data.newReplies, function(index, value) {
+ loadNewReply(value);
+ });
+ /* do it again in 5 seconds. */
+ setTimeout(getStatus, 5000);
+ } else {
+ /* data.success was false, wait 30 seconds. */
+ setTimeout(getStatus, 30000);
+ }
+ }, function(xmlHttpRequest, textStatus, error) {
+ /* something really bad happend, wait a minute. */
+ setTimeout(getStatus, 60000);
+ })
+}
+
+var loadedPosts = {};
+var loadedReplies = {};
+
+function loadNewPost(postId) {
+ if (postId in loadedPosts) {
+ return;
+ }
+ loadedPosts[postId] = true;
+ $.getJSON("ajax/getPost.ajax", { "post" : postId }, function(data, textStatus) {
+ if ((data != null) && data.success) {
+ var firstOlderPost = null;
+ $("#sone #posts .post").each(function() {
+ if (getPostTime(this) < data.post.time) {
+ firstOlderPost = $(this);
+ return false;
+ }
+ });
+ newPost = $(data.post.html).addClass("hidden");
+ if (firstOlderPost != null) {
+ newPost.insertBefore(firstOlderPost);
+ } else {
+ $("#sone #posts .post:last").after(newPost);
+ }
+ ajaxifyPost(newPost);
+ newPost.slideDown();
+ }
+ });
+}
+
+function loadNewReply(replyId) {
+ if (replyId in loadedReplies) {
+ return;
+ }
+ loadedReplies[replyId] = true;
+ $.getJSON("ajax/getReply.ajax", { "reply": replyId }, function(data, textStatus) {
+ /* find post. */
+ $("#sone #posts .post#" + data.reply.postId).each(function() {
+ var firstNewerReply = null;
+ $(this).find(".replies .reply").each(function() {
+ if (getReplyTime(this) > data.reply.time) {
+ firstNewerReply = $(this);
+ return false;
+ }
+ });
+ newReply = $(data.reply.html);
+ if (firstNewerReply != null) {
+ newReply.insertAfter(firstNewerReply);
+ } else {
+ $(this).find(".replies .reply:last").after(newReply);
+ }
+ ajaxifyReply(newReply);
+ });