feat: add boost certification to feed list

This commit is contained in:
lawvs 2024-10-23 13:45:10 +08:00
parent af9d95b1da
commit 7001455920
5 changed files with 70 additions and 0 deletions

View File

@ -0,0 +1,46 @@
import { useTranslation } from "react-i18next"
import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger } from "~/components/ui/tooltip"
import { cn } from "~/lib/utils"
import type { FeedOrListRespModel } from "~/models"
import { useBoostModal, useIsFeedBoosted } from "./hooks"
export const BoostCertification = ({
feed,
className,
}: {
feed: FeedOrListRespModel
className?: string
}) => {
const showBoostModal = useBoostModal()
const { t } = useTranslation()
const isFeedBoosted = useIsFeedBoosted(feed.id)
if (!isFeedBoosted) return null
return (
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<i
className={cn(
"i-mgc-rocket-cute-fi ml-1.5 shrink-0 cursor-pointer text-amber-500 hover:bg-amber-400",
className,
)}
onClick={(e) => {
e.stopPropagation()
showBoostModal(feed.id)
}}
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent className="px-4 py-2">
<div className="flex items-center text-base">
<i className="i-mgc-rocket-cute-fi mr-2 shrink-0 text-amber-500" />
{t("boost.feed_being_boosted")}
</div>
</TooltipContent>
</TooltipPortal>
</Tooltip>
)
}

View File

@ -1,7 +1,9 @@
import { atom } from "jotai"
import { useCallback } from "react"
import { useAsyncModal } from "~/components/ui/modal/helper/use-async-modal"
import { useAuthQuery, useI18n } from "~/hooks/common"
import { createAtomHooks } from "~/lib/jotai"
import { boosts } from "~/queries/boosts"
import { BoostModalContent } from "./modal"
@ -27,3 +29,17 @@ export const useBoostModal = () => {
[present, t],
)
}
const [, , useFeedBoostMap, , getFeedBoostMap, setFeedBoostMap] = createAtomHooks(
atom<Record<string, boolean>>({}),
)
export const updateFeedBoostStatus = (feedId: string, isBoosted: boolean) => {
const prev = getFeedBoostMap()
setFeedBoostMap({ ...prev, [feedId]: isBoosted })
}
export const useIsFeedBoosted = (feedId: string) => {
const map = useFeedBoostMap()
return map[feedId] ?? false
}

View File

@ -24,6 +24,7 @@ import { useListById } from "~/store/list"
import { subscriptionActions, useSubscriptionByFeedId } from "~/store/subscription"
import { useFeedUnreadStore } from "~/store/unread"
import { BoostCertification } from "../boost/boost-certification"
import { feedColumnStyles } from "./styles"
import { UnreadNumber } from "./unread-number"
@ -122,6 +123,7 @@ const FeedItemImpl = ({ view, feedId, className }: FeedItemProps) => {
<FeedIcon fallback feed={feed} size={16} />
<div className="truncate">{getPreferredTitle(feed)}</div>
{isFeed && <FeedCertification feed={feed} className="text-[15px]" />}
{isFeed && <BoostCertification feed={feed} className="text-[15px]" />}
{isFeed && feed.errorAt && (
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>

View File

@ -9,6 +9,7 @@ import { apiClient } from "~/lib/api-fetch"
import { FeedViewType } from "~/lib/enum"
import { capitalizeFirstLetter } from "~/lib/utils"
import type { FeedModel, InboxModel, ListModelPoplutedFeeds, SubscriptionModel } from "~/models"
import { updateFeedBoostStatus } from "~/modules/boost/hooks"
import { SubscriptionService } from "~/services"
import { entryActions } from "../entry"
@ -173,6 +174,10 @@ class SubscriptionActions {
} else if ("inboxes" in subscription) {
inboxes.push(subscription.inboxes)
}
if ("boost" in subscription) {
updateFeedBoostStatus(subscription.feedId, subscription.boost.boosters.length > 0)
}
}
this.updateCategoryOpenState(transformedData.filter((s) => s.category || s.defaultCategory))
feedActions.upsertMany(feeds)

View File

@ -29,6 +29,7 @@
"app.toggle_sidebar": "Toggle Sidebar",
"beta_access": "Beta Access",
"boost.boost_feed": "Boost Feed",
"boost.feed_being_boosted": "Feed being boosted",
"discover.any_url_or_keyword": "Any URL or Keyword",
"discover.default_option": " (default)",
"discover.feed_description": "The description of this feed is as follows, and you can fill out the parameter form with the relevant information.",