feat(entry-content): integrate AI translation support in EntryContent component

This commit is contained in:
DIYgod 2025-12-15 12:55:44 +08:00
parent b422034df9
commit 899eb7309f
No known key found for this signature in database
1 changed files with 32 additions and 2 deletions

View File

@ -8,6 +8,7 @@ import { useFeedById } from "@follow/store/feed/hooks"
import type { FeedModel } from "@follow/store/feed/types"
import { useIsInbox } from "@follow/store/inbox/hooks"
import { useSubscriptionByFeedId } from "@follow/store/subscription/hooks"
import { useEntryTranslation } from "@follow/store/translation/hooks"
import { thenable } from "@follow/utils"
import { stopPropagation } from "@follow/utils/dom"
import { EventBus } from "@follow/utils/event-bus"
@ -17,7 +18,9 @@ import { useAnimationControls } from "motion/react"
import * as React from "react"
import { memo, useEffect, useRef, useState } from "react"
import { useShowAITranslation } from "~/atoms/ai-translation"
import { useEntryIsInReadability } from "~/atoms/readability"
import { useActionLanguage } from "~/atoms/settings/general"
import { AppErrorBoundary } from "~/components/common/AppErrorBoundary"
import { Focusable } from "~/components/common/Focusable"
import { m } from "~/components/common/Motion"
@ -40,6 +43,7 @@ import { EntryScrollingAndNavigationHandler } from "./components/entry-content/E
import { EntryTitleMetaHandler } from "./components/entry-content/EntryTitleMetaHandler"
import type { EntryContentProps } from "./components/entry-content/types"
import { getEntryContentLayout } from "./components/layouts"
import type { EntryLayoutProps } from "./components/layouts/types"
import { SourceContentPanel } from "./components/SourceContentView"
import { useEntryContent } from "./hooks"
@ -71,6 +75,13 @@ const EntryContentImpl: Component<EntryContentProps> = ({
const isInReadabilityMode = useEntryIsInReadability(entryId)
const { error, content, isPending } = useEntryContent(entryId)
const enableTranslation = useShowAITranslation()
const actionLanguage = useActionLanguage()
const entryTranslation = useEntryTranslation({
entryId,
language: actionLanguage,
enabled: enableTranslation,
})
const routeView = useRouteParamsSelector((route) => route.view)
const subscriptionView = subscription?.view
@ -133,6 +144,16 @@ const EntryContentImpl: Component<EntryContentProps> = ({
}, [scrollerRef])
const scrollerRefObject = React.useMemo(() => ({ current: scrollerRef }), [scrollerRef])
const layoutTranslation = React.useMemo(
() =>
entryTranslation
? {
content: entryTranslation.content ?? undefined,
title: entryTranslation.title ?? undefined,
}
: undefined,
[entryTranslation?.content, entryTranslation?.title],
)
return (
<div className={cn(className, "flex flex-col @container")}>
<EntryTitleMetaHandler entryId={entryId} />
@ -219,6 +240,7 @@ const EntryContentImpl: Component<EntryContentProps> = ({
view={view}
compact={compact}
noMedia={noMedia}
translation={layoutTranslation}
/>
)}
</article>
@ -269,8 +291,16 @@ const AdaptiveContentRenderer: React.FC<{
view: FeedViewType
compact?: boolean
noMedia?: boolean
}> = ({ entryId, view, compact = false, noMedia = false }) => {
translation?: EntryLayoutProps["translation"]
}> = ({ entryId, view, compact = false, noMedia = false, translation }) => {
const LayoutComponent = getEntryContentLayout(view)
return <LayoutComponent entryId={entryId} compact={compact} noMedia={noMedia} />
return (
<LayoutComponent
entryId={entryId}
compact={compact}
noMedia={noMedia}
translation={translation}
/>
)
}