From baaa7cd90b8c19aeef58642da9879e5faffbf9fe Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 11 Oct 2024 21:29:41 +0800 Subject: [PATCH] fix: discover search update Signed-off-by: Innei --- apps/renderer/src/modules/discover/form.tsx | 12 +++- .../feeds/[feedId]/[entryId]/index.tsx | 66 +++++++++---------- .../app-grid-layout-container-provider.tsx | 5 +- apps/renderer/src/store/subscription/hooks.ts | 12 +++- apps/renderer/src/store/subscription/store.ts | 52 ++++++++++----- 5 files changed, 86 insertions(+), 61 deletions(-) diff --git a/apps/renderer/src/modules/discover/form.tsx b/apps/renderer/src/modules/discover/form.tsx index 03bc97832..bff4bd376 100644 --- a/apps/renderer/src/modules/discover/form.tsx +++ b/apps/renderer/src/modules/discover/form.tsx @@ -145,9 +145,15 @@ export function DiscoverForm({ type = "search" }: { type?: string }) { jotaiStore.set( discoverSearchDataAtom, produce(currentData, (draft) => { - const sub = draft.find( - (i) => i.feed?.id === item.feed?.id || i.list?.id === item.list?.id, - ) + const sub = draft.find((i) => { + if (item.feed) { + return i.feed?.id === item.feed.id + } + if (item.list) { + return i.list?.id === item.list.id + } + return false + }) if (!sub) return sub.isSubscribed = true sub.subscriptionCount = -~(sub.subscriptionCount as number) diff --git a/apps/renderer/src/pages/(main)/(layer)/feeds/[feedId]/[entryId]/index.tsx b/apps/renderer/src/pages/(main)/(layer)/feeds/[feedId]/[entryId]/index.tsx index f912f40fc..36c9dc575 100644 --- a/apps/renderer/src/pages/(main)/(layer)/feeds/[feedId]/[entryId]/index.tsx +++ b/apps/renderer/src/pages/(main)/(layer)/feeds/[feedId]/[entryId]/index.tsx @@ -1,5 +1,5 @@ import { useWheel } from "@use-gesture/react" -import { AnimatePresence, easeOut } from "framer-motion" +import { easeOut } from "framer-motion" import type { FC, PropsWithChildren } from "react" import { useState } from "react" import { useHotkeys } from "react-hotkeys-hook" @@ -48,40 +48,38 @@ export const Component = () => { } return ( - - - - {wideMode && ( - // Close button - navigate({ entryId: null })} - > - - - )} + + + {wideMode && ( + // Close button + navigate({ entryId: null })} + > + + + )} - - - - + + + ) } diff --git a/apps/renderer/src/providers/app-grid-layout-container-provider.tsx b/apps/renderer/src/providers/app-grid-layout-container-provider.tsx index 3e1a9472c..295d1ca22 100644 --- a/apps/renderer/src/providers/app-grid-layout-container-provider.tsx +++ b/apps/renderer/src/providers/app-grid-layout-container-provider.tsx @@ -35,7 +35,4 @@ export const AppLayoutGridContainerProvider: FC = ({ children ) } -export const useAppLayoutGridContainerWidth = () => { - const width = useContext(AppLayoutGridContainerWidthContext) - return width -} +export const useAppLayoutGridContainerWidth = () => useContext(AppLayoutGridContainerWidthContext) diff --git a/apps/renderer/src/store/subscription/hooks.ts b/apps/renderer/src/store/subscription/hooks.ts index 759046e80..748fee22e 100644 --- a/apps/renderer/src/store/subscription/hooks.ts +++ b/apps/renderer/src/store/subscription/hooks.ts @@ -42,7 +42,11 @@ export const useFolderFeedsByFeedId = ({ feedId, view }: { feedId?: string; view }) export const useListSubscriptionCount = () => - useSubscriptionStore((state) => Object.values(state.data).filter((s) => !!s.listId).length) + useSubscriptionStore( + (state) => + Object.values(state.data).filter((s) => !!s.listId && state.subscriptionIdSet.has(s.listId)) + .length, + ) export const useInboxSubscriptionCount = () => useSubscriptionStore( @@ -55,6 +59,8 @@ export const useInboxSubscriptionCount = () => export const useFeedSubscriptionCount = () => useSubscriptionStore( (state) => - // FIXME: Backend data compatibility - Object.values(state.data).filter((s) => !!s.feedId && !s.listId && !s.inboxId).length, + Object.values(state.data).filter( + // FIXME: Backend data compatibility + (s) => !!s.feedId && !s.listId && !s.inboxId && state.subscriptionIdSet.has(s.feedId), + ).length, ) diff --git a/apps/renderer/src/store/subscription/store.ts b/apps/renderer/src/store/subscription/store.ts index 9cc45f916..508c4cc6e 100644 --- a/apps/renderer/src/store/subscription/store.ts +++ b/apps/renderer/src/store/subscription/store.ts @@ -40,6 +40,10 @@ interface SubscriptionState { * Value: Record */ categoryOpenStateByView: Record> + /** + * Store the subscription ids that current user followed. + */ + subscriptionIdSet: Set } function morphResponseData(data: SubscriptionModel[]): SubscriptionFlatModel[] { @@ -86,6 +90,7 @@ export const useSubscriptionStore = createZustandStore("subsc data: {}, feedIdByView: { ...emptyDataIdByView }, categoryOpenStateByView: { ...emptyCategoryOpenStateByView }, + subscriptionIdSet: new Set(), })) const set = useSubscriptionStore.setState @@ -96,8 +101,24 @@ type MarkReadFilter = { startTime: number endTime: number } - +let subscribeOnce = false class SubscriptionActions { + constructor() { + if (subscribeOnce) return + subscribeOnce = true + // autorun + useSubscriptionStore.subscribe((next, prev) => { + if (next.feedIdByView !== prev.feedIdByView) { + const allSubscriptionIds = Object.values(next.feedIdByView).flat() + set((state) => { + return { + ...state, + subscriptionIdSet: new Set(allSubscriptionIds), + } + }) + } + }) + } async fetchByView(view?: FeedViewType) { const res = await apiClient.subscriptions.$get({ query: { @@ -287,22 +308,19 @@ class SubscriptionActions { }, }), async () => { - set((state) => - produce(state, (state) => { - Object.keys(state.data).forEach((id) => { - if (idSet.has(id)) { - const subscription = state.data[id] - const feed = getFeedById(subscription.feedId) - if (!feed || feed.type !== "feed") return - const { siteUrl } = feed - if (!siteUrl) return - const parsed = parse(siteUrl) - subscription.category = null - // The logic for removing Category here is to use domain as the default category name. - parsed.domain && - (subscription.defaultCategory = capitalizeFirstLetter(parsed.domain)) - } - }) + immerSet((state) => + Object.keys(state.data).forEach((id) => { + if (idSet.has(id)) { + const subscription = state.data[id] + const feed = getFeedById(subscription.feedId) + if (!feed || feed.type !== "feed") return + const { siteUrl } = feed + if (!siteUrl) return + const parsed = parse(siteUrl) + subscription.category = null + // The logic for removing Category here is to use domain as the default category name. + parsed.domain && (subscription.defaultCategory = capitalizeFirstLetter(parsed.domain)) + } }), ) const { data } = get()