Skip to content

Commit

Permalink
fix: improve perform for feed column (#1708)
Browse files Browse the repository at this point in the history
  • Loading branch information
lawvs authored Nov 22, 2024
1 parent 0f32364 commit 1f349ed
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 158 deletions.
217 changes: 115 additions & 102 deletions apps/renderer/src/hooks/biz/useEntryActions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FeedViewType } from "@follow/constants"
import { useCallback } from "react"
import { useCallback, useMemo } from "react"

import {
getReadabilityStatus,
Expand Down Expand Up @@ -72,107 +72,120 @@ export const useEntryActions = ({ entryId, view }: { entryId: string; view?: Fee
const isShowSourceContent = useShowSourceContent()
const getCmd = useGetCommand()
const runCmdFn = useRunCommandFn()
if (!entryId) return []
const actionConfigs = [
{
id: COMMAND_ID.integration.saveToEagle,
onClick: runCmdFn(COMMAND_ID.integration.saveToEagle, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToReadwise,
onClick: runCmdFn(COMMAND_ID.integration.saveToReadwise, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToInstapaper,
onClick: runCmdFn(COMMAND_ID.integration.saveToInstapaper, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToOmnivore,
onClick: runCmdFn(COMMAND_ID.integration.saveToOmnivore, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToObsidian,
onClick: runCmdFn(COMMAND_ID.integration.saveToObsidian, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToOutline,
onClick: runCmdFn(COMMAND_ID.integration.saveToOutline, [{ entryId }]),
},
{
id: COMMAND_ID.entry.tip,
onClick: runCmdFn(COMMAND_ID.entry.tip, [{ entryId, feedId: feed?.id }]),
hide: isInbox || feed?.ownerUserId === whoami()?.id,
shortcut: shortcuts.entry.tip.key,
},
{
id: COMMAND_ID.entry.unstar,
onClick: runCmdFn(COMMAND_ID.entry.unstar, [{ entryId }]),
hide: !entry?.collections,
shortcut: shortcuts.entry.toggleStarred.key,
},
{
id: COMMAND_ID.entry.star,
onClick: runCmdFn(COMMAND_ID.entry.star, [{ entryId, view }]),
hide: !!entry?.collections,
shortcut: shortcuts.entry.toggleStarred.key,
},
{
id: COMMAND_ID.entry.delete,
onClick: runCmdFn(COMMAND_ID.entry.delete, [{ entryId }]),
hide: !isInbox,
shortcut: shortcuts.entry.copyLink.key,
},
{
id: COMMAND_ID.entry.copyLink,
onClick: runCmdFn(COMMAND_ID.entry.copyLink, [{ entryId }]),
hide: !entry?.entries.url,
shortcut: shortcuts.entry.copyTitle.key,
},
{
id: COMMAND_ID.entry.openInBrowser,
onClick: runCmdFn(COMMAND_ID.entry.openInBrowser, [{ entryId }]),
},
{
id: COMMAND_ID.entry.viewSourceContent,
onClick: runCmdFn(COMMAND_ID.entry.viewSourceContent, [{ entryId }]),
hide: isShowSourceContent || !entry?.entries.url,
},
{
id: COMMAND_ID.entry.viewEntryContent,
onClick: runCmdFn(COMMAND_ID.entry.viewEntryContent, []),
hide: !isShowSourceContent,
active: true,
},
{
id: COMMAND_ID.entry.share,
onClick: runCmdFn(COMMAND_ID.entry.share, [{ entryId }]),
hide: !entry?.entries.url || !("share" in navigator),
shortcut: shortcuts.entry.share.key,
},
{
id: COMMAND_ID.entry.read,
onClick: runCmdFn(COMMAND_ID.entry.read, [{ entryId }]),
hide: !entry || !!entry.read || !!entry.collections || !!inList,
shortcut: shortcuts.entry.toggleRead.key,
},
{
id: COMMAND_ID.entry.unread,
onClick: runCmdFn(COMMAND_ID.entry.unread, [{ entryId }]),
hide: !entry || !entry.read || !!entry.collections || !!inList,
shortcut: shortcuts.entry.toggleRead.key,
},
]
.filter((config) => !config.hide)
.map((config) => {
const cmd = getCmd(config.id)
if (!cmd) return null
return {
...config,
name: cmd.label.title,
icon: cmd.icon,
}
})
.filter((i) => i !== null)
const actionConfigs = useMemo(() => {
if (!entryId) return []
return [
{
id: COMMAND_ID.integration.saveToEagle,
onClick: runCmdFn(COMMAND_ID.integration.saveToEagle, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToReadwise,
onClick: runCmdFn(COMMAND_ID.integration.saveToReadwise, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToInstapaper,
onClick: runCmdFn(COMMAND_ID.integration.saveToInstapaper, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToOmnivore,
onClick: runCmdFn(COMMAND_ID.integration.saveToOmnivore, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToObsidian,
onClick: runCmdFn(COMMAND_ID.integration.saveToObsidian, [{ entryId }]),
},
{
id: COMMAND_ID.integration.saveToOutline,
onClick: runCmdFn(COMMAND_ID.integration.saveToOutline, [{ entryId }]),
},
{
id: COMMAND_ID.entry.tip,
onClick: runCmdFn(COMMAND_ID.entry.tip, [{ entryId, feedId: feed?.id }]),
hide: isInbox || feed?.ownerUserId === whoami()?.id,
shortcut: shortcuts.entry.tip.key,
},
{
id: COMMAND_ID.entry.unstar,
onClick: runCmdFn(COMMAND_ID.entry.unstar, [{ entryId }]),
hide: !entry?.collections,
shortcut: shortcuts.entry.toggleStarred.key,
},
{
id: COMMAND_ID.entry.star,
onClick: runCmdFn(COMMAND_ID.entry.star, [{ entryId, view }]),
hide: !!entry?.collections,
shortcut: shortcuts.entry.toggleStarred.key,
},
{
id: COMMAND_ID.entry.delete,
onClick: runCmdFn(COMMAND_ID.entry.delete, [{ entryId }]),
hide: !isInbox,
shortcut: shortcuts.entry.copyLink.key,
},
{
id: COMMAND_ID.entry.copyLink,
onClick: runCmdFn(COMMAND_ID.entry.copyLink, [{ entryId }]),
hide: !entry?.entries.url,
shortcut: shortcuts.entry.copyTitle.key,
},
{
id: COMMAND_ID.entry.openInBrowser,
onClick: runCmdFn(COMMAND_ID.entry.openInBrowser, [{ entryId }]),
},
{
id: COMMAND_ID.entry.viewSourceContent,
onClick: runCmdFn(COMMAND_ID.entry.viewSourceContent, [{ entryId }]),
hide: isShowSourceContent || !entry?.entries.url,
},
{
id: COMMAND_ID.entry.viewEntryContent,
onClick: runCmdFn(COMMAND_ID.entry.viewEntryContent, []),
hide: !isShowSourceContent,
active: true,
},
{
id: COMMAND_ID.entry.share,
onClick: runCmdFn(COMMAND_ID.entry.share, [{ entryId }]),
hide: !entry?.entries.url || !("share" in navigator),
shortcut: shortcuts.entry.share.key,
},
{
id: COMMAND_ID.entry.read,
onClick: runCmdFn(COMMAND_ID.entry.read, [{ entryId }]),
hide: !entry || !!entry.read || !!entry.collections || !!inList,
shortcut: shortcuts.entry.toggleRead.key,
},
{
id: COMMAND_ID.entry.unread,
onClick: runCmdFn(COMMAND_ID.entry.unread, [{ entryId }]),
hide: !entry || !entry.read || !!entry.collections || !!inList,
shortcut: shortcuts.entry.toggleRead.key,
},
]
.filter((config) => !config.hide)
.map((config) => {
const cmd = getCmd(config.id)
if (!cmd) return null
return {
...config,
name: cmd.label.title,
icon: cmd.icon,
}
})
.filter((i) => i !== null)
}, [
entry,
entryId,
feed?.id,
feed?.ownerUserId,
getCmd,
inList,
isInbox,
isShowSourceContent,
runCmdFn,
view,
])

return actionConfigs
}
39 changes: 6 additions & 33 deletions apps/renderer/src/hooks/biz/useFeedActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { env } from "@follow/shared/env"
import { UrlBuilder } from "@follow/utils/url-builder"
import { isBizId } from "@follow/utils/utils"
import { useMutation } from "@tanstack/react-query"
import { useMemo, useRef } from "react"
import { useMemo } from "react"
import { useTranslation } from "react-i18next"
import { toast } from "sonner"

Expand All @@ -19,7 +19,7 @@ import { FeedForm } from "~/modules/discover/feed-form"
import { InboxForm } from "~/modules/discover/inbox-form"
import { ListForm } from "~/modules/discover/list-form"
import { ListCreationModalContent } from "~/modules/settings/tabs/lists/modals"
import { entries } from "~/queries/entries"
import { useResetFeed } from "~/queries/feed"
import { getFeedById, useFeedById } from "~/store/feed"
import { useInboxById } from "~/store/inbox"
import { listActions, useListById, useOwnedListByView } from "~/store/list"
Expand Down Expand Up @@ -73,9 +73,7 @@ export const useFeedActions = ({
const subscription = useSubscriptionByFeedId(feedId)
const { present } = useModalStack()
const deleteSubscription = useDeleteSubscription({})
const claimFeed = useFeedClaimModal({
feedId,
})
const claimFeed = useFeedClaimModal()

const navigateEntry = useNavigateEntry()
const isEntryList = type === "entryList"
Expand Down Expand Up @@ -116,7 +114,7 @@ export const useFeedActions = ({
: t("sidebar.feed_actions.claim"),
shortcut: "C",
click: () => {
claimFeed()
claimFeed({ feedId })
},
},
...(isFeedOwner
Expand Down Expand Up @@ -331,7 +329,7 @@ export const useFeedActions = ({
view,
])

return { items }
return items
}

export const useListActions = ({ listId, view }: { listId: string; view: FeedViewType }) => {
Expand Down Expand Up @@ -424,7 +422,7 @@ export const useListActions = ({ listId, view }: { listId: string; view: FeedVie
return items
}, [list, t, present, deleteSubscription, subscription, navigateEntry, listId, view])

return { items }
return items
}

export const useInboxActions = ({ inboxId }: { inboxId: string }) => {
Expand Down Expand Up @@ -520,28 +518,3 @@ export const useRemoveFeedFromFeedList = (options?: {
},
})
}

export const useResetFeed = () => {
const { t } = useTranslation()
const toastIDRef = useRef<string | number | null>(null)

return useMutation({
mutationFn: async (feedId: string) => {
toastIDRef.current = toast.loading(t("sidebar.feed_actions.resetting_feed"))
await apiClient.feeds.reset.$get({ query: { id: feedId } })
},
onSuccess: (_, feedId) => {
entries.entries({ feedId }).invalidateRoot()
toast.success(
t("sidebar.feed_actions.reset_feed_success"),
toastIDRef.current ? { id: toastIDRef.current } : undefined,
)
},
onError: () => {
toast.error(
t("sidebar.feed_actions.reset_feed_error"),
toastIDRef.current ? { id: toastIDRef.current } : undefined,
)
},
})
}
23 changes: 13 additions & 10 deletions apps/renderer/src/modules/claim/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@ import { getFeedById } from "~/store/feed"

import { FeedClaimModalContent } from "./feed-claim-modal"

export const useFeedClaimModal = ({ feedId }: { feedId?: string }) => {
export const useFeedClaimModal = () => {
const { present } = useModalStack()
const { t } = useTranslation()

return useCallback(() => {
if (!feedId) return
return useCallback(
({ feedId }: { feedId?: string }) => {
if (!feedId) return

const feed = getFeedById(feedId)
const feed = getFeedById(feedId)

if (!feed) return
if (!feed) return

present({
title: t("feed_claim_modal.title"),
content: () => createElement(FeedClaimModalContent, { feedId }),
})
}, [feedId, present])
present({
title: t("feed_claim_modal.title"),
content: () => createElement(FeedClaimModalContent, { feedId }),
})
},
[present, t],
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const EntryItemWrapper: FC<
} & PropsWithChildren
> = ({ entry, view, children, itemClassName, style }) => {
const actionConfigs = useEntryActions({ entryId: entry.entries.id })
const { items: feedItems } = useFeedActions({
const feedItems = useFeedActions({
feedId: entry.feedId || entry.inboxId,
view,
type: "entryList",
Expand Down
3 changes: 2 additions & 1 deletion apps/renderer/src/modules/feed-column/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const setFeedListSortOrder = (order: FeedListSortOrder) => {
})
}

export const SELECT_NOTHING = []
export const [
,
useSelectedFeedIds,
Expand All @@ -43,7 +44,7 @@ export const [
getSelectedFeedIds,
setSelectedFeedIds,
useSelectedFeedIdsSelector,
] = createAtomHooks(atom<string[]>([]))
] = createAtomHooks(atom<string[]>(SELECT_NOTHING))

export const [, , useFeedAreaScrollProgressValue, , , setFeedAreaScrollProgressValue] =
createAtomHooks(atom(0))
2 changes: 1 addition & 1 deletion apps/renderer/src/modules/feed-column/category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ function FeedCategoryImpl({ data: ids, view, categoryOpenStateData }: FeedCatego
</div>
</div>
)}
<AnimatePresence>
<AnimatePresence initial={false}>
{open && (
<m.div
ref={itemsRef}
Expand Down
Loading

0 comments on commit 1f349ed

Please sign in to comment.