mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Add scroll to bottom button
This commit is contained in:
@@ -2,19 +2,20 @@ import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
||||||
import { useEvent, useMount } from "react-use"
|
import { useEvent, useMount } from "react-use"
|
||||||
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso"
|
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso"
|
||||||
|
import styled from "styled-components"
|
||||||
import { ClaudeAsk, ClaudeSayTool, ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
|
import { ClaudeAsk, ClaudeSayTool, ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
|
||||||
|
import { findLast } from "../../../../src/shared/array"
|
||||||
import { combineApiRequests } from "../../../../src/shared/combineApiRequests"
|
import { combineApiRequests } from "../../../../src/shared/combineApiRequests"
|
||||||
import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences"
|
import { combineCommandSequences } from "../../../../src/shared/combineCommandSequences"
|
||||||
import { getApiMetrics } from "../../../../src/shared/getApiMetrics"
|
import { getApiMetrics } from "../../../../src/shared/getApiMetrics"
|
||||||
import { useExtensionState } from "../../context/ExtensionStateContext"
|
import { useExtensionState } from "../../context/ExtensionStateContext"
|
||||||
import { vscode } from "../../utils/vscode"
|
import { vscode } from "../../utils/vscode"
|
||||||
import Announcement from "./Announcement"
|
import HistoryPreview from "../history/HistoryPreview"
|
||||||
import { normalizeApiConfiguration } from "../settings/ApiOptions"
|
import { normalizeApiConfiguration } from "../settings/ApiOptions"
|
||||||
|
import Announcement from "./Announcement"
|
||||||
import ChatRow from "./ChatRow"
|
import ChatRow from "./ChatRow"
|
||||||
import ChatTextArea from "./ChatTextArea"
|
import ChatTextArea from "./ChatTextArea"
|
||||||
import HistoryPreview from "../history/HistoryPreview"
|
|
||||||
import TaskHeader from "./TaskHeader"
|
import TaskHeader from "./TaskHeader"
|
||||||
import { findLast } from "../../../../src/shared/array"
|
|
||||||
|
|
||||||
interface ChatViewProps {
|
interface ChatViewProps {
|
||||||
isHidden: boolean
|
isHidden: boolean
|
||||||
@@ -41,7 +42,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
|
|
||||||
// we need to hold on to the ask because useEffect > lastMessage will always let us know when an ask comes in and handle it, but by the time handleMessage is called, the last message might not be the ask anymore (it could be a say that followed)
|
// we need to hold on to the ask because useEffect > lastMessage will always let us know when an ask comes in and handle it, but by the time handleMessage is called, the last message might not be the ask anymore (it could be a say that followed)
|
||||||
const [claudeAsk, setClaudeAsk] = useState<ClaudeAsk | undefined>(undefined)
|
const [claudeAsk, setClaudeAsk] = useState<ClaudeAsk | undefined>(undefined)
|
||||||
|
const [showScrollToBottom, setShowScrollToBottom] = useState(false)
|
||||||
const [enableButtons, setEnableButtons] = useState<boolean>(false)
|
const [enableButtons, setEnableButtons] = useState<boolean>(false)
|
||||||
const [primaryButtonText, setPrimaryButtonText] = useState<string | undefined>(undefined)
|
const [primaryButtonText, setPrimaryButtonText] = useState<string | undefined>(undefined)
|
||||||
const [secondaryButtonText, setSecondaryButtonText] = useState<string | undefined>(undefined)
|
const [secondaryButtonText, setSecondaryButtonText] = useState<string | undefined>(undefined)
|
||||||
@@ -494,6 +495,15 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
[expandedRows, modifiedMessages, visibleMessages.length, toggleRowExpansion]
|
[expandedRows, modifiedMessages, visibleMessages.length, toggleRowExpansion]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleScroll = useCallback<React.UIEventHandler<HTMLDivElement>>((event) => {
|
||||||
|
const scroller = event.currentTarget
|
||||||
|
const scrollTop = scroller.scrollTop
|
||||||
|
const scrollHeight = scroller.scrollHeight
|
||||||
|
const clientHeight = scroller.clientHeight
|
||||||
|
const scrollToBottomThreshold = 600
|
||||||
|
setShowScrollToBottom(scrollHeight - scrollTop - clientHeight > scrollToBottomThreshold)
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -565,7 +575,22 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
itemContent={itemContent}
|
itemContent={itemContent}
|
||||||
atBottomStateChange={setIsAtBottom}
|
atBottomStateChange={setIsAtBottom}
|
||||||
atBottomThreshold={100}
|
atBottomThreshold={100}
|
||||||
|
onScroll={handleScroll}
|
||||||
/>
|
/>
|
||||||
|
{showScrollToBottom ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
padding: "10px 15px 0px 15px",
|
||||||
|
}}>
|
||||||
|
<ScrollToBottomButton
|
||||||
|
onClick={() =>
|
||||||
|
virtuosoRef.current?.scrollTo({ top: Number.MAX_SAFE_INTEGER, behavior: "smooth" })
|
||||||
|
}>
|
||||||
|
<span className="codicon codicon-chevron-down" style={{ fontSize: "18px" }}></span>
|
||||||
|
</ScrollToBottomButton>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
opacity:
|
opacity:
|
||||||
@@ -602,6 +627,7 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
</VSCodeButton>
|
</VSCodeButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<ChatTextArea
|
<ChatTextArea
|
||||||
@@ -626,4 +652,24 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ScrollToBottomButton = styled.div`
|
||||||
|
background-color: color-mix(in srgb, var(--vscode-toolbar-hoverBackground) 55%, transparent);
|
||||||
|
border-radius: 3px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
height: 25px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: color-mix(in srgb, var(--vscode-toolbar-hoverBackground) 90%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: color-mix(in srgb, var(--vscode-toolbar-hoverBackground) 70%, transparent);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export default ChatView
|
export default ChatView
|
||||||
|
|||||||
Reference in New Issue
Block a user