diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIChatRoot.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIChatRoot.tsx index 636c8c438..7a8a55b84 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIChatRoot.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/AIChatRoot.tsx @@ -1,3 +1,4 @@ +import { atom } from "jotai" import type { FC, PropsWithChildren } from "react" import { useEffect, useMemo, useRef } from "react" @@ -5,7 +6,11 @@ import { Focusable } from "~/components/common/Focusable" import { HotkeyScope } from "~/constants" import type { AIPanelRefs } from "../../store/AIChatContext" -import { AIChatStoreContext, AIPanelRefsContext } from "../../store/AIChatContext" +import { + AIChatStoreContext, + AIPanelRefsContext, + AIRootStateContext, +} from "../../store/AIChatContext" import { ChatSliceActions } from "../../store/chat-core/chat-actions" import { useChatActions, useCurrentChatId } from "../../store/hooks" import { createAIChatStore } from "../../store/store" @@ -58,7 +63,16 @@ export const AIChatRoot: FC = ({ const Element = ( - {children} + ({ + isScrolledBeyondThreshold: atom(false), + }), + [], + )} + > + {children} + ) diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx index e5bc2a3da..c881affca 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/components/layouts/ChatHeader.tsx @@ -1,11 +1,13 @@ import { ActionButton } from "@follow/components/ui/button/index.js" import { cn } from "@follow/utils" +import { useAtomValue } from "jotai" import type { ReactNode } from "react" import { useCallback } from "react" import { AIChatPanelStyle, setAIPanelVisibility, useAIChatPanelStyle } from "~/atoms/settings/ai" import { useBlockActions, useChatActions, useCurrentTitle } from "~/modules/ai-chat/store/hooks" +import { useAIRootState } from "../../store/AIChatContext" import { ChatMoreDropdown } from "./ChatMoreDropdown" import { EditableTitle } from "./EditableTitle" import { TaskReportDropdown } from "./TaskReportDropdown" @@ -43,8 +45,17 @@ const ChatHeaderLayout = ({ const isFloating = useAIChatPanelStyle() === AIChatPanelStyle.Floating + const { isScrolledBeyondThreshold } = useAIRootState() + const isScrolledBeyondThresholdValue = useAtomValue(isScrolledBeyondThreshold) + return ( -
+
{isFloating && (
{ const shouldShowScrollToBottom = hasMessages && !isAtBottom && !isLoadingHistory + const { isScrolledBeyondThreshold } = useAIRootState() + const setIsScrolledBeyondThreshold = useSetAtom(isScrolledBeyondThreshold) + const handleScroll = useCallback( + (event: React.UIEvent) => { + const { scrollTop } = event.currentTarget + setIsScrolledBeyondThreshold(scrollTop > SCROLLED_BEYOND_THRESHOLD) + }, + [setIsScrolledBeyondThreshold], + ) return (
@@ -234,6 +246,7 @@ const ChatInterfaceContent = ({ centerInputOnEmpty }: ChatInterfaceProps) => { ) : ( <> shortcut.enabled) || [] + const { isScrolledBeyondThreshold } = useAIRootState() + const setIsScrolledBeyondThreshold = useSetAtom(isScrolledBeyondThreshold) + const handleScroll = useCallback( + (event: React.UIEvent) => { + const { scrollTop } = event.currentTarget + setIsScrolledBeyondThreshold(scrollTop > SCROLLED_BEYOND_THRESHOLD) + }, + [setIsScrolledBeyondThreshold], + ) return (
{/* Header Section - Always Present */} diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/constants/index.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/constants/index.ts new file mode 100644 index 000000000..e3b6e31f7 --- /dev/null +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/constants/index.ts @@ -0,0 +1 @@ +export const SCROLLED_BEYOND_THRESHOLD = 100 diff --git a/apps/desktop/layer/renderer/src/modules/ai-chat/store/AIChatContext.ts b/apps/desktop/layer/renderer/src/modules/ai-chat/store/AIChatContext.ts index 39e51d9f3..03181c769 100644 --- a/apps/desktop/layer/renderer/src/modules/ai-chat/store/AIChatContext.ts +++ b/apps/desktop/layer/renderer/src/modules/ai-chat/store/AIChatContext.ts @@ -1,3 +1,4 @@ +import type { PrimitiveAtom } from "jotai" import { createContext, use } from "react" import type { StoreApi } from "zustand" import type { UseBoundStoreWithEqualityFn } from "zustand/traditional" @@ -22,3 +23,17 @@ export const useAIChatStore = () => { } return store } + +export type AIRootStateContext = { + isScrolledBeyondThreshold: PrimitiveAtom +} + +export const AIRootStateContext = createContext(null!) + +export const useAIRootState = () => { + const context = use(AIRootStateContext) + if (!context) { + throw new Error("useAIRootState must be used within a AIRootStateContext") + } + return context +}