fix: discover search update
Signed-off-by: Innei <i@innei.in>
This commit is contained in:
parent
3608bfb66e
commit
baaa7cd90b
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<AnimatePresence mode="popLayout">
|
||||
<AppLayoutGridContainerProvider>
|
||||
<EntryGridContainer showEntryContent={showEntryContent} wideMode={wideMode}>
|
||||
{wideMode && (
|
||||
// Close button
|
||||
<ActionButton
|
||||
className={cn(
|
||||
"absolute left-3 top-3 z-10 duration-200",
|
||||
shouldHeaderPaddingLeft
|
||||
? "left-[calc(theme(width.3)+theme(width.feed-col))]"
|
||||
: "left-3",
|
||||
)}
|
||||
tooltip="Close"
|
||||
shortcut="Escape"
|
||||
disableTriggerShortcut
|
||||
onClick={() => navigate({ entryId: null })}
|
||||
>
|
||||
<i className="i-mgc-close-cute-re size-5" />
|
||||
</ActionButton>
|
||||
)}
|
||||
<AppLayoutGridContainerProvider>
|
||||
<EntryGridContainer showEntryContent={showEntryContent} wideMode={wideMode}>
|
||||
{wideMode && (
|
||||
// Close button
|
||||
<ActionButton
|
||||
className={cn(
|
||||
"absolute left-3 top-3 z-10 duration-200",
|
||||
shouldHeaderPaddingLeft
|
||||
? "left-[calc(theme(width.3)+theme(width.feed-col))]"
|
||||
: "left-3",
|
||||
)}
|
||||
tooltip="Close"
|
||||
shortcut="Escape"
|
||||
disableTriggerShortcut
|
||||
onClick={() => navigate({ entryId: null })}
|
||||
>
|
||||
<i className="i-mgc-close-cute-re size-5" />
|
||||
</ActionButton>
|
||||
)}
|
||||
|
||||
<EntryContent
|
||||
entryId={realEntryId}
|
||||
classNames={{
|
||||
header: shouldHeaderPaddingLeft
|
||||
? "ml-[calc(theme(width.feed-col)+theme(width.8))]"
|
||||
: wideMode
|
||||
? "ml-8"
|
||||
: "",
|
||||
}}
|
||||
/>
|
||||
</EntryGridContainer>
|
||||
</AppLayoutGridContainerProvider>
|
||||
</AnimatePresence>
|
||||
<EntryContent
|
||||
entryId={realEntryId}
|
||||
classNames={{
|
||||
header: shouldHeaderPaddingLeft
|
||||
? "ml-[calc(theme(width.feed-col)+theme(width.8))]"
|
||||
: wideMode
|
||||
? "ml-8"
|
||||
: "",
|
||||
}}
|
||||
/>
|
||||
</EntryGridContainer>
|
||||
</AppLayoutGridContainerProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,4 @@ export const AppLayoutGridContainerProvider: FC<PropsWithChildren> = ({ children
|
|||
)
|
||||
}
|
||||
|
||||
export const useAppLayoutGridContainerWidth = () => {
|
||||
const width = useContext(AppLayoutGridContainerWidthContext)
|
||||
return width
|
||||
}
|
||||
export const useAppLayoutGridContainerWidth = () => useContext(AppLayoutGridContainerWidthContext)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ interface SubscriptionState {
|
|||
* Value: Record<string, boolean>
|
||||
*/
|
||||
categoryOpenStateByView: Record<FeedViewType, Record<string, boolean>>
|
||||
/**
|
||||
* Store the subscription ids that current user followed.
|
||||
*/
|
||||
subscriptionIdSet: Set<string>
|
||||
}
|
||||
|
||||
function morphResponseData(data: SubscriptionModel[]): SubscriptionFlatModel[] {
|
||||
|
|
@ -86,6 +90,7 @@ export const useSubscriptionStore = createZustandStore<SubscriptionState>("subsc
|
|||
data: {},
|
||||
feedIdByView: { ...emptyDataIdByView },
|
||||
categoryOpenStateByView: { ...emptyCategoryOpenStateByView },
|
||||
subscriptionIdSet: new Set<string>(),
|
||||
}))
|
||||
|
||||
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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue