From: David ‘Bombe’ Roden Date: Tue, 29 Nov 2011 08:00:13 +0000 (+0100) Subject: Merge branch 'release-0.7.5' X-Git-Tag: 0.7.5 X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=refs%2Ftags%2F0.7.5;hp=ba4811ca5360e93b449629132b4c6583aa82eb1a;p=Sone.git Merge branch 'release-0.7.5' --- diff --git a/pom.xml b/pom.xml index 3afca0e..96a9494 100644 --- a/pom.xml +++ b/pom.xml @@ -2,12 +2,12 @@ 4.0.0 net.pterodactylus sone - 0.7.4 + 0.7.5 net.pterodactylus utils - 0.11.3 + 0.11.4 junit diff --git a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java index 5e52b0e..6a2c1ca 100644 --- a/src/main/java/net/pterodactylus/sone/main/SonePlugin.java +++ b/src/main/java/net/pterodactylus/sone/main/SonePlugin.java @@ -83,7 +83,7 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr } /** The version. */ - public static final Version VERSION = new Version(0, 7, 4); + public static final Version VERSION = new Version(0, 7, 5); /** The logger. */ private static final Logger logger = Logging.getLogger(SonePlugin.class); diff --git a/src/main/java/net/pterodactylus/sone/notify/ListNotification.java b/src/main/java/net/pterodactylus/sone/notify/ListNotification.java index 74e3100..cf658bd 100644 --- a/src/main/java/net/pterodactylus/sone/notify/ListNotification.java +++ b/src/main/java/net/pterodactylus/sone/notify/ListNotification.java @@ -161,4 +161,46 @@ public class ListNotification extends TemplateNotification { elements.clear(); } + // + // OBJECT METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + int hashCode = super.hashCode(); + for (T element : elements) { + hashCode ^= element.hashCode(); + } + return hashCode; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object object) { + if (!(object instanceof ListNotification)) { + return false; + } + ListNotification listNotification = (ListNotification) object; + if (!super.equals(listNotification)) { + return false; + } + if (!key.equals(listNotification.key)) { + return false; + } + if (elements.size() != listNotification.elements.size()) { + return false; + } + for (int index = 0; index < elements.size(); ++index) { + if (!elements.get(index).equals(listNotification.elements.get(index))) { + return false; + } + } + return true; + } + } diff --git a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java index 095db9e..b0d31d2 100644 --- a/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java +++ b/src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java @@ -21,6 +21,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -31,6 +32,8 @@ import net.pterodactylus.sone.web.page.FreenetRequest; import net.pterodactylus.sone.web.page.FreenetTemplatePage; import net.pterodactylus.util.collection.ListBuilder; import net.pterodactylus.util.collection.MapBuilder; +import net.pterodactylus.util.notify.Notification; +import net.pterodactylus.util.object.HashCode; import net.pterodactylus.util.template.Template; import net.pterodactylus.util.template.TemplateContext; import freenet.clients.http.SessionManager.Session; @@ -259,7 +262,10 @@ public class SoneTemplatePage extends FreenetTemplatePage { templateContext.set("latestEdition", webInterface.getCore().getUpdateChecker().getLatestEdition()); templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); templateContext.set("latestVersionTime", webInterface.getCore().getUpdateChecker().getLatestVersionDate()); - templateContext.set("notifications", ListNotificationFilters.filterNotifications(webInterface.getNotifications().getNotifications(), currentSone)); + List notifications = ListNotificationFilters.filterNotifications(webInterface.getNotifications().getNotifications(), currentSone); + Collections.sort(notifications, Notification.CREATED_TIME_SORTER); + templateContext.set("notifications", notifications); + templateContext.set("notificationHash", HashCode.hashCode(notifications)); } /** diff --git a/src/main/java/net/pterodactylus/sone/web/WebInterface.java b/src/main/java/net/pterodactylus/sone/web/WebInterface.java index 5ba3be7..094d2a4 100644 --- a/src/main/java/net/pterodactylus/sone/web/WebInterface.java +++ b/src/main/java/net/pterodactylus/sone/web/WebInterface.java @@ -82,7 +82,7 @@ import net.pterodactylus.sone.web.ajax.EditImageAjaxPage; import net.pterodactylus.sone.web.ajax.EditProfileFieldAjaxPage; import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage; import net.pterodactylus.sone.web.ajax.GetLikesAjaxPage; -import net.pterodactylus.sone.web.ajax.GetNotificationAjaxPage; +import net.pterodactylus.sone.web.ajax.GetNotificationsAjaxPage; import net.pterodactylus.sone.web.ajax.GetPostAjaxPage; import net.pterodactylus.sone.web.ajax.GetReplyAjaxPage; import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage; @@ -658,7 +658,7 @@ public class WebInterface implements CoreListener { pageToadlets.add(pageToadletFactory.createPageToadlet(new GetImagePage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetTranslationPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetStatusAjaxPage(this))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new GetNotificationAjaxPage(this))); + pageToadlets.add(pageToadletFactory.createPageToadlet(new GetNotificationsAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DismissNotificationAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new CreatePostAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new CreateReplyAjaxPage(this))); @@ -872,6 +872,7 @@ public class WebInterface implements CoreListener { public void postRemoved(Post post) { newPostNotification.remove(post); localPostNotification.remove(post); + mentionNotification.remove(post); } /** @@ -881,6 +882,15 @@ public class WebInterface implements CoreListener { public void replyRemoved(PostReply reply) { newReplyNotification.remove(reply); localReplyNotification.remove(reply); + if (!getMentionedSones(reply.getText()).isEmpty()) { + boolean isMentioned = false; + for (PostReply existingReply : getCore().getReplies(reply.getPost())) { + isMentioned |= getCore().isNewReply(reply.getId()) && !getMentionedSones(existingReply.getText()).isEmpty(); + } + if (!isMentioned) { + mentionNotification.remove(reply.getPost()); + } + } } /** diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationAjaxPage.java deleted file mode 100644 index 6cdbf12..0000000 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationAjaxPage.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Sone - GetNotificationAjaxPage.java - Copyright © 2010 David Roden - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.pterodactylus.sone.web.ajax; - -import java.io.IOException; -import java.io.StringWriter; - -import net.pterodactylus.sone.data.Post; -import net.pterodactylus.sone.data.PostReply; -import net.pterodactylus.sone.data.Sone; -import net.pterodactylus.sone.main.SonePlugin; -import net.pterodactylus.sone.notify.ListNotification; -import net.pterodactylus.sone.notify.ListNotificationFilters; -import net.pterodactylus.sone.web.WebInterface; -import net.pterodactylus.sone.web.page.FreenetRequest; -import net.pterodactylus.util.json.JsonObject; -import net.pterodactylus.util.notify.Notification; -import net.pterodactylus.util.notify.TemplateNotification; -import net.pterodactylus.util.template.TemplateContext; - -/** - * The “get notification” AJAX handler returns a number of rendered - * notifications. - * - * @author David ‘Bombe’ Roden - */ -public class GetNotificationAjaxPage extends JsonPage { - - /** - * Creates a new “get notification” AJAX page. - * - * @param webInterface - * The Sone web interface - */ - public GetNotificationAjaxPage(WebInterface webInterface) { - super("getNotification.ajax", webInterface); - } - - // - // JSONPAGE METHODS - // - - /** - * {@inheritDoc} - */ - @Override - protected boolean needsFormPassword() { - return false; - } - - /** - * {@inheritDoc} - */ - @Override - protected boolean requiresLogin() { - return false; - } - - /** - * {@inheritDoc} - */ - @Override - @SuppressWarnings("unchecked") - protected JsonObject createJsonObject(FreenetRequest request) { - String[] notificationIds = request.getHttpRequest().getParam("notifications").split(","); - JsonObject jsonNotifications = new JsonObject(); - Sone currentSone = getCurrentSone(request.getToadletContext(), false); - for (String notificationId : notificationIds) { - Notification notification = webInterface.getNotifications().getNotification(notificationId); - if (notification == null) { - // TODO - show error - continue; - } - if ("new-post-notification".equals(notificationId)) { - notification = ListNotificationFilters.filterNewPostNotification((ListNotification) notification, currentSone, false); - } else if ("new-reply-notification".equals(notificationId)) { - notification = ListNotificationFilters.filterNewReplyNotification((ListNotification) notification, currentSone); - } else if ("mention-notification".equals(notificationId)) { - notification = ListNotificationFilters.filterNewPostNotification((ListNotification) notification, currentSone, false); - } - if (notification == null) { - // TODO - show error - continue; - } - jsonNotifications.put(notificationId, createJsonNotification(request, notification)); - } - return createSuccessJsonObject().put("notifications", jsonNotifications); - } - - // - // PRIVATE METHODS - // - - /** - * Creates a JSON object from the given notification. - * - * @param request - * The request to load the session from - * @param notification - * The notification to create a JSON object - * @return The JSON object - */ - private JsonObject createJsonNotification(FreenetRequest request, Notification notification) { - JsonObject jsonNotification = new JsonObject(); - jsonNotification.put("id", notification.getId()); - StringWriter notificationWriter = new StringWriter(); - try { - if (notification instanceof TemplateNotification) { - TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext().mergeContext(((TemplateNotification) notification).getTemplateContext()); - templateContext.set("core", webInterface.getCore()); - templateContext.set("currentSone", webInterface.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()); - templateContext.set("latestEdition", webInterface.getCore().getUpdateChecker().getLatestEdition()); - templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); - templateContext.set("latestVersionTime", webInterface.getCore().getUpdateChecker().getLatestVersionDate()); - templateContext.set("notification", notification); - ((TemplateNotification) notification).render(templateContext, notificationWriter); - } else { - notification.render(notificationWriter); - } - } catch (IOException ioe1) { - /* StringWriter never throws, ignore. */ - } - jsonNotification.put("text", notificationWriter.toString()); - jsonNotification.put("createdTime", notification.getCreatedTime()); - jsonNotification.put("lastUpdatedTime", notification.getLastUpdatedTime()); - jsonNotification.put("dismissable", notification.isDismissable()); - return jsonNotification; - } - -} diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java new file mode 100644 index 0000000..d88aae9 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java @@ -0,0 +1,155 @@ +/* + * Sone - GetNotificationsAjaxPage.java - Copyright © 2011 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.sone.web.ajax; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.main.SonePlugin; +import net.pterodactylus.sone.notify.ListNotificationFilters; +import net.pterodactylus.sone.web.WebInterface; +import net.pterodactylus.sone.web.page.FreenetRequest; +import net.pterodactylus.util.json.JsonArray; +import net.pterodactylus.util.json.JsonObject; +import net.pterodactylus.util.notify.Notification; +import net.pterodactylus.util.notify.TemplateNotification; +import net.pterodactylus.util.object.HashCode; +import net.pterodactylus.util.template.TemplateContext; + +/** + * AJAX handler to return all current notifications. + * + * @author David ‘Bombe’ Roden + */ +public class GetNotificationsAjaxPage extends JsonPage { + + /** + * Creates a new “get notifications” AJAX handler. + * + * @param webInterface + * The Sone web interface + */ + public GetNotificationsAjaxPage(WebInterface webInterface) { + super("getNotifications.ajax", webInterface); + } + + // + // JSONPAGE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + protected boolean needsFormPassword() { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean requiresLogin() { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + protected JsonObject createJsonObject(FreenetRequest request) { + Sone currentSone = getCurrentSone(request.getToadletContext(), false); + Collection notifications = webInterface.getNotifications().getNotifications(); + List filteredNotifications = ListNotificationFilters.filterNotifications(notifications, currentSone); + Collections.sort(filteredNotifications, Notification.CREATED_TIME_SORTER); + int notificationHash = HashCode.hashCode(filteredNotifications); + JsonArray jsonNotifications = new JsonArray(); + for (Notification notification : filteredNotifications) { + jsonNotifications.add(createJsonNotification(request, notification)); + } + return createSuccessJsonObject().put("notificationHash", notificationHash).put("notifications", jsonNotifications).put("options", createJsonOptions(currentSone)); + } + + // + // PRIVATE METHODS + // + + /** + * Creates a JSON object from the given notification. + * + * @param request + * The request to load the session from + * @param notification + * The notification to create a JSON object + * @return The JSON object + */ + private JsonObject createJsonNotification(FreenetRequest request, Notification notification) { + JsonObject jsonNotification = new JsonObject(); + jsonNotification.put("id", notification.getId()); + StringWriter notificationWriter = new StringWriter(); + try { + if (notification instanceof TemplateNotification) { + TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext().mergeContext(((TemplateNotification) notification).getTemplateContext()); + templateContext.set("core", webInterface.getCore()); + templateContext.set("currentSone", webInterface.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()); + templateContext.set("latestEdition", webInterface.getCore().getUpdateChecker().getLatestEdition()); + templateContext.set("latestVersion", webInterface.getCore().getUpdateChecker().getLatestVersion()); + templateContext.set("latestVersionTime", webInterface.getCore().getUpdateChecker().getLatestVersionDate()); + templateContext.set("notification", notification); + ((TemplateNotification) notification).render(templateContext, notificationWriter); + } else { + notification.render(notificationWriter); + } + } catch (IOException ioe1) { + /* StringWriter never throws, ignore. */ + } + jsonNotification.put("text", notificationWriter.toString()); + jsonNotification.put("createdTime", notification.getCreatedTime()); + jsonNotification.put("lastUpdatedTime", notification.getLastUpdatedTime()); + jsonNotification.put("dismissable", notification.isDismissable()); + return jsonNotification; + } + + /** + * Creates a JSON object that contains all options that are currently in + * effect for the given Sone (or overall, if the given Sone is {@code null} + * ). + * + * @param currentSone + * The current Sone (may be {@code null}) + * @return The current options + */ + private JsonObject createJsonOptions(Sone currentSone) { + JsonObject options = new JsonObject(); + if (currentSone != null) { + options.put("ShowNotification/NewSones", currentSone.getOptions().getBooleanOption("ShowNotification/NewSones").get()); + options.put("ShowNotification/NewPosts", currentSone.getOptions().getBooleanOption("ShowNotification/NewPosts").get()); + options.put("ShowNotification/NewReplies", currentSone.getOptions().getBooleanOption("ShowNotification/NewReplies").get()); + } + return options; + } + +} diff --git a/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java b/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java index 5f2103a..1f23e4a 100644 --- a/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java +++ b/src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java @@ -37,6 +37,7 @@ import net.pterodactylus.util.filter.Filters; import net.pterodactylus.util.json.JsonArray; import net.pterodactylus.util.json.JsonObject; import net.pterodactylus.util.notify.Notification; +import net.pterodactylus.util.object.HashCode; /** * The “get status” AJAX handler returns all information that is necessary to @@ -90,11 +91,7 @@ public class GetStatusAjaxPage extends JsonPage { } /* load notifications. */ List notifications = ListNotificationFilters.filterNotifications(webInterface.getNotifications().getNotifications(), currentSone); - Collections.sort(notifications, Notification.LAST_UPDATED_TIME_SORTER); - JsonArray jsonNotificationInformations = new JsonArray(); - for (Notification notification : notifications) { - jsonNotificationInformations.add(createJsonNotificationInformation(notification)); - } + int notificationHash = HashCode.hashCode(notifications); /* load new posts. */ Set newPosts = webInterface.getNewPosts(); if (currentSone != null) { @@ -145,7 +142,7 @@ public class GetStatusAjaxPage extends JsonPage { jsonReply.put("postSone", reply.getPost().getSone().getId()); jsonReplies.add(jsonReply); } - return createSuccessJsonObject().put("loggedIn", currentSone != null).put("options", createJsonOptions(currentSone)).put("sones", jsonSones).put("notifications", jsonNotificationInformations).put("newPosts", jsonPosts).put("newReplies", jsonReplies); + return createSuccessJsonObject().put("loggedIn", currentSone != null).put("options", createJsonOptions(currentSone)).put("sones", jsonSones).put("notificationHash", notificationHash).put("newPosts", jsonPosts).put("newReplies", jsonReplies); } /** @@ -192,24 +189,6 @@ public class GetStatusAjaxPage extends JsonPage { } /** - * Creates a JSON object that only contains the ID and the last-updated time - * of the given notification. - * - * @see Notification#getId() - * @see Notification#getLastUpdatedTime() - * @param notification - * The notification - * @return A JSON object containing the notification ID and last-updated - * time - */ - private JsonObject createJsonNotificationInformation(Notification notification) { - JsonObject jsonNotification = new JsonObject(); - jsonNotification.put("id", notification.getId()); - jsonNotification.put("lastUpdatedTime", notification.getLastUpdatedTime()); - return jsonNotification; - } - - /** * Creates a JSON object that contains all options that are currently in * effect for the given Sone (or overall, if the given Sone is {@code null} * ). diff --git a/src/main/resources/static/javascript/sone.js b/src/main/resources/static/javascript/sone.js index a3dbc64..e271246 100644 --- a/src/main/resources/static/javascript/sone.js +++ b/src/main/resources/static/javascript/sone.js @@ -1088,6 +1088,24 @@ function ajaxifyNotification(notification) { } /** + * Returns the notification hash. This hash is used in {@link #getStatus()} to + * determine whether the notifications changed and need to be reloaded. + */ +function getNotificationHash() { + return $("#sone #notification-area #notification-hash").text(); +} + +/** + * Sets the notification hash. + * + * @param notificationHash + * The new notification hash + */ +function setNotificationHash(notificationHash) { + $("#sone #notification-area #notification-hash").text(notificationHash); +} + +/** * Retrieves element IDs from notification elements. * * @param notification @@ -1182,6 +1200,33 @@ function getStatus() { if (!notLoggedIn) { showOfflineMarker(!online); } + if (data.notificationHash != getNotificationHash()) { + console.log("Old hash: ", getNotificationHash(), ", new hash: ", data.notificationHash); + requestNotifications(); + } + /* process new posts. */ + $.each(data.newPosts, function(index, value) { + loadNewPost(value.id, value.sone, value.recipient, value.time); + }); + /* process new replies. */ + $.each(data.newReplies, function(index, value) { + loadNewReply(value.id, value.sone, value.post, value.postSone); + }); + /* do it again in 5 seconds. */ + setTimeout(getStatus, 5000); + } else { + /* data.success was false, wait 30 seconds. */ + setTimeout(getStatus, 30000); + } + }, function() { + statusRequestQueued = false; + ajaxError(); + }); +} + +function requestNotifications() { + ajaxGet("getNotifications.ajax", {}, function(data, textStatus) { + if (data && data.success) { /* search for removed notifications. */ $("#sone #notification-area .notification").each(function() { notificationId = $(this).attr("id"); @@ -1219,69 +1264,29 @@ function getStatus() { } }); /* process notifications. */ - notificationIds = []; $.each(data.notifications, function(index, value) { oldNotification = getNotification(value.id); - if ((oldNotification.length == 0) || (value.lastUpdatedTime > getNotificationLastUpdatedTime(oldNotification))) { - notificationIds.push(value.id); + notification = ajaxifyNotification(createNotification(value.id, value.lastUpdatedTime, value.text, value.dismissable)).hide(); + if (oldNotification.length != 0) { + if ((oldNotification.find(".short-text").length > 0) && (notification.find(".short-text").length > 0)) { + opened = oldNotification.is(":visible") && oldNotification.find(".short-text").hasClass("hidden"); + notification.find(".short-text").toggleClass("hidden", opened); + notification.find(".text").toggleClass("hidden", !opened); + } + checkForRemovedSones(oldNotification, notification); + checkForRemovedPosts(oldNotification, notification); + checkForRemovedReplies(oldNotification, notification); + oldNotification.replaceWith(notification.show()); + } else { + $("#sone #notification-area").append(notification); + if (value.id.substring(0, 5) != "local") { + notification.slideDown(); + setActivity(); + } } }); - if (notificationIds.length > 0) { - loadNotifications(notificationIds); - } - /* process new posts. */ - $.each(data.newPosts, function(index, value) { - loadNewPost(value.id, value.sone, value.recipient, value.time); - }); - /* process new replies. */ - $.each(data.newReplies, function(index, value) { - loadNewReply(value.id, value.sone, value.post, value.postSone); - }); - /* do it again in 5 seconds. */ - setTimeout(getStatus, 5000); - } else { - /* data.success was false, wait 30 seconds. */ - setTimeout(getStatus, 30000); + setNotificationHash(data.notificationHash); } - }, function() { - statusRequestQueued = false; - ajaxError(); - }); -} - -/** - * Requests multiple notifications from Sone and displays them. - * - * @param notificationIds - * Array of IDs of the notifications to load - */ -function loadNotifications(notificationIds) { - ajaxGet("getNotification.ajax", {"notifications": notificationIds.join(",")}, function(data, textStatus) { - if (!data || !data.success) { - // TODO - show error - return; - } - $.each(data.notifications, function(index, value) { - oldNotification = getNotification(value.id); - notification = ajaxifyNotification(createNotification(value.id, value.lastUpdatedTime, value.text, value.dismissable)).hide(); - if (oldNotification.length != 0) { - if ((oldNotification.find(".short-text").length > 0) && (notification.find(".short-text").length > 0)) { - opened = oldNotification.is(":visible") && oldNotification.find(".short-text").hasClass("hidden"); - notification.find(".short-text").toggleClass("hidden", opened); - notification.find(".text").toggleClass("hidden", !opened); - } - checkForRemovedSones(oldNotification, notification); - checkForRemovedPosts(oldNotification, notification); - checkForRemovedReplies(oldNotification, notification); - oldNotification.replaceWith(notification.show()); - } else { - $("#sone #notification-area").append(notification); - if (value.id.substring(0, 5) != "local") { - notification.slideDown(); - setActivity(); - } - } - }); }); } @@ -1511,6 +1516,7 @@ function markSoneAsKnown(soneElement, skipRequest) { $(soneElement).removeClass("new"); if ((typeof skipRequest == "undefined") || !skipRequest) { ajaxGet("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": "sone", "id": getSoneId(soneElement)}); + requestNotifications(); } } } @@ -1523,6 +1529,7 @@ function markPostAsKnown(postElements, skipRequest) { $(postElement).removeClass("new"); if ((typeof skipRequest == "undefined") || !skipRequest) { ajaxGet("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": "post", "id": getPostId(postElement)}); + requestNotifications(); } })(postElement); } @@ -1539,6 +1546,7 @@ function markReplyAsKnown(replyElements, skipRequest) { $(replyElement).removeClass("new"); if ((typeof skipRequest == "undefined") || !skipRequest) { ajaxGet("markAsKnown.ajax", {"formPassword": getFormPassword(), "type": "reply", "id": getReplyId(replyElement)}); + requestNotifications(); } })(replyElement); } diff --git a/src/main/resources/templates/include/head.html b/src/main/resources/templates/include/head.html index cd9eddf..ae642dc 100644 --- a/src/main/resources/templates/include/head.html +++ b/src/main/resources/templates/include/head.html @@ -15,6 +15,8 @@
+ +