diff --git a/commafeed-client/src/app/types.ts b/commafeed-client/src/app/types.ts index 5eea230f..9866e1aa 100644 --- a/commafeed-client/src/app/types.ts +++ b/commafeed-client/src/app/types.ts @@ -113,6 +113,7 @@ export interface MarkRequest { id: string read: boolean olderThan?: number + insertedBefore?: number keywords?: string excludedSubscriptions?: number[] } diff --git a/commafeed-client/src/components/content/FeedEntries.tsx b/commafeed-client/src/components/content/FeedEntries.tsx index be291edd..d560f5ed 100644 --- a/commafeed-client/src/components/content/FeedEntries.tsx +++ b/commafeed-client/src/components/content/FeedEntries.tsx @@ -279,7 +279,8 @@ export function FeedEntries() { req: { id: source.id, read: true, - olderThan: entriesTimestamp, + olderThan: Date.now(), + insertedBefore: entriesTimestamp, }, }) ) diff --git a/commafeed-client/src/components/header/MarkAllAsReadButton.tsx b/commafeed-client/src/components/header/MarkAllAsReadButton.tsx index d0495e08..4bfee456 100644 --- a/commafeed-client/src/components/header/MarkAllAsReadButton.tsx +++ b/commafeed-client/src/components/header/MarkAllAsReadButton.tsx @@ -27,7 +27,8 @@ export function MarkAllAsReadButton(props: { iconSize: number }) { req: { id: source.id, read: true, - olderThan: entriesTimestamp, + olderThan: Date.now(), + insertedBefore: entriesTimestamp, }, }) ) @@ -78,7 +79,8 @@ export function MarkAllAsReadButton(props: { iconSize: number }) { req: { id: source.id, read: true, - olderThan: entriesTimestamp - threshold * 24 * 60 * 60 * 1000, + olderThan: Date.now() - threshold * 24 * 60 * 60 * 1000, + insertedBefore: entriesTimestamp, }, }) ) diff --git a/commafeed-server/src/main/java/com/commafeed/backend/service/FeedEntryService.java b/commafeed-server/src/main/java/com/commafeed/backend/service/FeedEntryService.java index 9db9f9f8..e94d96b7 100644 --- a/commafeed-server/src/main/java/com/commafeed/backend/service/FeedEntryService.java +++ b/commafeed-server/src/main/java/com/commafeed/backend/service/FeedEntryService.java @@ -1,6 +1,5 @@ package com.commafeed.backend.service; -import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -108,30 +107,30 @@ public class FeedEntryService { feedEntryStatusDAO.saveOrUpdate(status); } - public void markSubscriptionEntries(User user, List subscriptions, Date olderThan, List keywords) { + public void markSubscriptionEntries(User user, List subscriptions, Date olderThan, Date insertedBefore, + List keywords) { List statuses = feedEntryStatusDAO.findBySubscriptions(user, subscriptions, true, keywords, null, -1, -1, null, false, false, null, null, null); - markList(statuses, olderThan); + markList(statuses, olderThan, insertedBefore); cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0])); cache.invalidateUserRootCategory(user); } - public void markStarredEntries(User user, Date olderThan) { + public void markStarredEntries(User user, Date olderThan, Date insertedBefore) { List statuses = feedEntryStatusDAO.findStarred(user, null, -1, -1, null, false); - markList(statuses, olderThan); + markList(statuses, olderThan, insertedBefore); } - private void markList(List statuses, Date olderThan) { - List list = new ArrayList<>(); - for (FeedEntryStatus status : statuses) { - if (!status.isRead()) { - Date entryDate = status.getEntry().getUpdated(); - if (olderThan == null || entryDate == null || olderThan.after(entryDate)) { - status.setRead(true); - list.add(status); - } - } - } - feedEntryStatusDAO.saveOrUpdate(list); + private void markList(List statuses, Date olderThan, Date insertedBefore) { + List statusesToMark = statuses.stream().filter(s -> { + Date entryDate = s.getEntry().getUpdated(); + return olderThan == null || entryDate == null || entryDate.before(olderThan); + }).filter(s -> { + Date insertedDate = s.getEntry().getInserted(); + return insertedBefore == null || insertedDate == null || insertedDate.before(insertedBefore); + }).toList(); + + statusesToMark.forEach(s -> s.setRead(true)); + feedEntryStatusDAO.saveOrUpdate(statusesToMark); } } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java b/commafeed-server/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java index e5ed7317..d9cd6b6b 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java @@ -22,11 +22,14 @@ public class MarkRequest implements Serializable { @Schema(description = "mark as read or unread", requiredMode = RequiredMode.REQUIRED) private boolean read; - @Schema( - description = "only entries older than this, pass the timestamp you got from the entry list to prevent marking an entry that was not retrieved", - requiredMode = RequiredMode.NOT_REQUIRED) + @Schema(description = "mark only entries older than this", requiredMode = RequiredMode.NOT_REQUIRED) private Long olderThan; + @Schema( + description = "pass the timestamp you got from the entry list to avoid marking entries that may have been fetched in the mean time and never displayed", + requiredMode = RequiredMode.NOT_REQUIRED) + private Long insertedBefore; + @Schema( description = "only mark read if a feed has these keywords in the title or rss content", requiredMode = RequiredMode.NOT_REQUIRED) diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/resource/CategoryREST.java b/commafeed-server/src/main/java/com/commafeed/frontend/resource/CategoryREST.java index aabe6d86..c42fb60f 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/resource/CategoryREST.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/resource/CategoryREST.java @@ -243,21 +243,22 @@ public class CategoryREST { Preconditions.checkNotNull(req.getId()); Date olderThan = req.getOlderThan() == null ? null : new Date(req.getOlderThan()); + Date insertedBefore = req.getInsertedBefore() == null ? null : new Date(req.getInsertedBefore()); String keywords = req.getKeywords(); List entryKeywords = FeedEntryKeyword.fromQueryString(keywords); if (ALL.equals(req.getId())) { List subs = feedSubscriptionDAO.findAll(user); removeExcludedSubscriptions(subs, req.getExcludedSubscriptions()); - feedEntryService.markSubscriptionEntries(user, subs, olderThan, entryKeywords); + feedEntryService.markSubscriptionEntries(user, subs, olderThan, insertedBefore, entryKeywords); } else if (STARRED.equals(req.getId())) { - feedEntryService.markStarredEntries(user, olderThan); + feedEntryService.markStarredEntries(user, olderThan, insertedBefore); } else { FeedCategory parent = feedCategoryDAO.findById(user, Long.valueOf(req.getId())); List categories = feedCategoryDAO.findAllChildrenCategories(user, parent); List subs = feedSubscriptionDAO.findByCategories(user, categories); removeExcludedSubscriptions(subs, req.getExcludedSubscriptions()); - feedEntryService.markSubscriptionEntries(user, subs, olderThan, entryKeywords); + feedEntryService.markSubscriptionEntries(user, subs, olderThan, insertedBefore, entryKeywords); } return Response.ok().build(); } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/resource/FeedREST.java b/commafeed-server/src/main/java/com/commafeed/frontend/resource/FeedREST.java index 10b15e48..c3d116bc 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/resource/FeedREST.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/resource/FeedREST.java @@ -322,12 +322,14 @@ public class FeedREST { Preconditions.checkNotNull(req.getId()); Date olderThan = req.getOlderThan() == null ? null : new Date(req.getOlderThan()); + Date insertedBefore = req.getInsertedBefore() == null ? null : new Date(req.getInsertedBefore()); String keywords = req.getKeywords(); List entryKeywords = FeedEntryKeyword.fromQueryString(keywords); FeedSubscription subscription = feedSubscriptionDAO.findById(user, Long.valueOf(req.getId())); if (subscription != null) { - feedEntryService.markSubscriptionEntries(user, Collections.singletonList(subscription), olderThan, entryKeywords); + feedEntryService.markSubscriptionEntries(user, Collections.singletonList(subscription), olderThan, insertedBefore, + entryKeywords); } return Response.ok().build(); } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/resource/fever/FeverREST.java b/commafeed-server/src/main/java/com/commafeed/frontend/resource/fever/FeverREST.java index 0eb64fed..622fa70a 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/resource/fever/FeverREST.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/resource/fever/FeverREST.java @@ -189,8 +189,8 @@ public class FeverREST { if (params.containsKey("mark") && params.containsKey("id") && params.containsKey("as")) { long id = Long.parseLong(params.get("id")); String before = params.get("before"); - Date olderThan = before == null ? null : Date.from(Instant.ofEpochSecond(Long.parseLong(before))); - mark(user, params.get("mark"), id, params.get("as"), olderThan); + Date insertedBefore = before == null ? null : Date.from(Instant.ofEpochSecond(Long.parseLong(before))); + mark(user, params.get("mark"), id, params.get("as"), insertedBefore); } return resp; @@ -306,7 +306,7 @@ public class FeverREST { }).toList(); } - private void mark(User user, String source, long id, String action, Date olderThan) { + private void mark(User user, String source, long id, String action, Date insertedBefore) { if ("item".equals(source)) { if ("read".equals(action) || "unread".equals(action)) { feedEntryService.markEntry(user, id, "read".equals(action)); @@ -317,12 +317,12 @@ public class FeverREST { } } else if ("feed".equals(source)) { FeedSubscription subscription = feedSubscriptionDAO.findById(user, id); - feedEntryService.markSubscriptionEntries(user, Collections.singletonList(subscription), olderThan, null); + feedEntryService.markSubscriptionEntries(user, Collections.singletonList(subscription), null, insertedBefore, null); } else if ("group".equals(source)) { FeedCategory parent = feedCategoryDAO.findById(user, id); List categories = feedCategoryDAO.findAllChildrenCategories(user, parent); List subscriptions = feedSubscriptionDAO.findByCategories(user, categories); - feedEntryService.markSubscriptionEntries(user, subscriptions, olderThan, null); + feedEntryService.markSubscriptionEntries(user, subscriptions, null, insertedBefore, null); } }