mirror of
https://github.com/cline/cline.git
synced 2025-06-03 03:59:07 +00:00
Cosmetic updates
This commit is contained in:
parent
ade506d1f8
commit
3a4e8b8d96
BIN
icons/icon.png
BIN
icons/icon.png
Binary file not shown.
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.6 KiB |
@ -5,7 +5,7 @@
|
|||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"icon": "icons/icon.png",
|
"icon": "icons/icon.png",
|
||||||
"galleryBanner": {
|
"galleryBanner": {
|
||||||
"color": "#C1DCEA",
|
"color": "#C7D1D9",
|
||||||
"theme": "light"
|
"theme": "light"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -330,6 +330,9 @@ export class TerminalProcess extends EventEmitter<TerminalProcessEvents> {
|
|||||||
data = lines.join("\n")
|
data = lines.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sometimes chunks have leading/trailing commas which we'll remove too
|
||||||
|
data = data.replace(/^,+|,+$/g, "")
|
||||||
|
|
||||||
// For non-immediately returning commands we want to show loading spinner right away but this wouldnt happen until it emits a line break, so as soon as we get any output we emit "" to let webview know to show spinner
|
// For non-immediately returning commands we want to show loading spinner right away but this wouldnt happen until it emits a line break, so as soon as we get any output we emit "" to let webview know to show spinner
|
||||||
if (!didEmitEmptyLine && !this.fullOutput && data) {
|
if (!didEmitEmptyLine && !this.fullOutput && data) {
|
||||||
this.emit("line", "") // empty line to indicate start of command output stream
|
this.emit("line", "") // empty line to indicate start of command output stream
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { VSCodeBadge, VSCodeButton, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react"
|
import { VSCodeBadge, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react"
|
||||||
import deepEqual from "fast-deep-equal"
|
import deepEqual from "fast-deep-equal"
|
||||||
import React, { memo, useMemo } from "react"
|
import React, { memo, useMemo } from "react"
|
||||||
import ReactMarkdown from "react-markdown"
|
import ReactMarkdown from "react-markdown"
|
||||||
@ -103,11 +103,11 @@ const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessa
|
|||||||
<ProgressIndicator />
|
<ProgressIndicator />
|
||||||
),
|
),
|
||||||
cost != null ? (
|
cost != null ? (
|
||||||
<span style={{ color: normalColor, fontWeight: "bold" }}>API Request Complete</span>
|
<span style={{ color: normalColor, fontWeight: "bold" }}>API Request</span>
|
||||||
) : apiRequestFailedMessage ? (
|
) : apiRequestFailedMessage ? (
|
||||||
<span style={{ color: errorColor, fontWeight: "bold" }}>API Request Failed</span>
|
<span style={{ color: errorColor, fontWeight: "bold" }}>API Request Failed</span>
|
||||||
) : (
|
) : (
|
||||||
<span style={{ color: normalColor, fontWeight: "bold" }}>Making API Request...</span>
|
<span style={{ color: normalColor, fontWeight: "bold" }}>API Request...</span>
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
case "followup":
|
case "followup":
|
||||||
@ -299,15 +299,19 @@ const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessa
|
|||||||
...headerStyle,
|
...headerStyle,
|
||||||
marginBottom: cost == null && apiRequestFailedMessage ? 10 : 0,
|
marginBottom: cost == null && apiRequestFailedMessage ? 10 : 0,
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
}}>
|
cursor: "pointer",
|
||||||
|
userSelect: "none",
|
||||||
|
WebkitUserSelect: "none",
|
||||||
|
MozUserSelect: "none",
|
||||||
|
msUserSelect: "none",
|
||||||
|
}}
|
||||||
|
onClick={onToggleExpand}>
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
<div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
||||||
{icon}
|
{icon}
|
||||||
{title}
|
{title}
|
||||||
{cost != null && cost > 0 && <VSCodeBadge>${Number(cost)?.toFixed(4)}</VSCodeBadge>}
|
{cost != null && cost > 0 && <VSCodeBadge>${Number(cost)?.toFixed(4)}</VSCodeBadge>}
|
||||||
</div>
|
</div>
|
||||||
<VSCodeButton appearance="icon" aria-label="Toggle Details" onClick={onToggleExpand}>
|
<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
|
||||||
<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
|
|
||||||
</VSCodeButton>
|
|
||||||
</div>
|
</div>
|
||||||
{cost == null && apiRequestFailedMessage && (
|
{cost == null && apiRequestFailedMessage && (
|
||||||
<>
|
<>
|
||||||
@ -391,24 +395,12 @@ const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessa
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "var(--vscode-editor-inactiveSelectionBackground)",
|
marginTop: -10,
|
||||||
borderRadius: "3px",
|
width: "100%",
|
||||||
padding: "8px",
|
|
||||||
whiteSpace: "pre-line",
|
|
||||||
wordWrap: "break-word",
|
|
||||||
}}>
|
}}>
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
display: "block",
|
|
||||||
fontStyle: "italic",
|
|
||||||
marginBottom: "8px",
|
|
||||||
opacity: 0.8,
|
|
||||||
}}>
|
|
||||||
The user made the following changes:
|
|
||||||
</span>
|
|
||||||
<CodeAccordian
|
<CodeAccordian
|
||||||
diff={tool.diff!}
|
diff={tool.diff!}
|
||||||
path={tool.path!}
|
isFeedback={true}
|
||||||
isExpanded={isExpanded}
|
isExpanded={isExpanded}
|
||||||
onToggleExpand={onToggleExpand}
|
onToggleExpand={onToggleExpand}
|
||||||
/>
|
/>
|
||||||
@ -627,7 +619,8 @@ const Markdown = memo(({ markdown }: { markdown?: string }) => {
|
|||||||
// react-markdown lets us customize elements, so here we're using their example of replacing code blocks with SyntaxHighlighter. However when there are no language matches (` or ``` without a language specifier) then we default to a normal code element for inline code. Code blocks without a language specifier shouldn't be a common occurrence as we prompt Claude to always use a language specifier.
|
// react-markdown lets us customize elements, so here we're using their example of replacing code blocks with SyntaxHighlighter. However when there are no language matches (` or ``` without a language specifier) then we default to a normal code element for inline code. Code blocks without a language specifier shouldn't be a common occurrence as we prompt Claude to always use a language specifier.
|
||||||
// when claude wraps text in thinking tags, he doesnt use line breaks so we need to insert those ourselves to render markdown correctly
|
// when claude wraps text in thinking tags, he doesnt use line breaks so we need to insert those ourselves to render markdown correctly
|
||||||
const parsed = markdown?.replace(/<thinking>([\s\S]*?)<\/thinking>/g, (match, content) => {
|
const parsed = markdown?.replace(/<thinking>([\s\S]*?)<\/thinking>/g, (match, content) => {
|
||||||
return `_<thinking>_\n\n${content}\n\n_</thinking>_`
|
return content
|
||||||
|
// return `_<thinking>_\n\n${content}\n\n_</thinking>_`
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div style={{ wordBreak: "break-word", overflowWrap: "anywhere" }}>
|
<div style={{ wordBreak: "break-word", overflowWrap: "anywhere" }}>
|
||||||
@ -704,6 +697,13 @@ const Markdown = memo(({ markdown }: { markdown?: string }) => {
|
|||||||
whiteSpace: "pre-line",
|
whiteSpace: "pre-line",
|
||||||
wordBreak: "break-word",
|
wordBreak: "break-word",
|
||||||
overflowWrap: "anywhere",
|
overflowWrap: "anywhere",
|
||||||
|
backgroundColor: "var(--vscode-textCodeBlock-background)",
|
||||||
|
color: "var(--vscode-textPreformat-foreground)",
|
||||||
|
fontFamily: "var(--vscode-editor-font-family)",
|
||||||
|
fontSize: "var(--vscode-editor-font-size)",
|
||||||
|
borderRadius: "3px",
|
||||||
|
border: "1px solid var(--vscode-textSeparator-foreground)",
|
||||||
|
// padding: "2px 4px",
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</code>
|
</code>
|
||||||
|
@ -602,11 +602,12 @@ const ChatView = ({ isHidden, showAnnouncement, hideAnnouncement, showHistoryVie
|
|||||||
// Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410)
|
// Since we have maxRows, when text is long enough it starts to overflow the bottom padding, appearing behind the thumbnails. To fix this, we use a transparent border to push the text up instead. (https://stackoverflow.com/questions/42631947/maintaining-a-padding-inside-of-text-area/52538410#52538410)
|
||||||
borderTop: "9px solid transparent",
|
borderTop: "9px solid transparent",
|
||||||
borderBottom: `${thumbnailsHeight + 9}px solid transparent`,
|
borderBottom: `${thumbnailsHeight + 9}px solid transparent`,
|
||||||
borderRight: "54px solid transparent",
|
borderColor: "transparent",
|
||||||
borderLeft: "9px solid transparent",
|
// borderRight: "54px solid transparent",
|
||||||
|
// borderLeft: "9px solid transparent", // NOTE: react-textarea-autosize doesn't calculate correct height when using borderLeft/borderRight so we need to use horizontal padding instead
|
||||||
// Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused
|
// Instead of using boxShadow, we use a div with a border to better replicate the behavior when the textarea is focused
|
||||||
// boxShadow: "0px 0px 0px 1px var(--vscode-input-border)",
|
// boxShadow: "0px 0px 0px 1px var(--vscode-input-border)",
|
||||||
padding: 0,
|
padding: "0 50px 0 9px",
|
||||||
cursor: textAreaDisabled ? "not-allowed" : undefined,
|
cursor: textAreaDisabled ? "not-allowed" : undefined,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
}}
|
}}
|
||||||
|
@ -7,6 +7,7 @@ interface CodeAccordianProps {
|
|||||||
diff?: string
|
diff?: string
|
||||||
language?: string | undefined
|
language?: string | undefined
|
||||||
path?: string
|
path?: string
|
||||||
|
isFeedback?: boolean
|
||||||
isExpanded: boolean
|
isExpanded: boolean
|
||||||
onToggleExpand: () => void
|
onToggleExpand: () => void
|
||||||
}
|
}
|
||||||
@ -19,7 +20,7 @@ The replace method removes these matched characters, effectively trimming the st
|
|||||||
*/
|
*/
|
||||||
const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
|
const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
|
||||||
|
|
||||||
const CodeAccordian = ({ code, diff, language, path, isExpanded, onToggleExpand }: CodeAccordianProps) => {
|
const CodeAccordian = ({ code, diff, language, path, isFeedback, isExpanded, onToggleExpand }: CodeAccordianProps) => {
|
||||||
const inferredLanguage = useMemo(
|
const inferredLanguage = useMemo(
|
||||||
() => code && (language ?? (path ? getLanguageFromPath(path) : undefined)),
|
() => code && (language ?? (path ? getLanguageFromPath(path) : undefined)),
|
||||||
[path, language, code]
|
[path, language, code]
|
||||||
@ -33,7 +34,7 @@ const CodeAccordian = ({ code, diff, language, path, isExpanded, onToggleExpand
|
|||||||
overflow: "hidden", // This ensures the inner scrollable area doesn't overflow the rounded corners
|
overflow: "hidden", // This ensures the inner scrollable area doesn't overflow the rounded corners
|
||||||
border: "1px solid var(--vscode-editorGroup-border)",
|
border: "1px solid var(--vscode-editorGroup-border)",
|
||||||
}}>
|
}}>
|
||||||
{path && (
|
{(path || isFeedback) && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
color: "var(--vscode-descriptionForeground)",
|
color: "var(--vscode-descriptionForeground)",
|
||||||
@ -42,25 +43,34 @@ const CodeAccordian = ({ code, diff, language, path, isExpanded, onToggleExpand
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
padding: "6px 10px",
|
padding: "6px 10px",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
|
userSelect: "none",
|
||||||
|
WebkitUserSelect: "none",
|
||||||
|
MozUserSelect: "none",
|
||||||
|
msUserSelect: "none",
|
||||||
}}
|
}}
|
||||||
onClick={onToggleExpand}>
|
onClick={onToggleExpand}>
|
||||||
<span
|
<div style={{ display: "flex", alignItems: "center" }}>
|
||||||
style={{
|
{isFeedback && (
|
||||||
whiteSpace: "nowrap",
|
<span className="codicon codicon-feedback" style={{ marginRight: "6px" }}></span>
|
||||||
overflow: "hidden",
|
)}
|
||||||
textOverflow: "ellipsis",
|
<span
|
||||||
marginRight: "8px",
|
style={{
|
||||||
fontSize: "11px",
|
whiteSpace: "nowrap",
|
||||||
// trick to get ellipsis at beginning of string
|
overflow: "hidden",
|
||||||
direction: "rtl",
|
textOverflow: "ellipsis",
|
||||||
textAlign: "left",
|
marginRight: "8px",
|
||||||
}}>
|
fontSize: "11px",
|
||||||
{removeLeadingNonAlphanumeric(path) + "\u200E"}
|
// trick to get ellipsis at beginning of string
|
||||||
</span>
|
direction: "rtl",
|
||||||
|
textAlign: "left",
|
||||||
|
}}>
|
||||||
|
{isFeedback ? "User Edits" : removeLeadingNonAlphanumeric(path ?? "") + "\u200E"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
|
<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(!path || isExpanded) && (
|
{(!(path || isFeedback) || isExpanded) && (
|
||||||
<div
|
<div
|
||||||
//className="code-block-scrollable" this doesn't seem to be necessary anymore, on silicon macs it shows the native mac scrollbar instead of the vscode styled one
|
//className="code-block-scrollable" this doesn't seem to be necessary anymore, on silicon macs it shows the native mac scrollbar instead of the vscode styled one
|
||||||
style={{
|
style={{
|
||||||
|
@ -28,7 +28,8 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
|
|||||||
onClose,
|
onClose,
|
||||||
}) => {
|
}) => {
|
||||||
const { apiConfiguration } = useExtensionState()
|
const { apiConfiguration } = useExtensionState()
|
||||||
const [isExpanded, setIsExpanded] = useState(false)
|
const [isTaskExpanded, setIsTaskExpanded] = useState(true)
|
||||||
|
const [isTextExpanded, setIsTextExpanded] = useState(false)
|
||||||
const [showSeeMore, setShowSeeMore] = useState(false)
|
const [showSeeMore, setShowSeeMore] = useState(false)
|
||||||
const textContainerRef = useRef<HTMLDivElement>(null)
|
const textContainerRef = useRef<HTMLDivElement>(null)
|
||||||
const textRef = useRef<HTMLDivElement>(null)
|
const textRef = useRef<HTMLDivElement>(null)
|
||||||
@ -68,11 +69,11 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
|
|||||||
const { height: windowHeight, width: windowWidth } = useWindowSize()
|
const { height: windowHeight, width: windowWidth } = useWindowSize()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isExpanded && textContainerRef.current) {
|
if (isTextExpanded && textContainerRef.current) {
|
||||||
const maxHeight = windowHeight * (1 / 2)
|
const maxHeight = windowHeight * (1 / 2)
|
||||||
textContainerRef.current.style.maxHeight = `${maxHeight}px`
|
textContainerRef.current.style.maxHeight = `${maxHeight}px`
|
||||||
}
|
}
|
||||||
}, [isExpanded, windowHeight])
|
}, [isTextExpanded, windowHeight])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (textRef.current && textContainerRef.current) {
|
if (textRef.current && textContainerRef.current) {
|
||||||
@ -83,7 +84,7 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
|
|||||||
const isOverflowing = textRef.current.scrollHeight > textContainerHeight
|
const isOverflowing = textRef.current.scrollHeight > textContainerHeight
|
||||||
// necessary to show see more button again if user resizes window to expand and then back to collapse
|
// necessary to show see more button again if user resizes window to expand and then back to collapse
|
||||||
if (!isOverflowing) {
|
if (!isOverflowing) {
|
||||||
setIsExpanded(false)
|
setIsTextExpanded(false)
|
||||||
}
|
}
|
||||||
setShowSeeMore(isOverflowing)
|
setShowSeeMore(isOverflowing)
|
||||||
}
|
}
|
||||||
@ -96,10 +97,10 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
|
|||||||
backgroundColor: "var(--vscode-badge-background)",
|
backgroundColor: "var(--vscode-badge-background)",
|
||||||
color: "var(--vscode-badge-foreground)",
|
color: "var(--vscode-badge-foreground)",
|
||||||
borderRadius: "3px",
|
borderRadius: "3px",
|
||||||
padding: "12px",
|
padding: "9px 10px 9px 14px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: "8px",
|
gap: 6,
|
||||||
position: "relative",
|
position: "relative",
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
}}>
|
}}>
|
||||||
@ -109,144 +110,191 @@ const TaskHeader: React.FC<TaskHeaderProps> = ({
|
|||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}>
|
}}>
|
||||||
<span style={{ fontWeight: "bold" }}>Task</span>
|
<div
|
||||||
<VSCodeButton
|
style={{
|
||||||
appearance="icon"
|
display: "flex",
|
||||||
onClick={onClose}
|
alignItems: "center",
|
||||||
style={{ marginTop: "-6px", marginRight: "-4px" }}>
|
cursor: "pointer",
|
||||||
|
marginLeft: -2,
|
||||||
|
userSelect: "none",
|
||||||
|
WebkitUserSelect: "none",
|
||||||
|
MozUserSelect: "none",
|
||||||
|
msUserSelect: "none",
|
||||||
|
flexGrow: 1,
|
||||||
|
minWidth: 0, // This allows the div to shrink below its content size
|
||||||
|
}}
|
||||||
|
onClick={() => setIsTaskExpanded(!isTaskExpanded)}>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", flexShrink: 0 }}>
|
||||||
|
<span className={`codicon codicon-chevron-${isTaskExpanded ? "down" : "right"}`}></span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginLeft: 6,
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
flexGrow: 1,
|
||||||
|
minWidth: 0, // This allows the div to shrink below its content size
|
||||||
|
}}>
|
||||||
|
<span style={{ fontWeight: "bold" }}>Task{!isTaskExpanded && ":"}</span>
|
||||||
|
{!isTaskExpanded && <span style={{ marginLeft: 4 }}>{task.text}</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!isTaskExpanded && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
|
backgroundColor: "color-mix(in srgb, var(--vscode-badge-foreground) 70%, transparent)",
|
||||||
|
color: "var(--vscode-badge-background)",
|
||||||
|
padding: "2px 4px",
|
||||||
|
borderRadius: "500px",
|
||||||
|
fontSize: "11px",
|
||||||
|
fontWeight: 500,
|
||||||
|
display: "inline-block",
|
||||||
|
flexShrink: 0,
|
||||||
|
}}>
|
||||||
|
${totalCost?.toFixed(4)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<VSCodeButton appearance="icon" onClick={onClose} style={{ marginLeft: 10, flexShrink: 0 }}>
|
||||||
<span className="codicon codicon-close"></span>
|
<span className="codicon codicon-close"></span>
|
||||||
</VSCodeButton>
|
</VSCodeButton>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{isTaskExpanded && (
|
||||||
ref={textContainerRef}
|
<>
|
||||||
style={{
|
|
||||||
fontSize: "var(--vscode-font-size)",
|
|
||||||
overflowY: isExpanded ? "auto" : "hidden",
|
|
||||||
wordBreak: "break-word",
|
|
||||||
overflowWrap: "anywhere",
|
|
||||||
position: "relative",
|
|
||||||
}}>
|
|
||||||
<div
|
|
||||||
ref={textRef}
|
|
||||||
style={{
|
|
||||||
display: "-webkit-box",
|
|
||||||
WebkitLineClamp: isExpanded ? "unset" : 3,
|
|
||||||
WebkitBoxOrient: "vertical",
|
|
||||||
overflow: "hidden",
|
|
||||||
whiteSpace: "pre-wrap",
|
|
||||||
wordBreak: "break-word",
|
|
||||||
overflowWrap: "anywhere",
|
|
||||||
}}>
|
|
||||||
{task.text}
|
|
||||||
</div>
|
|
||||||
{!isExpanded && showSeeMore && (
|
|
||||||
<div
|
<div
|
||||||
|
ref={textContainerRef}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
marginTop: -2,
|
||||||
right: 0,
|
fontSize: "var(--vscode-font-size)",
|
||||||
bottom: 0,
|
overflowY: isTextExpanded ? "auto" : "hidden",
|
||||||
display: "flex",
|
wordBreak: "break-word",
|
||||||
alignItems: "center",
|
overflowWrap: "anywhere",
|
||||||
|
position: "relative",
|
||||||
}}>
|
}}>
|
||||||
<div
|
<div
|
||||||
|
ref={textRef}
|
||||||
style={{
|
style={{
|
||||||
width: 30,
|
display: "-webkit-box",
|
||||||
height: "1.2em",
|
WebkitLineClamp: isTextExpanded ? "unset" : 3,
|
||||||
background:
|
WebkitBoxOrient: "vertical",
|
||||||
"linear-gradient(to right, transparent, var(--vscode-badge-background))",
|
overflow: "hidden",
|
||||||
}}
|
whiteSpace: "pre-wrap",
|
||||||
/>
|
wordBreak: "break-word",
|
||||||
|
overflowWrap: "anywhere",
|
||||||
|
}}>
|
||||||
|
{task.text}
|
||||||
|
</div>
|
||||||
|
{!isTextExpanded && showSeeMore && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: 30,
|
||||||
|
height: "1.2em",
|
||||||
|
background:
|
||||||
|
"linear-gradient(to right, transparent, var(--vscode-badge-background))",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
color: "var(--vscode-textLink-foreground)",
|
||||||
|
paddingRight: 0,
|
||||||
|
paddingLeft: 3,
|
||||||
|
backgroundColor: "var(--vscode-badge-background)",
|
||||||
|
}}
|
||||||
|
onClick={() => setIsTextExpanded(!isTextExpanded)}>
|
||||||
|
See more
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{isTextExpanded && showSeeMore && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
color: "var(--vscode-textLink-foreground)",
|
color: "var(--vscode-textLink-foreground)",
|
||||||
paddingRight: 0,
|
marginLeft: "auto",
|
||||||
paddingLeft: 3,
|
textAlign: "right",
|
||||||
backgroundColor: "var(--vscode-badge-background)",
|
paddingRight: 2,
|
||||||
}}
|
}}
|
||||||
onClick={() => setIsExpanded(!isExpanded)}>
|
onClick={() => setIsTextExpanded(!isTextExpanded)}>
|
||||||
See more
|
See less
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{isExpanded && showSeeMore && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
color: "var(--vscode-textLink-foreground)",
|
|
||||||
marginLeft: "auto",
|
|
||||||
textAlign: "right",
|
|
||||||
paddingRight: 2,
|
|
||||||
}}
|
|
||||||
onClick={() => setIsExpanded(!isExpanded)}>
|
|
||||||
See less
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{task.images && task.images.length > 0 && <Thumbnails images={task.images} />}
|
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "center",
|
|
||||||
}}>
|
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
|
|
||||||
<span style={{ fontWeight: "bold" }}>Tokens:</span>
|
|
||||||
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
|
||||||
<i
|
|
||||||
className="codicon codicon-arrow-up"
|
|
||||||
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-2px" }}
|
|
||||||
/>
|
|
||||||
{tokensIn?.toLocaleString()}
|
|
||||||
</span>
|
|
||||||
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
|
||||||
<i
|
|
||||||
className="codicon codicon-arrow-down"
|
|
||||||
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-2px" }}
|
|
||||||
/>
|
|
||||||
{tokensOut?.toLocaleString()}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{(apiConfiguration?.apiProvider === "openai" || apiConfiguration?.apiProvider === "ollama") && (
|
|
||||||
<ExportButton />
|
|
||||||
)}
|
)}
|
||||||
</div>
|
{task.images && task.images.length > 0 && <Thumbnails images={task.images} />}
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
||||||
{(doesModelSupportPromptCache || cacheReads !== undefined || cacheWrites !== undefined) && (
|
<div
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
|
style={{
|
||||||
<span style={{ fontWeight: "bold" }}>Cache:</span>
|
display: "flex",
|
||||||
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
justifyContent: "space-between",
|
||||||
<i
|
alignItems: "center",
|
||||||
className="codicon codicon-database"
|
}}>
|
||||||
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-1px" }}
|
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
|
||||||
/>
|
<span style={{ fontWeight: "bold" }}>Tokens:</span>
|
||||||
+{(cacheWrites || 0)?.toLocaleString()}
|
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
||||||
</span>
|
<i
|
||||||
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
className="codicon codicon-arrow-up"
|
||||||
<i
|
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-2px" }}
|
||||||
className="codicon codicon-arrow-right"
|
/>
|
||||||
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: 0 }}
|
{tokensIn?.toLocaleString()}
|
||||||
/>
|
</span>
|
||||||
{(cacheReads || 0)?.toLocaleString()}
|
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
||||||
</span>
|
<i
|
||||||
</div>
|
className="codicon codicon-arrow-down"
|
||||||
)}
|
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-2px" }}
|
||||||
{apiConfiguration?.apiProvider !== "openai" && apiConfiguration?.apiProvider !== "ollama" && (
|
/>
|
||||||
<div
|
{tokensOut?.toLocaleString()}
|
||||||
style={{
|
</span>
|
||||||
display: "flex",
|
</div>
|
||||||
justifyContent: "space-between",
|
{(apiConfiguration?.apiProvider === "openai" ||
|
||||||
alignItems: "center",
|
apiConfiguration?.apiProvider === "ollama") && <ExportButton />}
|
||||||
}}>
|
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
|
|
||||||
<span style={{ fontWeight: "bold" }}>API Cost:</span>
|
|
||||||
<span>${totalCost?.toFixed(4)}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<ExportButton />
|
|
||||||
|
{(doesModelSupportPromptCache || cacheReads !== undefined || cacheWrites !== undefined) && (
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" }}>
|
||||||
|
<span style={{ fontWeight: "bold" }}>Cache:</span>
|
||||||
|
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
||||||
|
<i
|
||||||
|
className="codicon codicon-database"
|
||||||
|
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: "-1px" }}
|
||||||
|
/>
|
||||||
|
+{(cacheWrites || 0)?.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
<span style={{ display: "flex", alignItems: "center", gap: "3px" }}>
|
||||||
|
<i
|
||||||
|
className="codicon codicon-arrow-right"
|
||||||
|
style={{ fontSize: "12px", fontWeight: "bold", marginBottom: 0 }}
|
||||||
|
/>
|
||||||
|
{(cacheReads || 0)?.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{apiConfiguration?.apiProvider !== "openai" &&
|
||||||
|
apiConfiguration?.apiProvider !== "ollama" && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
|
||||||
|
<span style={{ fontWeight: "bold" }}>API Cost:</span>
|
||||||
|
<span>${totalCost?.toFixed(4)}</span>
|
||||||
|
</div>
|
||||||
|
<ExportButton />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
</>
|
||||||
</div>
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* {apiProvider === "kodu" && (
|
{/* {apiProvider === "kodu" && (
|
||||||
<div
|
<div
|
||||||
@ -284,10 +332,12 @@ const ExportButton = () => (
|
|||||||
<VSCodeButton
|
<VSCodeButton
|
||||||
appearance="icon"
|
appearance="icon"
|
||||||
onClick={() => vscode.postMessage({ type: "exportCurrentTask" })}
|
onClick={() => vscode.postMessage({ type: "exportCurrentTask" })}
|
||||||
style={{
|
style={
|
||||||
marginBottom: "-2px",
|
{
|
||||||
marginRight: "-2.5px",
|
// marginBottom: "-2px",
|
||||||
}}>
|
// marginRight: "-2.5px",
|
||||||
|
}
|
||||||
|
}>
|
||||||
<div style={{ fontSize: "10.5px", fontWeight: "bold", opacity: 0.6 }}>EXPORT</div>
|
<div style={{ fontSize: "10.5px", fontWeight: "bold", opacity: 0.6 }}>EXPORT</div>
|
||||||
</VSCodeButton>
|
</VSCodeButton>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user