From bdc17c0f127e209688ebb87f2b22db47b03f0126 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Wed, 20 Aug 2025 19:53:10 +0800 Subject: [PATCH] fix(subscription): deduplicate feed IDs when feeds exist in both subscriptions and lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, if a feed was both directly subscribed and existed in a subscribed list, it would appear twice in the subscription IDs array, causing unread counts to be doubled in SubscriptionTabButton. Fixed by using Set to deduplicate feed IDs in: - getSubscriptionIdsByViewSelector - getSubscribedFeedIdAndInboxHandlesByView 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../store/src/modules/subscription/getter.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/internal/store/src/modules/subscription/getter.ts b/packages/internal/store/src/modules/subscription/getter.ts index 3bf84de26..252610eac 100644 --- a/packages/internal/store/src/modules/subscription/getter.ts +++ b/packages/internal/store/src/modules/subscription/getter.ts @@ -38,16 +38,20 @@ export const getSubscribedFeedIdAndInboxHandlesByView = ({ }): string[] => { if (typeof view !== "number") return [] const state = useSubscriptionStore.getState() - return Array.from(state.feedIdByView[view]) + + const feedIds = Array.from(state.feedIdByView[view]) .filter((i) => !excludePrivate || !state.data[i]?.isPrivate) .filter((i) => !excludeHidden || !state.data[i]?.hideFromTimeline) - .concat(view === FeedViewType.Articles ? getInboxList().map((i) => i.id) : []) - .concat( - Array.from(state.listIdByView[view]) - .filter((i) => !excludePrivate || !state.data[i]?.isPrivate) - .filter((i) => !excludeHidden || !state.data[i]?.hideFromTimeline) - .flatMap((id) => getListFeedIds(id) ?? []), - ) + + const inboxIds = view === FeedViewType.Articles ? getInboxList().map((i) => i.id) : [] + + const listFeedIds = Array.from(state.listIdByView[view]) + .filter((i) => !excludePrivate || !state.data[i]?.isPrivate) + .filter((i) => !excludeHidden || !state.data[i]?.hideFromTimeline) + .flatMap((id) => getListFeedIds(id) ?? []) + + // Use Set to remove duplicates when feeds exist in both subscriptions and lists + return Array.from(new Set([...feedIds, ...inboxIds, ...listFeedIds])) } export const getSubscribedFeedIdsByView = (view: FeedViewType): string[] => { @@ -151,9 +155,12 @@ const sortGroupedSubscriptionByUnread = ( // Store selector functions (for React hooks) export const getSubscriptionIdsByViewSelector = (state: StateType) => (view: FeedViewType) => { - return Array.from(state.feedIdByView[view]) - .concat(view === FeedViewType.Articles ? getInboxList().map((i) => i.id) : []) - .concat(Array.from(state.listIdByView[view]).flatMap((id) => getListFeedIds(id) ?? [])) + const feedIds = Array.from(state.feedIdByView[view]) + const inboxIds = view === FeedViewType.Articles ? getInboxList().map((i) => i.id) : [] + const listFeedIds = Array.from(state.listIdByView[view]).flatMap((id) => getListFeedIds(id) ?? []) + + // Use Set to remove duplicates when feeds exist in both subscriptions and lists + return Array.from(new Set([...feedIds, ...inboxIds, ...listFeedIds])) } export const getFeedSubscriptionIdsByViewSelector =