Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 5 additions & 113 deletions webview-ui/src/components/common/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { memo, useEffect, useRef, useCallback, useState } from "react"
import styled from "styled-components"
import { useCopyToClipboard } from "@src/utils/clipboard"
import { getHighlighter, isLanguageLoaded, normalizeLanguage, ExtendedLanguage } from "@src/utils/highlighter"
import { bundledLanguages } from "shiki"
import { getHighlighter, isLanguageLoaded, normalizeLanguage } from "@src/utils/highlighter"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unused imports should be removed:

  • WrapText and AlignJustify from lucide-react (no longer used after removing word wrap toggle)
  • ExtendedLanguage from highlighter utils (no longer used after removing language selection)
  • bundledLanguages from shiki (was only used for the language dropdown)

import type { ShikiTransformer } from "shiki"
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
import { Fragment, jsx, jsxs } from "react/jsx-runtime"
import { ChevronDown, ChevronUp, WrapText, AlignJustify, Copy, Check } from "lucide-react"
import { ChevronDown, ChevronUp, Copy, Check } from "lucide-react"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ChevronDown, ChevronUp, Copy, Check imports from lucide-react should be cleaned up to remove the unused WrapText and AlignJustify icons:

import { useAppTranslation } from "@src/i18n/TranslationContext"
import { StandardTooltip } from "@/components/ui"

Expand Down Expand Up @@ -38,7 +37,6 @@ interface CodeBlockProps {
initialWordWrap?: boolean
collapsedHeight?: number
initialWindowShade?: boolean
onLanguageChange?: (language: string) => void
}

const CodeBlockButton = styled.button`
Expand Down Expand Up @@ -167,52 +165,6 @@ export const StyledPre = styled.div<{
}
`

const LanguageSelect = styled.select`
font-size: 12px;
color: var(--vscode-foreground);
opacity: 0.4;
font-family: monospace;
appearance: none;
background: transparent;
border: none;
cursor: pointer;
padding: 4px;
margin: 0;
vertical-align: middle;
height: 24px;

& option {
background: var(--vscode-editor-background);
color: var(--vscode-foreground);
padding: 0;
margin: 0;
}

&::-webkit-scrollbar {
width: 6px;
}

&::-webkit-scrollbar-thumb {
background: var(--vscode-scrollbarSlider-background);
}

&::-webkit-scrollbar-track {
background: var(--vscode-editor-background);
}

&:hover {
opacity: 1;
background: var(--vscode-toolbar-hoverBackground);
border-radius: 3px;
}

&:focus {
opacity: 1;
outline: none;
border-radius: 3px;
}
`

const CodeBlock = memo(
({
source,
Expand All @@ -222,12 +174,11 @@ const CodeBlock = memo(
initialWordWrap = true,
initialWindowShade = true,
collapsedHeight,
onLanguageChange,
}: CodeBlockProps) => {
const [wordWrap, setWordWrap] = useState(initialWordWrap)
// Use word wrap from props, default to true
const wordWrap = initialWordWrap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider documenting why wordWrap is now effectively read-only. The component accepts initialWordWrap but users can no longer toggle it. If this is intentional, a comment explaining the design decision would be helpful.

const [windowShade, setWindowShade] = useState(initialWindowShade)
const [currentLanguage, setCurrentLanguage] = useState<ExtendedLanguage>(() => normalizeLanguage(language))
const userChangedLanguageRef = useRef(false)
const currentLanguage = normalizeLanguage(language)
const [highlightedCode, setHighlightedCode] = useState<React.ReactNode>(null)
const [showCollapseButton, setShowCollapseButton] = useState(true)
const codeBlockRef = useRef<HTMLDivElement>(null)
Expand All @@ -240,16 +191,6 @@ const CodeBlock = memo(
const collapseTimeout1Ref = useRef<NodeJS.Timeout | null>(null)
const collapseTimeout2Ref = useRef<NodeJS.Timeout | null>(null)

// Update current language when prop changes, but only if user hasn't
// made a selection.
useEffect(() => {
const normalizedLang = normalizeLanguage(language)

if (normalizedLang !== currentLanguage && !userChangedLanguageRef.current) {
setCurrentLanguage(normalizedLang)
}
}, [language, currentLanguage])

// Syntax highlighting with cached Shiki instance and mounted state management
useEffect(() => {
// Set mounted state at the beginning of this effect
Expand Down Expand Up @@ -707,48 +648,6 @@ const CodeBlock = memo(
ref={copyButtonWrapperRef}
onMouseOver={() => updateCodeBlockButtonPosition()}
style={{ gap: 0 }}>
<LanguageSelect
value={currentLanguage}
style={{
width: `calc(${currentLanguage?.length || 0}ch + 9px)`,
}}
onClick={(e) => {
e.currentTarget.focus()
}}
onChange={(e) => {
const newLang = normalizeLanguage(e.target.value)
userChangedLanguageRef.current = true
setCurrentLanguage(newLang)
if (onLanguageChange) {
onLanguageChange(newLang)
}
}}>
<option
value={normalizeLanguage(language)}
style={{ fontWeight: "bold", textAlign: "left", fontSize: "1.2em" }}>
{normalizeLanguage(language)}
</option>
{
// Display all available languages in alphabetical order
Object.keys(bundledLanguages)
.sort()
.map((lang) => {
const normalizedLang = normalizeLanguage(lang)
return (
<option
key={normalizedLang}
value={normalizedLang}
style={{
fontWeight: normalizedLang === currentLanguage ? "bold" : "normal",
textAlign: "left",
fontSize: normalizedLang === currentLanguage ? "1.2em" : "inherit",
}}>
{normalizedLang}
</option>
)
})
}
</LanguageSelect>
{showCollapseButton && (
<StandardTooltip
content={t(`chat:codeblock.tooltips.${windowShade ? "expand" : "collapse"}`)}
Expand Down Expand Up @@ -787,13 +686,6 @@ const CodeBlock = memo(
</CodeBlockButton>
</StandardTooltip>
)}
<StandardTooltip
content={t(`chat:codeblock.tooltips.${wordWrap ? "disable_wrap" : "enable_wrap"}`)}
side="top">
<CodeBlockButton onClick={() => setWordWrap(!wordWrap)}>
{wordWrap ? <AlignJustify size={16} /> : <WrapText size={16} />}
</CodeBlockButton>
</StandardTooltip>
<StandardTooltip content={t("chat:codeblock.tooltips.copy_code")} side="top">
<CodeBlockButton onClick={handleCopy}>
{showCopyFeedback ? <Check size={16} /> : <Copy size={16} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ vi.mock("../../../i18n/TranslationContext", () => ({
"chat:codeblock.tooltips.copy_code": "Copy code",
"chat:codeblock.tooltips.expand": "Expand code block",
"chat:codeblock.tooltips.collapse": "Collapse code block",
"chat:codeblock.tooltips.enable_wrap": "Enable word wrap",
"chat:codeblock.tooltips.disable_wrap": "Disable word wrap",
}
return translations[key] || key
},
Expand Down
2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/ca/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/de/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/en/chat.json
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,6 @@
"tooltips": {
"expand": "Expand code block",
"collapse": "Collapse code block",
"enable_wrap": "Enable word wrap",
"disable_wrap": "Disable word wrap",
"copy_code": "Copy code"
}
},
Expand Down
2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/es/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/fr/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/hi/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/id/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/it/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/ja/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/ko/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/nl/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/pl/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/pt-BR/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/ru/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/tr/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/vi/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/zh-CN/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions webview-ui/src/i18n/locales/zh-TW/chat.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading