feat: add boost certification to feed list
This commit is contained in:
parent
af9d95b1da
commit
7001455920
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.",
|
||||
|
|
|
|||
Loading…
Reference in New Issue