X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=d3f50a1e4fdee6634f541fc8b1cd5df8d5ea0ab6;hb=2a3193f488ecff7496d7464e2e2213c82a2708a3;hp=d0898f1b226252c6ed33e503e9d51a1e465082fd;hpb=6b766ddf457077381e69a2ff0220222ad8da967e;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index d0898f1..d3f50a1 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -591,6 +591,23 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** + * Returns the time when the given was first followed by any local Sone. + * + * @param sone + * The Sone to get the time for + * @return The time (in milliseconds since Jan 1, 1970) the Sone has first + * been followed, or {@link Long#MAX_VALUE} + */ + public long getSoneFollowingTime(Sone sone) { + synchronized (soneFollowingTimes) { + if (soneFollowingTimes.containsKey(sone)) { + return soneFollowingTimes.get(sone); + } + return Long.MAX_VALUE; + } + } + + /** * Returns whether the target Sone is trusted by the origin Sone. * * @param origin @@ -1015,7 +1032,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.getOptions().addBooleanOption("ShowNotification/NewSones", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewPosts", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewReplies", new DefaultOption(true)); - sone.addFriend("nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI"); + followSone(sone, getSone("nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI")); touchConfiguration(); return sone; } @@ -1048,13 +1065,11 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis coreListenerManager.fireNewSoneFound(sone); for (Sone localSone : getLocalSones()) { if (localSone.getOptions().getBooleanOption("AutoFollow").get()) { - localSone.addFriend(sone.getId()); - touchConfiguration(); + followSone(localSone, sone); } } } } - remoteSones.put(identity.getId(), sone); soneDownloader.addSone(sone); setSoneStatus(sone, SoneStatus.unknown); soneDownloaders.execute(new Runnable() { @@ -1071,6 +1086,90 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** + * Lets the given local Sone follow the Sone with the given ID. + * + * @param sone + * The local Sone that should follow another Sone + * @param soneId + * The ID of the Sone to follow + */ + public void followSone(Sone sone, String soneId) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check(); + followSone(sone, getSone(soneId)); + } + + /** + * Lets the given local Sone follow the other given Sone. If the given Sone + * was not followed by any local Sone before, this will mark all elements of + * the followed Sone as read that have been created before the current + * moment. + * + * @param sone + * The local Sone that should follow the other Sone + * @param followedSone + * The Sone that should be followed + */ + public void followSone(Sone sone, Sone followedSone) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Followed Sone", followedSone).check(); + sone.addFriend(followedSone.getId()); + synchronized (soneFollowingTimes) { + if (!soneFollowingTimes.containsKey(followedSone)) { + long now = System.currentTimeMillis(); + soneFollowingTimes.put(followedSone, now); + for (Post post : followedSone.getPosts()) { + if (post.getTime() < now) { + markPostKnown(post); + } + } + for (PostReply reply : followedSone.getReplies()) { + if (reply.getTime() < now) { + markReplyKnown(reply); + } + } + } + } + touchConfiguration(); + } + + /** + * Lets the given local Sone unfollow the Sone with the given ID. + * + * @param sone + * The local Sone that should unfollow another Sone + * @param soneId + * The ID of the Sone being unfollowed + */ + public void unfollowSone(Sone sone, String soneId) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check(); + unfollowSone(sone, getSone(soneId, false)); + } + + /** + * Lets the given local Sone unfollow the other given Sone. If the given + * local Sone is the last local Sone that followed the given Sone, its + * following time will be removed. + * + * @param sone + * The local Sone that should unfollow another Sone + * @param unfollowedSone + * The Sone being unfollowed + */ + public void unfollowSone(Sone sone, Sone unfollowedSone) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Unfollowed Sone", unfollowedSone).check(); + sone.removeFriend(unfollowedSone.getId()); + boolean unfollowedSoneStillFollowed = false; + for (Sone localSone : getLocalSones()) { + unfollowedSoneStillFollowed |= localSone.hasFriend(unfollowedSone.getId()); + } + if (!unfollowedSoneStillFollowed) { + synchronized (soneFollowingTimes) { + soneFollowingTimes.remove(unfollowedSone); + } + } + touchConfiguration(); + } + + /** * Retrieves the trust relationship from the origin to the target. If the * trust relationship can not be retrieved, {@code null} is returned. * @@ -1202,9 +1301,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (newPosts) { for (Post post : sone.getPosts()) { post.setSone(storedSone); - if (!storedPosts.contains(post) && !knownPosts.contains(post.getId())) { - newPosts.add(post.getId()); - coreListenerManager.fireNewPostFound(post); + if (!storedPosts.contains(post)) { + if (post.getTime() < getSoneFollowingTime(sone)) { + knownPosts.add(post.getId()); + } else if (!knownPosts.contains(post.getId())) { + newPosts.add(post.getId()); + coreListenerManager.fireNewPostFound(post); + } } posts.put(post.getId(), post); } @@ -1223,9 +1326,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (newReplies) { for (PostReply reply : sone.getReplies()) { reply.setSone(storedSone); - if (!storedReplies.contains(reply) && !knownReplies.contains(reply.getId())) { - newReplies.add(reply.getId()); - coreListenerManager.fireNewReplyFound(reply); + if (!storedReplies.contains(reply)) { + if (reply.getTime() < getSoneFollowingTime(sone)) { + knownReplies.add(reply.getId()); + } else if (!knownReplies.contains(reply.getId())) { + newReplies.add(reply.getId()); + coreListenerManager.fireNewReplyFound(reply); + } } replies.put(reply.getId(), reply); } @@ -1527,7 +1634,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.setReplies(replies); sone.setLikePostIds(likedPostIds); sone.setLikeReplyIds(likedReplyIds); - sone.setFriends(friends); + for (String friendId : friends) { + followSone(sone, friendId); + } sone.setAlbums(topLevelAlbums); soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint); }